GitHubのパーマリンクと選択範囲をコードスニペットとしてコピーするキーマップを設定した

開発時のメモを取ったりコードリーディングをする際に該当箇所へのパーマリンクだけではなく関心のある範囲のコードをノートに貼りたい時がありました。 そのための設定をgitlinker.nvimというプラグインと組み合わせて書いてみました。

gitlinker.nvimは、現在開いているファイルや選択行に対応するGitHubなどのリモートリポジトリへのパーマリンクの取得、そのパーマリンクをブラウザで開くなどの機能を提供するLua製のNeovimプラグインです。

github.com

下記のコードが今回追加した設定になります。 ScrapboxMarkdown形式でノートを書いていることが多いので、その2種類のフォーマットでコードをコピーできるようにしました。

https://github.com/tomato3713/dotfiles/blob/a382d5362f65881dcc98b268986f8a5ffbaf7512/nvim/dein.toml#L161-L207

local yank_markdown = function()
    local pos1 = vim.fn.getpos("v")[2]
    local pos2 = vim.fn.getcurpos()[2]

    local lstart = math.min(pos1, pos2)
    local lend = math.max(pos1, pos2)

    -- yank selected text
    local text = vim.api.nvim_buf_get_lines(0, tonumber(lstart)-1, tonumber(lend), false)

    local filename = vim.fn.expand('%:t')

    local yank_to_clipboard = function(text)
        return function(url)
            vim.fn.setreg('+', table.concat({url, '``` ' .. filename, text, '```'}, '\n'))
        end
    end

    require('gitlinker').get_buf_range_url("v", { action_callback =  yank_to_clipboard(table.concat(text, '\n')) })
end

local yank_scrapbox = function()
    local pos1 = vim.fn.getpos("v")[2]
    local pos2 = vim.fn.getcurpos()[2]

    local lstart = math.min(pos1, pos2)
    local lend = math.max(pos1, pos2)

    -- yank selected text
    local raw_text = vim.api.nvim_buf_get_lines(0, tonumber(lstart)-1, tonumber(lend), false)
    local text = {}
    for k, v in pairs (raw_text) do
        text[k] = '\t' .. v
    end

    local filename = vim.fn.expand('%:t')

    local yank_to_clipboard = function(text)
        return function(url)
            vim.fn.setreg('+', table.concat({url, 'code: ' .. filename, text}, '\n'))
        end
    end

    require('gitlinker').get_buf_range_url("v", { action_callback =  yank_to_clipboard(table.concat(text, '\n')) })
end
vim.keymap.set('v', '<leader>gs', yank_scrapbox, {silent = true, desc = 'yank links and selected text in Scrapbox format'})
vim.keymap.set('v', '<leader>gm', yank_markdown, {silent = true, desc = 'yank links and selected text in Markdown format'})

<leader>gsScrapbox形式で<leader>gmMarkdown形式でコピーするようにキーマッピングを設定しています。 実際に貼り付けられるテキストは次の形式になっています。

Scrapbox形式の場合

{パーマリンク}
code: {ファイル名}
\t{選択範囲のテキスト}

Markdown形式の場合

{パーマリンク}
``` {ファイル名}
{選択範囲のテキスト}
```