Open7

【ライト層向け】VSCode を活かしつつ Vim + tmux の操作感に近づけたときのメモ

yuyu

VSCode で Vim + tmux の操作感を目指して設定した時のメモです。
実装中の操作についてはマウスゼロでやりたいことはできてるかなと思っています。

Vim のキーバインドは好きなんだけど、設定を頑張りすぎるのはちょっと辛いって感じなので同じ様な人がいれば参考になればと思います。

モチベーション

一人でただただコーディングするなら快適なのは Vim ですが、チームで開発しているとなんだかんだ VSCode の方が良い場面が多いと感じます。
なんだかんだ VSCode の方が見た目変えたり拡張機能入れたりは適当にバンバンやって大丈夫なので好きです。(結構気分で見た目を変えるので)

一番大きいのは Git のログを見るのがターミナルや Vim だと気に入るのがなく て、そこら辺は圧倒的に VSCode の方が便利だなって感じています。(特に視認性)

Git 操作自体はコマンドでやってるので変わらずです。

https://zenn.dev/yu_undefined/scraps/48258218a4d18e

エディタ遍歴

Eclipse → Atom → Sublime → Brackets → Atom → VSCode → Vim → NeoVim + Tmux → VSCode → NeoVim + Tmux(繰り返し)

何度も Vim と VSCode の行き来をしています。

方針

  • 設定を頑張りすぎない
  • Vim に完全に寄せるのではなく、Vim のキーバインドを使いつつ VSCode のいいとこどりをしたい
  • VSCode も活かす
  • 基本操作はマウスゼロ
  • 設定の移行は簡単にしたい
yuyu

VSCode に入れる拡張機能

検索すると Vim に関する拡張機能が2つ出てくると思いますが、僕が最終的に入れてるのは前者のシンプルな vscodevim.vim の方にしています。
どちらも使ったのですが、最終的に僕に合うのはこちらでした。

↓こっち
https://marketplace.visualstudio.com/items?itemName=vscodevim.vim

https://marketplace.visualstudio.com/items?itemName=asvetliakov.vscode-neovim

理由

vscode-neovim は vim の設定をそのまま活用して VSCode で Vim の挙動を再現していると思いますが、VSCode では特に使いたくない設定とかもそのまま使われてしまうというところが問題でした。

かといって、ターミナルを操作する際には Vim を触る時もあるので設定を VSCode 用に減らすのはちょっと嫌でした。
もしかしたら設定ファイルの中で VSCode との出しわけとかができるかもしれないですがどれを使ってどれを使わないのかとかを細かくいじるのが面倒に感じました。

また、設定ファイルの関係なのか動作がもっさりしたり想定していない挙動になったり(再現の限界?)があったりしたので使っていてストレスだったのでやめました。

vscodevim.vim の方は特に設定などは参照せずにキーバインドが導入されるだけの様なライトな感じなのが良いです。
ある程度の設定は VSCode 上で完結しますし、必要があれば設定ファイルを読み込むこともできます。
上記の理由から本当は設定ファイルは読み込ませたくなかったのですが、ヤンクとクリップボードの設定だけどうしても Vim 側で設定しないと理想の挙動にならなかったのでそれだけ書いた VSCode 用の .vimrc を用意して読み込ませています。

惜しいところ

コマンドモードの再現度が低い

シンプルな置き換え系のコマンドは動くんですが、範囲を指定したものだったり複雑なコマンドは動きません。
NeoVim の方なら動くんですが、個人的にはシンプルな置換だけできれば一旦いいかなと思ってます。

コマンド入力が見えづらい

VSCode のステータスバーが色々表示があったり文字が小さかったりするので見えづらいです。
NeoVim の方だとダイアログが表示されて入力できるので、もしこの入力方式になってくれたらほぼ完璧だと思います。

yuyu

設定は dotfiles で共有する

VSCode や Vim の設定は dotfiles を作ってそこで運用しています。
色々情報が載っているのでリポジトリは private にしていてお見せできないですが、新しいPCを手に入れたらまずはこの dotfiles からファイルをダウンロードして、手順に沿ってコマンドを叩けば諸々の設定が終わる様にしています。

その中で VSCode と Vim の設定も用意しています。

  • .vimrc(VSCode用)
  • keybindings.json
  • settings.json
  • snippets

これらのVSCodeの設定用に必要な以下のディレクトリやファイルを管理していて、本来あるべき場所に dotfiles においてあるファイルのシンボリックリンクを置く様にしています。

設定ファイル

.vimrc

設定は VSCode 側に寄せたかったので作らなくて済むなら作りたくないけど、クリップボードの連携が一番これが理想に近いのでこれだけ設定に書いてます。
キーバインドとか設定で似た様なことをしたけどなんか思った通りの動きにできなかった。

" VSCode 用の設定ファイル
vnoremap p "_dP
keybindings.json

NeoVim + Tmux の時の操作感を目指してこの設定になってます。

