nvim-treesitter / nvim-treesitter-textobjects

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error "E31: No such mapping" in file `select.lua` when trying to call `vim.keymap.del`

Bekaboo opened this issue · comments

Describe the bug

When the content of a buffer is changed by telescope's builtin action git_bcommits, nvim-treesitter-textobjects throws the error:

E5108: Error executing lua ...cker/start/telescope.nvim/lua/telescope/actions/init.lua:78
5: Vim(append):Error executing lua callback: vim/keymap.lua:0: E31: No such mapping
stack traceback:
        [C]: in function 'nvim_buf_del_keymap'
        vim/keymap.lua: in function 'del'
        ...r-textobjects/lua/nvim-treesitter/textobjects/select.lua:206: in function 'det
ach'
        ...er/start/nvim-treesitter/lua/nvim-treesitter/configs.lua:518: in function 'det
ach_module'
        ...er/start/nvim-treesitter/lua/nvim-treesitter/configs.lua:527: in function 'rea
ttach_module'
        ...er/start/nvim-treesitter/lua/nvim-treesitter/configs.lua:131: in function <...
er/start/nvim-treesitter/lua/nvim-treesitter/configs.lua:130>
        [C]: in function 'cmd'
        ...cker/start/telescope.nvim/lua/telescope/actions/init.lua:785: in function 'run
_replace_or_original'
        ...packer/start/telescope.nvim/lua/telescope/actions/mt.lua:65: in function 'run_
replace_or_original'
        ...packer/start/telescope.nvim/lua/telescope/actions/mt.lua:65: in function 'key_
func'
        ...k/packer/start/telescope.nvim/lua/telescope/mappings.lua:352: in function 'exe
cute_keymap'
        [string ":lua"]:1: in main chunk
stack traceback:
        [C]: in function 'cmd'
        ...cker/start/telescope.nvim/lua/telescope/actions/init.lua:785: in function 'run
_replace_or_original'
        ...packer/start/telescope.nvim/lua/telescope/actions/mt.lua:65: in function 'run_
replace_or_original'
        ...packer/start/telescope.nvim/lua/telescope/actions/mt.lua:65: in function 'key_
func'
        ...k/packer/start/telescope.nvim/lua/telescope/mappings.lua:352: in function 'exe
cute_keymap'
        [string ":lua"]:1: in main chunk

To Reproduce

Steps to reproduce the behavior:

