Ruby 2.7 で reline が入って irb で複数行編集ができるようになった。
% irb irb(main):001:0* 1 + irb(main):002:0* 2 + irb(main):003:0> 3 => 6 irb(main):004:0* 4 + irb(main):005:0* 5 + irb(main):006:0> 6 => 15 irb(main):007:0>
この状態で、^P で 4 + 5 + 6 という式が (3行の形のままで) 呼びだされる。 呼びだされた中では、^P, ^N, ^B, ^F で、上下左右にカーソルを動かせる。 一番上の行で ^P とすると、ヒストリから前の式が呼びだされる。 一番下の行で ^N とすると、ヒストリから次の式が呼びだされる。
なお、新しい式を入力しているときでもヒストリから呼びだした式と同様に、普通に上下に移動できる。
% ruby -v ruby 2.8.0dev (2019-12-26T01:58:26Z trunk dced0e5745) [x86_64-linux] % irb -v irb 1.2.1 (2019-12-24)
zsh では複数行編集が昔から可能である。
以下のように、複数行からなるコマンドを入力してもそのまま入力できる。
% echo 'a quote> b quote> c' a b c % echo 'd quote> e quote> f' d e f %
このように複数行な echo コマンドをふたつ入力した後、^P でヒストリをたどることができ、 ^P, ^N, ^B, ^F といっった (emacs 流の) カーソル移動が可能である。 (emacs binding の場合。vi binding の場合は vi 流になる。)
ここで、^P はヒストリを (過去方向に) たどる機能とカーソルを上に動かす機能が 混ざっていて、表示中のコマンドの一番上の行にカーソルがあるときはヒストリをたどり、 そうでないときはカーソルをひとつ上の行にに動かすという機能になっている。 カーソルを下方向に動かす ^N も同様で、一番下の行にカーソルがあるときは ヒストリを (未来方向に) たどるようになっている。
キーバインディングは bindkey で表示できるが、^N と ^P に対応するコマンドの名前も行かヒストリを移動する感じの名前になっている。
"^N" down-line-or-history "^P" up-line-or-history
なお、ヒストリをたどらないで、新しいコマンドを入力するときは (上の例にある quote> のように) 入力している文脈を表示してくれるのだが、 これはヒストリをたどったときには表示されない。 そのせいか、新しいコマンドを入力しているときと、ヒストリをたどったときはちょっと振る舞いが違うようである。 新しいコマンドの 2行め以降を入力しているときに ^P とすると、 上の行に動くのではなく、ヒストリをたどる動作になる。 ちょっと意外で、変な気がする。
% zsh --version zsh 5.7.1 (x86_64-debian-linux-gnu)
個人的には、zsh の複数行編集が便利なので、irb はあまり使わず、ruby -e を主に使っていた。 これからは変わるかもしれない。
readline は Ruby でも (reline 以前に) 使っていたライブラリである。
あまり知られていない気がするのだが、 readline も複数行編集をいくらかサポートしている。
readline は bash でも使われているので、bash で試してみよう。
% bash --norc bash-5.0$ echo 'a > b > c' a b c bash-5.0$ echo 'd > e > f' d e f bash-5.0$
入力では、このように、とくに問題なく複数行の入力を受け付けられる。
ここで、^P でヒストリをたどると、後者の (3行の) コマンドが呼びだされる。 この3行の中でカーソルの左右移動 (^B, ^F) はでき、 左右移動を繰り返せば上下の行に移動できる。 しかし、残念なことに、直接に上下移動はできない。 ^P と ^N はヒストリをたどるコマンドになっており、ひとつの (複数行の) コマンドの中で 上下に動く機能ではないのである。
キーバインディングは bind -p で表示できるが、純粋にヒストリをたどる感じの名前になっている。
"\C-n": next-history "\C-p": previous-history
ここまで動くならもう少しで実用的な複数行編集になるんじゃないか、という感じの状態である。
% LANG=C bash --version GNU bash, version 5.0.3(1)-release (x86_64-pc-linux-gnu) Copyright (C) 2019 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software; you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
julia も複数行編集をサポートしているようである。
julia> 1 + 2 + 3 6 julia> 4 + 5 + 6 15 julia>
ここで、^P, ^N でヒストリを前後にたどれる。 最初、bash みたいに、ひとつの (複数行の) 式の中で、 上下に移動するのが面倒なのかなぁ、と思ったのだが、 ヒストリを呼びだした後、(^B や ^A で) カーソルを移動した後は ^P, ^N で 式内のカーソル移動ができるのでとくに問題はなさそうである。 そうやって移動しているときに、一番上の行の ^P, 一番下の行の ^N では ヒストリをたどる動作になっている。
たぶん、ヒストリを少ないキー入力でたどれるようにそうなっているのではないか。 (こうなっていると、ヒストリに複数行の式が入っている場合でも ^P ひとつでヒストリのエントリをひとつたどれる)
% julia -v julia version 1.0.3
Gauche も複数行編集をサポートしていると川合さんから教えてもらったので試した。 環境変数 GAUCHE_READ_EDIT を設定すると複数行編集が使えるようになる。
% GAUCHE_READ_EDIT= gosh gosh$ (+ 1 ......2 ......3) 6 gosh$ (+ 4 ......5 ......6) 15 gosh$
こうやって複数行の式をふたつ評価した後、 ^P, ^N でヒストリをたどり、 また、式内の行を上下に移動できる。 もちろん、^B, ^F で左右に移動できる。
新しい式を入力しているときでも普通に上下に移動できる。
% gosh -V Gauche scheme shell, version 0.9.6 [utf-8,pthreads], x86_64-pc-linux-gnu
試したことはないが、複数行編集が可能らしいものとして、以下があげられる。
Python "prompt toolkit" <URL:http://python-prompt-toolkit.readthedocs.io/en/stable/>
機能として "Multi-line input editing" があげられている
jline3 <URL:https://github.com/jline/jline3>
JLine autoindention のデモをみると、複数行のコマンドの入力中に カーソルを動かして上のほうを編集しているのがみてとれる。
[latest]