[
  {
    "key": "ctrl+t l",
    "command": "workbench.action.terminal.focusNextPane",
    "when": "terminalFocus"
  },
  {
    "key": "ctrl+t h",
    "command": "workbench.action.terminal.focusPreviousPane",
    "when": "terminalFocus"
  },
  {
    "key": "ctrl+t k",
    "command": "workbench.action.focusActiveEditorGroup",
    "when": "terminalFocus"
  },
  {
    "key": "ctrl+t j",
    "command": "workbench.action.terminal.focus",
    "when": "editorTextFocus || filesExplorerFocus"
  },
  {
    "key": "ctrl+t h",
    "command": "workbench.explorer.fileView.focus",
    "when": "editorTextFocus"
  },
  {
    "key": "ctrl+t l",
    "command": "workbench.action.focusActiveEditorGroup",
    "when": "filesExplorerFocus"
  },
  {
    "key": "a",
    "command": "explorer.newFile",
    "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceReadonly && !inputFocus"
  },
  {
    "key": "ctrl+a",
    "command": "explorer.newFolder",
    "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceReadonly && !inputFocus"
  },
  {
    "key": "d",
    "command": "deleteFile",
    "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceReadonly && !inputFocus"
  },
  {
    "key": "y",
    "command": "filesExplorer.copy",
    "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus"
  },
  {
    "key": "p",
    "command": "filesExplorer.paste",
    "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus"
  },
  {
    "key": "ctrl+o",
    "command": "explorer.openAndPassFocus",
    "when": "filesExplorerFocus && foldersViewVisible && !explorerResourceIsFolder && !inputFocus"
  },
  {
    "key": "cmd+down",
    "command": "-explorer.openAndPassFocus",
    "when": "filesExplorerFocus && foldersViewVisible && !explorerResourceIsFolder && !inputFocus"
  },
  {
    "key": "ctrl+t f",
    "command": "workbench.action.toggleEditorWidths",
    "when": "editorTextFocus"
  },
  {
    "key": "ctrl+t shift+f",
    "command": "workbench.action.evenEditorWidths",
    "when": "editorTextFocus"
  },
  {
    "key": "ctrl+t m",
    "command": "workbench.action.joinTwoGroups",
    "when": "editorTextFocus"
  },
  {
    "key": "ctrl+shift+n",
    "command": "workbench.action.terminal.rename",
    "when": "terminal.active"
  }
]
settings.json

"vim.vimrc.path": "/Users/[ユーザー名]/.vimrc", のユーザー名は伏せてますが、PCの設定に合わせたものに変えて使っています。
ターミナルで実際に動かす Vim は NeoVim にしていて、nvim/config の方に設定を書いてあるのでユーザーのところにある .vimrc は VSCode 用として使ってます。

{
  "workbench.colorTheme": "GitHub Dark",
  "workbench.iconTheme": "material-icon-theme",
  "workbench.startupEditor": "none",
  "material-icon-theme.folders.theme": "classic",
  "terminal.integrated.fontFamily": "MesloLGS NF",
  "editor.tabSize": 2,
  "editor.minimap.enabled": false,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.cursorSurroundingLines": 999,
  "security.workspace.trust.enabled": false,
  "security.workspace.trust.emptyWindow": false,
  "vim.hlsearch": true,
  "vim.statusBarColorControl": false,
  "vim.useSystemClipboard": true,
  "vim.surround": true,
  "vim.replaceWithRegister": true,
  "vim.easymotion": true,
  "vim.leader": "<space>",
  "vim.vimrc.enable": true,
  "vim.vimrc.path": "/Users/[ユーザー名]/.vimrc",
  "vim.normalModeKeyBindingsNonRecursive": [
    {
      "before": ["j"],
      "after": ["g", "j"]
    },
    {
      "before": ["k"],
      "after": ["g", "k"]
    },
    {
      "before": ["x"],
      "after": ["\"", "_", "x"]
    },
    {
      "before": ["s"],
      "after": ["\"", "_", "s"]
    },
    {
      "before": ["<Esc>", "<Esc>"],
      "commands": [":nohlsearch"],
      "when": "editorTextFocus && vim.active && vim.mode != 'Insert'"
    }
  ],
  "[markdown]": {
    "editor.formatOnSave": false
  },
  "[frag]": {
    "editor.formatOnSave": false
  },
  "[vert]": {
    "editor.formatOnSave": false
  },
  "[glsl]": {
    "editor.formatOnSave": false
  },
  "window.openFoldersInNewWindow": "on",
  "window.zoomLevel": 1,
  "terminal.integrated.tabs.enabled": false
}
yuyu

VSCode でのターミナルの操作

ターミナルの表示/非表示

Ctrl + `

VSCode のデフォルト

ターミナルへのフォーカス移動

Ctrl + tj

Tmux のプレフィックスを t にしていたのでその名残
vim の上下の移動のイメージで下に移動する時は j

{
  "key": "ctrl+t j",
  "command": "workbench.action.terminal.focus",
  "when": "editorTextFocus || filesExplorerFocus"
}

ターミナルからエディタへのフォーカス移動

Ctrl + tk

Tmux のプレフィックスを t にしていたのでその名残
vim の上下の移動のイメージで上に移動する時は k

{
  "key": "ctrl+t k",
  "command": "workbench.action.focusActiveEditorGroup",
  "when": "terminalFocus"
},

新規のターミナルウィンドウを開く

+ Ctrl + `

