後悔しているがやめられない開発効率向上術

僕はdotfiles系リポジトリ*1のコミット数を合計するだけで2261コミットある、.vimrcばっかりいじっていて開発が全然進まないタイプの人間で、つまり開発環境にとてもこだわりがある。

こだわりすぎて他に誰もやってなさそうな数々のカスタマイズを生み出してしまったが、やらなければよかったと後悔しているものが多くあるので、僕のような人が新たに生まれないよう、やめておけばよかったテクニックとその法則のようなものを紹介したい。

後悔しているもの

C-h, C-y, C-u, C-oでウィンドウ切り替え

Windows, macOS, Linux問わず以下のグローバルなキーバインドを設定している。

  • C-h: ターミナルにウィンドウ切り替え
  • C-y: IntelliJかCLionにウィンドウ切り替え
  • C-u: Google Chromeにウィンドウ切り替え
  • C-o: TwitterかSlackにウィンドウ切り替え

Vimはターミナル内で起動しており、コードを書いている間基本的に上記4つのウィンドウだけで生活するようにしている。 macOSでいうCommand+Tabみたいなショートカットでウィンドウを切り替える場合、まずそれを押してウィンドウがどういう順番で並んでいるか確認し、 その後目的のウィンドウにカーソルが辿りつくまで何度か同じキーを押す必要があり、2アクション以上必要になるが、 このショートカットがあると常に一瞬で目的のウィンドウを開くことができる。

何年もこれを使い続けた結果もうやめられなくなっているが、まず (シェルとかで使える) C-uみたいなちょっと便利な機能を潰しているのが困る。ペアプロ相手がC-uを使おうとしてブラウザが開いてびっくりされたことがある。また、見てわかる通りものすごく押しやすいキーバインドを消費しているため、ここに新たに他のウィンドウのショートカットを足そうとすると、似たような押しやすいショートカットを捨てることになる。これは大変だし、そもそもこのショートカットの数が増えると脳が混乱しそうなのでスケールしない。それと、何か新しいデスクトップアプリを使う必要が出てくる度に、諦めるか、ウィンドウ切り替えで不快な思いをすることになる。

対案としては、Slackのワークスペースを切り替えるのと似た感じでCtrl+1, Ctrl+2, ... みたいなもう少しコンフリクトしにくくスケールもしそうな割り当てにするか、まあそもそもこんな方法で生産性向上するのは諦めて大人しくCommand+Tabを使うというのが考えられる (やらなそう)。

半透明背景エディタ

これも全OS共通で、ターミナルの背景は半透明にしている。これは多分学生のころ見た目がかっこいいと思って始めたのだが、実用的なメリットとして、ターミナルを全画面表示にしていてもその裏側のブラウザやSlackに書いてある内容が読めるというものがある。で、気付くとこれに依存した生活をしてしまっていて、Vimもターミナルで起動しているためコードを書いている時もブラウザのドキュメントを透し見する癖がついたが、JetBrains IDEなどの背景が半透明化できないエディタで困ることになった。

Linuxではウィンドウを丸ごと半透明化するのは簡単なのだが、ウィンドウ全体を半透明化するのと背景だけ半透明化するのでは読みやすさが全然違うので話にならないし、macOSだとそもそもそれができるツールはOSのバージョンが上がるにつれ動かなくなったりしていった。それから、このウィンドウを重ねて見る生活はタイリングウィンドウマネージャでは実質不可能なことが多く、そういうウィンドウマネージャを選択肢から外すことになる。

デュアルディスプレイはディスプレイ間のマウスカーソルの移動が個人的になんとなく不快なのでいつもシングルディスプレイで作業をしているのだが、対案としては、ワイドディスプレイを使うようにして単にウィンドウを左右に並べるのがよさそうと思っているが、ケチなのでなかなかディスプレイが買えていない。

親指修飾キー

僕のキーボードの修飾キーは以下のような配置にして、全て親指で押している。

 [ C  ][ V  ][ B  ][ N  ][ M  ][ ,   ]
  [Ctrl][    Space    ][Shift][ Cmd ]

