📝

VSCodeVimからVSCode Neovimに移行したのでメモ

2024/01/22に公開

はじめに

こんにちは、今回はVSCodeVimからVSCode Neovimに移行したので、それに関するメモをまとめて記事にしています。

Neovimの環境はLazyVimを使用しています。その他のプラグインを使用している場合は適宜読み替えてください。

この記事の主な対象読者

  • VSCodeVimを使っている方
  • VSCode Neovimに興味がある方

なぜ移行を考えたか

まず、筆者のVim歴は10か月程度です。普段からVimエディタは使用せず、VSCodeVimを用いてVS Codeでコーディングをしています。

ただ、.での繰り返しや:を用いたコマンドを使いこなせておらず、Vimをちゃんと勉強したいなと思い、最近になってcrafzdogさんの設定を参考にLazyVimを用いたNeovimの環境を整えて少し触っていました。

結局、Copilot ChatやRemote SSHなどの有用な拡張機能が手放せないのでVS Codeを利用することにしたのですが、Neovimを触ったことでVSCodeVimが使いづらいと感じたため、VSCode Neovimに移行することを考えました。

移行するメリット

VSCodeVimとVSCode Neovimの違いはyubrotさんの記事にまとまっていますので、こちらを参照してください。

筆者のVSCodeVim環境ではundoが壊れるということはあまりありませんでしたが、カーソルの移動がもっさりしたり、Saveが重くなったりすることがあったので、やはりVSCode Neovimよりは劣っているように感じます。

特に、以下のように:hなどの主要コマンドが実装されていなかったり、コマンドの入力が分かりやすく表示されないのは我慢できませんでした。その点、VSCode Neovimはこの要件を満たしています。

VSCode Neovimの場合
VSCode Neovimでコマンドを打つと上部に表示され、見やすい

VSCodeVimの場合
VSCodeVimでコマンドを打つと下部に表示され、対応していないコマンドもある

VSCodeVimの設定

VSCodeVimは以下のように設定していました。

settings.json
/* Vim Settings */
  "vim.hlsearch": true,
  "vim.easymotion": true,
  "vim.leader": "<space>",
  "vim.useSystemClipboard": true,
  "vim.visualstar": true,
  "vim.camelCaseMotion.enable": true,
  "vim.insertModeKeyBindings": [
    {
      "before": [
        "j",
        "k"
      ],
      "after": [
        "<ESC>"
      ]
    }
  ],
  "vim.normalModeKeyBindings": [
    {
      "before": [
        "u"
      ],
      "commands": [
        {
          "command": "undo"
        }
      ]
    },
    {
      "before": [
        "<C-r>"
      ],
      "commands": [
        {
          "command": "redo"
        }
      ]
    },
    {
      "before": [
        "j"
      ],
      "after": [
        "g",
        "j"
      ]
    },
    {
      "before": [
        "k"
      ],
      "after": [
        "g",
        "k"
      ]
    },
    {
      "before": [
        "n"
      ],
      "after": [
        "n",
        "z",
        "z"
      ]
    },
    {
      "before": [
        "N"
      ],
      "after": [
        "N",
        "z",
        "z"
      ]
    },
    {
      "before": [
        "*"
      ],
      "after": [
        "*",
        "z",
        "z"
      ]
    },
    {
      "before": [
        "#"
      ],
      "after": [
        "#",
        "z",
        "z"
      ]
    },
    {
      "before": [
        "+"
      ],
      "after": [
        "<C-a>"
      ]
    },
    {
      "before": [
        "-"
      ],
      "after": [
        "<C-x>"
      ]
    },
    {
      "before": [
        "<Leader>",
        "/"
      ],
      "commands": [
        {
          "command": "editor.action.commentLine"
        }
      ]
    },
    {
      "before": [
        "<Leader>",
        "s"
      ],
      "after": [],
      "commands": [
        {
          "command": "workbench.action.files.save",
        }
      ]
    },
    {
      "before": [
        "<Leader>",
        "w"
      ],
      "after": [],
      "commands": [
        {
          "command": "workbench.action.closeActiveEditor",
        }
      ]
    },
    {
      "before": [
        "<C-h>",
      ],
      "after": [
        "^"
      ]
    },
    {
      "before": [
        "<C-l>",
      ],
      "after": [
        "$"
      ]
    },
    {
      "before": [
        "<Leader>",
        "m"
      ],
      "after": [
        "%"
      ]
    },
    {
      "before": [
        "<Leader>",
        "z"
      ],
      "commands": [
        ":noh"
      ]
    }
  ],
  "vim.visualModeKeyBindings": [
    {
      "before": [
        "<C-h>",
      ],
      "after": [
        "^"
      ]
    },
    {
      "before": [
        "<C-l>",
      ],
      "after": [
        "$"
      ]
    },
    {
      "before": [
        "<Leader>",
        "m"
      ],
      "after": [
        "%"
      ]
    },
  ]

