jとkでの移動を矯正するためのVim pluginを作った

本記事はVim Advent Calandar 2015の13日目です。

本来書こうと思っていたネタがあったんですが、若干ネタが大きかったため期間的に厳しく そのネタの内容を検討している時に思いついて作ったVim pluginについてご紹介します。

背景

みなさんはカーソル位置からスクリーン上に見える範囲の特定の行への移動はどのように操作されていますでしょうか?

Vimmerは十人十色なので、様々なやり方があると思います。

例えば

  • 気合でjjjjj・・・kkkkk・・・を使う
  • 5j5kなどを繰り返し実行して距離を詰めた後に最後微調整する
  • (relativenumberオプションを有効にするなどで) 目視で極力一発で目的の行に移動する
  • 様々な縦方向の移動コマンドの中から状況にあった移動コマンドを選択する (/, }, { などなど)
  • (vim-easymotionなどの) 移動系のVim pluginを使う
  • マウスが大好きでマウスを使う

他にも色々あるかと思います。

私は、上記の中で以下を組み合わせてやりたい派です。

  • 様々な縦方向の移動コマンドの中から、状況にあった移動コマンドを選択する
  • 5j5kなどを繰り返し実行して距離を詰めた後に最後微調整する

基本的には、j, k以外のその場に適したコマンドで移動できるところは移動して、 j, k以外の移動コマンドだと手詰まりだったり、面倒だったりした場合には、5j, 5k、 また、j, kで調整するというスタイルです。

効率化という意味ではベストではないかもしれませんが、素Vimでの操作も考えると別に悪くはなさそうです。 ただ、個人的に1点課題に感じているところがありました。

それが以下の部分です。

  • 5j5kなどcount指定で距離を詰めて移動する方

これ、やりたいと思っていますが、実は現状できていません。

じゃあ現状どうやっているかというとこれです。

  • 気合でjjjjj・・・kkkkk・・・を使う

私はOSのキーリピート速度を高速化して、速度的には不都合がないとはいえ、 個人的にはキーリピート速度の高速化は邪道だと思っていますし、 「素Vimでもそれなりのパフォーマンスで操作できる」をモットーで やっている身として、count指定を使えるところは、count指定する べきだし、したほうが効率的だと思うのです。

でも、長年の手癖は早々直せないもの。ということで、これを矯正するために vim-gothrough-jkというVim pluginを作ってみました。

vim-gothrough-jk

vim-gothrough-jkの機能は以下です。

  • j, kを連続で3回以上タイプするとgothroughモードに移行する
  • gothroughモードではj, kをタイプした時の移動幅が5になる。
  • gothroughモードでは 4秒待つか、count指定でj, k移動するか、j, k以外の移動(h, lなど)で通常のj, kに戻る

なお、以下の部分はカスタマイズ可能です(I/Fは変更の可能性があるためここには書きません)

  • どれくらいの間隔(ミリ秒)で連続でタイプしたらgothroughモードに移行するか(現状デフォルトは150ミリ秒)
  • 何回以上タイプしたらgothroughモードに移行するか(現状デフォルトは3回以上)
  • gothroughモード時にj, kで移動する移動幅の変更(現状デフォルトは5)
  • gothroughモードに移行した後、最後にj, kをタイプしてからどれくらいの間隔(ミリ秒)が空いたら通常のj, kに戻るか(現状デフォルトは4000)

以下に動作のスクリーンショットを載せます。

f:id:deris:20151213180358g:plain

3回下に移動した後に、移動幅が5になり、3回上に移動した後に移動幅が5になっていることがわかるかと思います。

わかりやすいように、どれくらいの間隔で連続でタイプしたらgothroughモードに移行するかの値を 大きめにしてやっていますが、実際はj, kを押しっぱなしでないと発動しないくらいでいいかと思います(デフォルトは150ミリ秒)。 環境によってカスタマイズすることを推奨します。

で、このVim pluginの機能でどうやって矯正されることを期待しているのかというと

  • j, kを連続で3回以上タイプするとgothroughモードになるので、count指定のj, kを使わないと近い距離に移動する際に移動しづらくなる。 (例えば、カーソル行から4行下に移動したい場合、jの連続タイプだと途中で移動幅が5に置き換わるので、最初から4jで移動することを意識せざるを得なくなる)
  • 途中から5j, 5kに移行するので、20行下程度でもそれなりに高速で調整できるため、素Vimに戻った時に違和感を感じて、5j, 5kを使いたくなる…(かも)