Assume using packer.nvim as the plugin manager.

  1. Clone packer.nvim to ~/.local/share/nvim/site/pack/packer/start

  2. Use the following minimal config:

    vim.cmd('packadd packer.nvim')
    require('packer').startup(function(use)
        use('wbthomason/packer.nvim')
    
        use({
            'nvim-treesitter/nvim-treesitter',
            config = function()
                local ts_configs = require('nvim-treesitter.configs')
                ts_configs.setup({
                    ensure_installed = require('utils.static').langs:list('ts'),
                    sync_install = true,
                    ignore_install = {},
                    highlight = {
                        enable = true,
                        additional_vim_regex_highlighting = false,
                    },
                    context_commentstring = {
                        enable = true,
                    },
                    textobjects = {
                        select = {
                            enable = true,
                            lookahead = true, -- Automatically jump forward to textobj
                            keymaps = {
                                -- You can use the capture groups defined in textobjects.scm
                                ['am'] = '@function.outer',
                                ['im'] = '@function.inner',
                                ['al'] = '@loop.outer',
                                ['il'] = '@loop.inner',
                                ['ak'] = '@class.outer',
                                ['ik'] = '@class.inner',
                                ['aa'] = '@parameter.outer',
                                ['ia'] = '@parameter.inner',
                                ['a/'] = '@comment.outer',
                                ['i/'] = '@comment.inner',
                                ['a*'] = '@comment.outer',
                                ['i*'] = '@comment.inner',
                            },
                        },
                        move = {
                            enable = true,
                            set_jumps = true, -- whether to set jumps in the jumplist
                            goto_next_start = {
                                [']m'] = '@function.outer',
                                [']]'] = '@function.outer',
                                [']k'] = '@class.outer',
                                [']}'] = '@class.outer',
                                [']a'] = '@parameter.outer'
                            },
                            goto_next_end = {
                                [']M'] = '@function.outer',
                                [']['] = '@function.outer',
                                [']K'] = '@class.outer',
                                [']{'] = '@class.outer',
                                [']A'] = '@parameter.outer'
                            },
                            goto_previous_start = {
                                ['[m'] = '@function.outer',
                                ['[['] = '@function.outer',
                                ['[k'] = '@class.outer',
                                ['[{'] = '@class.outer',
                                ['[a'] = '@parameter.outer'
                            },
                            goto_previous_end = {
                                ['[M'] = '@function.outer',
                                ['[]'] = '@function.outer',
                                ['[K'] = '@class.outer',
                                ['[}'] = '@class.outer',
                                ['[A'] = '@parameter.outer'
                            },
                        },
                        swap = {
                            enable = true,
                            swap_next = {
                                ['<C-l>'] = '@parameter.inner'
                            },
                            swap_previous = {
                                ['<C-h>'] = '@parameter.inner'
                            },
                        },
                        lsp_interop = {
                            enable = true,
                            border = 'single',
                            peek_definition_code = {
                                ['<leader>p'] = '@function.outer',
                            },
                        },
                    },
                })
            end,
        })
    
        use({
            'nvim-treesitter/nvim-treesitter-textobjects',
            requires = 'nvim-treesitter',
            after = 'nvim-treesitter',
        })
    
        use({
            'nvim-telescope/telescope.nvim',
            requires = 'nvim-lua/plenary.nvim',
            config = function()
                local telescope = require('telescope')
                telescope.setup()
            end,
        })
    end)

    save it as ~/.config/init_test.lua

  3. Run nvim -u ~/.config/init_test.lua.

  4. Inside neovim, open an arbitrary file tracked by git inside a local git repository.

  5. Inside neovim, run command :Telescope git_bcommits

  6. Select a random commit, press <Enter>

  7. See the error

Expected behavior

should not error.

Output of :checkhealth nvim-treesitter

nvim-treesitter: require("nvim-treesitter.health").check()

Installation ~
- OK `tree-sitter` found 0.20.7 (parser generator, only needed for :TSInstallFromGrammar)
- OK `node` found v19.4.0 (only needed for :TSInstallFromGrammar)
- OK `git` executable found.
- OK `cc` executable found. Selected from { vim.NIL, "cc", "gcc", "clang", "cl", "zig" }
  Version: cc (GCC) 12.2.0
- OK Neovim was compiled with tree-sitter runtime ABI version 14 (required >=13). Parsers must be compatible with runtime ABI.

OS Info:
{
  machine = "x86_64",
  release = "6.1.6-arch1-1",
  sysname = "Linux",
  version = "#1 SMP PREEMPT_DYNAMIC Sat, 14 Jan 2023 13:09:35 +0000"
} ~

Parser/Features         H L F I J
  - cpp                 ✓ ✓ ✓ ✓ ✓
  - make                ✓ . ✓ . ✓
  - vim                 ✓ ✓ ✓ . ✓
  - lua                 ✓ ✓ ✓ ✓ ✓
  - c                   ✓ ✓ ✓ ✓ ✓
  - python              ✓ ✓ ✓ ✓ ✓

  Legend: H[ighlight], L[ocals], F[olds], I[ndents], In[j]ections
         +) multiple parsers found, only one will be used
         x) errors found in the query, try to run :TSUpdate {lang} ~

Output of nvim --version

I'm currently on Neovim nightly, but this bug is consistent on stable version:

NVIM v0.9.0-dev-672+g4876654d4c
Build type: Release
LuaJIT 2.1.0-beta3
Compiled by zeng

Features: +acl +iconv +tui
See ":help feature-compile"

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/usr/share/nvim"

Run :checkhealth for more info

Additional context

The bug is cause by lua/nvim-treesitter/textobjects/select.lua, line 206, where we try to delete a buffer keymap:

