Open stevengj opened 7 years ago
The issue is that REPLCompletion is looking from the end of the string until it reaches a character that cannot be in a filename. This allows for things like:
julia> touch("test.txt")
julia> "testfile = te<tab>"
The exact code for this behavior is REPLCompletion#L459.
I'm still confused. Why does it think =
is a "character that cannot be in a filename"?
The regex seems to be to restrictive. Maybe it should be changed to:
m = match(r"[:*?<>|]| (?!\\)", reverse(partial))
Why not just look for the beginning of the string?
Because the then it will also look to the start of a cmd string. This would remove ability to `ls C:\\User<tab>
You could look for the beginning "
. If you find a beginning `
instead, you could backtrack and look for whitespace (since unquoted Cmd
arguments are whitespace-separated.)
@stevengj something like commit 0047250?
It still is looking for characters like !
... I'm thinking more along the lines of:
# Search backwards in s for the beginning " of a string.
# If incmd is true, then alternatively looks for a beginning `,
# and if so looks for whitespace. Returns the starting position
# (the first character after the opening ")
function findstartstring(s, incmd)
i = endof(s)
i = incmd ? rsearch(s, ('"','`'), i) : rsearch(s, '"', i)
if incmd && i > start(s) && s[i] == '`'
i = findlast(isspace, s)
end
return nextind(s, i)
end
The regex do not look for !
. The (?!\\)
part of the regex is a negative look ahead. That ensures it do not match an escaped character like \"
. See the explanation from regex101.
This it quite important to find the start of the string and not just a "
in the string. The input to the function could look like: "s=\"test\\\"
which is equivalent to writing s="test\"
in the console. To get whole string we need to consider whether "
is escaped.
Ah, I see. In the Cmd
case shouldn't it be r"[\"`\s](?!\\)"
then?
My first thought was the same, but as quotes has special meaning inside backticks it is unfortunately not as simple. Because a space inside quotes is still a valid path. I have implemented a quote aware completion in backticks in https://github.com/dhoegh/julia/commit/3639605272a99b1d4e473f0f39d89d91ba3d1d84, if you agree with the approach I will submit it as a PR.
Just came across a similar situation (perhaps the same issue). If I have two files called bar10
and bar20
, tab completion first completes bar
. If I press tab again, I get both names listed; if I press 1
and press tab again, it completes bar10
.
If, however, the files are called foo bar10
and foo bar20
, this doesn't work. It completes foo bar
, but then tab doesn't do anything, and pressing 1
doesn't help.
Interestingly, if I have the files bar10
and bar20
there, still, the tab completion thinks that the last half of the completed name (i.e., bar
) is the beginning of one of them, producing the same behavior as initially.
I noticed this when looking at JuliaLang/IJulia.jl#557 (cc @kalmarek). In the REPL:
completes to
"r=22222"
even though there is no such filename. Specifically,Base.REPLCompletions.completions("\"r=2", 4)
returns(String["22222\""], 4:4, true)
if the file"22222"
is the only file beginning with"2"
in the current directory.Seems to occur in Julia 0.4–0.7. cc @Keno