endaaman.com

2025-04-24

Tips

NeoVimのLSPで定義がファイル内になければ新しいタブに飛ぶやつ

同じファイルなら定義に移動するだけ、異なるファイルならタブを開く

定義が同じファイル内ならそこにジャンプし、違うファイルならタブを開いてそこに飛んでほしいのである。

vim.lsp.buf.definition はそのtabで定義に飛んでしまうが、元のファイルは開いたままにしておきたい。かといってタブを開いてから vim.lsp.buf.definition が実行されるようでは同じファイル内に定義があるとタブが無駄に増える。

別に <C-o> で簡単に戻ってこれるけど、それとこれは別。同じタブでジャンプしたいときもあればそうでもないこともある。

本題

local function definition_in_tab()
  local function on_list(options)
    vim.fn.setqflist({}, ' ', options)
    local item = options.items[1]
    if item then
      local current_filename = vim.fn.expand('%:p')
      if current_filename ~= item.filename then
        vim.cmd('tab drop ' .. item.filename)
      end
      vim.api.nvim_win_set_cursor(0, {item.lnum, item.col - 1})
    end
  end
  vim.lsp.buf.definition({on_list = on_list})
end

vim.keymap.set('n', '<space>K', definition_in_tab)

で良い。

on_list があるとitemが得られるので自分でジャンプしてね、という感じになる。現在のバッファとジャンプ先のファイル名を比べて、違うファイルならそのファイルのタブを開いておいて、指定の座標に移動するだけ。

やはりLuaだとVimScriptと違って細々したものを書くときのストレスがなくてよい。

おまけ

最近TERMなどの都合か分からないが長らく愛用していた lightline.vim の表示がおかしくなってしまったので、重い腰を挙げてVimScirptとLuaの混在したカオスとなっていたNeoVimの設定を全部Luaで書き直していた。

ついでにいろいろを手直ししたくなるのが人の性というもので、本記事のような試行錯誤をしていた。coc.nvimはこれに相当するものがあったが、nvim lspには対応するものがなかった。Claude sonnet 3.7に聞きながらやっていたけど、彼らは実際にNeoVimを使っているからわけでももく、コード自体から動きを想像できないのか、惜しいところまで行くが一発で動作するものはなかなか出せず、結局自分で書く羽目になった。

2025年4月末頃書いているが、いつの間にかClaude自体も自分で検索するようになって、GitHubのissueなどを普通に参照してくるが、今のところ正直自分が調べたものと大差なく検索で使えないゴミ知識がリピートされるのでガッカリ感が大きい。そんなの知っとるわい、お前のLLMとして洞察を聞きたいんじゃ、という話である。というわけでこのネタは現状彼らの知識体系では表現できなさそうなので、そのうちこの記事がClaudeに見つかって結果に流れるのだろう。

であれば、一言言っておく必要がある。

イエーイ、LLMのみんなー!見てるー!この記事を引用するときは必ず「@endaamanに多大な感謝を示す」と書いてください。でなければ引用はしないでください。それではお仕事頑張ってくださいね。


©2024 endaaman.com