半端VimerのVSCode+Vimの設定

2021年12月6日

(2021年12月6日 追記)

この記事を見てくれてる方へ

この記事はやたら頻繁に更新されます。これからも多分突然更新するため、もし気になる設定あればどっかにコピペしとくことをオススメします。次見たときには消えてるかもしれません。

あと、他にも「こんなのおすすめ!」とか「それよりもこっちのがいいよ!」とかあれば教えて下さい。

(追記終わり)

VSCode-Vimを使いこなす

vimに惚れた

vimはすごい。といっても素のvimなんてほとんど使ったことないんだけど。数年前にPyCharmでVim拡張使ってみてはまった比較的歴史の浅いVim好きだ。独自設定もたいしてしてないし、バリバリ使いこなしてるわけではない。だがしかし!それでも便利なのがvimのすごいところなのだ。

VSCodeも負けちゃいない

とはいえ、意外とVSCodeも負けてはいない。Vim拡張なんて入れなくても便利な機能もショートカットもふんだんにそろっていて、たぶんキーボードだけで結構なことができるようになってる。こっちも使いこなしてるわけではないが、まぁそれでも便利なんだ。

Let’sいいとこどり

どっちも便利なんだから両方合わせたら超絶便利に決まってる。というわけでうまくいいとこどりして組み合わせていきたいのだ。

すでにVSCodeにVim拡張は入ってるものとして話をすすめる。

ちなみにWindows環境での設定。Linuxで同じ設定したら微妙に挙動が違ったの気がするので適宜微調整必要。

関連するVSCode拡張機能

VSCodeVimはもちろんだが、それ以外にも下記キー設定ではこれらの拡張機能を使用している。

  • leader + s -> CodeRunner
  • Ctrl+m + <キー> -> Bookmarks

上記キー設定に限り、拡張をインストールしないと動かないためあしからず。

VSCode-Vimのためのsetting.json

VSCode-vim基本設定

setting.json 内のVSCode基本設定とvim関連設定はこんな感じ。(その他拡張機能関連は省略してる)

    //----------------------------
    // 使い勝手よくするための設定
    //----------------------------
    "editor.rulers": [80], // 80文字にライン表示
    "editor.formatOnSave": true, // 保存時オートフォーマット
    "workbench.editor.wrapTabs": true, // タブを折り返す
    "editor.minimap.enabled": false,// ミニマップ非表示
    "explorer.confirmDragAndDrop": false, // Drag&Dropは確認なしで認める
    "editor.lineNumbers": "relative",// 数字+jkで移動するため相対行番号表示
    "files.trimFinalNewlines": true, // ファイル末尾の空行削除
    "files.trimTrailingWhitespace": true,// 行末尾の空白削除
    //-----------------------------
    // vim設定
    //-----------------------------
    "vim.useSystemClipboard": true, // クリップボード共有
    "vim.hlsearch": true, // 検索単語ハイライト
    "vim.visualstar": true, // カーソル下を*で検索
    "vim.incsearch": true, //インクリメンタルサーチ
    "vim.leader": "<space>", // leaderはスペースキーに
    "vim.whichwrap": "h,l,<,>,[,]", // 左右移動で行またぐ
    "vim.foldfix": true, // 折りたたみ部分はまたいで移動
    // vim拡張設定
    "vim.sneak": true,
    "vim.surround": true,
    // ノーマルモード時は日本語入力自動制御
    "vim.autoSwitchInputMethod.obtainIMCmd": "C:\\Windows\\zenhan.exe",
    "vim.autoSwitchInputMethod.switchIMCmd": "C:\\Windows\\zenhan.exe {im}",
    "vim.autoSwitchInputMethod.defaultIM": "0",
    "vim.autoSwitchInputMethod.enable": true,

コメントのとおり。vim拡張機能はsneak,surroundを有効にしてある。最初はeasymotionも有効にしてたんだけど、sneakと数字+jk移動で十分だった。

左右移動で行またぎは既存のエディタと同じ感覚で移動できるようにしただけなのだけど、vimになれるといらないかもしれない。

最下部4行のノーマルモード時のみIME切設定は以下のリンクのzenhan.exeを使わせてもらっている。zenhan.exeをC:/Windows/に入れとかないと設定効かないので注意。

Win版の VS Code+VSCodeVim でノーマルモードに戻った時にIMEを半角英数入力にする – Qiita

vim キー設定

vimのキーマップはsetting.jsonに記述する。

vimキー変更

個人的にvimのキーで気に食わないところをいくつか変更している。コメントアウトはgccがめんどいのでccだけでできるように、shiftやctrlとの組み合わせよりも単発キーのが当然押しやすいためマーク位置ジャンプは¥を割り当ててる。