205    if query then
206      vim.keymap.del({ "o", "x" }, mapping, { buffer = bufnr })
207    end

for some reason, this mapping does not exist, so the error is thrown.

Change line 206 to

vim.cmd(string.format('silent!' .. 'lua vim.keymap.del({ "o", "x" }, %s, { buffer = %s })', mapping, bufnr))

solves the issue, however I belive this is just a temporary fix, there must be something wrong elsewhere.

A short video clip demonstrating this bug:

simplescreenrecorder-2023-01-17_02.59.42.mp4

Thanks for reporting. Was it working fine before today's commit or do you think it was like this before as well?

There is no @comment.inner available and I think that's the problem

Hope this is resolved by now.

Hm @kiyoon I am getting the same error using the latest on main with the current configuration in treesitter:

    textobjects = {
      select = {
        enable = true,
        lookahead = true,
        keymaps = {
          aB = "@block.outer",
          iB = "@block.inner",
          aC = "@conditional.outer",
          iC = "@conditional.inner",
          aF = "@function.outer",
          iF = "@function.inner",
          aL = "@loop.outer",
          iL = "@loop.inner",
          aP = "@parameter.outer",
          iP = "@parameter.inner",
          aX = "@class.outer",
          iX = "@class.inner",
        },
      },
      move = {
        enable = true,
        set_jumps = true,
        goto_next_start = {
          ["]b"] = { query = "@block.outer", desc = "Next block start" },
          ["]f"] = { query = "@function.outer", desc = "Next function start" },
          ["]p"] = { query = "@parameter.outer", desc = "Next parameter start" },
          ["]x"] = { query = "@class.outer", desc = "Next class start" },
        },
        goto_next_end = {
          ["]B"] = { query = "@block.outer", desc = "Next block end" },
          ["]F"] = { query = "@function.outer", desc = "Next function end" },
          ["]P"] = { query = "@parameter.outer", desc = "Next parameter end" },
          ["]X"] = { query = "@class.outer", desc = "Next class end" },
        },
        goto_previous_start = {
          ["[b"] = { query = "@block.outer", desc = "Previous block start" },
          ["[f"] = { query = "@function.outer", desc = "Previous function start" },
          ["[p"] = { query = "@parameter.outer", desc = "Previous parameter start" },
          ["[x"] = { query = "@class.outer", desc = "Previous class start" },
        },
        goto_previous_end = {
          ["[B"] = { query = "@block.outer", desc = "Previous block end" },
          ["[F"] = { query = "@function.outer", desc = "Previous function end" },
          ["[P"] = { query = "@parameter.outer", desc = "Previous parameter end" },
          ["[X"] = { query = "@class.outer", desc = "Previous class end" },
        },
      },
      swap = {
        enable = true,
        swap_next = {
          [">B"] = { query = "@block.outer", desc = "Swap next block" },
          [">F"] = { query = "@function.outer", desc = "Swap next function" },
          [">P"] = { query = "@parameter.inner", desc = "Swap next parameter" },
        },
        swap_previous = {
          ["<B"] = { query = "@block.outer", desc = "Swap previous block" },
          ["<F"] = { query = "@function.outer", desc = "Swap previous function" },
          ["<P"] = { query = "@parameter.inner", desc = "Swap previous parameter" },
        },
      },
      lsp_interop = {
        enable = true,
        border = "single",
        peek_definition_code = {
          ["<leader>lp"] = { query = "@function.outer", desc = "Peek function definition" },
          ["<leader>lP"] = { query = "@class.outer", desc = "Peek class definition" },
        },
      },
    }

I double checked and all of the queries I'm using I believe are available

Hi @mehalter, has it been working until recently? What happens if you change the select keymaps to be ["aB"] etc.?

@kiyoon Thanks for replying! The bug reported is solved but a new one is introduced.

When I preform :Telescope git_bcommits, treesitter-textobjects throws this error

