GNU screenのコピーモードは、vi風操作が可能ですが、以下の動作がvimと違って使いにくいので、
スクロールバッファを一時ファイルに保存してvimで編集するための方法です。
(vim以外のエディタでも同様の方法が可能)
- 日本語上での
w
等による単語単位移動の動作が異なる - 矩形選択方法が異なる(右端マーク操作)
i"
等のtext-objectは未対応(W
による単語選択がある程度))
による文単位の移動等は未対応
(ふと、MS-DOSでVz Editorを常駐させてコンソール出力をコピーしていたのと同様のことができないかと思いついたので。)
また、複数の離れた場所からコピーする必要がある場合、
「コピーモード開始、コピー対象文字列の場所に移動、コピー対象文字列を選択、ペースト」
を繰り返す手間がかかるのに対し、vimで編集する方法であれば、
コピーモード開始は1回ですみ、ペーストしたい文字列を編集して作ってから、1回だけペースト操作をすれば良くなります。
minmsgwait0defscrollback1000bufferfile$HOME/tmp/screen-xchgbindVeval'msgwait0'copy'stuff"g G$>"'screen'stuff"vim +$ $HOME/tmp/screen-xchg;exit^M"' 'msgwait1' 'echo""'
備考:
msgwait 0
で、邪魔になるメッセージ表示を抑制。g G$>
で、スクロールバッファを最初から最後までコピーしてbufferfileに書き出し。screen 'stuff "vim ..."'
で、新しくwindowを作ってそこでvimを起動。vimが終了されたらシェルをexitしてwindowを閉じる。vim +$
で、起動後に:$
を実行して最終行に移動。echo ""
で、msgwait 1
実行によって表示されるメッセージを即時消去。
vimからscreenのコピーバッファへのコピー
vimからscreenのコピーバッファへのコピーは、fakeclip.vim参照。
(もしくは、以下の記事のYankToScreen()参照。
http://qiita.com/deton/items/61466d630edbac6734ae#3-5 )
また、vimを直接呼ぶかわりに、一時ファイルを編集・保存したら、
その内容をscreenのコピーバッファに反映する以下のスクリプトを呼ぶ形でも可。
#!/bin/sh# edit file and copy to screen's buffer
vim +$ $HOME/tmp/screen-xchg
screen -X eval'msgwait 0' readbuf 'msgwait 1'
bashのedit-and-execute-command(C-xC-e
)との組み合わせ
エディタ起動後、vimで画面分割してscreenのコピーバッファを開いて、コマンドライン編集の参考用に使えるようにする。
(やっぱりコマンドライン実行したくなくなった場合はvimを:cq
で終了)
bindEeval'msgwait0'copy'stuff"g G$>"' 'stuff"^X^E:sp ~/tmp/screen-xchg^MG"' 'msgwait1' 'echo""'
複数行を,
付きで連結してのコピー
screenのコピー機能の、複数行を,
付きで連結してのコピー等は、vim側で適当に編集すればいいかと思っています。
めったに使わないので。
({dir1,dir2,dir3}/*.html
のように指定したい場合くらいしか使ったことが無いです。)
スクロールバッファに対してスクリプトを実行
vim起動以外にも、適当なスクリプトを作って、
直前のコマンドの出力結果のみを抽出したり等も可能。
(主にコマンドを実行した後になって何かしたい場合用。
コマンド実行前ならパイプを使えばいいので。)
直前のコマンドの出力結果を抽出してコピーする例:
bindPeval'msgwait0'copy'stuff"g G$>"'screen'stuff"picklastout.sh;exit^M"' 'msgwait1' 'echo""'# 以下では動かない模様。#bind P eval copy 'stuff "?deton@colinux:^Mnj /deton@colinux:^Mk$ "'
例: 直前の出力結果抽出スクリプト(vim(あるいはed)をバッチモードで使用)
#!/bin/sh
cp ~/tmp/screen-xchg ~/tmp/picklastout
vim -e -s ~/tmp/picklastout < ~/bin/picklastout.ed
#ed -s ~/tmp/picklastout < ~/bin/picklastout.ed > /dev/null 2>&1# remove last "\n"
head -c -1 ~/tmp/picklastout > ~/tmp/screen-xchg
screen -X eval'msgwait 0' readbuf 'msgwait 1'
$
?^deton@colinux:
1,.d
/^deton@colinux:/d
w
備考:
deton@colinux:
はプロンプト文字列。要変更。- シェルのコマンド引数としてペーストして使いやすいように、最後の改行を削除
例: 直前の出力結果抽出スクリプト(awk版)
#!/bin/sh
cat $HOME/tmp/screen-xchg | picklastout.awk >$HOME/tmp/picklastout
mv $HOME/tmp/picklastout $HOME/tmp/screen-xchg
screen -X eval'msgwait 0' readbuf 'msgwait 1'
#!/usr/bin/awk -fBEGIN{prevout="\n";}# CHANGEIT: prompt string/^deton@colinux:/{if(out!=""){prevout=out;}out="";next;}{out=out$0"\n";}END{# remove last "\n"printf("%s",substr(prevout,0,length(prevout)-1));}
備考: スクロールバッファ内容は表示内容なので元の出力と異なる場合あり
通常のscreenでのコピーと同様に以下は気を付ける必要あり。
- タブがスペースに展開される
- less等で長い行を表示した際、折り返されると、継続行とみなされない。
lynxの表示をコピーしたい場合のlynx側設定
lynxを使う場合、1スクリーンへの表示ごとにscrollback bufferがクリアされるので、
以下の設定をlynx.cfgでしておいた方が良いかもしれません。
さっき見ていたページの内容を参照したいことがよくあるので。
(遅いマシンだと少しちらつきが多くなるのが気になりますが)
ENABLE_SCROLLBACK:TRUE
関連
bindPeval"copy""stuff -k ku""stuff Y""stuff \033"# 以下でいい気も。#bind P eval "copy" "stuff kY"
(GNU Screenバージョン4.2がリリースされましたの記事からたどって、GNU Screen Watch: January 2011 - April 2013より。)
- (screenでなくVimShellを使う)