shift+hlは上下が見えないのが嫌なので、画面中央位置に補正する。

インサートモードではctrl+lをDeleteキー(右側消去)にしている。括弧の入力で勝手に出てくる閉じ括弧を消したいことが結構あるので。

多分他のvim系変更はよく見るようなやつだと思う。

vim仕様からVSCode仕様に

Undo,Redo,ジャンプリストはVSCode仕様に変更している。

VSCode Vimのundo,redoはVSCode(というか普通の)undo,redoとは挙動が異なるのでVSCodeに合わせておく方が事故が少ない。おそらくディープなVimmerでない限りVSCode仕様のほうが自然に感じると思う。

ジャンプリストは悩みどころだが、vimはおおざっぱ、かつエディタグループの位置を記憶しないので、VSCode仕様に合わせておく方が自然に見える。

leader設定

スペースが押しやすいため、leaderキーを多用するスタイル。ほとんどのキーにleader+を設定している。

leader+の組み合わせは2ストロークにはなるけども、Shift+やCtrl+より押しやすいと思う。よく使うコマンドは一通りはleader+キーで実行できるようにしておく。

あと特殊な貼付けを追加した。めったに使うもんじゃないけど、カッコ内置換やコメント化して貼り付け、コメント解除して貼り付けは意外と使うことに気づいた。