JISのHHKBという、スペースキーがトップクラスに短いキーボードを使っているため、これらの修飾キー全てがとても押しやすい。 何故こうしているかというと、Ctrlは元々Aの左で小指で押していたのだが、Emacsを使っていた時期にこれで小指が痛くなりまくったので、再発防止策としてVimに移行したが、それでもシェルやVim以外の場所でEmacsキーバインドを多用していたため、Ctrlを親指で押すようにしたら指が痛くなることがほとんどなくなった。あとSKKを使うようになってからShiftキーを多用するようになったが、これも小指が痛くなったので、親指で押すようにした。昔はSandS *2 を使っていたが、暴発が多いのでShiftキーは独立させている。

これ自体には後悔はないどころか、長くプログラマを続けるために指の負担を減らすことはとても大切だと思っているが、以下の制約がつくため間接的に後ろめたい気持ちがある。

JISキーボード

親指修飾キーはキーボードがUS配列だととても大変である。上記のキー配置はJIS配のHHKBのものだが、US配列のHHKBはこうなっている。

 [ C  ][ V  ][ B  ][ N  ][ M  ][ ,   ]
[             Space                ]

これは特に誇張とかなく本当にこうなっている。つまり、親指を軽く曲げて届く位置に一切修飾キーがない。大体スペース押すのにこんな広い範囲を使い分けるわけないんだから、スペースの無駄遣い*3である。

JISキーボードを使っていて何が困るかというと、僕はUSに住んでいるのだが、JIS配列のキーボードが居住国で買えなくなる。JIS配列のHHKBを買うために5000円くらい送料をかけてHHKBを買ったことがあるが、開封直後買い間違い*4に気付き、PFU開封したら絶対に返品を受けつけないため、もう一度5000円の送料をかけて別のモデルを買うはめになった。それから、USの会社ではJIS配列のMacBookを貸与してくれなかったり、対応していても注文から発送までにものすごく時間がかかったりする。

指を痛めるような選択は取れないので、これは今のところどうしようもない。歯を食いしばって法外な送料を払い、返品拒否にも耐え、カンファレンス会場やオンコールなどで外部キーボードを持ち運びたくないがUS配列のMacBookが貸与されている場合は、生産性を落とし指を痛めつつ作業することを覚悟しないといけない。

C-cによるVimのインサートモード抜け