VSCode のデフォルト

フォーカスしているターミナルウィンドウの名前を変更

+ Ctrl + n

VSCode のキーバインドで設定した

  {
    "key": "ctrl+shift+n",
    "command": "workbench.action.terminal.rename",
    "when": "terminal.active"
  }

次のターミナルウィンドウを表示

+ + ]

VSCode のデフォルト

フォーカスしているターミナルを閉じる

e と入力してエンター

exit コマンドのエイリアスを .zshrc で設定しているのでそれを使っている

ターミナルウィンドウのサイズを拡大/縮小する

拡大 + +
縮小 + +

yuyu

VSCode を立ち上げる

ランチャーアプリで Raycast を使っているのでその拡張機能で立ち上げています。
Raycast は Spotlight を上書きして + space で立ち上がる様にしています。

拡張機能はこちら
https://www.raycast.com/thomas/visual-studio-code

過去に立ち上げたことがあるプロジェクト

  • Raycast を立ち上げる
  • vs とか入力して Search Recent Projects を選択する
  • 過去に開いたことのあるプロジェクトが出てくるので開きたいプロジェクトを選択

新規でプロジェクトを立ち上がる

これもコマンドとかにできたらいいんですが今はターミナルを立ち上げてそこでコマンドでディレクトリを作って立ち上げる様にしています。

  • Raycast を立ち上げる
  • i と入力して候補に出てくる iTerm を選択してターミナルを開く
  • 任意のディレクトリに移動して mkdir でディレクトリを作る
  • code ディレクトリ名 で作ったディレクトリを VSCode で立ち上げる
yuyu

エクスプローラーの操作

左サイドメニューの開閉

+ b

VSCode のデフォルト

エクスプローラーを開く

+ e

VSCode のデフォルト

エクスプローラーへのフォーカス移動

Ctrl + th

Tmux のプレフィックスを t にしていたのでその名残
vim の左右の移動のイメージで左に移動する時は h

{
  "key": "ctrl+t h",
  "command": "workbench.explorer.fileView.focus",
  "when": "editorTextFocus"
}

エクスプローラーからエディタへのフォーカス移動

Ctrl + tl

Tmux のプレフィックスを t にしていたのでその名残
vim の左右の移動のイメージで上に移動する時は l

{
  "key": "ctrl+t l",
  "command": "workbench.action.focusActiveEditorGroup",
  "when": "filesExplorerFocus"
}

エクスプローラー内の上下左右の移動

h, j, k, l

vim の拡張機能のデフォルト

新規ファイル作成

a

{
  "key": "a",
  "command": "explorer.newFile",
  "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceReadonly && !inputFocus"
}

新規ディレクトリ作成

Ctrl + a

{
  "key": "ctrl+a",
  "command": "explorer.newFolder",
  "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceReadonly && !inputFocus"
}

ファイル/ディレクトリ名の変更

enter

VSCode のデフォルト

ファイル/ディレクトリの削除

d

{
  "key": "d",
  "command": "deleteFile",
  "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceReadonly && !inputFocus"
}

ファイル/ディレクトリのコピー

y

{
  "key": "y",
  "command": "filesExplorer.copy",
  "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus"
}

ファイル/ディレクトリの貼り付け

p

{
  "key": "p",
  "command": "filesExplorer.paste",
  "when": "explorerViewletVisible && filesExplorerFocus && !explorerResourceIsRoot && !explorerResourceReadonly && !inputFocus"
}

ファイルを開く

o

VSCode のデフォルト

ファイルを開いて、そのファイルにフォーカスを当てる

Ctrl + o

VSCode のデフォルトだと + なんですが、個人的には合わなかったので上書きをしています

{
  "key": "ctrl+o",
  "command": "explorer.openAndPassFocus",
  "when": "filesExplorerFocus && foldersViewVisible && !explorerResourceIsFolder && !inputFocus"
},
{
  "key": "cmd+down",
  "command": "-explorer.openAndPassFocus",
  "when": "filesExplorerFocus && foldersViewVisible && !explorerResourceIsFolder && !inputFocus"
}
yuyu

エディタの操作

基本は VSCode のデフォルトを使っていますが、タブ移動など一部は Vim の拡張機能のデフォルトを使っています。

新規ファイルを開く

+n

VSCode のデフォルト

タブを移動

gt で右
gT で左

タブを閉じる

+ w

VSCode のデフォルト

Vim 拡張機能のデフォルト

分割されたウィンドウの移動

Ctrl + wh, j, k, l

Vim の拡張機能のデフォルト

ホバーした時に表示される注釈を表示する

+ k + i

VSCode のデフォルト
個人的にこれがかなり便利

ファイル検索

+ p

VSCode のデフォルト

文字列検索

+ f

VSCode のデフォルト