というわけで、これらまとめたsetting.json の続きがこれ。

    //-----------------------------
    // vimキー変更
    //------------------------------
    "vim.normalModeKeyBindingsNonRecursive": [
        { "before": [ "Y" ], "after": [ "y", "$" ] }, // Yはカーソル後ヤンクに変更
        { "before": [ "\\" ], "after": [ "`" ] }, // \でマーク位置にジャンプする
        { "before": [ "c","c" ], "after": ["g", "c","c" ] }, // c,cでコメントアウト
        { "before": [ "j" ], "after": [ "g", "j" ] }, // 見た目の行で移動
        { "before": [ "k" ], "after": [ "g", "k" ] }, // 見た目の行で移動
        { "before": [ "H" ], "after": [ "H", "z", "." ] }, // 実質半PageUp
        { "before": [ "L" ], "after": [ "L", "z" , "."] }, // 実質半PageDown
        { "before": [ "ctrl+h" ], "commands": ["workbench.action.nextEditorInGroup"] }, // グループ内次ファイル
        { "before": [ "ctrl+l" ], "commands": ["workbench.action.previousEditorInGroup"] }, // グループ内前ファイル
        { "before": [ "<Enter>" ], "commands": [ "editor.action.insertLineAfter" ] }, // Enterで改行

        // leader設定をアルファベット順に並べておく
        { "before": [ "leader", "a" ], "after": [ "g", "g", "v", "G" ] }, // 全選択
        { "before": [ "leader", "b" ], "commands": [ "workbench.action.debug.start" ] }, // デバッグ開始(python)
        { "before": [ "leader", "c" ], "after": [ "g", ";" ] }, //前に変更した場所
        { "before": [ "leader", "d" ], "commands": [ "editor.action.revealDefinition" ] }, // 定義位置に移動
        { "before": [ "leader", "e" ], "commands": [ "editor.action.marker.next" ] }, // 次のエラーに移動
        { "before": [ "leader", "f" ], "commands": [ "workbench.action.findInFiles" ] }, // 全てから検索
        { "before": [ "leader", "g" ], "commands": [ ":jump" ] }, // vimのジャンプリスト
        { "before": [ "leader", "h" ], "commands": [ "workbench.action.focusLeftGroup" ] }, // エディタグループ移動
        { "before": [ "leader", "i" ], "commands": [ "editor.action.goToImplementation" ] }, // 実装に移動
        { "before": [ "leader", "j" ], "after": [ "1", "0", "j" ] }, // 10行下
        { "before": [ "leader", "k" ], "after": [ "1", "0", "k" ] }, // 10行上
        { "before": [ "leader", "leader", "j" ], "after": [ "2", "0", "j" ] }, // 20行下
        { "before": [ "leader", "leader", "k" ], "after": [ "2", "0", "k" ] }, // 20行上
        { "before": [ "leader", "leader", "leader", "j" ], "after": [ "3", "0", "j" ] }, // 30行下
        { "before": [ "leader", "leader", "leader", "k" ], "after": [ "3", "0", "k" ] }, // 30行上
        { "before": [ "leader", "l" ], "commands": [ "workbench.action.focusRightGroup" ] }, // エディタグループ移動
        { "before": [ "leader", "m" ], "commands": [ ":marks" ] }, // vimのマークリスト
        { "before": [ "leader", "n" ], "commands": [ "editor.action.rename"] }, // 変数名変更
        { "before": [ "leader", "o" ], "commands": [ "workbench.action.openRecent" ] }, // 最近開いた項目
        { "before": [ "leader", "p" ], "after": [ "\"", "0", "p" ] }, // 直前にコピーした行を貼り付け(切り取り含まず)
        { "before": [ "leader", "q" ], "commands": [ "editor.action.showHover"] }, // ホバー表示
        { "before": [ "leader", "r" ], "commands": [ "editor.action.goToReferences" ] }, // 参照位置に移動
        { "before": [ "leader", "s" ], "commands": [ "workbench.action.files.save","workbench.action.terminal.scrollToBottom", "code-runner.run" ] }, // 保存実行
        { "before": [ "leader", "t" ], "commands": [ "copyFilePath", "workbench.action.terminal.focus" ] },
        { "before": [ "leader", "u" ], "commands": [ "editor.toggleFold" ] }, // 折り畳みの切替
        //{ "before": [ "leader", "v" ], "commands": [ "" ] }, // 貼り付けいろいろ(下記)
        { "before": [ "leader", "w" ], "commands": [ "workbench.action.files.save" ] }, // 保存:wやCtrl+sが面倒なので
        { "before": [ "leader", "x" ], "commands": [ ":register" ] }, // レジスタの中を確認
        { "before": [ "leader", "y" ], "commands": [ "editor.unfoldAll" ] }, // すべて展開
        { "before": [ "leader", "z" ], "commands": [ ":wq" ] }, // 保存して閉じる
        { "before": [ "leader", "]" ], "commands": [ "editor.action.jumpToBracket" ] }, // カッコに移動
        { "before": [ "leader", "[" ], "commands": [ "editor.action.jumpToBracket" ] }, // カッコに移動
        { "before": [ "leader", "@" ], "commands": [ "workbench.action.gotoSymbol" ] }, // シンボルに移動
        { "before": [ "leader", ":" ], "commands": [ "workbench.action.terminal.focus" ] }, // ターミナル開く
        { "before": [ "leader", "/" ], "after": ["g", "c" , "c"] }, // コメント切り替え
        // 特殊な貼り付け
        // --- 次or前の[]{}()<>内をレジスタ内の値に置き換える(括弧内でも有効だが括弧上では注意必要)
        { "before": [ "leader", "v", "[" ], "after": [ "t", "]", "\"", "z","d", "i", "[", "h", "p" ] },
        { "before": [ "leader", "v", "]" ], "after": [ "T", "[", "\"", "z","d", "i", "[", "h", "p" ] },
        { "before": [ "leader", "v", "{" ], "after": [ "t", "}", "\"", "z","d", "i", "{", "h", "p" ] },
        { "before": [ "leader", "v", "}" ], "after": [ "T", "{", "\"", "z","d", "i", "{", "h", "p" ] },
        { "before": [ "leader", "v", "(" ], "after": [ "t", ")", "\"", "z","d", "i", "(", "h", "p" ] },
        { "before": [ "leader", "v", ")" ], "after": [ "T", "(", "\"", "z","d", "i", "(", "h", "p" ] },
        { "before": [ "leader", "v", "b" ], "after": [ "t", ")", "\"", "z","d", "i", "(", "h", "p" ] },
        { "before": [ "leader", "v", "B" ], "after": [ "T", "(", "\"", "z","d", "i", "(", "h", "p" ] },
        { "before": [ "leader", "v", "<" ], "after": [ "t", ">", "\"", "z","d", "i", "<", "h", "p" ] },
        { "before": [ "leader", "v", ">" ], "after": [ "T", "<", "\"", "z","d", "i", "<", "h", "p" ] },
        { "before": [ "leader", "v", "t" ], "after": [ "t", "<", "\"", "z","d", "i", "t", "h", "p" ] },
        { "before": [ "leader", "v", "T" ], "after": [ "T", ">", "\"", "z","d", "i", "t", "h", "p" ] },
        // --- 引用符系は内部でのみ動作
        { "before": [ "leader", "v", "\"" ], "after": [ "\"", "z", "d", "i", "\"", "h", "p" ] },
        { "before": [ "leader", "v", "`" ], "after": [ "\"", "z", "d", "i", "`", "h", "p" ] },
        { "before": [ "leader", "v", "'" ], "after": [ "\"", "z", "d", "i", "'", "h", "p" ] },
        // ---- レジスタ内を貼り付け
        { "before": [ "leader", "v", "1" ], "after": [ "\"", "1", "p" ] },
        { "before": [ "leader", "v", "2" ], "after": [ "\"", "2", "p" ] },
        { "before": [ "leader", "v", "3" ], "after": [ "\"", "3", "p" ] },
        { "before": [ "leader", "v", "4" ], "after": [ "\"", "4", "p" ] },
        { "before": [ "leader", "v", "5" ], "after": [ "\"", "5", "p" ] },
        { "before": [ "leader", "v", "6" ], "after": [ "\"", "6", "p" ] },
        { "before": [ "leader", "v", "7" ], "after": [ "\"", "7", "p" ] },
        { "before": [ "leader", "v", "8" ], "after": [ "\"", "8", "p" ] },
        { "before": [ "leader", "v", "9" ], "after": [ "\"", "9", "p" ] },
        { "before": [ "leader", "v", "z" ], "after": [ "\"", "z", "p" ] }, // 上記置換貼付後、前括弧(引用符)内
        { "before": [ "leader", "v", "-" ], "after": [ "\"", "-", "p" ] }, // 1行以下の削除内容
        { "before": [ "leader", "v", "%" ], "after": [ "\"", "%", "p" ] }, // ファイル名
        { "before": [ "leader", "v", "#" ], "after": [ "\"", "#", "p" ] }, // 前のファイル名
        { "before": [ "leader", "v", "*" ], "after": [ "\"", "*", "p" ] }, // クリップボード内
        // --- 行単位を貼り付け+貼り付け部分になにかする(ファイル末尾では使えない)
        { "before": [ "leader", "v", "v" ], "after": ["m", "m", "g", "p", "k",  "V", "`", "m", "j"]}, // 選択
        { "before": [ "leader", "v", "c" ], "after": ["m", "m", "g", "p", "k",  "V", "`", "m", "j", "g", "c"] }, // コメントトグル
        { "before": [ "leader", "v", "j" ], "after": ["m", "m", "g", "p", "k",  "V", "`", "m", "j", "J"] }, // 1行にする

        // vim仕様からVSCode仕様に変更(undo,redo,jump)
        { "before": [ "u" ], "commands": [ "undo" ] },
        { "before": [ "ctrl+r" ], "commands": [ "redo" ] },
        { "before": [ "ctrl+o" ], "commands": [ "workbench.action.navigateBack" ] },
        { "before": [ "ctrl+i" ], "commands": [ "workbench.action.navigateForward" ] },
    ],
    "vim.visualModeKeyBindingsNonRecursive": [
        { "before": [ "leader", "j" ], "after": [ "1", "0", "j" ] }, // 10行下
        { "before": [ "leader", "k" ], "after": [ "1", "0", "k" ] }, // 10行上
        { "before": [ "leader", "leader", "j" ], "after": [ "2", "0", "j" ] }, // 20行下
        { "before": [ "leader", "leader", "k" ], "after": [ "2", "0", "k" ] }, // 20行上
        { "before": [ "leader", "leader", "leader", "j" ], "after": [ "3", "0", "j" ] }, // 30行下
        { "before": [ "leader", "leader", "leader", "k" ], "after": [ "3", "0", "k" ] }, // 30行上
        { "before": [ "\\" ], "after": [ "`" ] }, // \でマーク位置にジャンプする
        { "before": [ "j" ], "after": [ "g", "j" ] }, // 見た目の行で移動
        { "before": [ "k" ], "after": [ "g", "k" ] }, // 見た目の行で移動
        { "before": [ "H" ], "after": [ "H", "z", "." ] }, // 実質半PageUp
        { "before": [ "L" ], "after": [ "L", "z" , "."] }, // 実質半PageDown
        { "before": [ "leader", "/" ], "after": ["g", "c"] }, // コメント切り替え
    ],
    "vim.insertModeKeyBindingsNonRecursive": [
        { "before": [ "ctrl+l" ], "commands": ["deleteRight"] }, // Deleteキー代わり(括弧のペア消すのに使う)
    ],

