-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Path with space completion fix for REPL #8838
Conversation
function shell_parse(raw::String, interp::Bool) | ||
s = strip(raw) | ||
function shell_parse(raw::String, interp::Bool; strip_r::Bool=true) | ||
s = strip_r ? strip(raw) : lstrip(raw) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why wouldn't you just call the strip function on the argument before calling this function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just need the function not to strip the last space away when "\\ "
occurs. I just need to disable the strip it do on the raw variable. I could do the following and then just strip the input string before it is sent to the function.
function shell_parse(raw::String, interp::Bool; should_strip::Bool=true)
s = should_strip ? strip(raw) : raw
And then the keyword argument is just a bool that controls whether the string should be stripped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, that's a pointless option: if you want to strip the argument before doing anything else, then strip it before passing it to the function. You can write the call site like this:
Base.shell_parse(endswith(scs, "\\ ") ? strip(scs) : scs, true)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point is that today it look like:
function shell_parse(raw::String, interp::Bool)
s = strip(raw)
This means that the string is default stripped in both ends, but I would like to keep the last space in when the string endswith(scs, "\\ ")
scs="C:\\Progam\\ "
and today I cannot force it not to strip the last space away in the string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any transformation of the string to be parsed to be done before passing it to the parsing function can be done without complicating the signature of the parsing function. Please do it that way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm slightly suspicious that shell parse is involved in parsing this in the first place, but that's a different story.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes exactly, I will change it to you suggestion @StefanKarpinski.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the stripping respect quoting with \
? It seems like it should. Maybe that's the only problem here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because that's how the shell parses things: if strips leading and trailing whitespace and then splits on spaces (modulo quoting).
not quite, the shell has to be able to gracefully handle files that end in spaces. I can make a file "a "
, and a file "a"
, and bash can tell the difference:
~/Documents/no-backup/julia$ cat a
I'm a
~/Documents/no-backup/julia$ cat a\
I'm a_space
dropping the trailing spaces can even lead to bugs: http://www.exploit-monday.com/2013/02/WindowsFileConfusion.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case, the correct fix here does seem to be to make sure that quoted spaces are respected by shell_parse
.
I have now fixed the
|
Still not quite what I had in mind. I'll take a crack at it later. |
f333eec
to
1289276
Compare
1289276
to
adca441
Compare
I have rebased and simplified the code and made some test cases. @StefanKarpinski did you get time for making the
For completion in strings it works perfectly. If it gets merged without a version of the |
Sorry, I haven't gotten around to this yet. However, the correct way to fix this issue is to get rid of the whitespace stripping I originally put in and instead build whitespace stripping into the |
Yes it strips whitespaces from the front and from the end it strips the whitespaces but it respects the backslash escaped spaces. |
Ah, ok, carry on then. I approve of this approach. Sorry for snoozing on this so long – I swear last I looked it didn't work this way! |
@tkelman, can you sanity check this and merge if it seems reasonable? |
I'll add it to my list of things to test after 0.3.3. |
Awesome good work at 0.3.3 👍 |
@dhoegh this works pretty nicely, I like it. Thanks for your continued improvements here! |
Path with space completion fix for REPL
@tkelman you are very fast:+1:, should it be backported to 0.3.4? |
@dhoegh possibly but not right away, let's wait for people to run with it on master for a few days at least. |
Whoops, I merged this too soon, no backporting until the bug mentioned here #9137 (comment) is fixed |
Fix error regarding unescape_string introduced by #8838
@@ -187,12 +187,13 @@ function completions(string, pos) | |||
partial = string[1:pos] | |||
inc_tag = Base.incomplete_tag(parse(partial , raise=false)) | |||
if inc_tag in [:cmd, :string] | |||
startpos = nextind(partial, rsearch(partial, non_filename_chars, pos)) | |||
m = match(r"[\t\n\r\"'`@\$><=;|&\{]| (?!\\)",reverse(partial)) | |||
startpos = length(partial)-(m == nothing ? 1 : m.offset) + 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ivarne, @tkelman I think I have made the same mistanke here it should properly be:
startpos = nextind(partial, nextind(partial, length(partial) - (m == nothing ? 1 : m.offset)))
It does not crash the REPL but it can't complete on "ß C:\\
.
Sorry about the mess I made now I understand the difficulties in indexing in strings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't crash when it should, because of #7811.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since m.offset is guaranteed to be the offset of an ASCII character (that's what you were searching for), and ASCII characters are always represented by a single code unit in UTF-xx, isn't length(partial) - (m == nothing ? 1 : m.offset) + 2
endof(s) - start + 1
nextind(s,endof(s)) - start
okay here?
This fixes completion for paths with spaces in both shell mode and julia mode ex:
The main changes is in the
completions
that is used when completing in julia mode. The changes to get it working in shell mode is only 5 lines. If any of you have time to look at it @tkelman, @lucasb-eyer it would be greatly appreciated.@StefanKarpinski could you approve the changes I made in the
shell_parse
? The main reason for the change is when a string is parsed to theshell_parse
function like:"C:\\Progams\\ "
this would throw an error before due to the ending space is removed and then the string has a dangling\
. To prevent it from removing the space I use the keyword argument like:Base.shell_parse(string[r], true, strip_r=!endswith(string[r], "\\ ")
and then it do not trim the space away when the string ends on"\\ "
.