2011/12/24

開発版GNU Screenでコピペを極める

本記事は ターミナルマルチプレクサ Advent Calendar 2011 : ATND の24日目です。23日目は tmuxのペイン切り替えをscreenみたくする(ターミナルマルチプレクサ Advent Calendar 2011 23日目) - kozo2のはてなダイアリー でした。やはり screen に慣れてしまうと tmux 操作の最初のとっかかりが難しそうですね。使いやすい点はどんどん取り入れて自分が操作しやすい環境を整えることが大事ですね。さて今回は開発版 GNU Screen で強化された点も踏まえて、コピーペーストについて書いてみようと思います。

コピペを制するものは端末を制す

ターミナルマルチプレクサはスクロールバックバッファを自由に操作できますので大変優れたコピペツールとしても使えます。今回の Advent Calendar でもそのあたりのテクニックがいくつか紹介されています。

ここでは GNU Screen のコピーモードで出来る操作についてまとめたいと思います。

GNU Screen のコピーモードで使用できるキー

copy モードで使用できるキーを screen(1) をベースにまとめます。
  は数値を前につけることで数量を指定できるキーです。  は開発版で追加されたキーです。

カーソル移動に関するキー

  • 文字単位のカーソル移動
    • h, Ctrl-H, 一つ左に移動
    • j, Ctrl-N, 一つ下に移動
    • k, Ctrl-P, 一つ上に移動
    • l, 一つ右に移動
    • - 一つ上の行の先頭文字に移動
    • + 一つ下の行の先頭文字に移動
    • 0, Ctrl-A 行頭に移動
    • ^ 先頭文字に移動
    • $ 行末文字に移動
    • | 指定した絶対桁に移動
  • 単語単位のカーソル移動
    • w 次の単語の文字先頭に移動
    • b 前の単語の文字先頭に移動
    • e 現在の単語の文字末尾に移動
    • B 単語の前に移動
    • E 単語の後に移動
  • 行単位のカーソル移動
    • H ウィンドウ最上行の先頭に移動
    • M ウィンドウ中央行の先頭に移動
    • L ウィンドウ最下行の先頭に移動
    • g, Home コピーバッファの先頭に移動
    • G, End コピーバッファの指定した行の先頭に移動(指定しない場合はコピーバッファの最終行)
    • % 指定したパーセンテージの行の先頭に移動(指定しない場合はコピーバッファの先頭行)
    • Ctrl-Y 一行上に移動(カーソルの位置は保ったまま)
    • Ctrl-E 一行下に移動(カーソルの位置は保ったまま)
  • ページ単位のカーソル移動
    • Ctrl-U 半ページ上に移動(カーソルの表示位置は保ったまま)
    • Ctrl-D 半ページ下に移動(カーソルの表示位置は保ったまま)
    • Ctrl-B 一ページ上に移動(カーソルはウィンドウ最上行に移動)
    • Ctrl-F 一ページ下に移動(カーソルはウィンドウ最下行に移動)
  • 検索によるカーソル移動
    • / vi 形式の前方検索
    • ? vi 形式の後方検索
    • n vi 形式の順方向再検索
    • N vi 形式の逆方向再検索
    • Ctrl-S Emacs 形式の前方インクリメンタル検索(※)
    • Ctrl-R Emacs 形式の後方インクリメンタル検索(※)
      • ※検索した単語にカーソルを移動するには Esc
      • ※インクリメンタル検索モードを抜けるには Ctrl-G または Esc
  • 現在行の文字検索によるカーソル移動
    • fX カーソル位置から右に検索して見つかった文字 X に移動
    • tX カーソル位置から右に検索して見つかった文字 X の一つ前に移動
    • FX カーソル位置から左に検索して見つかった文字 X に移動
    • TX カーソル位置から左に検索して見つかった文字 X の一つ後に移動
    • ; f/F/t/T による検索を右に再実行
    • , f/F/t/T による検索を左に再実行
コピーモード中に移動する方法はいくつもありますが vi で使えるものはほぼ使えます。vim 使いの私としては逆方向再検索ができるようになったのは大きいです。文字検索による移動もカーソル位置の微調整に役立ちますね。

Emacs 使いの方は markkeys でコピーモードのキーマップを変更できます。GNU screen [interface] によると stuff と組み合わせることで2ストロークキーの割り当ても出来るみたいです。Ctrl-A は開発版で追加されていますね。

