Skip to content

Commit

Permalink
add old-repl path completion behavior to new-repl
Browse files Browse the repository at this point in the history
Cf. #5343
  • Loading branch information
nolta committed Mar 26, 2014
1 parent 320b519 commit 2c22b90
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 25 deletions.
90 changes: 74 additions & 16 deletions base/REPLCompletions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -99,32 +99,90 @@ module REPLCompletions
suggestions
end

function complete_path(path::ByteString)
matches = ByteString[]
dir,prefix = splitdir(path)
if length(dir) == 0
files = readdir()
elseif isdir(dir)
files = readdir(dir)
else
return matches
end
for file in files
if beginswith(file, prefix)
p = joinpath(dir, file)
push!(matches, isdir(p) ? joinpath(p,"") : p)
end
end
matches
end

const non_word_chars = " \t\n\"\\'`@\$><=:;|&{}()[].,+-*/?%^~"

function completions(string,pos)
startpos = pos
startpos = min(pos,1)
dotpos = 0
while startpos >= 1
c = string[startpos]
if c < 0x80 && in(char(c), non_word_chars)
if c != '.'
startpos = nextind(string,startpos)
break
elseif dotpos == 0
dotpos = startpos
instring = false
incmd = false
escaped = false
nearquote = false
i = start(string)
while i <= pos
c,j = next(string, i)
if c == '\\'
if instring
escaped $= true
end
nearquote = false
elseif c == '\''
if !instring
nearquote = true
end
elseif c == '"'
if !escaped && !nearquote && !incmd
instring $= true
end
escaped = nearquote = false
elseif c == '`'
if !escaped && !nearquote && !instring
incmd $= true
end
escaped = nearquote = false
else
escaped = nearquote = false
end
if startpos == 1
break
if c < 0x80
if instring || incmd
if in(c, " \t\n\"\\'`@\$><=;|&{(")
startpos = j
end
elseif in(c, non_word_chars)
if c == '.'
dotpos = i
else
startpos = j
end
end
end
startpos = prevind(string,startpos)
i = j
end

if instring || incmd
r = startpos:pos
paths = complete_path(string[r])
if instring && length(paths) == 1
paths[1] *= "\""
end
return sort(paths), r
end

ffunc = (mod,x)->true
suggestions = UTF8String[]
r = rsearch(string,"using",startpos)
if !isempty(r) && all(isspace,string[nextind(string,last(r)):prevind(string,startpos)])
# We're right after using. Let's look only for packages
# and modules we can reach form here
# and modules we can reach from here

# If there's no dot, we're in toplevel, so we should
# also search for packages
Expand Down Expand Up @@ -166,7 +224,7 @@ module REPLCompletions
files = readdir(dir)
end
# Filter out files and directories that do not begin with the partial name we were
# completiong and append "/" to directories to simplify further completion
# completing and append "/" to directories to simplify further completion
ret = map(filter(x->beginswith(x,name),files)) do x
if !isdir(joinpath(dir,x))
return x
Expand All @@ -175,8 +233,8 @@ module REPLCompletions
end
end
r = (nextind(string,pos-sizeof(name))):pos
return (ret,r,string[r])
elseif isexpr(arg,:escape) && (isexpr(arg.args[1],VERSION >= v"0.3-" ? :incomplete : :continue) || isexpr(arg.args[1],:error))
return (ret,r)
elseif isexpr(arg,:escape) && (isexpr(arg.args[1],:incomplete) || isexpr(arg.args[1],:error))
r = first(last_parse):prevind(last_parse,last(last_parse))
partial = scs[r]
ret, range = completions(partial,endof(partial))
Expand Down
19 changes: 11 additions & 8 deletions base/Readline.jl
Original file line number Diff line number Diff line change
Expand Up @@ -925,14 +925,17 @@ module Readline
# the we could be in the middle of a multi-byte
# sequence, here but that's ok, since any
# whitespace we're interested in is only one byte
if position(buf) != 0
c = buf.data[position(buf)]
else
c = '\n'
end
if c == ' ' || c == '\n' || c == '\t'
edit_insert(s," "^4)
return
i = position(buf)
if i != 0
c = buf.data[i]
if c == '\n' || c == '\t' ||
# hack to allow path completion in cmds
# after a space, e.g., `cd <tab>`, while still

This comment has been minimized.

Copy link
@Keno

Keno Mar 30, 2014

Member

Shouldn't we just change this for shell mode then?

# allowing multiple indent levels
(c == ' ' && i > 3 && buf.data[i-1] == ' ')
edit_insert(s," "^4)
return
end
end
Readline.completeLine(s)
Readline.refresh_line(s)
Expand Down
2 changes: 1 addition & 1 deletion base/file.jl
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ function readdir(path::String)
# The list of dir entries is returned as a contiguous sequence of null-terminated
# strings, the first of which is pointed to by ptr in uv_readdir_req.
# The following lines extracts those strings into dirent
entries = String[]
entries = ByteString[]
offset = 0

for i = 1:file_count
Expand Down

3 comments on commit 2c22b90

@Keno
Copy link
Member

@Keno Keno commented on 2c22b90 Mar 26, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also submit these as pull requests to the appropriate packages?

@nolta
Copy link
Member Author

@nolta nolta commented on 2c22b90 Mar 26, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just about to submit a pull request for this branch.

@Keno
Copy link
Member

@Keno Keno commented on 2c22b90 Mar 26, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Please sign in to comment.