register

さてそろそろ register に興味を持つお年頃になってまいりました。とりあえず :h registers を読んでおもしれーと思ったことをまとめ。けっこう独特というか local rule が多いというか、まぁ文化だよな。

  • unnamed register ( :h quote_quote )
    • 名前がないにもかかわらず "" で参照できるよくわからん register 。 black hole register への指定付き以外のあらゆる copy と cut 操作 ( yank と delete というのが canonical なんだけどまぁ ) はこいつを書き換えているらしい。で、 pP で挿入されるのはこいつの中身、と。
  • numbered registers ( :h quote_number )
    • 番号付きってことは履歴みたいな感じで使ってんのかなと思いつつ大体そんな感じなんだけど微妙に違うので単純な履歴としては扱えない感じ ? とりあえず register 指定のない copy, cut 操作時に書き換えられるというのはすべての番号共通らしい。 "ay とか "_3dd とかやってもこいつらは書き換わらないということだね。
    • "0 は直前に yank された内容が入る。こいつは特別扱いぽい。
    • "1 〜 "9 には 1 行以上 delete された場合と %, (, ), `, /, ?, n, N, {, } の motion つき delete command を実行した場合に入るということらしい。とりあえず motion を受け付けるのは d のみなのでたとえば d) だとか dn だとかは番号付き register に入るけど diw とか df. は入らない。で、 1 番が直前に delete した text で 2 番がその前に delete したもので…、と 9 番まで覚えててそれ以降は破棄される。
    • じゃあ 1 行未満が delete されちまったときはどうすんだというと次に出てくる small delete register というのが使われるらしい。テラ複雑。大規模な ( もしくは大規模になる可能性のある ) 削除を行った際に restore しやすいようにこういう風になってんのかな。あーやべ、あの文章消すんじゃなかったとかいうときにすぐに recovery きくので安心的な。
  • small delete register ( :h quote_- )
    • register 指定なしかつ 1 行未満の delete の場合こいつにつっこまれる。
    • うーんどういう場合に使うんだ…。 mapping や recording で yank と delete が混在するときとか…、もかなり限定的だなぁ。普通に直前に delete したものっていう意味で paste ( put が以下略 ) するときに意識的に使うと混線が少なくなって精神的にも良いよということなのかな。
  • named registers ( :h quote_alpha )
    • a-zA-Z の範囲で 1 文字の名前がついている register 。指定しない限りは使われないらしい。大文字小文字で 52 個自由に使えるのかってーとそういうわけではないらしく、小文字で指定したときはそのまま copy or cut したものをつっこむんだけど大文字で指定すると小文字になおしたものに追加する形になる、ので実質 26 個。さらに 'cpoptions' に ">" を指定していると行として追加されるとか。
    • 適当なところで "ayiw したあとに "Ayiw とすると "a に入ってた単語に今の caret の下にある単語が追加される。このとき match(&cpoptions, '>') が偽ならそのまま、真なら追加される単語の前に改行が入る、と。
    • 小文字での指定はよく使う単語や式なんかをいれておいて paste しまくるというのは普通にする ( insert mode で <C-r> のあとに任意の register 名を押すと楽に paste できる - :h i_CTRL-R ) とは思うんだけど大文字が有効そうなのってあんまり思い浮かばないなぁ。 script 書いたり recording させたりすると実はすごい ?
  • read-only registers ( :h quote_., :h quote_%, :h quote_#, :h quote_: )
    • その名の通り paste 専用。 register 名を指定して明示的に変更するということは出来ないんだけど変更自体は暗黙的に自分が行っている、というと混乱の元か。とりあえず 4 つあって ". は直前の insert mode で入力した内容で paste 時に 'textwidth' とかの影響を受けるよ、と書いてある。 "% と "# はそれぞれ current / alternate file が相対 path で 。最後の ": は直前の command-line mode で打った内容。
    • "% と "# はまぁわからんでもないというかよくわかるんだけど他 2 つは意識的に使うのは難しそげ。やっぱり scriptic な使い方しか浮かばない。
  • expression register ( :h quote_= )
    • 厳密には register ではないんだけど paste 専用で任意の expression ( :h expression ) を評価した結果を貼っ付けてくれる、らしい。たとえば insert mode で <C-r>= とか押すと command-line に caret が出てきて expression を入力できるようになる。ここでたとえば expand("%:e") とか打つと編集中の file の拡張子が挿入される。
    • これかなりおもしろいんだけど使いどころが難しいというか日常的に使えるようになるにはもう少しかかりそうというか。てか使えてうれしい expression をそんなに知らないという悲しい現実。
  • selection and drop registers ( :h quotestar, :h quoteplus, :h quote_~ )
    • vim の外とやりとりするための register 。 Windows だと clipboard 、 X11 だと…、わかんね ( 触ったことはあるけどよく知らない ) 。とりあえず Windows での扱いとしてはコピペするためにこの register を指定するということだけ知っていれば OK か。具体的には "+y"+pWindows の場合 "*y"*p でも同じみたいなんだけど gvim の menu に出てるのが plus の方なので canonical なのは plus なのかな、と。
    • で、コピペすんのにいちいち register 指定しなきゃならんの ? って場合は 'clipboard' に unnamed を指定すればいいらしい。そうすると "* を unnamed register として扱うようになるので ydp のみで済むようになる。ってかおれこういう設定あるの知らなくてずっときたんだけど今知ってにょろーんとしてる。まぁ copy も cut も頻繁にするし vim の register と clipboard は別という概念が染みついているのでこの設定をすると clipboard の中身が知らんうちに変わってる !! とか驚くかもしれんけど。
    • "~ は vimdrop した内容を記憶してるらしい。つっても +dnd feature 付きで compile されてないと使えないと書いてあって :version で調べてみたらなかったんだけど。あーでもなんか GTK でしか使えないって書いてある。
  • black hole register ( :h quote_ )
    • この名前の sense は 20 世紀的だよなぁと思いつつとりあえず指定しても何もおこらないという register らしい。 delete したいけど他の register の中身 ( 特に unnamed register ) を壊したくない場合に使う。 paste 時に指定しても何も出てこない、ってのはわかるんだけど指定できる意味あんのかな。単純に指定できないようにする意味がないのか、何かに使えるのか。
  • last search pattern register ( :h quote_/ )
    • 直前の検索に使った pattern が入ってる register 。 n や 'hlsearch' でこの register の中身が使われているらしい。 copy と cut が出来ない代わりに :let で書き換え可能というちょっと変わった特徴も持ってるらしい ( 他には unnamed register も書き換え可能みたい ) 。 paste は普通に出来る。
    • 試しに何か適当に検索したあとに :let @/="" ( pattern の clear ) とかすると n もきかなくなるし highlight もされなくなる。これは日常的に使っていけるけど同時に説明されてる v:searchforward で検索方向の制御も可能な点を考えると script を書くときにつかってねってことなのかな。

let での register 書き換えは "" や "/ 以外でもできた。ってか read-only register 以外は出来るみたい。 help には上記の 2 つしかできないぽく書かれているけど 1 文字かつ writable なものを let で更新可能ってのはあれか、別に明示的にこれは writable だよと書いてあるものってわけじゃなくて copy や cut で中身が変わるものって意味か。あーここらへん掘り下げてくと特定の BufNew, BufRead, FileType あたりの event に named register の登録を引っかけて定型句を登録しておくとか使えるな。あーでも夢がひろがりんぐってだけじゃなくて管理も面倒になるか。まぁそれはそれで。

で、まぁ人間の記憶はあいまいなもので ( 中略 ) 迷ったら :display を打てば今の register の状況がわかると最後に書いてある。んーここ読んだだけでかなり使いこなせてる感が増した。てかこの entry 書いてる間にすごい勢いで編集方法変わってったんだけど。