💞
Vim script / Neovim luaで現在のファイルのパスと行数をコピーするコマンド
この記事はVim駅伝の2025-06-27の記事です。
前回の記事はs-showさんのNix を使って複数バージョンの Neovim をインストールする方法です。
Vim駅伝は常に参加者を募集しています。詳しくはこちらのページをご覧ください。
設定ファイルに入れて使っている、「現在のファイルのパスと行数をコピーするコマンド」を共有します。
同様の機能を提供しているプラグインもいろいろあると思いますが、このくらいなら自分の設定に入れておいても良いのではと思います。
定義
Vim script版
function! s:copy_path(target, range, line1, line2) abort
" defaultはrelative path
let expr = '%'
if a:target == 'full path'
let expr ..= ':p'
elseif a:target == 'file name'
let expr ..= ':t'
endif
let range_str = ''
if a:range > 0
if a:line1 == a:line2
let range_str = '#L' .. a:line1
else
let range_str = '#L' .. a:line1 .. '-L' .. a:line2
endif
endif
let result = expand(expr) .. range_str
let @* = result
echo 'Copy ' .. a:target .. ': ' .. result
endfunction
command! -range CopyFullPath call s:copy_path('full path', <range>, <line1>, <line2>)
command! -range CopyFileName call s:copy_path('file name', <range>, <line1>, <line2>)
command! -range CopyRelativePath call s:copy_path('relative path', <range>, <line1>, <line2>)
Neovim lua版
local function get_range_str(opts)
if opts.range ~= 2 then
return ''
end
if opts.line1 == opts.line2 then
return '#L' .. opts.line1
end
return '#L' .. opts.line1 .. '-L' .. opts.line2
end
local function copy_path(opts, target)
local expr = '%'
if target == 'full path' then
expr = '%:p'
elseif target == 'file name' then
expr = '%:t'
end
local path = vim.fn.expand(expr) .. get_range_str(opts)
vim.fn.setreg('*', path)
vim.notify('Copied ' .. target .. ': ' .. path)
end
vim.api.nvim_create_user_command('CopyFullPath', function(opts)
copy_path(opts, 'full path')
end, { range = true, desc = 'Copy the full path of the current file to the clipboard' })
vim.api.nvim_create_user_command('CopyRelativePath', function(opts)
copy_path(opts, 'relative path')
end, { range = true, desc = 'Copy the relative path of the current file to the clipboard' })
vim.api.nvim_create_user_command('CopyFileName', function(opts)
copy_path(opts, 'file name')
end, { range = true, desc = 'Copy the file name of the current file to the clipboard' })
つかいかた
:CopyFileName
のように呼び出すと、vimrc
のように、現在のファイル名をコピーします。
また、ビジュアルモードから:'<,'>CopyRelativePath
のように使うこともできます。この場合は.config/nvim/init.lua#120
のように行数がコピーされます。複数行を選択していた場合には.config/nvim/init.lua#120-L125
のようになります。
なお、unnamed(*
)レジスタを使っているので、ほかのレジスタが良い場合は書き換えてください。
Discussion