E5108: Error executing lua ...packer/opt/telescope.nvim/lua/telescope/actions/init.lua:785
: Vim(append):Error executing lua callback: ...r-textobjects/lua/nvim-treesitter/textobjec
ts/attach.lua:84: bad argument #1 to 'ipairs' (table expected, got string)
stack traceback:
        [C]: in function 'ipairs'
        ...r-textobjects/lua/nvim-treesitter/textobjects/attach.lua:84: in function 'detac
h'
        ...cker/opt/nvim-treesitter/lua/nvim-treesitter/configs.lua:518: in function 'deta
ch_module'
        ...cker/opt/nvim-treesitter/lua/nvim-treesitter/configs.lua:527: in function 'reat
tach_module'
        ...cker/opt/nvim-treesitter/lua/nvim-treesitter/configs.lua:131: in function <...c
ker/opt/nvim-treesitter/lua/nvim-treesitter/configs.lua:130>
        [C]: in function 'cmd'
        ...packer/opt/telescope.nvim/lua/telescope/actions/init.lua:785: in function 'run_
replace_or_original'
        ...k/packer/opt/telescope.nvim/lua/telescope/actions/mt.lua:65: in function 'run_r
eplace_or_original'
        ...k/packer/opt/telescope.nvim/lua/telescope/actions/mt.lua:65: in function 'key_f
unc'
        ...ack/packer/opt/telescope.nvim/lua/telescope/mappings.lua:352: in function 'exec
ute_keymap'
        [string ":lua"]:1: in main chunk
stack traceback:
        [C]: in function 'cmd'
        ...packer/opt/telescope.nvim/lua/telescope/actions/init.lua:785: in function 'run_
replace_or_original'
        ...k/packer/opt/telescope.nvim/lua/telescope/actions/mt.lua:65: in function 'run_r
eplace_or_original'
        ...k/packer/opt/telescope.nvim/lua/telescope/actions/mt.lua:65: in function 'key_f
unc'
        ...ack/packer/opt/telescope.nvim/lua/telescope/mappings.lua:352: in function 'exec
ute_keymap'
        [string ":lua"]:1: in main chunk

and here is the config I'm currently using (invalid keymaps removed):

  local ts_configs = require('nvim-treesitter.configs')
  ts_configs.setup({
    ensure_installed = require('utils.static').langs:list('ts'),
    sync_install = true,
    ignore_install = {},
    highlight = {
      enable = not vim.g.vscode,
      additional_vim_regex_highlighting = false,
    },
    textobjects = {
      select = {
        enable = true,
        lookahead = true, -- Automatically jump forward to textobj
        keymaps = {
          -- You can use the capture groups defined in textobjects.scm
          ['am'] = '@function.outer',
          ['im'] = '@function.inner',
          ['al'] = '@loop.outer',
          ['il'] = '@loop.inner',
          ['ak'] = '@class.outer',
          ['ik'] = '@class.inner',
          ['aa'] = '@parameter.outer',
          ['ia'] = '@parameter.inner',
          ['a/'] = '@comment.outer',
          ['a*'] = '@comment.outer',
        },
      },
      move = {
        enable = true,
        set_jumps = true, -- whether to set jumps in the jumplist
        goto_next_start = {
          [']m'] = '@function.outer',
          [']]'] = '@function.outer',
          [']k'] = '@class.outer',
          [']}'] = '@class.outer',
          [']a'] = '@parameter.outer'
        },
        goto_next_end = {
          [']M'] = '@function.outer',
          [']['] = '@function.outer',
          [']K'] = '@class.outer',
          [']{'] = '@class.outer',
          [']A'] = '@parameter.outer'
        },
        goto_previous_start = {
          ['[m'] = '@function.outer',
          ['[['] = '@function.outer',
          ['[k'] = '@class.outer',
          ['[{'] = '@class.outer',
          ['[a'] = '@parameter.outer'
        },
        goto_previous_end = {
          ['[M'] = '@function.outer',
          ['[]'] = '@function.outer',
          ['[K'] = '@class.outer',
          ['[}'] = '@class.outer',
          ['[A'] = '@parameter.outer'
        },
      },
      swap = {
        enable = true,
        swap_next = {
          ['<C-l>'] = '@parameter.inner'
        },
        swap_previous = {
          ['<C-h>'] = '@parameter.inner'
        },
      },
      lsp_interop = {
        enable = true,
        border = 'single',
        peek_definition_code = {
          ['<leader>p'] = '@function.outer',
        },
      },
    },
  })