なお、一般向けに今のデフォルト値にしていますが、移動幅を20くらいにすると、ハードモードになり 矯正もかなり進むのではないかと思っているので、私はしばらくそれで運用してみるつもりです。

類似Vim plugin

vim-hardtime

名前を失念してしまいリンクを貼れず申し訳ないのですが、(Lingr上でryunixさんに教えていただきました。 ありがとうございました。) vim-hardtimeは、j, kを連続で一定回数以上タイプすると、 しばらく(1秒とか)sleepするため、j, kを連続タイプしないよう矯正できます。

Vim pluginの着想は、ここから来た部分が大きいです。

ただ、流石にsleepはやり過ぎだなぁと思って、もう少し有用に使えて、 でも矯正にもなるような機能は無いかなぁと考え、現状の仕様にしました。

vim-accelerated-jk

vim-accelerated-jkj, kでの移動を加速度的に 速くできるVim pluginです。(実際は加速度を計算しているわけではなく、タイプ数に応じて移動幅を増やしています)

最初は似ていると気づかなかったのですが、j, kで、移動幅を変更するという点でかなり似ています。

気づいた時点で、新規にVim pluginを書き起こすか、vim-accelerated-jkの Pull Requestですますか悩んだのですが、用途もやりたいことも(多分)微妙に違うので、新規に書き起こすことにしました。

(もし、気になる機能があったらこれを見た作者のLindanさんが vim-accelerated-jkに輸入してくれるはず…)

まとめ

以上が、j, kでの移動を矯正するためのVim plugin、vim-gothrough-jkの紹介でした。

本題とはそれますが、Vimレベルが上がるのでvimrc読書会に参加することをおすすめします。 私は最近あまり顔を出せていませんが、毎週土曜日23時からやってます。

それではVim Advent Calendar 2015の13日目の記事を終わります。

Happy Vim Life!

VimConf2015に参加しました

2015/11/21(土)に株式会社ミクシィで開催されたVimConf2015に参加してきたので感想レポートを書きました。

当日まで

最初は一般参加で登録していて、ネタと時間がなかったため今年は発表するかどうか迷ったのですが、 Lindanさんに若干煽られ?「海外Vimmerが開発したVim pluginの紹介」というタイトルで、LT枠に登録しました。

ただ、Vim pluginの紹介でデモをやろうと思った時点で、LTでは全然時間が足りなそうということに 気づき、vim-jp/vimconfのissuesで時間を分けてもらえないか相談したところ、thincaさんに時間を 譲っていただき事なきを得ました。thincaさんありがとうございました。

