I'm using cmd library to create simple command line interface with code completion. Problem occurs when command argument contains special characters. Code completion runs only on last part separated by these special characters.
Here is simple code to test it:
class Test(Cmd):
def complete_test(self, text, line, b, e):
print(text)
print(line)
print(b)
print(e)
Type test and argument containing, for example, slash. Only last part after / is included in text, and if you return something, only this last part gets replaced.
I used comments under this answer to fix problems with other special characters. But I can't just do readline.set_completer_delims(""), because code completion does not work. I need to at least set space as delimiter (readline.set_completer_delims(" ")), so that it code completion finds where argument starts. But now I can't pass paths containing spaces (see my completion code below):
def complete_export(self, text:str, line:str, begidx, endidx):
return [x for x in glob(text + "*") if x.startswith(text)]
My export command only requires one argument - path, so ideal behavior would be to consider first space as beginning of argument and other spaces would be considered part of path.
Note: I have realized that it's possible to use line argument, and extract path manually, but code completion would still replace only last part, so path would have to be edited. I submitted this as an answer, but it's not very elegant solution.
Here is solution manually separating path from line, performing globbing and returning only parts of path after spaces that are already present. One problem is, that if paths contain spaces, if you press tab twice, you get suggestions only for rest of text after space. Depending on use case, this might be problem.
def complete_export(self, text:str, line:str, begidx, endidx):
path = line[line.find(" ")+1:] # get everything after space
return [" ".join(x.split(" ")[(line.count(" ") - 1):]) for x in glob(path + "*")] # completion suggestions after last space
Related
I have started using pylatex four days ago to automate report generation (I have no earlier experience in latex as well). The text that I want to enter in the latex report has been generated by an online server and stored in my file as a text file. In the text file, there exist places with more than one simultaneous space for proper formatting and aligning (Protein Sequence Alignment). Hence, while simply trying to use .append, pylatex seems to ignore all the extra spaces on its own. I searched the internet with various relevant terms, but could not find any answer for pylatex. I did find some latex answers, exploring which I tried to incorporate pylatex's NoEscape and explicitly replacing " " (double spaces) with " \space ", it seems to work for some lines as expected, but not for others (maybe some of the places have \ (or some other special characters for latex) which are expected to be meaningful but could not understand what it actually means since it does not even exist (for example \clo). Can someone please suggest a method where I can simply allow the simultaneous existence of the spaces, which is also visible in the final document without the need to think about the existence of a possible special character that needs to be escaped. The following code snippets that I used might be of use to answer/understand my query.
i = 0
with doc.create(Subsection('Details')):
with open(whatcheck_detail, 'r') as fh:
lines = fh.read().split("#")[1:]
for line in lines:
i += 1
line = line.replace(" ", " \space ").replace("#", "\#") + "\n"
if "Note:" in line:
print(i)
# doc.append(TextColor(line))
doc.append(NoEscape(line))
elif "Warning:" in line:
print(i)
# line = "\color{blue} " + line
doc.append(NoEscape(line))
# doc.append(TextColor("blue", line))
elif "Error:" in line:
print(i)
# line = "\color{red} " + line
doc.append(NoEscape(line))
# doc.append(TextColor("red", line))
And the following is the screenshot of the last part of the error report.
Error Description upon running the above script.
Following are the images of what is happening by using the simple pylatex code doc.append(TextColor("color", line)), and what is actually in the text file (which is how I want it to be on PDF generated by latex/pylatex).
What is happening to the text in the output file.
What is in the text file, or how do I want it.
Thank you!
if file is not None:
content = file.readlines()
if 'I' and 'J' in content:
display_oval()
else:
display_polygon()
in this case,suppose i opened a file containing I&J . i expect to call display_oval() but it calls display_polygon(). when i opened file not containing I&J,display_polygon() calls as expected.
when i replaced 'I' and 'J'with 'I' or 'J',when i opened a file containing I&J,display_oval() works fine. But when i opened file not containing I&J, nothing works.
I want to call display_oval()if file contains I&J and display_polygon()otherwise. how it can be done?
You have a couple of intersecting issues with your code.
Thie first issue is that 'I' and 'J' in content gets grouped as ('I') and ('J' in content), which is surely not what you intend. A string like 'I' is always truthy, so testing in that way is not useful. You probably mean 'I' in content and 'J' in content`.
But that's not enough to fix your code (it makes fewer inputs match, not more). The condition will still not work right because your content is a list of strings, all but the last of which will be newline terminated. When done on a list, the in operator expects exact matches, not substring matches as in does when both arguments are strings.
I'm not exactly sure what fix would be best for that second issue. It depends on the logic of your program, and the contents of your file. If you want to test if I and J show up as individual lines in the file (each separately, on a line with no other characters), you might want to test for 'I\n' in content and 'J\n' in content using the same content you're using now. On the other hand, if you want to check for a capital I and J characters anywhere in the text of the file, without regard to lines, then you probably need to change content instead of changing the matching logic. Use content = file.read() to read the whole file into a single string, rather than a list of strings. Then 'I' in content will do a substring search.
I'm going through lpthw and am messing with the open() function. The code I copied includes "target = open(filename, 'd'). I'm wondering why I have to include the 'd'?
I copied this code directly from the book. When I remove the 'd', the code fails, but I can't find any explanation of why it's necessary. I changed the 'd' to another letter and the code works fine.
from sys import argv
script, filename = argv
print(f"We're going to erase {filename}.")
print("If you don't want that, hit CTRL-C (^C).")
print("If you do want that, hit RETURN.")
input("?")
print("Opening the file...")
target = open(filename, 'd')
print("Truncating the file. Goodbye!")
target.truncate()
The second argument ('d') is a mode which tells the interpreter and developer which way the file will be used.
Mode :
Including a mode argument is optional because a default value of ‘r’ will be assumed if it is omitted. The ‘r’ value stands for read mode, which is just one of many.
I have a function that prints the number of pixels found in an image and then asks the user how they would like to proceed. As long as the interpreter hasn't moved on from the function I want all the output to be indented accordingly.
One such 'sub output' (the input prompt) needs to be multiple lines. So I kick off with the 3*quote (''') followed by two spaces to create the indentation. At the end of the question 'how would you like to proceed?' I use a hard return. An extra indentation is assumed by the text editor so I remove it causing the following list of suggestions to line up flush with the input variable command. Here's how it looks:
def returnColors():
#
# lots of code that does stuff...
#
print("The source image contains", lSize, "px.")
print("")
command=input(''' What would you like to do? You can say:
get all
get unique
''')
The problem with this is that the interpreter is acknowledging the indentation that separates the function body from the function statement as actual string contents, causing the output to look like this:
The source image contains 512 px.
What would you like to do? You can say...
get all
get unique
|
The only way to avoid this is by breaking indentation in the interpreter. Although I know it works, it doesn't look very good. So what options do I have?
EDIT: Just because I have the screenshot_
One thing that you should keep in mind is that once you have start a multiline string declaration, all the text until it is closed is taken as is and syntax (ie, indentation) is no longer considered.
You can start your multiline with an explicit new line so that everything in the multiline string can be indented together in code.
IE.
command=input('''
What would you like to do? You can say:
get all
get unique
''')
would print out the prompt with a new line on top, but the formatting of the text is more explicitly shown and should appear as seen.
OR you could use the \n for each new line in the string to get it formatted more correctly and remember to use a single \ after each new line. E.g.
instead of:
''' What would you like to do? You can say:
get all
get unique
'''
Try
' What would you like to do? You can say:\
\n\
\n get all\
\n get unique\
\n'
The indent won't matter, no matter where you use \n at the beginning of new line, the input() will output the same. This is will give the same input() string:
' What would you like to do? You can say:\
\n\
\n get all\
\n get unique\
\n'
I wanted to find a line, then match several words within that line BUT instead of substituting them I would prefer to simply save them (by appending to a register, or exporting to a file).
Is back-referencing (i.e. submatch(1) or \1) doable in this regards, or is that only through the substitution? I realize I could substitute back to the file I am working on - altering it - but I would prefer to export it.
Is there a way to call a function (to save the submatch) within substitute without damaging the file? Or, preferably, use the global search to capture a portion of the line and then pass that as a parameter onto a function call that would do the saving as desired?
Try
:%s/pattern \(saved portion\)/\=[submatch(0), SaverFunc(submatch(1))][0]/
or
:%s/pattern \(saved portion\)\zs/\=SaverFunc(submatch(1))[-1]
. In last case SaverFunc must return either string or number (without explicit :return statement it will return number 0). It does not matter which string or number will be returned: string_or_number[-1] always expands to an empty string.
You might be looking for :h :global and do something like this:
:g/pattern/call func_to_get_and_save_text()
That would call the function on every line matching the given pattern.