ruby-jp Slack#supportで、Reline.readmultilineで Ctrl+D (EOF) で入力完成させたいという話が30日ぐらい前にあって、 そのスレッドに追加のコメントがあって目についたので、ちょっと調べてみました。

動作確認バージョン

調べた範囲の内容はバージョンによる違いはほとんどないと思って、1個のバージョンでしか確認していません。 ソースコードへのリンクは ruby/reline のこの記事を執筆した時点の最新版を参照しています。

  • ruby 3.1.3
  • reline 0.3.1

.inputrc での分岐

reline/config.rbの238行目あたりにあるように、 $if Ruby$if Reline$endif でくくると Bash などの Readline を使った他のプログラムに影響せずに設定を書けます。

$if Ruby
# RubyやRelineだけで使う設定
$endif

Ctrl-D の設定変更

EmacsモードのEnterと同じ挙動にしたいなら、 ed_newline にすれば良いようなので、以下のように設定すれば Ctrl+D で Enter などと同じように入力を完了できました。(入力途中なら継続行になりました。)

$if Ruby
"\C-d": ed_newline
$endif

「Reline を vi モードで動かすと Ctrl-D で入力完了になります。」という ima1zumi さんのコメントがあったので、 viのコマンドモードのCtrl+Dvi_end_of_transmissionviのインサートモードのCtrl+Dvi_list_or_eof の設定も試してみました。

$if Ruby
"\C-d": vi_end_of_transmission
#"\C-d": vi_list_or_eof
$endif

reline/line_editor.rbをみると vi_end_of_transmissionvi_list_or_eofalias_method で実体は同じようでした。

irb 上でいろいろ試してみると、 ed_newline は完全に Enter と同じ挙動ですが、 vi_list_or_eof は入力がないときには irb が終了するという挙動になりました。

まとめ

デフォルトのemacsモードの Ctrl+D は末尾以外ならカーソル位置の文字を削除で、末尾だと何もしません。 vi_list_or_eof だと入力が空なら EOF で、入力があれば Enter と同じなので、この挙動の方が便利だと思ったら、以下の設定を ~/.inputrc に入れておくと良さそうです。

$if Ruby
"\C-d": vi_list_or_eof
$endif
Disqus Comments

Kazuhiro NISHIYAMA

Ruby のコミッターとかやってます。 フルスタックエンジニア(って何?)かもしれません。 About znzに主なアカウントをまとめました。

znz znz


Published