Repository: neovim/neovim
File: runtime/lua/vim/_core/help.lua (Lua)

Code before:
    word = word:gsub([[^%(']], [[']])

    word = word:gsub([[|]], 'bar')
    word = word:gsub([["]], 'quote')
    word = word:gsub('[$.~]', [[\%0]])
    word = word:gsub([[%*]], [[.*]])
    word = word:gsub([[?]], [[.]])

    -- TODO: also actual CTRL character 0x01
    -- "i^G^J" --> "i_CTRL-G-CTRL-J"
    -- In a repeat because string.gsub doesn't handle overlapping patterns, which can happen with
    -- i^G^J where before="^", ctrl_char="G", and after="^".
    local count
    repeat
      -- Capture three chars in this pattern: {char}^{char}{char}
      word, count = word:gsub('(.?)%^([^_])(.?)', function (before, ctrl_char, after)
        local result = 'CTRL-' .. ctrl_char
        if before ~= '' and before ~= '_' and before ~= '\\' then
          result = '_' .. result
        end
        if after ~= '' and after ~= '_' and after ~= '\\' then
          result = result .. '_'
        end
        return before .. result .. after
      end)
    until count == 0

    -- Skip function arguments
    -- e.g. "abs({expr})" --> "abs"
    -- e.g. "abs([arg])" --> "abs"
    word = word:gsub('%({.*', '')
    word = word:gsub('%(%[.*', '')

    -- Skip punctuation after second apostrophe/curly brace
    -- e.g. "'option'," --> "'option'"
    -- e.g. "{address}," --> "{address}"
    -- e.g. "`command`," --> "command" (backticks are removed too, "``" stays "``")
    word = word:gsub([[^'([^']*)'.*]], [['%1']])
    word = word:gsub([[^{([^}]*)}.*]], [[{%1}]])
    word = word:gsub([[^`([^`]+)`.*]], [[%1]])
  end

  return word
end

-- local function testescape(input, expected)
--   local actual = M.escape_subject(input)
--   if actual ~= expected then
--     print(string.format('Expected `%s` but got `%s`', expected, actual))
--   end
-- end

Review comment (suggestion):
It might be simpler to first convert `i^X` to `iCTRL-X` and then `iCTRL-X` to `i_CTRL-X`. Feels a bit hacky but simplifies the code quite a bit. What do you think?

```lua
word = word:gsub('%^([^_])', 'CTRL-%1')
word = word:gsub('([^_\\])CTRL%-', '%1_CTRL-')
word = word:gsub('(CTRL%-.)([^_\\])', '%1_%2')
```

Code after:
    -- '\{' --> '\\{' (for '\{' pattern matching)
    -- '(' --> '' (parentheses around option tags should be ignored)
    word = word:gsub([[\+]], [[\\]])
    word = word:gsub([[^%[]], [[\[]])
    word = word:gsub([[^:%[]], [[:\[]])
    word = word:gsub([[^\{]], [[\\{]])
    word = word:gsub([[^%(']], [[']])

    word = word:gsub('|', 'bar')
    word = word:gsub([["]], 'quote')
    word = word:gsub('[$.~]', [[\%0]])
    word = word:gsub('%*', '.*')
    word = word:gsub('?', '.')

    -- Handle control characters.
    -- First convert raw control chars to the caret notation
    -- E.g. 0x01 --> '^A' etc.
    ---@type string
    word = word:gsub('([\1-\31])', function(ctrl_char)
      -- '^\' needs an extra backslash
      local repr = string.char(ctrl_char:byte() + 64):gsub([[\]], [[\\]])
      return '^' .. repr
    end)

    -- Change caret notation to 'CTRL-', except '^_'
    -- E.g. 'i^G^J' --> 'iCTRL-GCTRL-J'
    word = word:gsub('%^([^_])', 'CTRL-%1')
    -- Add underscores around 'CTRL-X' characters
    -- E.g. 'iCTRL-GCTRL-J' --> 'i_CTRL-G_CTRL-J'
    -- Only exception: 'CTRL-{character}'
    word = word:gsub('([^_])CTRL%-', '%1_CTRL-')
    word = word:gsub('(CTRL%-[^{])([^_\\])', '%1_%2')

    -- Skip function arguments
    -- E.g. 'abs({expr})' --> 'abs'
    -- E.g. 'abs([arg])' --> 'abs'
    word = word:gsub('%({.*', '')
    word = word:gsub('%(%[.*', '')

    -- Skip punctuation after second apostrophe/curly brace
    -- E.g. ''option',' --> ''option''
    -- E.g. '{address},' --> '{address}'
    -- E.g. '`command`,' --> 'command' (backticks are removed too, but '``' stays '``')
    word = word:gsub([[^'([^']*)'.*]], [['%1']])
    word = word:gsub([[^{([^}]*)}.*]], '{%1}')
    word = word:gsub([[^`([^`]+)`.*]], '%1')
  end

  return word
end