yeah it's been working until I updated the plugin this morning. Changing them to ["aB"] format has not affect also this is no different to the Lua parser in general so it wouldn't change anything

@Bekaboo @mehalter Can you update the plugin again? I just made the fix for #365 a couple of minutes ago.

@kiyoon just tested it and I am getting the same error on the new version

Error detected while processing User Autocommands for "AstroLspSetup"..FileType Autocommands for "*":                                                                                                                                                                    
Error executing lua callback: vim/keymap.lua:0: E31: No such mapping                                                                                                                                                                                                     
stack traceback:                                                                                                                                                                                                                                                         
        [C]: in function 'nvim_buf_del_keymap'                                                                                                                                                                                                                           
        vim/keymap.lua: in function 'del'                                                                                                                                                                                                                                
        ...r-textobjects/lua/nvim-treesitter/textobjects/select.lua:208: in function 'detach'                                                                                                                                                                            
        ...vim/lazy/nvim-treesitter/lua/nvim-treesitter/configs.lua:518: in function 'detach_module'                                                                                                                                                                     
        ...vim/lazy/nvim-treesitter/lua/nvim-treesitter/configs.lua:527: in function 'reattach_module'                                                                                                                                                                   
        ...vim/lazy/nvim-treesitter/lua/nvim-treesitter/configs.lua:131: in function <...vim/lazy/nvim-treesitter/lua/nvim-treesitter/configs.lua:130>                                                                                                                   
        [C]: in function 'nvim_exec_autocmds'                                                                                                                                                                                                                            
        /home/micah/.config/nvim/lua/plugins/lsp.lua:32: in function </home/micah/.config/nvim/lua/plugins/lsp.lua:30>                                                                                                                                                   
        [C]: in function 'nvim_exec_autocmds'                                                                                                                                                                                                                            
        /home/micah/.config/nvim/lua/core/utils/init.lua:161: in function </home/micah/.config/nvim/lua/core/utils/init.lua:161>    
        ```

@Bekaboo @mehalter Can you update the plugin again? I just made the fix for #365 a couple of minutes ago.

Thanks, the latest version works.

I actually cannot reproduce this, maybe it only throws error when using autocommands etc.
However I have an idea why this can be wrong.
@mehalter Does all the select mapping work? Is the new update not getting some of the mappings for example, and it is trying to unset the keymaps?

@kiyoon yeah all of the mappings are available, one thing you could do is instead of checking the mapping directly and always deleting it if it's set like you are doing:

            if vim.fn.mapcheck(mapping, mode, false) ~= "" then
              vim.keymap.del(mode, mapping, { buffer = bufnr })
            end

you could just do pcall(vim.keymap.del, mode, mapping, { buffer = bufnr })

and it will delete the mapping if it exists and fail silently if it doesn't exist and therefore cannot delete

Also just for reference, I can replicate it with just this:

    textobjects = {
      select = {
        enable = true,
        lookahead = true,
        keymaps = {
          aX = "@class.outer",
          iX = "@class.inner",
        },
      },
    },

the other mappings do not complain at all

@mehalter Okay, I can do that. The issue happens only in :Telescope git_bcommits? So there are some types of buffers that reject to add mappings it seems

No, this is completely separate from :Telescope git_bcommits. This is just from me setting up the plugin

I just tested and I have no issues with :Telescope git_bcommits but this is after I have dismissed the error when the plugin was initially loaded

Also @kiyoon I just found that opening a file directly vs. opening a file after I have opened neovim can have very different results as well. Different keymaps are having issues with the deletion. I think it will definitely be beneficial to just wrap the deletion in a pcall method so it fails silently. It seems to be extremely unreliable currently