diff --git a/vendor/clink.lua b/vendor/clink.lua index 83ef0c0..0593ae1 100644 --- a/vendor/clink.lua +++ b/vendor/clink.lua @@ -51,11 +51,37 @@ local function get_unknown_color() end --- --- Makes a string safe to use as the replacement in string.gsub +-- Escapes special characters in a string.gsub `find` parameter, so that it +-- can be matched as a literal plain text string, i.e. disable Lua pattern +-- matching. See "Patterns" (https://www.lua.org/manual/5.2/manual.html#6.4.1). +-- @param {string} text Text to escape +-- @returns {string} Escaped text --- -local function verbatim(s) - s = string.gsub(s, "%%", "%%%%") - return s +local function escape_gsub_find_arg(text) + return text and text:gsub("([-+*?.%%()%[%]$^])", "%%%1") or "" +end + +--- +-- Escapes special characters in a string.gsub `replace` parameter, so that it +-- can be replaced as a literal plain text string, i.e. disable Lua pattern +-- matching. See "Patterns" (https://www.lua.org/manual/5.2/manual.html#6.4.1). +-- @param {string} text Text to escape +-- @returns {string} Escaped text +--- +local function escape_gsub_replace_arg(text) + return text and text:gsub("%%", "%%%%") or "" +end + +--- +-- Perform string.sub, but disable Lua pattern matching and just treat both +-- the `find` and `replace` parameters as a literal plain text replacement. +-- @param {string} str Text in which to perform find and replace +-- @param {string} find Text to find (plain text; not a Lua pattern) +-- @param {string} replace Replacement text (plain text; not a Lua pattern) +-- @returns {string} Copy of the input `str` with `find` replaced by `replace` +--- +local function gsub_plain(str, find, replace) + return string.gsub(str, escape_gsub_find_arg(find), escape_gsub_replace_arg(replace)) end -- Extracts only the folder name from the input Path @@ -153,7 +179,7 @@ local function set_prompt_filter() end if prompt_useHomeSymbol and string.find(cwd, clink.get_env("HOME")) then - cwd = string.gsub(cwd, clink.get_env("HOME"), prompt_homeSymbol) + cwd = gsub_plain(cwd, clink.get_env("HOME"), prompt_homeSymbol) end local uah = '' @@ -176,14 +202,14 @@ local function set_prompt_filter() local version_control = prompt_includeVersionControl and "{git}{hg}{svn}" or "" local prompt = "{uah}{cwd}" .. version_control .. cr .. get_lamb_color() .. "{env}{lamb}\x1b[0m " - prompt = string.gsub(prompt, "{uah}", uah) - prompt = string.gsub(prompt, "{cwd}", cwd) - prompt = string.gsub(prompt, "{env}", env) - clink.prompt.value = string.gsub(prompt, "{lamb}", prompt_lambSymbol) + prompt = gsub_plain(prompt, "{uah}", uah) + prompt = gsub_plain(prompt, "{cwd}", cwd) + prompt = gsub_plain(prompt, "{env}", env) + clink.prompt.value = gsub_plain(prompt, "{lamb}", prompt_lambSymbol) end local function percent_prompt_filter() - clink.prompt.value = string.gsub(clink.prompt.value, "{percent}", "%%") + clink.prompt.value = gsub_plain(clink.prompt.value, "{percent}", "%") end --- @@ -532,13 +558,13 @@ local function git_prompt_filter() color = colors.conflict end - clink.prompt.value = string.gsub(clink.prompt.value, "{git}", " "..color.."("..verbatim(branch)..")") + clink.prompt.value = gsub_plain(clink.prompt.value, "{git}", " "..color.."("..branch..")") return false end end -- No git present or not in git file - clink.prompt.value = string.gsub(clink.prompt.value, "{git}", "") + clink.prompt.value = gsub_plain(clink.prompt.value, "{git}", "") return false end @@ -577,13 +603,13 @@ local function hg_prompt_filter() end local result = color .. "(" .. branch .. ")" - clink.prompt.value = string.gsub(clink.prompt.value, "{hg}", " "..verbatim(result)) + clink.prompt.value = gsub_plain(clink.prompt.value, "{hg}", " "..result) return false end end -- No hg present or not in hg repo - clink.prompt.value = string.gsub(clink.prompt.value, "{hg}", "") + clink.prompt.value = gsub_plain(clink.prompt.value, "{hg}", "") end local function svn_prompt_filter() @@ -636,13 +662,13 @@ local function svn_prompt_filter() color = colors.dirty end - clink.prompt.value = string.gsub(clink.prompt.value, "{svn}", " "..color.."("..verbatim(branch)..")") + clink.prompt.value = gsub_plain(clink.prompt.value, "{svn}", " "..color.."("..branch..")") return false end end -- No svn present or not in svn file - clink.prompt.value = string.gsub(clink.prompt.value, "{svn}", "") + clink.prompt.value = gsub_plain(clink.prompt.value, "{svn}", "") return false end