発表内容は、最近全然新しいVim pluginを試せていなかったため、実益を兼ねVim plugin紹介にしよう と思ったはいいものの、Vim plugin選定に向けて、以下の様な制限を設けてしまったため、 調査にかなり時間がかかりました。(何個Vim plugin見たか覚えていない…

  • 私が使ったことがない or 使っていない
  • 日本語で紹介したページがない(or 非常に少ない)
  • プログラミング言語非依存

前日に微妙に喉に違和感を感じて当日どうなるか心配でしたが、そこまでひどくなかったのとユンケルのおかけでなんとかなりました。

前日は深夜4時まで資料を書きなおしたり、youtubeここらへんを 見てイメトレしたりしてました。

私の発表

発表スライドは以下にあげています

English version is here

発表練習出来ていなかったこともあり、時間を気にしてちょっと駆け足になってしまった感があり、 なんとなくでもわかってもらえたか不安だったりします。

類似Vim pluginで、いくつか会場にいらっしゃっている方のVim pluginを紹介したのに、 時間を気にして紹介できませんでした…(ここで紹介しておくと、thincaさんのthinca/vim-ref、 Lindanさんのrhysd/devdocs.vim、haya14busaさんのhaya14busa/vim-undoreplayです)

同じく類似Vim pluginで、AndrewRadev/inline_edit.vimの類似Vim pluginに、thincaさんのthinca/vim-partedit を載せてないという凡ミス(知っていたのに)をしました…

発表の際に、リストの中で 5個以上知っている方はいますかとアンケートを取ったところ、 一人もいなかったっぽいので、目的の一つは達せたような気がします。(実際に役に立つかどうかはわからないけど

ちなみに最後のOne more thingですが、あまりに微妙だったせいか、良かったとも悪かったとも誰からもふれられず、 懇親会の際、やっとbasyuraさんに「最後のOne more thingは完全に余計でしたねw」とありがたいツッコミを頂き、 きっと他の参加者の方も同じような気持ちだったんだろうなぁと思いましたが、私がやりたかっただけなのでまったく反省はしていない ( ー`дー´)キリッ

唯一反省点は、One more thingまでの持っていき方がちょっとイメトレしていた時と違ってあまりうまくできなかったので そこが心残りです

あとは、どうせやるなら自作Vim pluginとかもう少しまともなネタを用意したかったっていうのはありますが時間がなく断念…

人生で一度できれば十分なので、多分もうやることはないでしょうw

(是非もう一度見たいという声があればやぶさかではない)

雑多な感想

他の発表者の方の感想は、他の参加者の方が色々上げてくれるはずなので、雑多な感想を

  • 発表は皆クオリティが高くて、もっと発表うまくならねば、というか面白いネタを仕入れるために日々精進せねばと思いました
  • kaoriyaさんのプレゼンが、ラップトップのトラブルにより急遽スライドなし発表に切り替わったのですが、あまりに自然すぎてすごいとしか言いようがなかった…(私もアドリブ力がほしい)
  • LindanさんのブラウザでVim動かす発表で、ブラウザ上で普通にVim pluginが動いていて、「すごい」という言葉しか出てこなかった(犬)
  • gu4さんが5年yokohama.vimを続けたという意識の高いLTをされていて、私がまじめにVimを触り始めたのも大体一番初めのyokohama.vimからなので、5年たったのかぁと感慨深い気持ちになりました
  • 今年の懇親会は極力面識のない方とお話しようと思い、「Vimは何に使ってますか?」というキーワードを元に、3, 4人には話しかけることができ面白い話も聞けたので良かった(nviの話したり、私のVim pluginのduzzle.vimをやっていただいていたり、yoshiko_pgさんにvim-rengbang使ってみますと言っていただいたり、Lingr上でしか把握していなかったzcheeさんとお話したりなどなど)
  • ただ、懇親会楽しすぎてあっという間でもっと色々な方とお話したかったなぁという心残りもありました
  • そして話すのに夢中で寿司を全然食べられなかった…
  • そして話すのに夢中で寿司を全然食べられなかった…(大事なことなので二回
  • kaoriyaさん、ujihisaさんとお話できる(本当に)めったにない機会なのでお話させていただきました。vimconfに参加した方でお話していない方がいたら、是非来年は話しかけることをおすすめします!(そして私にも話しかけてくれると嬉しい)
  • 総じて例年以上に最高でした

終わりに

まだ、当日の余韻に浸っていますが、非常に濃い1日を過ごすことができました。

主催のdictavさん、VimConf2015運営にかかわられた皆さん、発表された皆さん、参加者の皆さん、会場を貸していただいた 株式会社ミクシィさん、本当にありがとうございました。

またどこかのVim関係の勉強会でお会いしましょう!

Happy Vim Life!

スマートフォンでVimを操作するためにやっておいたほうがいいこと

この記事はVim Advent Calendar 2014の13日目の記事です。
12日目はokuramasafumiさんによるVimを体系的に学ぶつもりのない人のためのVim講座―Exコマンド編でした。

はじめに

なぜスマートフォンVimを操作する必要があるのか?

当たり前ですが、VimはPC用キーボードでの操作用に最適化されており 他の入力機器での操作は想定されておりません。

では、なぜそんなVimスマートフォンで操作する必要があるのか、 それには例えば以下のような理由があります。

  • VPS設定中だけどもう出かける時間だ。外でノートPCいじる時間もないし…
  • 自鯖の調子がおかしいので設定確認して再起動したい。でもあと2時間は帰れない…
  • Vimが触りたくて禁断症状がでそう。でも今満員電車の中だ…

こんなときスマートフォン(とサーバーをいじるためのSSHクライアント)が あれば解決できそうです。

しかし、スマートフォンでコンソールおよびVimを扱うのは中々 難しいことです。今回はこういう状況のためにどのように備えて おくべきかをご紹介したいと思います。

なお、Bluetoothキーボードはもちろん、両手を使えないような 状況を想定してお話します。 (満員電車の中でBluetoothキーボードはもちろん、両手は自由にならないですよね)

なぜVimなのか?

Vimmerにとっては完全に愚問ですが、Vimmer以外の方にとっても 今回想定するケースではVimを使うのが一番現実的な解となると思います。

  1. 大抵の環境(UNIX系)にVimは確実に入っている
  2. Vimならスマートフォンキーボードでもある程度の操作に耐えうる操作体系を備えている

2 については後述しますが、スマートフォンで端末に接続して文書を参照・編集したいと 思った場合は、Vimmer以外の方もVimを使うことをおすすめします。

今回話さないこと

今回話す対象とするのは、SSHでどこかの端末に接続してVimを操作する ケースに限ります。

このため、iOS用のVimアプリや、 Android用のVimアプリで の話は出てきませんのであらかじめご了承ください。

下準備

スマートフォンSSHクライアントを入れる

何はともあれSSHクライアントがなければ始まりません。 SSHクライアントは好きなアプリを使ってもらえばいいです。

私はスマートフォンiPhoneなので有料アプリのPrompt のバージョン1を使っています。

本題とは関係ないのですが、今回記事を書いている時に Promptのバージョン2が出ていることに気づきました。 スマフォアプリにしてはそこそこお高いですが、 バージョン1には大分お世話になったので お布施の意味で購入しようと思います。 なお、本記事執筆時点ではまだバージョン2を使っていないため、 バージョン2の使い勝手はまだわかりません。

他のSSHクライアントを使ったことがないので、比較はできませんが Promptは以下の点が気に入ってます。

  • 秘密鍵ファイルをアプリフォルダに突っ込んで指定するだけで公開鍵暗号方式で接続できる
  • 過去に実行したコマンドの補完がポップアップで表示される
  • (今回は関係ないですが) Bluetoothキーボードにも対応している
  • あまり落ちたりせずそこそこ安定している

上記はバージョン1の評価です。

今回はSSHクライアントの紹介記事ではないのでスクリーンショットを貼って 紹介を終わります。

f:id:deris:20141213163548p:plain

スマートフォンでのソフトウェアキーボード操作になれる

大体の人はスマートフォンでの操作に慣れていると思いますが、 スマートフォンでのキータイプに慣れていない人は以下のアプリなどで 練習を積んでおくといいかと思います。 当然ですがスマートフォンでのキータイプがおぼつかなければ、 スマートフォンでのVim操作もおぼつかないものになります。

タイピングの神様 iOS版

タイピングの神様 Android版

練習する際は、日本語入力ではなく言語をEnglishで練習しましょう。 端末操作では日本語入力速度はあまり関係ないので。

なお、片手で操作するのであれば、フリック入力がお勧めです。 なれるとqwertyのソフトウェアキーボードよりも若干早くタイプ出来ます。 (と思って試してみたけど実際トントンくらいでした… ただ、日本語入力であれば慣れるとフリック入力の方断然が早いです。 慣れている方を使えばいいかと思います。)

参考までに私のタイプ成績を載せておきます。上がフリック入力、下がqwertyです。 どちらも利き手親指のみで操作しています。 (ほとんど変わりませんね…)

f:id:deris:20141213162947p:plain

f:id:deris:20141213162954p:plain

指1つでVimを操作するための設定

さて、ここからが本題です。

と言っても、実は普通にPC用キーボードでVimを操作する時と 意識することはそこまで変わりません。

ただ、スマートフォンで操作するという性質上、より強く意識したほうがいいこと いくつかあります。 また、スマートフォンのソフトウェアキーボードの性質なども 考慮に入れる必要があります。

Vimの基礎を忠実に

最近のスマートフォンは高性能だし、ネットワークも高速なので そこまで気にしないかもしれませんが、スマートフォンでのSSH接続は、 リアルタイムにレスポンスが帰ってこず、数100ミリ秒、 場合によっては数秒レスポンスに時間がかかることがあります。

特に電波が悪いところで作業をすると、レスポンスまでの時間が 数秒単位になります。

一つ一つの操作のレスポンスが遅いと、例えば普段h, j, k, lの 連打などで移動していると、1行、1文字ごとの移動で、レスポンスを待たされ 目に見えて操作効率が落ちます。

このため、スマートフォンでは単体でのh, j, k, lは極力使わないようにし、 よりタイプ数が少なくてすむ以下のような操作を極力使うようにした方がいいです。 つまりVimの基礎を忠実にということですね。 タイプ数(端末への要求数)が少なくなれば、それだけレスポンスに待たされる時間 も減ります。

移動内容 入力キー
単語移動 w, b, e
指定文字移動 f, t
行末行頭移動 ^, $
ファイルの先頭、末尾移動 gg, G
指定行移動 [指定行の数]gg
ページ移動 <C-f><C-b>
段落移動 {, }
検索 /
単語検索 *, #, g*, g#
カウント指定 5h, 5j, 5k, 5lなど

ここら辺は、普通のVimmerなら無意識でやっていることかもしれませんが、 キーリピートを高速化して操作している方もいると思うので特に そういう方は注意をしましょう。 全然使いこなせていない方は、日頃から意識して使うようにしましょう。

このような、1キーストロークでの移動の機能がデフォルトで多く用意されているため、 スマートフォンでの編集は、他のエディタよりもVimの方が優位性が あると思います。

極力Ctrl, Shiftなどを使わないようにする

スマートフォンでタイプするとわかると思いますが、 スマートフォンのソフトウェアキーボードはPC用キーボードと 比較して記号が非常に打ちづらいです。 また、SSHクライアント端末では用意されていることもありますが、 スマートフォンのデフォルトのソフトウェアキーボードはCtrlが ありません。

上記のことを考慮し、極力、記号、Ctrlを使用しないような キーマッピングをしておくことをおすすめします。

例えば、上記で上げた行末行頭移動の^, $は記号ですし、 ページ前方後方移動の<C-f>, <C-b>Ctrlを使うので 記号、Ctrlを使わないキーにキーマッピングしておくといいでしょう。

また、よく使うコマンドも合わせてキーマッピングしておくと いいでしょう。

下記設定例は、よく使うコマンド(ファイル保存、ウィンドウを閉じる) 記号、Ctrlを使う移動をキーマッピングしています。 (<Space>はソフトウェアキーボードでもローマ字と合わせて最初から 表示されている貴重なキーなのでprefixとして使うことをおすすめします。 なお、PC用キーボードでも同様に押しやすかったりします。)

" ファイル保存
nnoremap <Space>w  :<C-u>w<CR>
" ウィンドウを閉じる
nnoremap <Space>q  :<C-u>q<CR>

" 行頭、行末移動
nnoremap <Space>h  ^
vnoremap <Space>h  ^
nnoremap <Space>l  $
vnoremap <Space>l  $

" ページ前方、後方移動
nnoremap <Space>j  <C-f>
vnoremap <Space>j  <C-f>
nnoremap <Space>k  <C-b>
vnoremap <Space>k  <C-b>

また、submodeプラグインを使って、 移動専用のモードを用意するのもお勧めです。

submodeは、Vimの normalモードやinsertモードのようなモードを、擬似的に 作り、そのモードでだけ使用できるキーマッピングを設定する事ができます。

以下の設定では、submodeを使って、 縦方向移動効率化モードを作っています。

" 縦移動の効率化(要submode pluginインストール)
call submode#enter_with('ex-move', 'nv', '', '<Space><Space>', '<Nop>')
call submode#leave_with('ex-move', 'nv', '', '<Space>')
call submode#map('ex-move', 'nv', '', 'j', '<C-f>zz')
call submode#map('ex-move', 'nv', '', 'k', '<C-b>zz')
call submode#map('ex-move', 'nv', '', 'n', '5jzz')
call submode#map('ex-move', 'nv', '', 'm', '5kzz')
call submode#map('ex-move', 'nv', '', 'l', '}zz')
call submode#map('ex-move', 'nv', '', 'h', '{zz')

<Space>を2回タイプすることにより、縦方向移動効率化モードに入ります。 縦方向移動効率化モードに入っている間は、j, kでページ前後方向スクロール、 n, m5j, 5kl, hで段落前後移動ができます。 移動操作が終わったら、<Space>を1回タイプすることでモードを抜けます。

それぞれ1キーストロークで目的の操作を可能にしており 押しづらいキーのタイプ数を大分抑えられることがわかると思います。

上記設定はPC用キーボードでも有用ですが、入力効率が落ちるスマートフォンでは 更に有用になります。

このように、よく使いそうだけどタイプしづらいキーはキーマッピングしておく とスマートフォンでの操作がグッとやりやすくなります。

Ctrlを極力使わないような設定が簡単にかけることも、 スマートフォンでの編集が、他のエディタよりもVimの方が 優位性がある理由の一つとなります。

おまけ

自分は常用していないので、詳しくご紹介出来ないのですが、 vim-easymotionというプラグインを入れると 移動時のキータイプ数がかなり減らせそうなので、スマートフォンでのVim操作にあっている かも知れません。

vim-easymotionについては、現メンテナである haya14busaさんの記事が詳しいのでご紹介までにリンクを張っておきます

Vim-EasyMotionでカーソル移動を爆速にして生産性をもっと向上させる

まとめ

以上が、スマートフォンVimを操作するためにやっておいたほうがいいことです。

何かあった時のために、スマートフォンからVimをさわれるよう普段から準備を してはいかがでしょうか?

それではVim Advent Calendar 2014の13日目の記事を終わります。

Happy Vim Life!

ぼくのかんがえたさいしょうのvimrc

この記事はVim Advent Calendar 2013の171日目の記事です。
170日目はmanga_osyoさんによるvim-operator-alignta つくったでした。

本記事では、ぼくのかんがえたさいしょうのvimrcを紹介します。

はじめに

さいしょうのvimrcとは?

何か中二病っぽいタイトルですが、わりとまじめに考えて作ったものです。

タイトルをパッと見て、「最小?最強のタイポじゃないの?」 と思われた方もいるかもしれません。 しかし、最強のvimrcではありません。 最小 のvimrcです。

私がここで言っている最小のvimrcとは以下のような意味です。

Vim pluginを入れず、必要最小限の設定だけをまとめたvimrc

Vim pluginを入れずというのがミソです。 また、ここで言っている最小限の設定とは、(個人的に)どうしても 必要なオプション設定とキーマッピングなどのことです。

さいしょうのvimrc作った理由

仕事上テスト機などの共用で使うようなマシンで、 ちょっと設定ファイルなどを編集したい場合に、 勝手にVimプラグインを入れづらかったり、 わざわざVimプラグインをいれるまでもなかったりする場合があります。

こういう時、私は今まで特に設定なしでVimを使っていたのですが、 バリバリカスタマイズした自分のvimrcに慣れきっていると、 操作が微妙にぎこちなくなります。 (もちろん操作できないということはないですが。。。)

かと言って、いつも使っているvimrcをそのまま入れると プラグインの設定がたくさんあるため、大量のエラーで まともに動きません。

このような背景があり、カスタマイズバリバリのvimrcとは別に ちょっとしたvimrc、つまり自分にとって最小限の設定を記載した vimrcを書くことにしました。 小さいvimrcであれば、さっとコピーしてさっと使うことが でき便利です。

さいしょうのvimrc

ぼくのかんがえたさいしょうのvimrcは、 .minimal_vimrcにおいてます。

今後変更するかもしれないので現時点(2014/5/21)での最新にリンクしています。

中身について簡単にざっとご紹介します。

なお、下記設定は全部を自分で考えたものではなく どなたかのvimrcを真似させていただいたものもあります。 どれがどなたの設定か覚えていないのですが、 この場を借りて御礼申し上げます。

syntax enable

構文ハイライトを有効にしています。 これでファイルタイプ別に色付けされるようになります。

set number
set ruler
set list
set listchars=tab:>-,trail:-,nbsp:%,extends:>,precedes:<,eol:<
set incsearch
set hlsearch
set nowrap
set showmatch
set whichwrap=h,l
set nowrapscan
set ignorecase
set smartcase
set hidden
set history=2000
set autoindent
set expandtab
set tabstop=2
set shiftwidth=2
set helplang=en

オプション設定は完全に好みなので、細かく説明はしません。
個人的には、行番号表示(number)や、検索周り(incsearch,hlsearch,ignorecase)、 行頭/行末でのカーソル移動(whichwrap)、隠れバッファ(hidden) あたりは、設定しておかないと操作しづらいです。

colorscheme desert

背景色黒ベースのカラースキーマが好きなのでdesertに設定しています。

nnoremap <Space>w  :<C-u>w<CR>
nnoremap <Space>q  :<C-u>q<CR>
nnoremap <Space>Q  :<C-u>q!<CR>

ファイル保存、ウィンドウクローズをキーにマッピングしてます。 タイプ数はそんなに変わらないと思われるかもしれませんが、 <Enter>を押さなくていい分、手軽にタイプ出来ますし、 :w[<Enter>などのタイポなども気にしなくてよくなります。
<Space>も非常にタイプしやすくプレフィクスキーにお勧めです。

nnoremap ;  :
nnoremap :  ;
vnoremap ;  :
vnoremap :  ;

よく使うコマンドラインモードに入るための:と、 よりタイプしやすい;を入れ替えています。
特にASCII配列キーボードだと、:はタイプ しづらいので、個人的に必須です。

nnoremap <Space>h  ^
nnoremap <Space>l  $

行頭/行末移動のキーを、マッピングしています。
タイプ数が多くなって押しづらくなってるじゃないかと 思わるかもしれませんが、デフォルトの^$は、 <Shift>と一緒にホームポジションから遠いキーを押す必要があるため、 押しづらく小指が疲弊してしまいます。
マッピングしている<Space>h<Space>lは片手でタイプ できてお勧めです。
<Space>は押しやすいので、Vimでキーをマッピングする際、 <Space>をプレフィクスキーとして使うと便利です。

nnoremap k   gk
nnoremap j   gj
vnoremap k   gk
vnoremap j   gj
nnoremap gk  k
nnoremap gj  j
vnoremap gk  k
vnoremap gj  j

表示行移動であるgjgkと、実際の行移動であるjkを 入れ替えています。
set wrapの設定をして、1行が表示上ラップしている場合に、 gjgkは、表示上の行での移動なのでjkより 便利なときがあるため入れ替えています。

nnoremap <Space>/  *<C-o>
nnoremap g<Space>/ g*<C-o>

*は、カーソル位置の単語で前方検索します。 これは非常に便利なコマンドで、よく使うのですが、 *はASCII配列キーボードだと、<Shift>を押しながら ホームポジションから遠いキーをタイプする必要があるので ちょっと押しづらいです。
そこで、<Space>/マッピングしています。 片手でタイプできてお勧めです。

g*は、*と違い、単語の一部にもマッチします。 こちらも同様にマッピングしています。

nnoremap <expr> n <SID>search_forward_p() ? 'nzv' : 'Nzv'
nnoremap <expr> N <SID>search_forward_p() ? 'Nzv' : 'nzv'
vnoremap <expr> n <SID>search_forward_p() ? 'nzv' : 'Nzv'
vnoremap <expr> N <SID>search_forward_p() ? 'Nzv' : 'nzv'

function! s:search_forward_p()
  return exists('v:searchforward') ? v:searchforward : 1
endfunction

nNは、最後の/?を繰り返します。

/で検索した場合と、?で検索した場合で、 nNで移動する方向が異なるのが不便でした。 このため、/?のどちらで検索した場合でも、nで前方検索 Nで後方検索するよう設定しています。

nnoremap <Space>o  :<C-u>for i in range(v:count1) \| call append(line('.'), '') \| endfor<CR>
nnoremap <Space>O  :<C-u>for i in range(v:count1) \| call append(line('.')-1, '') \| endfor<CR>

インサートモードに入らずに、カーソル行の下もしくは上に空行を挿入します。 countにも対応しているので、10<Space>oで10行挿入できます。

空行を挿入する+αも参考ください。

nnoremap <silent> tt  :<C-u>tabe<CR>
nnoremap <C-p>  gT
nnoremap <C-n>  gt

タブ関連のキーマッピングです。

私はタブを多用するので、新規タブの作成をタイプしやすいttに割り当てています。

また、タブ移動は、複数タブを確認しながら移動する場合に、 gtgtgtgtとタイプするするのがタイプしづらかったため <C-p><C-n>マッピングしています。

nnoremap <silent> <Esc><Esc> :<C-u>nohlsearch<CR>

set hlsearchで、検索時にマッチするテキストが強調表示されます。 検索テキストの強調表示は便利なのですが、検索が終わった後は 強調表示をオフにしたいので、nohlsearchコマンドを使います。

nohlsearchコマンドはちょいちょい使うため、<Esc><Esc>マッピングしています。

nnoremap ZZ <Nop>
nnoremap ZQ <Nop>

nnoremap Q gq

危険なキーを無効 or 別のキーにマッピングしています。

ZZZQはそれぞれ、「ファイルを保存して終了」、 「ファイルを保存せずに終了」です。

タイプしやすくて便利だったりするのですが、あまりに タイプしやすく、ZZをタイプするつもりが誤ってZQを タイプして悲しい気持ちになることが多々あります。 そのため、使わないよう空マップ<Nop>に指定してます。

また、QはExモードに切り替えます。 通常の使用でExモードを使うことはほとんどないため テキストを整形するgqマッピングしています。

onoremap aa  a>
onoremap ia  i>
onoremap ar  a]
onoremap ir  i]
onoremap ad  a"
onoremap id  i"

テキストオブジェクトで、i)i}などは、 ibiBに割り当てられていて、i)i}とタイプするのと 比較してタイプしやすいのですが、 i>i]i"はそのまま記号をタイプする必要があり 押しづらいため、上記のようにマッピングしています。

このキーマッピングの副作用として、上記テキストオブジェクト は、ASCII配列キーボードでもJIS配列キーボードでも同じキーで 操作する事ができるようになります。

inoremap jk  <Esc>

ノーマルモードに戻るための<Esc>はタイプしづらいので、 jkマッピングしています。 jkであれば、編集でjkを入力することはほとんどないですし、 誤ってノーマルモードでタイプしても上下移動するだけですみます。 何よりホームポジションを移動せずにタイプできるので 非常にタイプしやすいです。

このキーマッピングは人を選ぶと思います。

nnoremap gs  :<C-u>%s///g<Left><Left><Left>
vnoremap gs  :s///g<Left><Left><Left>

置換コマンドは多用するのですが、いちいちタイプするのが 面倒なので、gsキーにマッピングしています。
これで、gsとタイプすることで、即座に置換する文字列 の入力に移れます。

cnoremap <C-f>  <Right>
cnoremap <C-b>  <Left>
cnoremap <C-a>  <C-b>
cnoremap <C-e>  <C-e>
cnoremap <C-u> <C-e><C-u>
cnoremap <C-v> <C-f>a

コマンドラインモードでの移動をEmacsライクなキーに設定しています。

まとめ

以上が、ぼくのかんがえたさいしょうのvimrcのご紹介でした。
皆さんも、自分だけの「ぼくのかんがえたさいしょうのvimrc」を作ってみてはいかがでしょうか?

本題とはそれますが、Vimレベルが上がるのでvimrc読書会に参加することをおすすめします。毎週土曜日23時からやってます。

それではVim Advent Calendar 2013の171日目を終わります。

Vimのタブで開いているバッファのdiffを簡単に表示するpluginを書いた

Vim

この記事はVim Advent Calendar 2013の57日目の記事です。
56日目はmanga_osyoさんによる:substitute をプレビューする over.vim にスクロール機能を実装したでした。

本記事では、Vimのタブで開いているバッファのdiffを簡単に表示するpluginを書いたのでご紹介します。

※ちなみに本日1/26は、私derisの誕生日だったりします。いわゆる誕生日VACです。わーい、めでたいですね(棒

vim-diffbuf

vim-diffbufはタブで 開いているバッファ同士のdiffをとるのが面倒で作ったpluginです。
(同一タブ内で開いていればwindo diffthisで一発なんですけどね…)

diffの対象にしたい1つ目のバッファをカレントバッファとした状態でDiffBufコマンドを 実行し、diff対象にしたいもう1つのバッファでも同様にDiffBufコマンドを実行すると、 新規タブ上で垂直分割した2つのdiff対象のバッファのdiffを開きます。

実際の動作は以下のGIFアニメを見てください。

screenshot

上記GIFアニメの例では、別タブで2つの無名バッファが開かれており、 それぞれのバッファをカレントバッファとした状態でDiffBufコマンドを 実行することで2つのバッファのdiffを新規タブで開いています。

vim-diffbufでは、1つ目のdiff対象でDiffBufコマンドを実行すると 内部で、diff対象を保存します。2つめのdiffでDiffBufコマンドを 実行した時に、2つのdiffを表示します。この際内部で保存したdiff対象 はクリアするため、再度、DiffBufコマンドを実行することで、別の diff対象同士のdiffをとることが可能です。

future work

まだ作りたてなので、インターフェースは、引数なしのDiffBufコマンド (と同様の関数diffbuf#diffbuf)のみと非常に単純なpluginです。 また、diffを開く際も、新規タブ&垂直分割と固定です。 そのうち機能拡張しようと思いますが、とりあえず使いながら使いづらいところを 拡張していこうと思っています。

今のところ思いつくのは以下のような拡張です。

  • バッファ番号指定のdiff
  • 開くウィンドウの指定(新規タブか既存タブか、垂直分割か水平分割か)

もし、要望があればフィードバックしていだけるとうれしいです。

まとめ

以上が、Vimで既存バッファをvimdiffしたいときに便利なpluginについてのご紹介でした。

本題とはそれますが、Vimレベルが上がるのでvimrc読書会に参加することをおすすめします。毎週土曜日23時からやってます。

それではVim Advent Calendar 2013の57日目を終わります。

明日のVim Advent Calendar 2013はhaya14busaさんです。