emacs上のターミナルを最強に
TRANSCRIPT
![Page 1: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/1.jpg)
Emacs上のターミナルを最強に
伊奈林太郎
2012-10-20 @関西Emacs#x06
伊奈林太郎 Emacs 上のターミナルを最強に 1
![Page 2: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/2.jpg)
ターミナル使ってますか?
◮ 素のターミナル◮ 標準的なターミナルエミュレータ
xterm, gnome-terminal, Terminal.app, ...
◮ マルチプレクサscreen, tmux, ...
◮ sshといっしょになってるものPuTTY, Tera Term, ...
◮ Emacs上term.el
◮ 使ってないeshell.el, ...
◮ その他伊奈林太郎 Emacs 上のターミナルを最強に 2
![Page 3: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/3.jpg)
ターミナル使ってますか?
◮ 素のターミナル◮ 標準的なターミナルエミュレータ
xterm, gnome-terminal, Terminal.app, ...
◮ マルチプレクサscreen, tmux, ...
◮ sshといっしょになってるものPuTTY, Tera Term, ...
◮ Emacs上term.el
◮ 使ってないeshell.el, ...
◮ その他伊奈林太郎 Emacs 上のターミナルを最強に 2
![Page 4: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/4.jpg)
ターミナルとEmacs
ターミナルエミュレータを使う理由
◮ ncursesアプリもちゃんと動いてほしい
◮ 素の端末を触るときにパニくらない
Emacsとの共存
◮ Emacsは別窓で◮ ウィンドウが増えてうざい◮ 端末とのコピペが面倒
◮ screenの中でEmacs◮ キーボードだけでコピペ◮ Emacsごと detach
伊奈林太郎 Emacs 上のターミナルを最強に 3
![Page 5: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/5.jpg)
screenのままならないところ
◮ 改造しにくい
◮ CJK ambiguous width
◮ 問題の切り分けが難しくなる
◮ (Xなどの)クリップボードとの連携
◮ 面倒なハックが必要
◮ 環境変数の引き渡し
◮ 外部からのコマンド発行で解決 (要開発版)
#この辺は tmuxでも同じですね
伊奈林太郎 Emacs 上のターミナルを最強に 4
![Page 6: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/6.jpg)
すべてEmacsでやる
◮ CJK,クリップボードなどもOK
◮ detachもできる(emacs --daemon)
◮ Emacs本体と連携⊚
◮ 操作性を一体に
◮ Lispで改造しまくり
伊奈林太郎 Emacs 上のターミナルを最強に 5
![Page 7: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/7.jpg)
Emacs内端末エミュレータterm.el
使い方M-x term, M-x ansi-term
特徴— 2つのモード◮ term-char-mode
◮ 打ったものがそのまま端末へ
◮ term-line-mode
◮ Emacsのバッファに近い編集
しくみ
◮ process-filterで制御シーケンスを解釈
◮ バッファに put-text-propertyしながら表示
伊奈林太郎 Emacs 上のターミナルを最強に 6
![Page 8: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/8.jpg)
term.elのいけてないところ
◮ キーがほぼすべて端末に持っていかれる◮ M-xとかきかない◮ でも ESCとかどっちで認識すべき?
◮ 端末が 1つしか開けない(内部的には可能だけどインタフェースが無い)
◮ 色が 8色しかない
◮ term-line-modeがちょっと貧弱
◮ コードがレガシーで拡張しにくい◮ 関数がでかい◮ hookも少ない
◮ 遅い
伊奈林太郎 Emacs 上のターミナルを最強に 7
![Page 9: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/9.jpg)
term+.el — term.elを強化する
主な機能
◮ 256色対応 / xterm互換性向上
◮ キーバインド強化
◮ 編集機能の強化
◮ ログ機能
◮ マルチプレクサ (+マルチセッション)
◮ シェル連携強化
伊奈林太郎 Emacs 上のターミナルを最強に 8
![Page 10: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/10.jpg)
term+.elをとりあえず使ってみる
ダウンロード→真っ新な状態でのお試し$ git clone git://github.com/tarao/term-plus-all.git$ cd term-plus-all$ git submodule update --init$ make emacs # or make term
# or make EMACS=emacs-snapshot term
注意点
◮ Emacs 24.1.50で開発してます
◮ 22はサポートしません◮ 23は細かいところが不安定かも◮ 24.2はおそらくOK◮ 24.3 (24.2.50)の term.elの変更には未対応
伊奈林太郎 Emacs 上のターミナルを最強に 9
![Page 11: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/11.jpg)
デモ
伊奈林太郎 Emacs 上のターミナルを最強に 10
![Page 12: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/12.jpg)
term+.el — term.elを強化する
主な機能
◮ 256色対応 / xterm互換性向上
◮ キーバインド強化
◮ 編集機能の強化
◮ ログ機能
◮ マルチプレクサ (+マルチセッション)
◮ シェル連携強化
伊奈林太郎 Emacs 上のターミナルを最強に 11
![Page 13: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/13.jpg)
256色対応 / xterm互換性(require 'xterm-256color)
256色対応
◮ 256色表示の制御シーケンスの解釈を実装
◮ ついでに斜体 ,取り消し線等にも対応
◮ 原理的には 24bit色に対応可能 (cf. Konsole)(24bit色表示しようとするアプリはあるのか?)
xterm互換性 (TERM=xterm-256color)
◮ TERM=eterm-256colorを定義すればよい?◮ たいていのアプリは terminfoなんか見てない
◮ xtermを騙れば 256色表示しようとしてくれる
◮ 騙るからには xterm制御シーケンスを処理 (不完全)
伊奈林太郎 Emacs 上のターミナルを最強に 12
![Page 14: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/14.jpg)
term+.el — term.elを強化する
主な機能
◮ 256色対応 / xterm互換性向上
◮ キーバインド強化
◮ 編集機能の強化
◮ ログ機能
◮ マルチプレクサ (+マルチセッション)
◮ シェル連携強化
伊奈林太郎 Emacs 上のターミナルを最強に 13
![Page 15: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/15.jpg)
キーバインド強化 [1/2](require 'term+)
端末に奪わせないキーを定義
◮ term+char-mapに define-key
定義 するだけ(multi-term.elでもできますね)
◮ 定義済みのキー (M-x des-fun, term-char-mode)
C-q 後続のキーをそのまま端末に渡すC-y 端末へ貼り付け
M-RET 編集モード (term-line-mode)へスイッチESC 端末へ ESCを送るC-c 0.5秒間何も入力がなければ端末へ C-c
直後に何か入力すればプレフィックスキー◮ Emacs本体で実行 (nilをマップ): M-x, M-:, C-x
伊奈林太郎 Emacs 上のターミナルを最強に 14
![Page 16: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/16.jpg)
キーバインド強化 [2/2](require 'key-intercept)
後続のキーがあるかどうかで意味が違う!
ESC 端末へ ESCを送る
M-x ふつうの M-x
C-c 0.5秒間何も入力がなければ端末へ C-c
直後に何か入力すればプレフィックスキー
実装: key-intercept.el
◮ https://github.com/tarao/key-intercept-el
◮ プレフィックスキーにもコマンドを割り当てるhttp://d.hatena.ne.jp/tarao/20120427/1335527960
伊奈林太郎 Emacs 上のターミナルを最強に 15
![Page 17: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/17.jpg)
term+.el — term.elを強化する
主な機能
◮ 256色対応 / xterm互換性向上
◮ キーバインド強化
◮ 編集機能の強化
◮ ログ機能
◮ マルチプレクサ (+マルチセッション)
◮ シェル連携強化
伊奈林太郎 Emacs 上のターミナルを最強に 16
![Page 18: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/18.jpg)
編集機能強化 [1/2](require 'term+)
編集モード (term-line-mode)中は
◮ 入力フィールド外では読取専用
◮ SPCで選択開始もう一度SPCで範囲コピー→編集モード終了
◮ RET, ESCで編集モード終了
◮ 入力フィールド内ではふつうのバッファ
◮ ただし RETで端末に送信◮ ふつうの改行は C-j◮ 別のメジャーモードにもできる
e.g. シェルのプロンプトに sh-modeで入力
伊奈林太郎 Emacs 上のターミナルを最強に 17
![Page 19: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/19.jpg)
編集機能強化 [1/2](require 'term+)
編集モード (term-line-mode)中は
◮ 入力フィールド外では読取専用
◮ SPCで選択開始もう一度SPCで範囲コピー→編集モード終了
◮ RET, ESCで編集モード終了
◮ 入力フィールド内ではふつうのバッファ
◮ ただし RETで端末に送信◮ ふつうの改行は C-j◮ 別のメジャーモードにもできる
e.g. シェルのプロンプトに sh-modeで入力
伊奈林太郎 Emacs 上のターミナルを最強に 17
![Page 20: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/20.jpg)
編集機能強化 [2/2](require 'multi-mode-util)
入力フィールドだけ別モード
◮ あらかじめどのモードにするか指定 (後述)
◮ 編集モードに入ると indirect buffer
間接バッファ を作成
◮ multi-mode.el
http://www.loveshack.ukfsn.org/emacs/multi-mode.el
◮ multi-mode-util.el
https://github.com/tarao/multi-mode-util
伊奈林太郎 Emacs 上のターミナルを最強に 18
![Page 21: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/21.jpg)
term+.el — term.elを強化する
主な機能
◮ 256色対応 / xterm互換性向上
◮ キーバインド強化
◮ 編集機能の強化
◮ ログ機能
◮ マルチプレクサ (+マルチセッション)
◮ シェル連携強化
伊奈林太郎 Emacs 上のターミナルを最強に 19
![Page 22: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/22.jpg)
ログ機能(require 'term+)
term-start-output-log◮ term.elに元からある (ほぼデバッグ用)
term+hardcopy (C-c h)◮ 一画面だけテキスト保存 (追記可)◮ screenの:hardcopy相当
term+start-buffer-log (C-c l)◮ いままでの累積テキストを保存◮ 表示限界 (2048行)を超えた分も保存
term+start-record (C-c r)◮ 端末の制御シーケンスを時系列で保存◮ ttyrec互換 (ttyplayで再生可)
伊奈林太郎 Emacs 上のターミナルを最強に 20
![Page 23: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/23.jpg)
term+.el — term.elを強化する
主な機能
◮ 256色対応 / xterm互換性向上
◮ キーバインド強化
◮ 編集機能の強化
◮ ログ機能
◮ マルチプレクサ (+マルチセッション)
◮ シェル連携強化
伊奈林太郎 Emacs 上のターミナルを最強に 21
![Page 24: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/24.jpg)
マルチプレクサ [1/3](require 'term+mux)
やりたいこと
◮ 複数の端末をタブ表示(tabbar.el, emux.elでもできますね)
◮ 編集モード以外のときはモードラインをタブに
◮ セッション (ユーザ/ホストの別)ごとにグループ化
◮ 同一セッションからは 1つだけバッファ一覧に
◮ セッション内の選択中のタブが代表◮ 一覧中ではバッファ名ではなくセッション名
伊奈林太郎 Emacs 上のターミナルを最強に 22
![Page 25: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/25.jpg)
マルチプレクサ [2/3]タブグループ(require 'term+mux)
実装: tab-group.el
◮ https://github.com/tarao/tab-group-el
◮ 車輪の再発明
◮ tabbar.elでできることはだいたいできる
◮ モードラインにも表示できる
◮ バッファをひとまとめにできる
◮ かっこいいタブ選択UI
◮ D&Dでタブ移動
伊奈林太郎 Emacs 上のターミナルを最強に 23
![Page 26: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/26.jpg)
マルチプレクサ [3/3]セッション管理(require 'term+mux)
M-x term+mux-new
◮ 現在のセッションで (or選択して)端末を開く
M-x term+mux-new-command
◮ 現在のセッションで指定のコマンドを実行
M-x term+mux-remote-session
◮ ユーザ/ホストを指定してセッションを作成
◮ シェル端末も 1つ開く
◮ ローカルで rootなら sudoする◮ リモートなら sshする
伊奈林太郎 Emacs 上のターミナルを最強に 24
![Page 27: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/27.jpg)
term+.el — term.elを強化する
主な機能
◮ 256色対応 / xterm互換性向上
◮ キーバインド強化
◮ 編集機能の強化
◮ ログ機能
◮ マルチプレクサ (+マルチセッション)
◮ シェル連携強化
伊奈林太郎 Emacs 上のターミナルを最強に 25
![Page 28: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/28.jpg)
シェル連携
できること◮ 編集モード
◮ 編集モードでのメジャーモード指定◮ バッファ内容を引き継いで編集モードへ
◮ ユーザ/ホスト/ディレクトリ通知◮ ファイル転送 (open / view / get / put)◮ シェルコマンド履歴選択◮ マルチプレクサ
◮ タブタイトル設定◮ cdd (別タブの現在ディレクトリを取得)
方法◮ 端末内から特殊な制御コマンドを送る
伊奈林太郎 Emacs 上のターミナルを最強に 26
![Page 29: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/29.jpg)
シェル連携 [1/6]編集モード
M-iで sh-modeの編集モードへ (zsh)function switch-to-line-mode-insert () {1
local buf="$BUFFER"2
zle kill-buffer3
zle -R # reset command line4
echo -ne "\e]51;mode;sh-mode\e\\" > /dev/tty5
echo -ne "\e]52;i;$buf\e\\" > /dev/tty6
}7
zle -N switch-to-line-mode-insert8
bindkey '^[i' switch-to-line-mode-insert9
参照 https://raw.github.com/tarao/dotfiles/master/.zsh/eterm.zsh
伊奈林太郎 Emacs 上のターミナルを最強に 27
![Page 30: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/30.jpg)
シェル連携 [2/6]セッション情報
ユーザ名/ホスト名を通知host=`hostname` # ホスト名10
echo -ne "\e]51;host;$host\e\\" > /dev/tty11
user=`id -run` # ユーザ名12
echo -ne "\e]51;user;$user\e\\" > /dev/tty13
ディレクトリ通知 (zsh)function precmd_eterm_cwd () {14
local dir; dir=`pwd`15
echo -ne "\e]51;cd;$dir\e\\" > /dev/tty16
}17
typeset -Uga precmd_functions # これは一回だけ18
precmd_functions+=precmd_eterm_cwd19
◮ Emacs側の default-directoryが変更される◮ TRAMPでリモートファイルも開ける
伊奈林太郎 Emacs 上のターミナルを最強に 28
![Page 31: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/31.jpg)
シェル連携 [3/6]ファイル転送
function o() { # シェルで見えてるファイルを開く20
echo -ne "\e]51;open;$1\e\\" > /dev/tty }21
function v() { # シェルで見えてるファイルを view-modeで開く22
echo -ne "\e]51;view;$1\e\\" > /dev/tty }23
function get() { # シェルで見えてるファイルを手元にコピー24
echo -ne "\e]51;get;$1\e\\" > /dev/tty }25
function put() { # シェルで見えてる場所に26
# ファイルを選択してコピー27
echo -ne "\e]51;put;\e\\" > /dev/tty }28
◮ セッション情報を通知しておく必要あり◮ get/putはFTPと同じ向き
◮ putするとミニバッファでファイルを訊く◮ diredインタフェースでの複数選択も可
伊奈林太郎 Emacs 上のターミナルを最強に 29
![Page 32: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/32.jpg)
シェル連携 [4/6]履歴選択
C-rで履歴選択 (zsh)echo -ne "\e]51;histfile;$HISTFILE\e\\" >/dev/tty #一回だけ29
30
function history-search-eterm () {31
local buf="$BUFFER"32
zle kill-buffer33
echo -ne "\e]52;h;$buf\e\\" > /dev/tty }34
zle -N history-search-eterm35
bindkey '^R' history-search-eterm36
◮ 類似: zshの履歴検索に anything.elを使うhttp://d.hatena.ne.jp/tarao/20100429/1272509893
伊奈林太郎 Emacs 上のターミナルを最強に 30
![Page 33: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/33.jpg)
シェル連携 [5/6]マルチプレクサ
タブタイトル変更
◮ screenの \ekSTR\e\\ 形式
◮ tmuxの \e]2;STR\e\\ 形式
参考 https://raw.github.com/tarao/dotfiles/master/.zsh/screen-title.zsh
cdd
◮ 他のタブの `pwd`に移動する◮ オリジナルは id:secondlifeさん (screen用)
http://d.hatena.ne.jp/secondlife/20080218/1203303528
参照 https://raw.github.com/tarao/dotfiles/master/.zsh/eterm.zsh
伊奈林太郎 Emacs 上のターミナルを最強に 31
![Page 34: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/34.jpg)
シェル連携 [6/6]カスタマイズ
定義済みの特殊制御コマンドを調べる◮ M-x des-fun, term-emulate-terminal
◮ M-x term+control-command-list
新しい特殊制御コマンドを定義する(require 'term+vars)37
(defun my-control-command (text) ...)38
(term+new-control-command39
"START" "END " 'my-control-command)40
例(defun term+open (files &optional find-file) ...)41
(term+new-control-command42
"\033]51;open;" "\033\\" 'term+open)43
伊奈林太郎 Emacs 上のターミナルを最強に 32
![Page 35: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/35.jpg)
まとめ
Emacs上でだって端末機能をフルに使いたい!
◮ 256色対応
◮ xterm互換性向上
◮ キーバインド
Emacsなのをいいことに魔改造
◮ 編集機能の強化
◮ ログ機能
◮ マルチプレクサをまるごと実装
◮ シェル連携しまくり
伊奈林太郎 Emacs 上のターミナルを最強に 33
![Page 36: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/36.jpg)
参考URL
伊奈林太郎.
このスライド.
http://up.orezdnu.org/papers/kansai-emacs/%23x06/slide/slide.pdf.
INA Lintaro.
term+.elのソースリポジトリ.
https://github.com/tarao/term-plus-el.
INA Lintaro.
term+.elの emacs側設定例.
https://github.com/tarao/dotfiles/blob/master/.emacs.d/init/term.el
https://github.com/tarao/dotfiles/blob/master/.emacs.d/init/tarao/term.el .
INA Lintaro.
term+.elのシェル側設定例.
https://github.com/tarao/dotfiles/blob/master/.zsh/eterm.zsh.
伊奈林太郎 Emacs 上のターミナルを最強に 34
![Page 37: Emacs上のターミナルを最強に](https://reader031.vdocuments.pub/reader031/viewer/2022030216/5888b26d1a28ab80248b5b1f/html5/thumbnails/37.jpg)
おわり