diff options
author | Guido Cella <guido@guidocella.xyz> | 2023-11-29 19:14:47 +0100 |
---|---|---|
committer | Dudemanguy <random342@airmail.cc> | 2023-12-15 15:44:48 +0000 |
commit | b09deda37a068fb5b88f8dfaaf579b87079eae82 (patch) | |
tree | ecb5963deecd45e9fa86d10ee2af8ad429746a7d /player/lua | |
parent | f805b180d00b10bdd0b5fa01197f5b53188d44f8 (diff) | |
download | mpv-b09deda37a068fb5b88f8dfaaf579b87079eae82.tar.bz2 mpv-b09deda37a068fb5b88f8dfaaf579b87079eae82.tar.xz |
console.lua: implement case-insensitive completion
This is useful for completing files and more rarely for profiles. It
will also be useful to third-party scripts interacting with the console
once the API to do it is merged.
Diffstat (limited to 'player/lua')
-rw-r--r-- | player/lua/console.lua | 74 |
1 files changed, 58 insertions, 16 deletions
diff --git a/player/lua/console.lua b/player/lua/console.lua index f7b2da9693..ef1a43a710 100644 --- a/player/lua/console.lua +++ b/player/lua/console.lua @@ -27,6 +27,7 @@ local opts = { -- multiplied by "scale". font_size = 16, border_size = 1, + case_sensitive = true, -- Remove duplicate entries in history as to only keep the latest one. history_dedup = true, -- The ratio of font height to font width. @@ -49,6 +50,7 @@ end local platform = detect_platform() if platform == 'windows' then opts.font = 'Consolas' + opts.case_sensitive = false elseif platform == 'darwin' then opts.font = 'Menlo' else @@ -901,30 +903,70 @@ function build_completers() return completers end --- Use 'list' to find possible tab-completions for 'part.' --- Returns a list of all potential completions and the longest --- common prefix of all the matching list items. -function complete_match(part, list) - local completions = {} +-- Find the longest common case-sensitive prefix of the entries in "list". +local function find_common_prefix(part, list) local prefix = nil for _, candidate in ipairs(list) do - if candidate:sub(1, part:len()) == part then - if prefix and prefix ~= candidate then - local prefix_len = part:len() - while prefix:sub(1, prefix_len + 1) - == candidate:sub(1, prefix_len + 1) do - prefix_len = prefix_len + 1 - end - prefix = candidate:sub(1, prefix_len) - else - prefix = candidate + if prefix and prefix ~= candidate then + local prefix_len = part:len() + while prefix:sub(1, prefix_len + 1) == candidate:sub(1, prefix_len + 1) do + prefix_len = prefix_len + 1 end + prefix = candidate:sub(1, prefix_len) + else + prefix = candidate + end + end + + return prefix +end + +-- Return the entries of "list" beginning with "part" and the longest common +-- prefix of the matches. +local function complete_match(part, list) + local completions = {} + + for _, candidate in pairs(list) do + if candidate:sub(1, part:len()) == part then completions[#completions + 1] = candidate end end - return completions, prefix + local prefix = find_common_prefix(part, completions) + + if opts.case_sensitive then + return completions, prefix + end + + completions = {} + local lower_case_completions = {} + local lower_case_part = part:lower() + + for _, candidate in pairs(list) do + if candidate:sub(1, part:len()):lower() == lower_case_part then + completions[#completions + 1] = candidate + lower_case_completions[#lower_case_completions + 1] = candidate:lower() + end + end + + local lower_case_prefix = find_common_prefix(lower_case_part, + lower_case_completions) + + -- Behave like GNU readline with completion-ignore-case On. + -- part = 'fooBA', completions = {'foobarbaz', 'fooBARqux'} => + -- prefix = 'fooBARqux', lower_case_prefix = 'foobar', return 'fooBAR' + if prefix then + return completions, prefix:sub(1, lower_case_prefix:len()) + end + + -- part = 'fooba', completions = {'fooBARbaz', 'fooBarqux'} => + -- prefix = nil, lower_case_prefix ='foobar', return 'fooBAR' + if lower_case_prefix then + return completions, completions[1]:sub(1, lower_case_prefix:len()) + end + + return {}, part end function common_prefix_length(s1, s2) |