2011/12/05

開発版GNU Screenを使ってみよう

本記事は ターミナルマルチプレクサ Advent Calendar 2011 : ATND の5日目です。4日目は tmux で main-vertical / main-horizontal で layout を変更と同時にカレント(アクティブ)のペインを main のペインにしたい - 写経日記 でした。tmux が人気で悔しい^H^H^H うらやましいですが、ここでは開発版の GNU Screen について何回かに分けて説明したいと思います。

なぜ開発版の GNU Screen なのか

GNU Screen がどのようなソフトウェアであるかは1日目の記事をご覧ください。ターミナルソフトウェアを使用して作業するときに欠かせないツールの一つです。

歴史のあるソフトウェアですので主要な PC-UNIX 環境にはパッケージが用意されていて、すでにインストールされていることが多いと思います。手元に用意できる環境で確認したところ次のようになっていました。
いくつかの OS における GNU Screen のバージョン (2011/12/04 現在)
OSscreen --versionrelease
Ubuntu/MintScreen version 4.00.03jw4 (FAU) 2-May-064.0.3-14ubuntu8
DebianScreen version 4.00.03jw4 (FAU) 2-May-064.0.3-14
Fedora 16Screen version 4.01.00devel (GNU) 2-May-064.1.0-0.4.20110328git8cf5ef.fc16
Scientific Linux 6.1Screen version 4.00.03 (FAU) 23-Oct-064.0.3-16.el6.i686
CentOS 5.7Screen version 4.00.03 (FAU) 23-Oct-064.0.3-4.el5
openSUSE 12.1Screen version 4.00.03 (FAU) 23-Oct-064.0.3-21.1.2
FreeBSD 8.2Screen version 4.00.03 (FAU) 23-Oct-064.0.3_10
Mac OS X LionScreen version 4.00.03 (FAU) 23-Oct-06
Oracle Solaris 11Screen version 4.00.03 (FAU) 23-Oct-0611.11.0,REV=2010.05.25.01.00
Cygwin 1.7Screen version 4.00.03 (FAU) 23-Oct-064.0.3-7
Fedora は流石です。でもそれ以外はベースとなっているバージョンは 2006 年のリリースである 4.0.3 です。開発は継続されています が、長いこと stable 版はリリースされていない状況です。それに耐えきれない?各 OS のメンテナの方々によって、独自パッチや開発版のパッチを取り込んだパッケージが提供されています。Ubuntu や Debian のパッケージはバージョン番号こそ 4.0.3 ですが縦分割もレイアウトも利用できます。

私は主に使用している Mac OS X や CentOS、FreeBSD では開発版をソースからコンパイルしていますので、いまさら感はありますが今回は具体的な導入手順や使用している設定を紹介します。

開発版 GNU Screen 導入手順

GNU Screen のソースコードは Git で管理されていますので、まずは git の導入から必要になる場合があります。導入手順と言っても、基本的にリポジトリからソースコードを取得して configure && make && make install です。バージョン管理やパッケージングを意識した構成はいろいろ考えられますが、いまのところ自分だけが使う設定ですのでホームディレクトリ以下に導入するようにしています。

RHEL 5 系 OS の場合は EPEL リポジトリなどからパッケージを導入すると手軽です。他にも GNU Autoconf (とそれが依存する GNU M4)の新しめのバージョンが必要になる場合がありますので、OS のバージョンがやや古い、あるいはパッケージの導入が難しい環境ではこれらも合わせてホームディレクトリ以下にソースコードから導入した方が良いかも知れません。(というか私はそうしています)

% wget http://ftp.gnu.org/gnu/m4/m4-1.4.16.tar.bz2
% tar xjf m4-1.4.16.tar.bz2
% cd m4-1.4.16 && ./configure --prefix=$HOME/local && make && make install

% wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.68.tar.bz2
% tar xjf autoconf-2.68.tar.bz2
% cd autoconf-2.68 && ./configure --prefix=$HOME/local && make && make install

以下が私が使用している手順です。

% git clone git://git.savannah.gnu.org/screen.git
% cd screen/src
% ./autogen.sh
% ./configure --prefix=$HOME/local \
              --enable-pam \
              --enable-colors256 \
              --enable-rxvt_osc \
              --enable-use-locale \
              --enable-telnet
% make
% make install
これだけです。期待させてスミマセン。何のひねりもありません。本当は個別にいくつかのパッチを当てていますが、ややこしくなるのでここでは省略しています。

領域を縦横無尽に操作する

これだけでは記事としてあまりにも中身がなさ過ぎますので、現在使用している .screenrc のなかで領域に関連するところについて紹介したいと思います。基本的な設定は以前まとめたものがありますのでそちらも参考にしてみてください。

stable 版向けの設定

普段 vim を使う事が多いので、その操作体系に類似したものを割り当てています。ポイントは Ctrl-A r(やCtrl-A Ctrl-R)で領域操作モード(仮称)に移行して、領域に関する操作(分割、削除、リサイズ)を連続的に行えるようにしています。モードを終了するには Ctrl-G など未割り当てのキーを使用します。

# switch focus to other region(like vim)
# orverride default `k'(kill), `t'(time), `b'(break) mappings.
bind j focus down
bind k focus up
bind t focus top
bind b focus bottom