この設定はVimmerのVimmerによるVimmerのためのVSCode環境構築を参考にしています。
上記の設定をVSCode Neovimで同じように設定します。

VSCode Neovimの設定

settings.json

VSCode NeovimはローカルのNeovimと設定ファイルを以下のように設定して読み込ませます。

settings.json
  /* NeoVim Settings */
  "vscode-neovim.neovimExecutablePaths.darwin": "/opt/homebrew/bin/nvim",
  "vscode-neovim.neovimInitVimPaths.darwin": "/Users/yutanishi/.config/nvim/init.lua",

init.lua

pathに指定したinit.luaは以下のように設定しています。

init.lua
if vim.g.vscode then
  require("config.keymaps")
  require("config.options")
else
  require("config.lazy")
end

vim.g.vscodeでVSCode Neovimを使用する場合の判定をしています。
keymapsoptionsのみを反映させたいので上記のようにしています。

keymaps.lua

keymaps.luaは以下のように設定しています。

keymaps.lua
local keymap = vim.keymap
local opts = { noremap = true, silent = true }

-- Insert mode mapping
keymap.set("i", "jk", "<ESC>", opts)

-- Normal mode mappings
keymap.set("n", "<C-h>", "^", opts)
keymap.set("n", "<C-l>", "$", opts)

-- Inc/Dec settings
keymap.set("n", "+", "<C-a>", opts)
keymap.set("n", "-", "<C-x>", opts)

-- To avoid easymotion
keymap.set("n", "s", '"_s', opts)

-- Visual mode mappings
keymap.set("v", "<C-h>", "^", opts)
keymap.set("v", "<C-l>", "$", opts)

options.lua

options.luaは以下のように設定しています。
ただ、元々多くの設定をしているのでどれが反映されているか分かっていません。
意図的に追加した設定を抜粋しています。

options.luaの抜粋
vim.g.mapleader = " "
vim.opt.clipboard = "unnamedplus"

設定で詰まったところ

Neovim移行で詰まったところは以下の3点です。

insert mode mappingが反映されない

keymaps.luaの設定を先述しましたが、VSCode Neovimではinsert modeに対するカスタムマッピング設定は適用できません。公式ドキュメントの通りにsettings.jsonを設定して解決しました。

settings.jsonの抜粋
  "vscode-neovim.compositeKeys": {
    "jk": {
      "command": "vscode-neovim.escape",
    }
  },

SpaceをLeaderに割り当てられない

options.luavim.g.mapleader = " "を設定しているのでSpaceがLeaderに割り当てられています。しかし、VSCode NeovimではLeaderを用いた操作が想定されていないようでこの設定は反映されませんでした。

仕方ないので、Spaceを用いたVS Codeの操作はkeybindings.jsonで設定して解決しました。

keybindings.jsonの抜粋
  {
    "key": "space s",
    "command": "workbench.action.files.save",
    "when": "neovim.mode == normal && editorTextFocus"
  },
  {
    "key": "space /",
    "command": "editor.action.commentLine",
    "when": "neovim.mode == normal && editorTextFocus"
  },
  {
    "key": "space w",
    "command": "workbench.action.closeActiveEditor",
    "when": "neovim.mode == normal && editorTextFocus"
  }

yankがclipboardにコピーされない

元々のLazyVimではカスタムの設定を追加しなくてもyankがclipboardにコピーされていました。
多分LazyVimのデフォルトの設定でそうなっていたので、VSCode Neovimでもコピーされるようにoptions.luaで明示的に設定しました。

options.luaの抜粋
vim.opt.clipboard = "unnamedplus"

解決できなかったこと

VSCode NeovimはLeaderの設定が反映されなかったので、下記のようにVS Codeの機能ではないLeaderを用いたカスタムキーバインドが適用できませんでした。もしわかる方がいらっしゃれば、コメントしていただけると嬉しいです。

ただ、普段からあまり使わない設定ばかりだったので、ダメージは0です。

settings.jsonの抜粋
    {
      "before": [
        "<Leader>",
        "m"
      ],
      "after": [
        "%"
      ]
    }

さいごに

VSCode Neovimに移行してからまだ2日しか経っていませんが、挙動のもっさり感もなくなり、普段使いのコマンドはすべて使えるので大満足です。
私はライトVimmerなので、VS Codeで使う場合はプラグインを入れる運用をしないつもりですが、色々とカスタマイズのしがいがありそうで良い拡張機能だと思いました。

GitHubで編集を提案

Discussion