🐼

NeovimのヘルプからNeovim docsを参照する

2024/12/08に公開

Neovimを使って設定やプラグインに関する記事を書く際、公式のヘルプドキュメントを参照することはよくあります。
しかし、単なるプレーンテキストの引用よりも、公式のオンラインドキュメント(Neovim doc)へのリンクを提供したいものです。

Neovimのヘルプを参照している最中に、カーソル位置や直前のタグをもとにオンラインドキュメントのURLを生成し、ブラウザで開けるようにしてみました。

スクリプト

--- Neovim本体のヘルプドキュメントを開いてるか判定する
local function is_runtime_doc()
  if vim.opt_local.buftype:get() ~= "help" then
    return false
  end
  local filepath = vim.fn.expand("%:p")
  local vimruntime = vim.env.VIMRUNTIME
  return vimruntime and filepath:find(vim.fs.joinpath(vimruntime, "doc")) ~= nil
end

--- 指定行からタグを抽出する
local function get_tag_from_line(line)
  return line:match("%*([^%*]+)%*")
end

--- 直近のタグを検索
local function find_closest_tag()
  -- 現在行でタグを抽出
  local current_line = vim.api.nvim_get_current_line()
  local tag = get_tag_from_line(current_line)

  -- 現在行にタグがなければ直前のタグを検索
  if not tag then
    local tag_pos = vim.fn.search("\\*.*\\*", "bn")
    if tag_pos > 0 then
      local tag_line = vim.fn.getline(tag_pos)
      tag = get_tag_from_line(tag_line)
    end
  end

  return tag
end

--- Neovim docsのURLを生成
local function generate_neovim_doc_url()
  local base_url = "https://neovim.io/doc/user/"
  local helpfile = vim.fn.expand("%:t:r")
  local tag = find_closest_tag()
  if tag then
    return string.format("%s%s.html#%s", base_url, helpfile, tag)
  else
    return string.format("%s%s.html", base_url, helpfile)
  end
end

--- Neovim docsを開く
local function open_neovim_doc()
  -- Neovim本体のヘルプドキュメントでない場合はスキップ
  if not is_runtime_doc() then
    print("This is not a runtime doc file. Skipping.")
    return
  end

  local doc_url = generate_neovim_doc_url()
  vim.ui.open(doc_url)
end

スクリプトの概略

全体を簡単に説明すると以下の通りです。

  1. Neovimヘルプ参照中か判定

    • 開いているファイルがヘルプか判定
    • 開いているファイルがNeovim runtime同梱のファイルか判定
  2. タグの抽出:

    • 現在のカーソル位置の行からタグ(*example-tag* の形式)を抽出
    • 見つからない場合、vim.fn.search を使い、カーソルの直前のタグを探す
  3. URLの生成:

    • 現在開いているヘルプファイル名(拡張子なし)とタグを組み合わせ、公式ドキュメントのURLを生成
    • タグが見つからない場合は、ファイル全体のURLとする
  4. ブラウザで開く:

    • vim.ui.open を使用して生成したURLをブラウザで開く

open_neovim_doc() を呼び出せば、今の行、または直前にあるタグの行がNeovim docsで開けます。

あまり網羅的にテストしていないので、イレギュラーなタグなどがあるとうまくタグを拾えない場合などもあるかもしれません。

Discussion