# continuous region operations(like vim)
# orverride default `^R'(wrap) mapping.
bind ^R           eval                'command -c region' 'echo "[Region]"'
bind r            eval                'command -c region' 'echo "[Region]"'
bind ^J           eval 'focus down'   'command -c region' 'echo "[Region] (focus down)"'
bind ^K           eval 'focus up'     'command -c region' 'echo "[Region] (focus up)"'
bind -c region ^J eval 'focus down'   'command -c region' 'echo "[Region] (focus up)"'
bind -c region ^K eval 'focus up'     'command -c region' 'echo "[Region] (focus up)"'
bind -c region ^T eval 'focus top'    'command -c region' 'echo "[Region] (focus top)"'
bind -c region ^B eval 'focus bottom' 'command -c region' 'echo "[Region] (focus bottom)"'
bind -c region ^N eval 'focus down'   'command -c region' 'echo "[Region] (focus down)"'
bind -c region ^P eval 'focus up'     'command -c region' 'echo "[Region] (focus up)"'
bind -c region +  eval 'resize +1'    'command -c region' 'echo "[Region] (resize +1)"'
bind -c region -  eval 'resize -1'    'command -c region' 'echo "[Region] (resize -1)"'
bind -c region j  eval 'resize +1'    'command -c region' 'echo "[Region] (resize +1)"'
bind -c region k  eval 'resize -1'    'command -c region' 'echo "[Region] (resize -1)"'
bind -c region J  eval 'resize +10'   'command -c region' 'echo "[Region] (resize +10)"'
bind -c region K  eval 'resize -10'   'command -c region' 'echo "[Region] (resize -10)"'
bind -c region =  eval 'resize ='     'command -c region' 'echo "[Region] (resize =)"'
bind -c region .  eval 'resize min'   'command -c region' 'echo "[Region] (resize min)"'
bind -c region _  eval 'resize max'   'command -c region' 'echo "[Region] (resize max)"'
bind -c region n  eval 'split'        'command -c region' 'echo "[Region] (split)"'
bind -c region s  eval 'split' 'focus down' 'other' 'command -c region' 'echo "[Region] (split)"'
bind -c region c  eval 'remove'       'command -c region' 'echo "[Region] (remove)"'
bind -c region o  eval 'only'         'command -c region' 'echo "[Region] (only)"'
# just a little like emacs
bind -c region 1  eval 'only'         'command -c region' 'echo "[Region] (split)"'
bind -c region 2  eval 'split'        'command -c region' 'echo "[Region] (split)"'

開発版向けに追加している設定

次にこちらが開発版用に追加している設定。実際は .screenrc を別のファイルに分けて読み込ませていますが、先の設定に続けて記述すれば上書きされます。こちらも vim のように h/l で左右に移動などできるようにしています。なお「左右」の概念は、領域分割したときの状態によって逆になりますが、連続して操作できるので逆だと気づいても調整は楽です。

# switch focus to other region(like vim)
# override default `h'(hardcopy), `l'(redisplay) mapping
bind h focus left
bind l focus right

# re-define continuous region operation (vertical resize locally and focus next/prev)
bind -c region ^N eval 'focus next'       'command -c region' 'echo "[Region] (focus next)"'
bind -c region ^P eval 'focus prev'       'command -c region' 'echo "[Region] (focus prev)"'
bind -c region j  eval 'resize -l -v +1'  'command -c region' 'echo "[Region] (resize -l -v +1)"'
bind -c region k  eval 'resize -l -v -1'  'command -c region' 'echo "[Region] (resize -l -v -1)"'
bind -c region J  eval 'resize -l -v +10' 'command -c region' 'echo "[Region] (resize -l -v +10)"'
bind -c region K  eval 'resize -l -v -10' 'command -c region' 'echo "[Region] (resize -l -v -10)"'
bind -c region =  eval 'resize -l ='      'command -c region' 'echo "[Region] (resize -l =)"'

# add continuous region operation(like vim)
bind -c region ^H eval 'focus left'       'command -c region' 'echo "[Region] (focus left)"'
bind -c region ^L eval 'focus right'      'command -c region' 'echo "[Region] (focus right)"'
bind -c region <  eval 'resize -l -h -1'  'command -c region' 'echo "[Region] (resize -l -h -1)"'
bind -c region >  eval 'resize -l -h +1'  'command -c region' 'echo "[Region] (resize -l -h +1)"'
bind -c region h  eval 'resize -l -h -1'  'command -c region' 'echo "[Region] (resize -l -h -1)"'
bind -c region l  eval 'resize -l -h +1'  'command -c region' 'echo "[Region] (resize -l -h +1)"'
bind -c region H  eval 'resize -l -h -10' 'command -c region' 'echo "[Region] (resize -l -h -10)"'
bind -c region L  eval 'resize -l -h +10' 'command -c region' 'echo "[Region] (resize -l -h +10)"'
bind -c region ^V eval 'split -v'         'command -c region' 'echo "[Region] (split -v)"'
bind -c region v  eval 'split -v'         'command -c region' 'echo "[Region] (split -v)"'
bind -c region |  eval 'split -v'         'command -c region' 'echo "[Region] (split -v)"'
bind -c region 3  eval 'split -v'         'command -c region' 'echo "[Region] (split -v)"'
# greedy continuous resize region
bind -c region ^E eval 'resize ='         'command -c region' 'echo "[Region] (resize =)"'
bind -c region ^X eval 'resize max'       'command -c region' 'echo "[Region] (resize max)"'

おわりに

アドベントカレンダーなのにあまり関係のないネタでスミマセン。。。前から書こうとは思っていましたが自分に言い訳して放置していました。@matsuu さんが企画されたのを見かけて、「この流れに乗るしかない!」という思いで書かせて頂きました。この調子で layout 等の設定についても紹介してゆければと思います。

2 件のコメント:

  1. 一番最後の行にダブるクオートとクオートが抜けていますー

    返信削除
    返信
    1. ご指摘ありがとうございます。修正しました。

      削除