🔍

ヘルプ検索から始めるddu

2023/12/08に公開1

はじめに

皆さんVimでfuzzyfinderはお使いでしょうか?
fzf.vimでしょうか?
Neovimをお使いならtelescope.nvim?

私は闇のプラグインと名高いddu.vimをお勧めしています。



あー! そこ、設定が難しいから簡単なプラグインにしたいって言った人いるでしょ!
甘いですよ。
Vimmerならプラグインの設定は避けて通れないんですから。

https://twitter.com/ShougoMatsu/status/1706991121979834792

「設定させていただいてありがとうございます。」

これを言えるようにならなくては!

設定が面倒と思ってしまう要因のひとつとして、設定項目を探すのが大変ですよね。
この難易度をグッと下げる方法として、ヘルプが検索しやすくするという方法があります。

また一説では、独りでヘルプ検索できるようになることで、初心者Vimmerを卒業している説があります。
かくいう私も最初はVimの歩き方が分からず、vim-jpに参加して操作を教わっていましたが、気がつくとひとりでもVimの操作が熟達したりプラグインの設定に躓くことが少なくなりました。

まずはdduでvimのヘルプを検索できるようになるところから設定の喜びを覚えていきましょう!

必要なプラグインのインストール

さて、前置きが長くなりましたが、今回必要なプラグインは次のとおりになります。

denops.vimを動かすためにはdenoが必要です。
denoのインストール方法は、公式ページを確認してください。

またインストールに使用するプラグインマネージャは、現在お使いの物をご利用ください。
そして注意という訳ではありませんが、遅延起動などの設定は紹介しません。

まずは今回の記事を通して、dduを使ってヘルプを検索できるようになりましょう。

設定

次に紹介する設定をinit.vim.vimrcに追記してください。
Neovimでluaを使って設定している人もいると思いますので、luaでの設定も書いておきます。

vim scriptの場合
call ddu#custom#patch_global(#{
\   ui: 'ff',
\   uiParams: #{
\     ff: #{
\       startAutoAction: v:true,
\       autoAction: #{
\         delay: 0,
\         name: 'preview',
\       },
\       split: 'vertical',
\       splitDirection: 'topleft',
\       startFilter: v:true,
\       winWidth: '&columns / 2 - 2',
\       previewFloating: v:true,
\       previewHeight: '&lines - 8',
\       previewWidth: '&columns / 2 - 2',
\       previewRow: 1,
\       previewCol: '&columns / 2 + 1',
\     },
\   },
\   sourceOptions: #{
\     _: #{
\       matchers: ['matcher_substring'],
\     },
\     help: #{
\       defaultAction: 'open',
\     },
\   },
\ })

call ddu#custom#patch_local('help-ff', #{
\   sources: [{'name': 'help'}],
\ })

function! s:ddu_ff_keymaps() abort
  nnoremap <buffer> <CR>
  \ <Cmd>call ddu#ui#do_action('itemAction')<CR>
  nnoremap <buffer> i
  \ <Cmd>call ddu#ui#do_action('openFilterWindow')<CR>
  nnoremap <buffer> q
  \ <Cmd>call ddu#ui#do_action('quit')<CR>
endfunction

function! s:ddu_ff_filter_keymaps() abort
  inoremap <buffer> <CR>
  \ <Esc><Cmd>call ddu#ui#do_action('closeFilterWindow')<CR>
  nnoremap <buffer> <CR>
  \ <Cmd>call ddu#ui#do_action('closeFilterWindow')<CR>
endfunction

autocmd FileType ddu-ff call s:ddu_ff_keymaps()
autocmd FileType ddu-ff-filter call s:ddu_ff_filter_keymaps()

command! Help call ddu#start({'name': 'help-ff'})

luaの場合
vim.fn["ddu#custom#patch_global"]({
    ui = "ff",
    uiParams = {
        ff = {
            startAutoAction = true,
            autoAction = {
                delay = 0,
                name = "preview",
            },
            split = "vertical",
            splitDirection = "topleft",
            startFilter = true,
            winWidth = "&columns / 2 - 2",
            previewFloating = true,
            previewHeight = "&lines - 8",
            previewWidth = "&columns / 2 - 2",
            previewRow = 1,
            previewCol = "&columns / 2 + 1",
        },
    },
    sourceOptions = {
        _ = {
            matchers = { "matcher_substring" },
        },
        help = {
            defaultAction = "open",
        },
    },
})

vim.fn["ddu#custom#patch_local"]("help-ff", {
    sources = {
        { name = "help" },
    },
})

local keymap = vim.keymap.set
local ddu_do_action = vim.fn["ddu#ui#do_action"]

local function ddu_ff_keymaps()
    keymap("n", "<CR>", function()
        ddu_do_action("itemAction")
    end, { buffer = true })
    keymap("n", "i", function()
        ddu_do_action("openFilterWindow")
    end, { buffer = true })
    keymap("n", "q", function()
        ddu_do_action("quit")
    end, { buffer = true })
end

local function ddu_ff_filter_keymaps()
    keymap("i", "<CR>", function()
        vim.cmd.stopinsert()
        ddu_do_action("closeFilterWindow")
    end, { buffer = true })
    keymap("n", "<CR>", function()
        ddu_do_action("cloeFilterWindow")
    end, { buffer = true })
end

vim.api.nvim_create_autocmd("FileType", {
    pattern = "ddu-ff",
    callback = ddu_ff_keymaps,
})
vim.api.nvim_create_autocmd("FileType", {
    pattern = "ddu-ff-filter",
    callback = ddu_ff_filter_keymaps,
})

vim.api.nvim_create_user_command("Help", function()
    vim.fn["ddu#start"]({ name = "help-ff" })
end, {})

使い方

どちらの設定でも同じような操作になる設定をしました。

使い方としては、:Helpでdduによるヘルプ検索画面の表示と、自動的に検索フィルターへの遷移します。
探したいワードを入力することでヘルプの絞り込みを行ない、<CR>で検索結果一覧のウィンドウに移動できます。
検索結果一覧を上下移動することで、自動的にプレビューウィンドウが表示されるので、簡易的に内容を確認できます。

最終的に開きたいヘルプを選択することで、:h {helptag}を実行したときと同じようにヘルプを開くことができます。

検索結果一覧から抜ける場合は、qを入力することでdduのウィンドウを閉じることができます。

さいごに

今回紹介したdduの設定は、ほとんどexampleに含まれる内容しか使っていません。
記述量はそこそこありますが、設定の仕方は慣れてしまえば簡単な物です。

なによりも作者の設定…もといリファレンス実装はとても参考になりますし、コードリーディング力を鍛えることができるので、ヘルプの次に参考にしていただきたいです。

私もdduを含むShougowareを好んで使っていますので、気が向いたら設定を見て貰えるととても嬉しいです。

また、今回紹介した設定の細かい使い方に関しては、この設定をそのまま使えばヘルプ検索はかなり楽になるので、是非活用してみてください。

GitHubで編集を提案

Discussion

s_shows_show

自動的に検索フィルターに移動するために必要な設定である startFilter = true2024.3.11のコミット で削除されていますね。
その状況で自動的に検索フィルターに移動する方法については、ddu-ui の ヘルプ で紹介されています。
自動的に検索フィルターに移動する設定を調べる過程で上記の点に気付きましたので、参考までにお知らせします。