💾

Neovimで今開いているファイルのパスをコピーするスクリプトを作った話

2023/06/07に公開

この記事を読んで、参考になりそうな読者

Neovimで自前のスクリプトで何かをできるようにしたい方

動作確認した環境

OS: Mac ventura 13.3.1
editor: Neovim v.0.9.1

背景

Neovimでファイルを編集している際に、たまにファイル名やファイルパスをクリップボードへコピーすることがありました。その度に、コマンドモードのfでファイルパスを見ながら、パスを手打ちするかgit statusの実行結果から該当ファイルのパスをコピーしていました。
1回くらいならまだできますが、1日に何度もやる機会が出てきたときに耐えられなくなってしまい、自前スクリプトで、それらの作業を簡略化しようと思った次第です。

実装

Git管理しているファイルのパスをコピーできれば、とりあえずOKであるため、以下のようなコードを書いてみました。
ファイルのパスをコピーするスクリプトはこちらです。

local M = {}

function M.copy_relative_file_path()
  local absolute_file_path = vim.api.nvim_buf_get_name(0)
  local git_path = vim.fn.system("git rev-parse --show-toplevel")

  local relative_file_path = "/" .. string.sub(absolute_file_path, git_path:len() + 1)
  local copy_command = "echo " .. "\"." .. relative_file_path .. "\"" .. " | pbcopy"
  vim.fn.system(copy_command)
  print(relative_file_path)
  print("command:" .. copy_command)
  return true
end
return M

キーバインドはこちら!
copy file pathの略でcfにしています。cfpでも良かったんですが、キーの押しやすさ重視でcfにしました。

local copy_file_path = require('user_name/scripts/copy_relative_file_path')
vim.keymap.set('n', '<leader>cf', copy_file_path.copy_relative_file_path, { silent = true, noremap = true })

ここからは、コードの解説です。
まず、Neovimで現在開いているファイルのフルパスを取得できる関数です。

vim.api.nvim_buf_get_name(0)

例えば、~/.config/nvim/init.luaを開いている時は、/Users/user_name/.config/nvim/init.luaが返されます。

次にこのコードは、.gitディレクトリが存在するディレクトリで実行した時に、実行したディレクトリパスを返してくれます。

vim.fn.system("git rev-parse --show-toplevel")

例えば、~/.config/nvimディレクトリを起点にgit管理されているとします。このディレクトリ上で、実行すると/Users/user_name/.config/nvimを返してくれます。

この2つのコードから得たファイルパスを差し引くことで、開いているファイルの相対パスを取得することができます。

local relative_file_path = "/" .. string.sub(absolute_file_path, git_path:len() + 1)

この相対パスをNeovim上でシェルスクリプトを実行して、クリップボードへコピーします。
この処理は、別の方法が色々ありそうですが、今回はこちらで行いました。pbcoyコマンドはMacのクリップボードへコピーするコマンドであるため、他のOSを使用している方は動かないと思います。Windowsの方はclipが有効かなと思います。

local copy_command = "echo " .. "\"." .. relative_file_path .. "\"" .. " | pbcopy"
vim.fn.system(copy_command)

こんな感じで相対パスをクリップボードへ書き込み、cmd+vでペーストすることができます。

動かしてみた

このスクリプトは、git管理しているファイルに対してのみ、相対パスをコピーできます。そのため、git管理していないファイルのパスをコピーしたい場合、改造する必要がありますので、ご注意ください。

今後のVim活について

今後、自前のスクリプトを作成するだけでなく、Vim活として以下のものを進めていこうかなと考えています!

  • Vim本来のキー操作の習得
  • VSCodeにあるマークダウンのプレビュー機能や
  • Vim上でターミナルを開いたときの幅や高さをいい感じに調整したい。
  • Vim上でプルリクエストを作成できるようにしたい。
  • Vimの画面の縦半分にターミナルを表示したい
  • 新規作成したファイルに書き込むためのスニペットの強化

最後に

Discussion