telescope.nvim icon indicating copy to clipboard operation
telescope.nvim copied to clipboard

help_tags() does not escape special characters

Open vanaigr opened this issue 1 year ago • 4 comments

Description

using Telescope help_tags to jump to [==] (equivalence class) opens help for = instead.

Neovim version

NVIM v0.9.2
Build type: RelWithDebInfo
LuaJIT 2.1.1694082368

Operating system and version

Windows 10

Telescope version / branch / rev

1bb28df

checkhealth telescope

==============================================================================
Telescope: require("Telescope.health").check()

Checking for required plugins ~
- OK plenary installed.
- OK nvim-treesitter installed.

Checking external dependencies ~
- ERROR rg: not found. `live-grep` finder will not function without [BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep) installed.
- WARNING fd: not found. Install [sharkdp/fd](https://github.com/sharkdp/fd) for extended capabilities

===== Installed extensions ===== ~

Steps to reproduce

nvim -nu minimal.lua :Telescope help_tags<CR> [==]<CR>

Expected behavior

help_tags opens help for [==] (in runtime/doc/pattern.txt), the same file that is displayed in the preview.

image image

Actual behavior

Help is opened for = (in runtime/doc/change.txt) image

Minimal config

vim.cmd [[set runtimepath=$VIMRUNTIME]]
vim.cmd [[set packpath=/tmp/nvim/site]]
local package_root = '/tmp/nvim/site/pack'
local install_path = package_root .. '/packer/start/packer.nvim'
local function load_plugins()
  require('packer').startup {
    {
      'wbthomason/packer.nvim',
      {
        'nvim-telescope/telescope.nvim',
        requires = {
          'nvim-lua/plenary.nvim',
          { 'nvim-telescope/telescope-fzf-native.nvim', run = 'make' },
        },
      },
    },
    config = {
      package_root = package_root,
      compile_path = install_path .. '/plugin/packer_compiled.lua',
      display = { non_interactive = true },
    },
  }
end
_G.load_config = function()
  require('telescope').setup()
end
if vim.fn.isdirectory(install_path) == 0 then
  print("Installing Telescope and dependencies.")
  vim.fn.system { 'git', 'clone', '--depth=1', 'https://github.com/wbthomason/packer.nvim', install_path }
end
load_plugins()
require('packer').sync()
vim.cmd [[autocmd User PackerComplete ++once echo "Ready!" | lua load_config()]]

vanaigr avatar Apr 01 '24 14:04 vanaigr

:help for 'help' contains this paragraph:

 {subject} can include wildcards such as "*", "?" and
"[a-z]":
   :help z?	jump to help for any "z" command
   :help z.	jump to the help for "z."
But when a tag exists it is taken literally:
   :help :?	jump to help for ":?"

And in help [==]@en produced by telescope, '[' and ']' are treated as special characters.

https://github.com/nvim-telescope/telescope.nvim/blob/1bb28df3cfc241b961331f00dcb8d5b45fe3e4f0/lua/telescope/builtin/__internal.lua#L778-L784

vanaigr avatar Apr 01 '24 14:04 vanaigr

I think this might work for all characters, although I couldn't test it for non-ascii:

local lang = 'en'
local subject= '[==]'
local code_points = vim.fn.str2list(subject)
local escaped_str = '\\v'
for _, code in ipairs(code_points) do
    escaped_str = escaped_str .. '%U' .. string.format('%x', code)
end
escaped_str = escaped_str .. '@' .. lang
vim.cmd.help(escaped_str)

vanaigr avatar Apr 01 '24 14:04 vanaigr

Oof, I'm almost tempted to say "it's not our problem" considering :h [==] nets the same result...

Your solution is pretty interesting though - first time actually learning about all this "magic". But I think your concern is valid - particularly for non-utf8 encodings...

jamestrew avatar Apr 02 '24 00:04 jamestrew

couldn't test it for non-ascii

I tested it and it works for multibyte characters.

I also wrote a test to see which other help tags are affected: Results (for 0.9.5):

1605 :[vV\x16] autocmd.txt
autocmd.txt:755
repeat.txt:49

4482 [+cmd] editing.txt
editing.txt:489
motion.txt:315

4483 [..] pattern.txt
pattern.txt:1179
repeat.txt:16

4505 [==] pattern.txt
pattern.txt:1174
change.txt:564

8485 s/\= change.txt
change.txt:896
change.txt:184

8489 s/\\ change.txt
change.txt:813
change.txt:785

How to test:

# move tags file from neovim's runtime/doc/tags to current directory
nvim --clean -u tags-test.lua
tags-test.lua
-- quite slow!

local function goto_fixed(tag)
    local lang = 'en'
    local code_points = vim.fn.str2list(tag)
    local escaped_str = '\\v'
    for _, code in ipairs(code_points) do
        escaped_str = escaped_str .. '%U' .. string.format('%x', code)
    end
    escaped_str = escaped_str .. '@' .. lang
    vim.cmd.help(escaped_str)
end
local function goto_orig(tag)
    vim.cmd.help(tag .. '@en')
end
local function get_pos()
    local name = vim.fn.expand('%:t')
    local lnum = vim.fn.line('.')
    return name .. ':' .. lnum
end

vim.cmd('syntax off')
vim.cmd('set syntax=off')

local count = 0
local lines = vim.fn.readfile('tags')
Result = {}
for i, line in ipairs(lines) do
    local tag, file, _ = unpack(vim.split(line, '\t'))

    goto_fixed(tag)
    local fixed_pos = get_pos()
    goto_orig(tag)
    local orig_pos = get_pos()

    if fixed_pos ~= orig_pos then
        table.insert(Result, i..' '..tag..' '..file)
        table.insert(Result, fixed_pos)
        table.insert(Result, orig_pos)
        table.insert(Result, '')
    end

    ::next::

    count = count + 1
    if count == 100 then
        print(i, 'of', #lines)
        vim.cmd('redraw!')
        count = 0
    end
end

vim.cmd('close')

print('Done')
vim.api.nvim_buf_set_lines(0, 0, 0, false, Result)

vanaigr avatar Apr 29 '24 04:04 vanaigr