C-cはご存知の通りSIGINTを送るショートカットであるが、Vimでインサートモードにいる時にC-cを使うと、何故かインサートモードを抜けてくれる。EscはAの左に配置していて、これでもまあまあ押しやすいし基本的にはそっちを使っているのだが、上記のような修飾キー配置をしていると、現在の指の置き場次第ではC-cがEscよりも押しやすくなってしまう。それで、気付かないうちにEscではなくC-cをたまに使うようになってしまった。実際には Esc や C-[ で抜けるのとは違う挙動になるため、C-cでインサートモードを抜けるのは行儀が悪いだけでなく機能的な不便もある。Pythonを使って実装されたVimプラグインを使うと、プラグインが動いている間にC-cすると例外が発生してVimがエラーになったりする。

まあ普通にEsc使えで終わりなのだが、VimでC-cを使って困る状況を意識的に増やさないとなかなか矯正されないかもしれない。

Vimでしか設定できないキーバインド

Vimでは現在のモードに応じてキーバインドを設定できる。インサートモード以外では任意の文字を打ち込む必要がなくなるため、いくつかの普通のキーが何も使われずにおいてある状態になる。従って、スペースキーやセミコロンなどの大変押しやすいキーをプレフィクスキーにすることができ、具体的には ;u でUnite.vimを開いたり、スペース→Tで新しいタブを開いたりしている。これで何が困るかというと、Vimの外で生活する時にそれとキーバインドを揃えることがとても難しくなる。IntelliJのIdeaVimだと.ideavimrcで似たような設定ができるのだが、IdeaVimが効かないモーダルが開くとそこでは.ideavimrcの設定が使えないので、Vim以外でVimと同じ操作感を再現するのが困難になってしまう。

対案としては、何かキーバインドを設定するときはVimでしか設定できなそうなものを使うのではなく、普通に修飾キーを組み合わせ、モードに依存しないショートカットにするのが良い。

エディタの垂直分割

VimIntelliJのIdeaVimで:vsし、左右にソースを並べてコードを書くことが結構あるのだが、画面を分割した時の挙動がエディタによって異なるため操作感がかなり変わるのが結構困る。というか、画面を分割した時のIntelliJ側の挙動が圧倒的に不便で、垂直分割した後左で関数定義にジャンプする時に左で新たなウィンドウが開くのではなく、右側に同じファイルが開き済みの場合何故か右の画面が遷移してしまい、右に何かを出しっぱなしにして左でコードを書きたいみたいな時に大変不便。

そもそもVimだけ使う生活に戻すか、あるいは今IntelliJで書いているものは全て別のエディタ、例えばVSCodeで書くように変えようかなとか考えている*5

7/21 追記: @ka2n さんから "When navigating to a file prefer selecting existing tab in inactive split pane" をオフにするというテクを教わり、これで上述の不満は解消されることがわかった。ただこれが解消されても、Vimだとタブごとにペイン分割、IntelliJだとペインごとにタブ分割となる違いは依然として気になっていて、Vimの方が挙動的には便利だと思っているが、UI的にはIntelliJの方が自然なので、どうしようもないかもしれない。

後悔していないもの

Emacsキーバインド

矢印キーはホームポジションから遠いことが多いので、少なくともその点において、Emacsを使わなくなった今でもEmacsキーバインドは重宝している。 Emacsの C-何とか のキーバインドを奪ってくる不届き者のWebサイトも結構あるのだが、大体キーリマッパ側で矢印キーにリマップしてしまうなどの方法で不便を解消できることが多い。同様にC-a/C-eをHome/Endにリマップしたりするが、これらが微妙に違う挙動をするのは気にならないこともない*6のだが、まあ耐えられる範囲。

逆にC-x C-sみたいなキーシーケンスとか、マーク機能を利用したリマップに頼るのは、キーリマッパへの依存度が高くなりすぎるのでやめた方がいいだろうと思っていて、やっていない。

ちなみにmacOSは他のOSだとCtrlなショートカットがCommandキーに分離されているからEmacsキーバインドが使いやすく、WindowsLinuxではそれができないので不便みたいなことを言う人がいるが、Commandキーみたいなものはキーリマッパを使えばいくらでも生み出せるので、そういう人は単にエアプか、キーリマッパでも衝突回避しにくい深淵な使い方をしているかのどちらかだと思う。

非分割キーボード

今現在はノートPCもJIS配列なのだが、外部キーボードとノートPCについてるキーボードがおおむね配列が同じだと、外でノートPCだけで作業する時に操作感が大体同じになってとても便利。分割方法にもよるが、これはErgoDoxとかKinesisみたいな特殊な配列をしている分割キーボード*7だと、親指周りの操作感が変わってしまってノートPC単体での作業をするとき不便になる。

tmux

ターミナルで複数ウィンドウ・複数タブを使うかわりにtmuxの複数セッション・複数ウィンドウを利用している。個人的にはうっかりターミナルを閉じてもシェルのセッションが保たれる利点にはあまり依存してないのだが、どのOSでも操作感やUIが統一でき、画面の分割も簡単で、コピーモードを使って画面上のどのテキストもキーボード操作だけでコピーできるのがとても便利だと感じている。

SKK

普通のIMEのかわりにSKKを使うことで編集効率が上がっているかというとどうなのか何ともいえないが、SKKの操作感はVimキーバインドのような気持ちよさが少なくともある。これは他の人のPCを使う時に一見困りそうだが、意外と頭の切り替えがうまくいくし、そこでガッツリ何かを書かないといけないことはほぼないので、後悔することは少ない。ibus-skkAquaSKK、CorvusSKKを使っているが、どれもほぼ同じように操作できるので、移植性はむしろ高い。ibus-skkが全然メンテされてないのは気になるが、Linuxで使える別実装はいくらでもあるので致命的ではない*8

まとめ

要するに大切なのは移植性である。OSやエディタを変えても動く設定を使うのが望ましい。そもそも設定しなくても使えて、PCを初期化したり他の人のPCを使ったりしている時でも可能な操作をするのが理想的。

*1:https://github.com/k0kubun/dotfileshttps://github.com/k0kubun/legacy-dotfiles

*2:Space単押しはSpace、長押しでShiftになる特殊なキーバインド

*3:pun intended

*4:Type-Sを買おうと思ってたらType-Sではなかった。非Type-Sはうるさすぎて子供が寝ている時に使いづらいので、買い直した

*5:VSCodeにこの分割した時の問題があるかどうかはまだ検証できてないので、そうなっていればいいなという希望に過ぎない

*6:物理行頭/末と論理行頭/末の違い

*7:どちらも過去に使用していた

*8:それでもibus-skkを使っているのは、fctix-skkは挙動が遅いと感じるため