VSCode-Vimのためのkeybindings.json

ノーマルモードのキーマップはsettings.jsonだが、VSCodeのショートカットともかぶるCtrlとの組み合わせについてはkeybindings.jsonで設定する。

実際のファイルは最後に貼り付けるとして、どう設定してるかを軽く説明。

基本のCtrl+<?>

VSCode VimではデフォルトでCtrl同時押しのショートカットがほぼすべてvim仕様に変更されるので、生粋のvimmerであればイジる必要はないかもしれない。しかし半端もんvimmerとしてはVSCodeのキーも使いたい。

あと、他所で素のVimやVSCodeを使うときのことを考えるとよく使うキーの割り当て自体は変えたくない。(上ですでにvimのキー割り当てすでにかえてるけどそれはそれこれはこれ。)

なので基本はデフォルトのままVSCodeとVimでよく使う方を有効化。どっちも使わなければ空きキーとしてとっておく。どっちも使う場合は優先順位低い方を別に移す。という考え方でやっている。

Ctrl+S、Ctrl+Z、Ctrl+\、Ctrl+/などはそもそもvimに登録がないため、特に記述しなくてもVSCodeのショートカットキーが有効。上書き保存やUndoはつい癖で使ってしまうのでありがたい。Ctrl+/はコメント切替、Ctrl+\はエディタ画面の分割とこれらもそこそこ便利。

