Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 5608

GNU screenのスクロールバッファをvimで開いて、コピーモードのかわりに使う方法

$
0
0

GNU screenのコピーモードは、vi風操作が可能ですが、以下の動作がvimと違って使いにくいので、
スクロールバッファを一時ファイルに保存してvimで編集するための方法です。
(vim以外のエディタでも同様の方法が可能)

  • 日本語上でのw等による単語単位移動の動作が異なる
  • 矩形選択方法が異なる(右端マーク操作)
  • i"等のtext-objectは未対応(Wによる単語選択がある程度)
  • )による文単位の移動等は未対応

(ふと、MS-DOSでVz Editorを常駐させてコンソール出力をコピーしていたのと同様のことができないかと思いついたので。)

また、複数の離れた場所からコピーする必要がある場合、
「コピーモード開始、コピー対象文字列の場所に移動、コピー対象文字列を選択、ペースト」
を繰り返す手間がかかるのに対し、vimで編集する方法であれば、
コピーモード開始は1回ですみ、ペーストしたい文字列を編集して作ってから、1回だけペースト操作をすれば良くなります。

.screenrc
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のコピーバッファに反映する以下のスクリプトを呼ぶ形でも可。

vsbuf
#!/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で終了)

.screenrc
bindEeval'msgwait0'copy'stuff"g G$>"' 'stuff"^X^E:sp ~/tmp/screen-xchg^MG"' 'msgwait1' 'echo""'

複数行を,付きで連結してのコピー

screenのコピー機能の、複数行を,付きで連結してのコピー等は、vim側で適当に編集すればいいかと思っています。
めったに使わないので。
({dir1,dir2,dir3}/*.htmlのように指定したい場合くらいしか使ったことが無いです。)

スクロールバッファに対してスクリプトを実行

vim起動以外にも、適当なスクリプトを作って、
直前のコマンドの出力結果のみを抽出したり等も可能。

(主にコマンドを実行した後になって何かしたい場合用。
コマンド実行前ならパイプを使えばいいので。)

直前のコマンドの出力結果を抽出してコピーする例:

.screenrc
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)をバッチモードで使用)

picklastout.sh
#!/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'
picklastout.ed
$
?^deton@colinux:
1,.d
/^deton@colinux:/d
w

備考:

  • deton@colinux:はプロンプト文字列。要変更。
  • シェルのコマンド引数としてペーストして使いやすいように、最後の改行を削除

例: 直前の出力結果抽出スクリプト(awk版)

picklastout.sh
#!/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'
picklastout.awk
#!/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でしておいた方が良いかもしれません。
さっき見ていたページの内容を参照したいことがよくあるので。
(遅いマシンだと少しちらつきが多くなるのが気になりますが)

lynx.cfg
ENABLE_SCROLLBACK:TRUE

関連

.screenrc
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より。)


Viewing all articles
Browse latest Browse all 5608

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>