diff --git a/runtime/lua/vim/_core/help.lua b/runtime/lua/vim/_core/help.lua index cc410daf17..0dad8f93ff 100644 --- a/runtime/lua/vim/_core/help.lua +++ b/runtime/lua/vim/_core/help.lua @@ -39,7 +39,7 @@ local tag_exceptions = { ['expr-<=?'] = '<=?', ['expr-=?'] = '>=?', ['expr->?'] = '>?', ['expr-is?'] = 'is?', @@ -103,12 +103,16 @@ function M.escape_subject(word) -- Change caret notation to 'CTRL-', except '^_' -- E.g. 'i^G^J' --> 'iCTRL-GCTRL-J' - word = word:gsub('%^([^_])', 'CTRL-%1') + -- Only treat '^' as control notation when followed by a caret-notation + -- char (a letter or one of "?@[\]^{"); otherwise leave it literal so + -- patterns like ':set^=' are not wrongly split. '{' is included so + -- '^{char}' matches the 'CTRL-{char}' placeholder tag. + word = word:gsub('%^([%a?@\\[\\%]{^])', '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') + word = word:gsub('([^-_])CTRL%-', '%1_CTRL-') + word = word:gsub('(CTRL%-[^{])([^%u_\\-])', '%1_%2') -- Skip function arguments -- E.g. 'abs({expr})' --> 'abs' diff --git a/test/functional/ex_cmds/help_spec.lua b/test/functional/ex_cmds/help_spec.lua index 9263e23e3a..dcba0ac872 100644 --- a/test/functional/ex_cmds/help_spec.lua +++ b/test/functional/ex_cmds/help_spec.lua @@ -110,6 +110,7 @@ describe(':help', function() check_tag('help :[range]', '*:[range]*') check_tag('help [', '[') check_tag('help ]_^D', ']_CTRL-D') + check_tag('help :set^=', '*:set^=*') check_tag([[help $HOME]], [[*$HOME*]]) @@ -132,6 +133,12 @@ describe(':help', function() check_tag([[help i^x^y]], '*i_CTRL-X_CTRL-Y*') check_tag([[help CTRL-\_CTRL-N]], [[*CTRL-\_CTRL-N*]]) check_tag([[help i_CTRL-U-default]], [[*i_CTRL-U-default*]]) + check_tag([[help expr-=~?]], [[*expr-=~?*]]) + check_tag([[help map-CTRL-C]], '*map-CTRL-C*') + check_tag([=[help telnet-CTRL-]]=], '*telnet-CTRL-]*') + check_tag([[help c_CTRL-SHIFT-V]], '*c_CTRL-SHIFT-V*') + check_tag([[help i_CTRL-SHIFT-V]], '*i_CTRL-SHIFT-V*') + check_tag([[help c_CTRL-SHIFT-Q]], '*c_CTRL-SHIFT-Q*') check_tag([[exe "help i\\"]], [[*i_CTRL-\_CTRL-G*]]) check_tag([[exe "help \"]], '*CTRL-V*')