markkeys j=^N:k=^P:l=^F:0=^A:$=^E:^F=^V
bindkey -m -t ^[v    stuff ^B
bindkey -m    ^B     stuff h
bindkey -m -t ^[a    stuff \^
bindkey -m -t ^[f    stuff w
bindkey -m -t ^[b    stuff b
bindkey -m -t ^[0^[r stuff H
# Nothing for 'M'
bindkey -m -t ^[-^[r stuff L
bindkey -m -t ^[<    stuff g
bindkey -m -t ^[>    stuff G
bindkey -m -t ^[d    stuff " e "
なお、scrollback が大きな値でバッファがまだそれほど埋まっていないときには g% を入力しても何も無い先頭に移動してしまいますが、g w とすることで先頭文字に素早く移動できます。 カーソルが最下行で見応えがないと感じる場合は g w Ctrl-F Ctrl-B とでもすれば有効なバッファの先頭が最上行に表示されます。

マークに関するキー

コピーする範囲の開始点、終了点を設定するためのキーには次のようなものがあります。

  • Space, Enter, マウスクリック 開始点を設定、または終了点を設定してコピーモードを終了
  • y カーソル行の先頭文字を開始点として設定し、カーソルを行末に移動
  • Y カーソル行全体をコピーしてコピーモードを終了
  • W カーソル下の単語をコピーしてコピーモードを終了
  • a ペーストバッファに追記するモードのトグル切り替え
  • A 終了点の設定として押すと選択範囲をペーストバッファに追記してコピーモードを終了
  • o, x 開始点を設定した後に押すと、カーソル位置を開始点に変更して以前の開始点にカーソルを移動
手早く行をコピーしたいときには Y が使えますが、選択範囲の先頭文字からのコピーとなるため、先頭の空白も含めたい場合には注意が必要です。同じ事は y にも言えます。

その他のキー

  • c 矩形選択における左端を設定
  • C 矩形選択における右端を設定
  • v, V 選択範囲の左端を1桁目と9桁目でトグルする(vi で :set number している場合を想定、らしい)
  • J コピーした行を連結する際の区切りを設定。押した順に以下4つのトグルとなる
    1. 区切り文字なし
    2. 空白( )
    3. カンマ(,)
    4. 改行文字(LF) ※crlfon にしていると改行文字の前に復帰文字(CR)が追加される
  • > 終了点の設定として押すと選択範囲をコピー後、その内容を bufferfile で指定されているファイルに出力
  • Ctrl-G カーソル位置(桁、行)と scrollback に設定している行数、矩形選択している場合はその左端、右端をステータスラインに表示
v の扱いが難しいですが、矩形選択の左端の解除として使えます。同じようにして右端の解除は 1000 | C などとして最右端を設定することで代わりになります。

コピーモードの判別

開発版 GNU Screen では caption で使用できる文字エスケープにコピーモードかどうか判別できる %P が加わりました。これは %F(そのウィンドウにフォーカスがあるかどうか)と同じように条件式として使えます。私はコピーモード時にそれと分かるような文字列を表示するよう設定しています。

caption always '%?%F%{= gW}%:%{= Kk}%?%2n%f%07=%t%?%P *** copy/paste mode ***%:%?%='

使用例

矩形選択

例として適切かどうか分かりませんが、私はよく矩形選択を Oracle Database の SQL*Plus 上で使います。このツールは OSS なデータベースクライアントでは当たり前のヒストリ機能に対応していないので、二つ前に実行した SQL を再実行させたいときに少し難儀します。(一つ前ならバッファにあるので再実行したり、行指向の編集はできます)

そんなときは以下のような操作を行います。

  1. 行番号でインデントされている SQL の先頭にカーソルを合わせて c で左端を設定
  2. y で行全体を選択
  3. j を何回か押して SQL 全体を選択
  4. Space で終了点を設定(コピー)
  5. Ctrl-A ] で貼り付け
自分の管理下の環境であれば rlwrap を使うので単一行クエリにはあまり苦労しませんが、それが使えない環境や以前実行した複数行のクエリを再実行、再編集するときなどに役立ちます。とくにデータベース系のサーバでは証跡も兼ねて scrollback はかなり多めにしています。

行連結

これも例としては不自然かも知れませんが、パイプで繋げないケースでコマンド出力にあるファイル一覧を別のコマンドの引数に指定したいときがあります。そのようなときは無意識的に以下の操作を行っています。

  1. J J で空白による行連結を設定
  2. c で左端を設定
  3. 2 y で2行を選択
  4. Space で終了点を設定(コピー)
  5. コマンドを入力して、ファイル引数として Ctrl-A ] で貼り付け

おわりに

コピーモードについて screen(1) の単なる解説記事になってしまいましたが、いかがでしたでしょうか?開発版では使用できるキーがいくつか増えた程度の変更しかありませんが、すでに現在の stable 版でも機能としては十分です。コピーモード中のスクロールバックバッファ内でカーソルを自在に操作できると必要な情報を迅速に見つけられますし、それらを任意の形式でコピーしたものは単にウィンドウに貼り付ける以外にもいろいろと使い道があります。端末作業の可能性を広げるために、コピーモードでの操作をマスターしてみませんか?

以下はコピペしたものを screen 外で利用する方法についてまとめたものです。何かのヒントになれば幸いです。

0 件のコメント:

コメントを投稿