Skip to content

Commit

Permalink
Fixed compat mode for coloring args.
Browse files Browse the repository at this point in the history
In compatibility mode (_deprecated is true), argmatchers need to add
matches using nil as the match type (vs "word" or "arg") so that
compatibility mode can infer how to color the matches.
  • Loading branch information
chrisant996 committed Dec 12, 2020
1 parent 718c8d7 commit c42bf2c
Showing 1 changed file with 70 additions and 6 deletions.
76 changes: 70 additions & 6 deletions clink/lua/scripts/arguments.lua
Original file line number Diff line number Diff line change
Expand Up @@ -390,11 +390,12 @@ function _argmatcher:_generate(line_state, match_builder)
-- could be well out of range.
local matcher = reader._matcher
local arg_index = reader._arg_index
local match_type = ((not matcher._deprecated) and "arg") or nil

-- Are we left with a valid argument that can provide matches?
local add_matches = function(arg)
local add_matches = function(arg, match_type)
for key, _ in pairs(arg._links) do
match_builder:addmatch(key, "arg")
match_builder:addmatch(key, match_type)
end

for _, i in ipairs(arg) do
Expand All @@ -404,9 +405,9 @@ function _argmatcher:_generate(line_state, match_builder)
return j or false
end

match_builder:addmatches(j, "arg")
match_builder:addmatches(j, match_type)
else
match_builder:addmatch(i, "arg")
match_builder:addmatch(i, match_type)
end
end

Expand All @@ -416,12 +417,12 @@ function _argmatcher:_generate(line_state, match_builder)
-- Select between adding flags or matches themselves. Works in conjunction
-- with getwordbreakinfo()'s return.
if matcher._flags and matcher:_is_flag(line_state:getendword()) then
add_matches(matcher._flags._args[1])
add_matches(matcher._flags._args[1], match_type)
return true
else
local arg = matcher._args[arg_index]
if arg then
return add_matches(arg) and true or false
return add_matches(arg, match_type) and true or false
end
end

Expand Down Expand Up @@ -556,6 +557,69 @@ function clink.argmatcher(...)
return matcher
end

--------------------------------------------------------------------------------
--- -name: clink.dirmatches
--- -arg: word:string
--- -ret: table
--- -show: -- Make "cd" generate directory matches (no files).
--- -show: clink.argmatcher("cd")
--- -show: :addflags("/d")
--- -show: :argarg(({ clink.dirmatches })
--- You can use this function in an argmatcher to supply directory matches.
--- This automatically handles Readline tilde completion.
function clink.dirmatches(match_word)
local word = rl.expandtilde(match_word)

local root = path.getdirectory(word) or ""
if expanded then
root = rl.collapsetilde(root)
end

local matches = {}
for _, i in ipairs(os.globdirs(word.."*", true)) do
local m = path.join(root, i.name)
table.insert(matches, { match = m, type = i.type })
end
return matches
end

--------------------------------------------------------------------------------
--- -name: clink.filematches
--- -arg: word:string
--- -ret: table
--- -show: -- Make "foo --file" generate file matches, but other flags and args don't.
--- -show: -- And the third argument can be a file or $stdin or $stdout.
--- -show: clink.argmatcher("foo")
--- -show: :addflags(
--- -show:   "--help",
--- -show:   "--file"..clink.argmatcher():addarg({ clink.filematches })
--- -show: )
--- -show: :addarg({ "one", "won" })
--- -show: :addarg({ "two", "too" })
--- -show: :addarg({ clink.filematches, "$stdin", "$stdout" })
--- You can use this function in an argmatcher to supply file matches. This
--- automatically handles Readline tilde completion.<br/>
--- <br/>
--- Argmatchers default to matching files, so it's unusual to need this
--- function. However, some exceptions are when a flag needs to accept file
--- matches but other flags and arguments don't, or when matches need to include
--- more than files.
function clink.filematches(match_word)
local word = rl.expandtilde(match_word)

local root = path.getdirectory(word) or ""
if expanded then
root = rl.collapsetilde(root)
end

local matches = {}
for _, i in ipairs(os.globfiles(word.."*", true)) do
local m = path.join(root, i.name)
table.insert(matches, { match = m, type = i.type })
end
return matches
end



--------------------------------------------------------------------------------
Expand Down

0 comments on commit c42bf2c

Please sign in to comment.