💭

Vim の移動操作をわかりやすくした話

2022/09/14に公開

作ったもの

https://github.com/gen740/SmoothCursor.nvim

左の signcolumn に副カーソルを追加します。

作った理由

vimを使用している時、ggG<C-u><C-d> でよくカーソルを見失なってしまい、またページのスクロール方向もはっきりとしません。
もちろん、この問題を解決するように作られたプラグインは存在し、 cursorline を有効にしたり smooth scroll などと言ったプラグインも存在します。
しかし、私にはどちらもあまり好みの動き方ではありませんでした。
そこで、視覚的にわかりやすい副カーソルを作りカーソルを追従させるように描画させるプラグインを作成しました。

Code

このプラグインのコードの全文です。このプラグインは、全て lua で書いています。

local uv = vim.loop
local cursor_timer = uv.new_timer()

vim.cmd.sign("define smoothcursor text=>")

local function smoothcursor()
    -- 前のカーソルの位置が存在しないなら、現在の位置にする
    if vim.b.cursor_row_prev == nil then
        vim.b.cursor_row_prev = vim.fn.getcurpos(vim.fn.win_getid())[2]
    end
    vim.b.cursor_row_now = vim.fn.getcurpos(vim.fn.win_getid())[2]
    vim.b.diff = vim.b.cursor_row_prev - vim.b.cursor_row_now
    if math.abs(vim.b.diff) > 3 then -- たくさんジャンプしたら
        -- 動いているタイマーがあればストップする
        cursor_timer:stop()
        local counter = 1
        -- タイマーをスタートする
        uv.timer_start(cursor_timer, 0, 35, vim.schedule_wrap(
            function()
                vim.b.cursor_row_now = vim.fn.getcurpos(vim.fn.win_getid())[2]
                vim.b.diff = vim.b.cursor_row_prev - vim.b.cursor_row_now
                vim.b.cursor_row_prev = vim.b.cursor_row_prev -
                    ((vim.b.diff > 0) and math.ceil(vim.b.diff / 4) or math.floor(vim.b.diff / 4))
                vim.cmd.sign(string.format("unplace 31415 file=%s", vim.fn.expand("%:p")))
                vim.cmd.sign(string.format("place 31415 line=%d name=smoothcursor file=%s",
                    vim.b.cursor_row_prev, vim.fn.expand("%:p")))
                counter = counter + 1
                if counter > 200 or vim.b.diff == 0 then
                    cursor_timer:stop()
                end
            end)
        )
    else
        vim.b.cursor_row_prev = vim.b.cursor_row_now
        vim.cmd(string.format("silent! sign unplace 31415 file=%s", vim.fn.expand("%:p")))
        vim.cmd(string.format("silent! sign place 31415 line=%d name=smoothcursor file=%s",
            vim.b.cursor_row_now, vim.fn.expand("%:p")))
    end
end

コードは実にシンプルです。ある程度まとまって移動したらタイマーをスタートし、 sign に描画したカーソルを移動させるだけです。
上のコード中にはパラメーターをハードコードしていますが、パラメーターを調節すれば、追尾する速度を変化させることができます。

使い方

上の関数を、 CursorMoved,CursorMovedI で発火するようにオートコマンドを組めば簡単に利用できます。

GitHubで編集を提案

Discussion