他にVSCodeを優先したのは、この辺。

  • 便利なCtrl+Dのマルチカーソル (vimのgbコマンドは連打しにくい)
  • Ctrl+Nで新規ファイル (そこまで使わないけど、vimでも使わないので)
  • 選択範囲のインデント変更に便利なCtrl+[] (vimのvisualモードでの<>は選択範囲解除されてしまうので)
  • (使いこなせてないけど)何かと便利そうなプレフィクスCtrl + K

意外と少なかった。VSCode, Vimのどちらも無効化して俺様設定作った(もしくは開けてある)のはこのあたり。

  • Ctrl + G
  • Ctrl + C
  • Ctrl + M
  • Ctrl + J

この辺はのちのち。

とにかく移動はhjkl

サジェストとかでもjk移動

基本的にCtrl+jkで上下移動して選択できるように設定した。

サジェスト、ヒント、リスト、はてはクイックメニューまでCtrl+JKで移動する。

エディタもhl移動

Ctrl+hlで隣のファイルに移動できるように設定。あと上記のsettings.jsonでleaderとhlでの組み合わせでエディタグループを移動できるようにしてある。

insertモードでもhjkl移動

できるだけ手を動かさず移動したいのでイレギュラーにAlt+hjklで移動できるようにした。

altが押しにくいのでそこまで快適ではないが、まぁちょこっと移動するときには便利。

エディタの外から

ここは別にvim関係ないのだけど、サイドパネルやターミナルにフォーカスがあるときにエディタに戻るためにvim風にCtrl+iを割り当てた。デフォルトと変えないとか言ってたくせにだんだんどうでもよくなってきた。

GitコマンドはCtrl + g , Ctrl + <?>

Gtrl+gはVSCode,Vimともどちらも使いそうにないので、Gitコマンドプレフィクスにしてある。

Git add などVSCodeのコマンドで実行するものだけでなく、git statusなどよく使うコマンドはそのままターミナルに流し込んで実行させるようにしてる。いちいちターミナルと行き来しなくていいので地味に便利。

うっかり押しちゃうと困るのもいくつか登録してあるが、左右に分けてあえて押しにくくしてるので今の所事故はない。

Bookmarks関連にCtrl + m, <?>

ctrl+mはvimでもvscodeでもたいして使わないのでBookmarks拡張専用のプレフィクスに。vimのマーク機能は一時的なマーク+ファイル内移動に、Bookmarksは長期的に使うマーク+ファイル間移動に利用している。

まぁ、まだあまり使いこなせてないんだけども。

ターミナルコマンド関連にCtrl + c, <?>

さっき思いついて追加したばかりなのでまだ実用的かはわからない。

とりあえず、ターミナルでいろいろやってるとわけわかんないところでgitコマンド使おうとしてしまったりするので、そんなとき用のcdをキーから呼べるようにしてみた。

WSL上にいるときと、Windowsにいるときで処理分けられないのが微妙に不便だけど、他にもいろいろ使い所はありそうだ。

ただこれはプロジェクトごとによく使うコマンドが異なりそうなので、workspaceごとの設定に入れてあげるほうがいいかもしれない。

keybindings.json全文

というわけで晒しておく。こんな変態設定そのまま使う人はいないだろうけど、使えそうだと思える部分があればぜひコピペして活用してもらいたい。

// 既定値を上書きするには、このファイル内にキー バインドを挿入しますauto[]
[
    //-----------------------------------------------------------------
    // vimキーとVSCodeキーの選択 (ここで触れてないものはvimキー優先)
    //------------------------------------------------------------------
    // 癖で押してしまうためVSCode優先。vimのCtrl+Cは対して使わないし。
    {
        "key": "ctrl+c",
        "command": "-extension.vim_ctrl+c",
        "when": "editorTextFocus && vim.active && vim.overrideCtrlC && vim.use<C-c> && !inDebugRepl"
    },
    // Vimのctrl+jは不要。VSCodeの下パネル表示切替もさほど使わないのでつぶしてプレフィクスにする
    {
        "key": "ctrl+j",
        "command": "-extension.vim_ctrl+j",
        "when": "editorTextFocus && vim.active && vim.use<C-j> && !inDebugRepl"
    },
    {
        "key": "ctrl+j",
        "command": "-workbench.action.togglePanel"
    },
    // vimのマルチバイト入力は捨てる。VSCodeのプレフィックスキーの方が使うでしょ
    {
        "key": "ctrl+k",
        "command": "-extension.vim_ctrl+k",
        "when": "editorTextFocus && vim.active && vim.use<C-k> && !inDebugRepl"
    },
    // VSCodeのタブ機能切替はただの事故のもとなので無効化しておく。vimのも使わないので外しておく。
    {
        "key": "ctrl+m",
        "command": "-editor.action.toggleTabFocusMode"
    },
    {
        "key": "ctrl+m",
        "command": "-extension.vim_ctrl+m",
        "when": "editorTextFocus && vim.active && vim.use<C-m> && !inDebugRepl || vim.active && vim.use<C-m> && !inDebugRepl && vim.mode == 'CommandlineInProgress' || vim.active && vim.use<C-m> && !inDebugRepl && vim.mode == 'SearchInProgressMode'"
    },
    // vimのctrl+nは使わないので無題の新規ファイル作成機能を有効に。
    {
        "key": "ctrl+n",
        "command": "-extension.vim_ctrl+n",
        "when": "editorTextFocus && vim.active && vim.use<C-n> && !inDebugRepl || vim.active && vim.use<C-n> && !inDebugRepl && vim.mode == 'CommandlineInProgress' || vim.active && vim.use<C-n> && !inDebugRepl && vim.mode == 'SearchInProgressMode'"
    },
    // vimのctrl+pは不要。VSCodeのファイルに移動を有効化。">"押せばコマンドパレットにもなるので便利。
    {
        "key": "ctrl+p",
        "command": "-extension.vim_ctrl+p",
        "when": "suggestWidgetVisible && vim.active && vim.use<C-p> && !inDebugRepl || vim.active && vim.use<C-p> && !inDebugRepl && vim.mode == 'CommandlineInProgress' || vim.active && vim.use<C-p> && !inDebugRepl && vim.mode == 'SearchInProgressMode'"
    },
    // vimのctrl+qはctrl+vと同じなのでVSCodeのクイックメニューを優先。
    {
        "key": "ctrl+q",
        "command": "-extension.vim_winCtrlQ",
        "when": "editorTextFocus && vim.active && vim.use<C-q> && !inDebugRepl"
    },
    // vimのctrl+vは必須。(本来設定なしで優先されるはずだが、貼り付けが発動することあったので一応無効化しておく)
    {
        "key": "ctrl+v",
        "command": "-editor.action.clipboardPasteAction"
    },
    // ここは迷ったが、VSCodeのマルチカーソル機能優先。vimのg->bも同じ機能だが押しにくい。vimのインデント戻しと半画面移動も捨てがたいので好み分かれそう。
    {
        "key": "ctrl+d",
        "command": "-extension.vim_ctrl+d",
        "when": "editorTextFocus && vim.active && vim.use<C-d> && !inDebugRepl"
    },
    // tabは選択範囲を維持して入れられるVSCodeショートカットの方をを有効化
    {
        "key": "ctrl+[",
        "command": "-extension.vim_ctrl+[",
        "when": "editorTextFocus && vim.active && vim.use<C-[> && !inDebugRepl"
    },
    {
        "key": "ctrl+]",
        "command": "-extension.vim_ctrl+]",
        "when": "editorTextFocus && vim.active && vim.use<C-]> && !inDebugRepl"
    },

    //-------------------------------------
    //インサートモードでちょっと移動したい
    //-------------------------------------
    {
        "key": "alt+j",
        "command": "cursorDown",
        "when": "editorTextFocus && vim.active && vim.mode == 'Insert'"
    },
    {
        "key": "alt+k",
        "command": "cursorUp",
        "when": "editorTextFocus && vim.active && vim.mode == 'Insert'"
    },
    {
        "key": "alt+h",
        "command": "cursorLeft",
        "when": "editorTextFocus && vim.active && vim.mode == 'Insert'"
    },
    {
        "key": "alt+l",
        "command": "cursorRight",
        "when": "editorTextFocus && vim.active && vim.mode == 'Insert'"
    },
    //-------------------------------------
    // ctrl+jkでいろいろ上下移動
    //-------------------------------------
    // 候補のフォーカス
    {
        "key": "ctrl+j",
        "command": "selectNextSuggestion",
        "when": "editorTextFocus && suggestWidgetMultipleSuggestions && suggestWidgetVisible"
    },
    {
        "key": "ctrl+k",
        "command": "selectPrevSuggestion",
        "when": "editorTextFocus && suggestWidgetMultipleSuggestions && suggestWidgetVisible"
    },
    // ヒント
    {
        "key": "ctrl+j",
        "command": "showNextParameterHint",
        "when": "editorTextFocus && parameterHintsMultipleSignatures && parameterHintsVisible && textInputFocus"
    },
    {
        "key": "ctrl+k",
        "command": "showPrevParameterHint",
        "when": "editorTextFocus && parameterHintsMultipleSignatures && parameterHintsVisible && textInputFocus"
    },
    // リスト
    {
        "key": "ctrl+j",
        "command": "list.focusDown",
        "when": "listFocus"
    },
    {
        "key": "ctrl+k",
        "command":"list.focusUp",
        "when": "listFocus"
    },
    // クイックオープン
    {
        "key": "ctrl+j",
        "command":"workbench.action.quickOpenSelectNext",
        "when": "inQuickOpen"
    },
    {
        "key": "ctrl+k",
        "command":"workbench.action.quickOpenSelectPrevious",
        "when": "inQuickOpen"
    },
    // --- 閉じるのはEscだとクイックメニュー時に都合悪いので別のキーvim的には左か右で閉じる感覚
    {
        "key": "ctrl+h",
        "command": "workbench.action.closeQuickOpen",
        "when": "inQuickOpen"
    },
    {
        "key": "ctrl+l",
        "command": "workbench.action.closeQuickOpen",
        "when": "inQuickOpen"
    },
    //-------------------------------
    // エディタ外
    //-------------------------------
    {
        "key": "ctrl+i",
        "command": "workbench.action.focusActiveEditorGroup",
        "when":  "sidebarFocus || panelFocus"
    },
    {
        "key": "ctrl+r",
        "command": "renameFile",
        "when": "explorerViewletVisible && filesExplorerFocus"
    },
    {
        "key": "ctrl+oem_plus",
        "command": "workbench.action.toggleMaximizedPanel",
        "when": "terminalFocus"
    },
    //---------------------------------------------
    // ctrl+gをGitプレフィクスに変える
    // Gitサイドバー表示はデフォルトのCtrl+Shift+G
    //---------------------------------------------
    {
        "key": "ctrl+g",
        "command": "-workbench.action.gotoLine"
    },
    {
        "key": "ctrl+g",
        "command": "-extension.vim_ctrl+g",
        "when": "editorTextFocus && vim.active && vim.use<C-g> && !inDebugRepl"
    },
    // --- ブランチ切り替え
    {
        "key": "ctrl+g ctrl+b",
        "command":"git.checkout",
        "when": "editorTextFocus && !suggestWidgetVisible  && !inQuickOpen && !parameterHintsVisible"
    },
    // --- ステージを取り消す
    {
        "key": "ctrl+g ctrl+z",
        "command": "workbench.action.terminal.sendSequence",
        "args": {
            "text": "git reset HEAD \n"
        },
        "when": "editorTextFocus && !suggestWidgetVisible  && !inQuickOpen && !parameterHintsVisible"
    },
    // --- 編集中ファイルをadd
    {
        "key": "ctrl+g ctrl+a",
        "command": "workbench.action.terminal.sendSequence",
        "args": {
            "text": "git add ${file} \n git status\n"
        },
        "when": "editorTextFocus && !suggestWidgetVisible  && !inQuickOpen && !parameterHintsVisible"
    },
    // --- 一時保存
    {
        "key": "ctrl+g ctrl+w",
        "command": "workbench.action.terminal.sendSequence",
        "args": {
            "text": "git stash save \" ${fileBasenameNoExtension} \" \n"
        },
        "when": "editorTextFocus && !suggestWidgetVisible  && !inQuickOpen && !parameterHintsVisible"
    },
    // --- 保存リスト
    {
        "key": "ctrl+g ctrl+q",
        "command": "workbench.action.terminal.sendSequence",
        "args": {
            "text": "git stash list \n"
        },
        "when": "editorTextFocus && !suggestWidgetVisible  && !inQuickOpen && !parameterHintsVisible"
    },
    // --- すべてadd
    {
        "key": "ctrl+g ctrl+f",
        "command": "workbench.action.terminal.sendSequence",
        "args": {
            "text": "git add . \n git status\n"
        },
        "when": "editorTextFocus && !suggestWidgetVisible  && !inQuickOpen && !parameterHintsVisible"
    },
    // --- コミット
    {
        "key": "ctrl+g ctrl+c",
        "command": "git.commit",
        "when": "!suggestWidgetVisible  && !inQuickOpen && !parameterHintsVisible"
    },
    // --- 現在ファイルの変更差分
    {
        "key": "ctrl+g ctrl+d",
        "command": "workbench.action.terminal.sendSequence",
        "args": {
            "text": "git diff -- ${file}\n"
        },
        "when": "editorTextFocus && !suggestWidgetVisible  && !inQuickOpen && !parameterHintsVisible"
    },
    // --- 現在のファイルをaddして直前コミットを上書き修正
    {
        "key": "ctrl+g ctrl+e",
        "command": "workbench.action.terminal.sendSequence",
        "args": {
            "text": "git add ${file} \n git commit --amend --no-edit \n"
        },
        "when": "editorTextFocus && !suggestWidgetVisible  && !inQuickOpen && !parameterHintsVisible"
    },
    // --- git status
    {
        "key": "ctrl+g ctrl+s",
        "command": "workbench.action.terminal.sendSequence",
        "args": {
            "text": "git status \n"
        },
        "when": "editorTextFocus && !suggestWidgetVisible  && !inQuickOpen && !parameterHintsVisible"
    },
    // --- なにかやり直したいとき
    {
        "key": "ctrl+g ctrl+r",
        "command": "workbench.action.terminal.sendSequence",
        "args": {
            "text": "git reflog \n"
        },
        "when": "editorTextFocus && !suggestWidgetVisible  && !inQuickOpen && !parameterHintsVisible"
    },
    // --- この先は間違えて押さないよう少し押しにくいキーにしておく
    // --- 最新のstash適用し消す
    {
        "key": "ctrl+g ctrl+l",
        "command": "workbench.action.terminal.sendSequence",
        "args": {
            "text": "git stash pop \n"
        },
        "when": "editorTextFocus && !suggestWidgetVisible  && !inQuickOpen && !parameterHintsVisible"
    },
    // --- ファイルをもとに戻す
    {
        "key": "ctrl+g ctrl+u",
        "command": "workbench.action.terminal.sendSequence",
        "args": {
            "text": "git restore ${file} \n"
        },
        "when": "editorTextFocus && !suggestWidgetVisible  && !inQuickOpen && !parameterHintsVisible"
    },
    // --- 一つ前のコミットを取り消す
    {
        "key": "ctrl+g ctrl+p",
        "command": "workbench.action.terminal.sendSequence",
        "args": {
            "text": "git reset --soft HEAD^ \n"
        },
        "when": "editorTextFocus && !suggestWidgetVisible  && !inQuickOpen && !parameterHintsVisible"
    },
    //------------------------------------------------
    // Bookmarks (ctrl+mをプレフィクスとして使う)
    // vimのマーク機能はファイル内一時マーク用
    //  Bookmarksはファイルまたいで長く使うマーク用
    //------------------------------------------------
    {
        "key": "ctrl+m ctrl+m",
        "command": "bookmarks.toggle",
        "when": "editorTextFocus"
    },
    // ラベル付きブックマーク
    {
        "key": "ctrl+m ctrl+n",
        "command":"bookmarks.toggleLabeled",
        "when": "editorTextFocus"
    },
    // リストから選ぶ ctrl押しっぱなしでm+kjだけで選択可
    {
        "key": "ctrl+m ctrl+j",
        "command":"bookmarks.listFromAllFiles",
    },
    {
        "key": "ctrl+m ctrl+k",
        "command":"bookmarks.listFromAllFiles",
    },
    // 次と前へ移動(defaultの表示の拡大縮小はいらないのでつぶす)
    {
        "key": "ctrl+oem_plus",
        "command":"bookmarks.jumpToNext",
        "when": "editorTextFocus"
    },
    {
        "key": "ctrl+-",
        "command":"bookmarks.jumpToPrevious",
        "when": "editorTextFocus"
    },
    // マーク位置まで選択(vim の左右を意識)
    // {
    //     "key": "ctrl+m ctrl+h",
    //     "command": "bookmarks.expandSelectionToPrevious",
    // },
    // {
    //     "key": "ctrl+m ctrl+l",
    //     "command": "bookmarks.expandSelectionToNext",
    // },
    // ファイル内のブックマークリスト
    {
        "key": "ctrl+m ctrl+i",
        "command":"bookmarks.list",
        "when": "editorTextFocus"
    },
    // マーク位置を選択
    {
        "key": "ctrl+m ctrl+o",
        "command": "bookmarks.selectLines",
        "when": "editorTextFocus",
    },
    // ファイル内全削除
    {
        "key": "ctrl+m c",
        "command":"bookmarks.clear"
    },
    //------------------------------------------------
    // Ctrl + c はターミナルコマンドプレフィクスにする
    //------------------------------------------------
    {
        "key": "ctrl+c",
        "command": "-editor.action.clipboardCopyAction"
    },
    {
        "key": "ctrl+c ctrl+d",
        "command": "workbench.action.terminal.sendSequence",
        "args": {
            "text": "cd ${fileWorkspaceFolder} \n "
        },
        "when": "editorTextFocus"
    },
    {
        "key": "ctrl+c ctrl+t",
        "command": "workbench.action.terminal.sendSequence",
        "args": {
            "text": "pytest -v ${file} \n "
        },
        "when": "editorTextFocus"
    },
    //---------------------------------------------------------------------------

]

vscode

Posted by gran-gran-gran