IRB Reline Changes
at ruby-jp slack #irb
Past IRB Reline Changes
2024年までの分は IRB Reline Changes 2024
2025/01/01
Support inserting C-c C-z C-\ with quoted_insert by tompng · Pull Request #798 · ruby/reline
Readline vi emacs などには C-v (もしくは C-q ) に続いてキーを打つと制御文字も含めて任意の文字を入力できる機能があるんですが、
Relineでは C-c C-z C-\ だけは入力することができませんでした。(null文字も入力できないがこれはReadlineの仕様に合わせてる)
これらのキー入力では通常SIGINT SIGTSTP SIGQUITが送られるからですが、最近のRelineの変更により、C-v の直後の文字を読むときだけinterruptなしのrawモードに切り替えることができるようになって直りました。
2025/01/04
Extract contributing guideline into a CONTRIBUTING.md by st0012 · Pull Request #1056 · ruby/irb
README.mdの整理です。ContributingセクションをCONTRIBUTING.mdに分ける・不要な(古くて間違ってる)説明を消す、など
Refactor handling key in LineEditor by tompng · Pull Request #799 · ruby/reline
LineEditorに入力されたキーの情報が渡った後、どう処理するかの部分のリファクタリングです。
@waiting_proc (次のキー入力をどう処理するかを上書きする機構)
@vi_waiting_operator (viモードの時、カーソル移動操作の後、移動した範囲に対して特定の操作(削除・コピー・etc)をすることを予約するための機構)
などが設定されているときの特別処理が重複・分散していたのをまとめています。
2025/01/05
Fix bracketed paste and scrolling bug by tompng · Pull Request #801 · ruby/reline
ターミナル画面の高さよりも行数の多い入力をペーストした時のバグを修正しています。
ペースト中判定(stdinのバッファに読み込めるデータが残っているか)のチェックタイミングの問題
ペースト中判定の時はレンダリング及びカーソルの位置が画面内に入るよう入力行スクロールする処理をスキップしている
スクロールスキップしたせいでカーソルの座標が画面外にあるという状態をレンダリングした時のバグ
などが絡んでいました。
Refactor utf-8 strings and invalid strings in test code by tompng · Pull Request #800 · ruby/reline
テストコード中に "\M-[char]" "\M-\C-[char]" という形で不正なバイト列のUTF-8文字列を使っていたのをやめました。なお、Rubyの文字列リテラル "\M-a" は "\M-a".bytes == ['a'.ord | 0x80] と8bit目を強制的に立てた1byteの文字になります。
ターミナルエミュレータでAltキー(Metaキー)を押しながら他のキーを入力した時、"\e" + key がSTDINに入力されるんですが、テストコード中では "\M-[char]" を使いつつ、invalid byte sequence を\eに戻すような処理をしていました。
古い端末では、ASCII文字しか使われていない前提で、Metaキー入力は8bit目を立てた文字コードが入力されたらしいのですが、Relineは元々そんな入力に対応していません。
UTF-8として不正なバイト列を使うことは不便なだけでなく、以下の問題があります。
"\M-C\M-\C-A" == "Á" は Meta+C Meta+Ctrl+A なのか マルチバイト文字 Á の入力なのか判別がつかないのでMetaキーの表現方法として不完全
実際の入力 "\e" + key と異なるのでテストとして不適切
2025/01/12
Enter newline if cursor position is middle of input by ima1zumi · Pull Request #802 · ruby/reline
複数行入力で、最終行以外にカーソルがあるときにENTERを押すと入力の確定になっていたのを、改行文字が挿入されるようになりました。
以前から改行文字の挿入は Option(Alt)+Enter でできたんですが、便利なのに知っている人が少なく多分あまり使われてなかった
Option+Enterを今まで使っていた自分にとってはまだちょっと慣れない
Update to Unicode 16.0.0 by ima1zumi · Pull Request #803 · ruby/reline
Unicode のバージョンが 16.0.0 に上がりました。
これにより、ターミナル上で表示されるであろう横幅の計算の結果が幾つかの文字で少し変化します。
Gracefully handle incorrect command aliases by st0012 · Pull Request #1059 · ruby/irb
irbrcでコマンドのエイリアス設定を間違えた場合、そのエイリアスを使ったときに警告メッセージが出るようになりました。
Simplify vterm-yamatanooroti's steps by st0012 · Pull Request #1060 · ruby/irb
CI上での端末のE2Eテストの設定のリファクタリング
Print more actionable message when the exception may be an IRB bug by st0012 · Pull Request #1061 · ruby/irb
IRBのバグと思われるエラーが起きた時のメッセージを改善してruby/irbリポジトリのissueに書くよう案内しています。
IRB.conf SAVE_HISTORY should handle boolean values by st0012 · Pull Request #1062 · ruby/irb
IRB.conf[:SAVE_HISTORY] 履歴保存件数の設定に以前は true false が設定可能だったものの今はエラーになるらしく、
bool値を設定できそうな設定項目に見えることもあって実際に使っている人がいたため、true(デフォルト1000) false(無効) を以前同様に受け付けるようにしました。
DOC Remove unnecessary escape from completor class names by st0012 · Pull Request #1063 · ruby/irb
RDoc コメントのescape (定数と同名の文字列がリンクにならないようにするためのbackslash) のうち、今は不要になったものを消しています
Group private methods together in IRB::Context by st0012 · Pull Request #1064 · ruby/irb
Privateメソッドを private def ではなく privateの後ろに def で定義するようなリファクタリング
Drop ColorPrinter's workaround for BasicObject by st0012 · Pull Request #1051 · ruby/irb
ppがBasicObjectを扱えなかったため、IRBの方で特別扱いしていたのですが、pp 0.6.2 で修正されたため、特別扱いをやめつつ pp 0.6.2 をdependencyに追加しています。
2025/01/15
Support completion of code including ShareableConstantNode by tompng · Pull Request #55 · ruby/repl_type_completor
shareable_constant_valueコメントがある場合に補完ができないケースがある問題を修正しました。
定数への代入がShareableConstantNodeで包まれるんですが、このnodeの対応が抜けていました。
Fix nested it parameter completion by tompng · Pull Request #54 · ruby/repl_type_completor
ブロッックパラメーターのitをネストしていた場合の補完バグ修正です。
:outer.tap { it; 'inner'.tap{it}; it. の補完でinnerの補完候補が混ざっていました。
it(内部では _1 の名前でローカル変数テーブルに入れている)の変数テーブルを内側のblockで作り忘れていたせい。
Remove unnecessary bundle install on CI by st0012 · Pull Request #56 · ruby/repl_type_completor
CIの設定のリファクタリングです。bundler-cache: true を指定している場合 bundle install を明示的に実行する必要はないらしい
Fix empty block args bug tap{||} by tompng · Pull Request #20 · ruby/repl_type_completor
tap{||} を含んだコードで補完が出ない問題の修正です。
BlockParameterNode はあるものの、そのparametersがnilになっているレアケース
Fix anonymous class doc_namespace to use named superclass by tompng · Pull Request #13 · ruby/repl_type_completor
IRBでのドキュメント表示のために、ReplTypeCompletorは、今選択中の補完候補は "Class.method" ですよ、というのを返しています。
補完対象のオブジェクトが無名クラスのインスタンスの場合、".method" を返してしまい、このケースでRDocが遅くなる問題がありました。(その名前のメソッドがあるドキュメントを全て探すため?)
無名クラスだった場合にsuperclassを辿って名前のあるクラス名を使うようにしてます。
Remove supporting aset with block or kwargs because it is removed in ruby 3.4 by tompng · Pull Request #22 · ruby/repl_type_completor
a[&b]=c a[**b]=c などがあったケースの対応をやめています。3.4でSyntaxErrorになることに変わったため。
以前は x[**(a=A.new)]=1; a. や x[&(a=A.new)]=1; a. などが補完されていましたがテストコードも含め消しています。
Prism側のAPIもそのうち変わり得る(IndexOrWriteNodeのblockメソッドが消える・パースされ方が変わるなど)
Use Hash#compare_by_identity in DigTargets instead of __id__ by tompng · Pull Request #12 · ruby/repl_type_completor
補完対象のAST nodeを調べる処理で、nodeのオブジェクトとして完全一致を調べるためにHashに__id__を入れていたところ、
{}.compare_by_identity で済みそうだった(書いたときは存在を知らなかった)ので書き換えています
Colorize backref token bold green like global variables by tompng · Pull Request #1065 · ruby/irb
backref ($& $1 $2 など)がカラーリングされるようになりました。
$~ $! などはtokenとしてはgvarなんですがbackrefは違うんですね、(どちらも普通のグローバル変数とはちょっと違う特殊なやつ)
2025/01/22
Add copy command by Prajjwal · Pull Request #1044 · ruby/irb
copyコマンドが実装されました。copy 10.times.map{rand} などで実行結果をpretty_printsした結果をコピーすることと
copy で直前の実行結果をコピーすることができます。
コピーには pbcopy xclip -selection clipboard もしくは環境変数IRB_COPY_COMMANDなどで設定したコマンドを使います。
文字列コピーのエスケープシーケンスも使いたいが(例えばfallbackとして)、あれは使える端末が限られるからどうしたものか...
Show a quick preview of inspect result before pager launch by tompng · Pull Request #1040 · ruby/irb
1000000.times.to_a はpretty_printに10秒以上かかりますが、最初の1ページ目のプレビューを0.1秒で表示できるようになりました。
pretty_printはストリームでoutputするため、これの単純な実装方法はpagerのコマンドにストリームで流し込むだけで良いです(Pryがこの実装)。
が、世の中にはpretty_print中に標準出力にログを書き出すRubyアプリ(RailsのActiveRecord)が沢山あるため、
どのタイミングでログが出力されても画面が崩れないよう・またログが後から見れるようにするために1ページ目のみプレビュー方式にしました。
DOC Update documentation about the new copy command by st0012 · Pull Request #1067 · ruby/irb
コピーコマンドについてドキュメント追加
DOC Exclude the word IRB from RDoc's autolinking by st0012 · Pull Request #1068 · ruby/irb
RDocの仕様として、ドキュメント中のIRB Array Hashなどの文字列(定数が存在するものと同名のもの)は勝手にリンクになるのですが、
それを抑制するために \ でエスケープしていました。最新のRDocにオートリンクから除外する単語リストを指定できる機能が追加されたため、このエスケープを外しています。
Bump version to v1.15.0 by st0012 · Pull Request #1066 · ruby/irb
Release v1.15.0 · ruby/irb
IRB 1.15.0 released 🎉
Bump version to 0.1.10 by tompng · Pull Request #58 · ruby/repl_type_completor
ReplTypeCompletor 0.1.10 released 🎉
2025/01/24
Migrate IRB, Reline and Readline to bundled gems by hsbt · Pull Request #12624 · ruby/ruby
IRBとRelineがdefault gemからbundled gemになったようです
2025/01/27
IRB/RelineがBundled gemになった対応シリーズ
Migration for bundled gems by hsbt · Pull Request #811 · ruby/reline
bundled gems migration by hsbt · Pull Request #1078 · ruby/irb
gemspec の spec.files の指定方法を変えています。bundled gemの何か(テストかinstallか)の時、Dir.pwdが異なることがあることへの対応で Dir.chdir で囲っています。
IRBの方では、外部コマンドとしてIRBをテストする場合に、irb/lib reline/libのpathを渡すような変更も入れています。
ruby/rubyのbundled gemのテストではGemfile無しでテストされるようで、テスト対象とは違うreline・irbを読み込んでしまうことを防ぐためのようです。
Remove ruby-core workflow by st0012 · Pull Request #1075 · ruby/irb
Remove ruby-core workflow by tompng · Pull Request #812 · ruby/reline
Bundled gemになったので、default gemだった頃のruby/rubyで行われるものと同じテストをするworkflowを削除しています。
Add gem readline to Gemfile to fix failing ci jobs: readline by tompng · Pull Request #810 · ruby/reline
Gemfileにreadlineを追加しています。
RelineがGNU Readlineと互換性があるかどうかをテストするため、readline-extのテストをRelineで行うCIがあるんですが、
Readlineもbundled gemになったので、Gemfileにreadlineを追加しないとテストできなくなっていました。
Suppress irb_info measures ambiguous_width in command test by tompng · Pull Request #1074 · ruby/irb
irb_infoコマンドを実行すると文字幅が環境で異なる文字の文字幅計測が始まってしまうのですが、コマンドのテストではそれが起きないようにしました。
ruby/rubyのbundled gemのテストが止まってしまうなどの問題がありました。
(Process.spawn(command, pgroup: true) の中でSTDIN.rawを呼ぶ・stty rawコマンドを呼ぶとRubyのプロセスが応答しなくなるが理由がわからない Ruby無関係な気がするが...)
Fallback to Reline when require 'readline' fails by tompng · Pull Request #1076 · ruby/irb
IRBを irb --readline irb --singleline で起動した時、require 'readline' をするんですが、これが失敗しうるようになりました。Readlineがdefault gemではなくなったため。
その場合、Relineを使うようにしました。
(とりあえずこう対処したけど、最初からRelineを使っても良いのかもしれない)
Zero winsize bugfix by tompng · Pull Request #1073 · ruby/irb
Pagerのプレビュー表示部分を実装した結果、winsize=[0,0]の環境でIRBがinspectに失敗するようになった問題を修正しています。
docker run -it | cat などで発生する問題だと思うんですが、IRBに限らずemacs や vim や git show(で使われるpager)なども表示が崩れて正常に動かないので、環境の方を見直した方が良いはずです。
Refactor undo redo by tompng · Pull Request #809 · ruby/reline
undo redo 周りのリファクタリングです。
最近の別のリファクタリングにより、Relineに対するキー操作は(ペーストも含め)全てinput_keyメソッドで実行されるようになったため、undo redoバッファに操作を積むのもinput_keyメソッド内で完結するようになりました。
不要になったインスタンス変数(ローカル変数で済むため)の削除やメソッドの整理など。
Remove unused constant CAPNAME_KEY_BINDINGS by tompng · Pull Request #808 · ruby/reline
消し忘れの未使用の定数 Reline::ANSI::CAPNAME_KEY_BINDINGS を削除しました。
RelineがTerminfoを使っていた頃の、Terminfoのどの名前のkeyでRelineのどの動作をするか定義していた定数でした。
2025/03/20
(1ヶ月半まとめて)
Reject directory from Gem::Specification#files by hsbt · Pull Request #813 · ruby/reline
Ignore to contain directory to Gem::Specification#files by hsbt · Pull Request #1079 · ruby/irb
gemspecに書く、gemに含めるファイル一覧の指定方法を変えています。(ファイル名のみ指定し、ディレクトリ名は除外)
Use Reline::ANSI's buffer instead of calling STDIN.ungetc by tompng · Pull Request #815 · ruby/reline
STDIN.ungetcの使用を減らしました。入力のバッファをすでに持っているので、そこにpushするようにしています。
(ungetcは使えないこともある・irb.wasmでの対応が面倒になる、などの理由も)
Fix typo by ima1zumi · Pull Request #817 · ruby/reline
テストコードのtypo修正
Add gem fiddle to Gemfile (Only used in windows) by tompng · Pull Request #818 · ruby/reline
Gemfileにfiddleを追加(CI(win)が落ちた対策)
Basic setup for Reline's official documentation website by st0012 · Pull Request #820 · ruby/reline
Relineのドキュメントが生まれました。github pagesにデプロイされるように
(docs) Document the keys for completion by andyw8 · Pull Request #1082 · ruby/irb
補完候補を TAB Shift-TAB で選べることをドキュメントに追記
Disable scheduled jobs for forks by andyw8 · Pull Request #1084 · ruby/irb
Disable truffle-ruby scheduled job on forks by andyw8 · Pull Request #1087 · ruby/irb
スケジュールされたCI jobをforkしたリポジトリでは無効になるようにしています。
メインのjobと、(個別にoffにするために分けた)trufflerubyのjobそれぞれ。
こういうの、.github/workflows じゃなく、GitHubのUIで設定できて欲しいなあ
add context.ap_name test by QWYNG · Pull Request #1052 · ruby/irb
IRB.confのテストが漏れていた箇所(IRB.conf:AP_NAME)のテスト追加
Document USE_PAGER config by artur-intech · Pull Request #1086 · ruby/irb
IRB.conf:USE_PAGER についてのドキュメント追加
Allow arguments to be passed through Binding#irb by QWYNG · Pull Request #12796 · ruby/ruby
IRBをrequireせずに binding.irb を使うと自動でrequireされるんですが、その前後でbinding.irbの引数が異なっていました。
引数がforwardingされるようになりました。
Change InstanceType structure by tompng · Pull Request #57 · ruby/repl_type_completor
型情報の持ち方を変えました。実体のオブジェクトを型に変換するのではなく、型情報に(実体があれば)実体のオブジェクトも持たせ、
必要になった時に型に順次展開するようになりました。
code:ruby
# ローカル変数aが[1, 2, 'a'] の時
# Before
a.itself #=> ArrayInteger | Array に展開していた(展開の深さは固定)
a.sample #=> Integer | Array
# After
a.itself #=> Arrayunresolved(instances: 1, 2, 'a')
a.sample #=> Integer | Arrayunresolved(instances: 'a')
a.sample.sample #=> String
実体を持たせたことで、配列やHashに定義されているsingleton_methodも補完できるようになりました。
code:ruby
$LOAD_PATH.first.first.resol #=> resolve_feature_path が補完される
Handle RBS::Types::Intersection (fallback to union type) by tompng · Pull Request #59 · ruby/repl_type_completor
RBSでIntersection型で表現されているものが扱えなかったのを雑に(ひとまずUnion型と同じように扱う)修正しています。
2025/04/02
Bump version to 0.1.11 by tompng · Pull Request #61 · ruby/repl_type_completor
Release v0.1.11 · ruby/repl_type_completor
repl_type_completor 0.1.11 released :tada:
ローカル変数の値がネストの深い配列やHashの時の補完が良くなってます
2025/04/03
Bump version to 1.15.2 by tompng · Pull Request #1088 · ruby/irb
Release v1.15.2 · ruby/irb
IRB 1.15.2 released 🎉
2025/04/04
Bump version to 0.6.1 by tompng · Pull Request #823 · ruby/reline
Release v0.6.1 · ruby/reline
Reline 0.6.1 released 🎉
2025/04/09
Handle keyword local variables correctly by tompng · Pull Request #1085 · ruby/irb
IRBでは、ローカル変数の有無に依存してparse結果が変わるコードを正しくparse/tokenizeするために
Ripper.lex("lvar1=lvar2=lvar3=nil\n#{code}") のように1行めにローカル変数を定義する文を挿入してparse/tokenizeしています。
が、ローカル変数にキーワードと同名のもの(ifとかend)があるとうまく動いてくれない問題がありました。
"if=end=nil\n#{code}" がSyntax Errorになる。
これらのローカル変数はあってもなくてもparse結果に影響を与えないので除外しました。
なおキーワードと同名のローカル変数は def f(if:,end:) 1 in {if:,end:} binding.local_variable_set('if',1) などで作成できます
2025/04/26
Rescue more errors in get/set_screen_size by tompng · Pull Request #824 · ruby/reline
IO#winsize を呼ぶ時、IOが端末ではなくwinsizeが取れないケースを想定して Errno::ENOTTY や Errno::ENODEV などをrescueしているんですが
実際には Errno::EINVAL Errno::EOPNOTSUPP Errno::EBADF なども発生するらしく(他にも無数にあるかも)、それらのsuperclassである SystemCallError をrescueするようにしました。
2025/04/27
Avoid intermediate array from split by Maumagnaguagno · Pull Request #1093 · ruby/irb
debug系のコマンドを入力している時、入力末尾に # debug command という文字列が表示されるんですが、その表示条件とdebugコマンドのを修正しています。
プルリクのタイトルはAvoid intermediate arrayなんですが、そこはあまり重要ではない。
なお、通常のコマンドとコマンド名の色付け表示の条件もちょっと食い違っていて、直したほうが良さそう。
Change require path completion test not to use 'set' by tompng · Pull Request #62 · ruby/repl_type_completor
SetがRubyの組み込みクラスになったことにより、require ' の補完で set が出ることを期待するテストがruby-headで落ちていたことへの対処です。
他の適当なライブラリに変えるのではなく、repl_type_completor自身をテスト対象に使うことにしました。これなら何が合っても割と安定してくれるはず。
2025/05/08
Prefer filter_map and map+grep instead of map+compact and select+map by Maumagnaguagno · Pull Request #1094 · ruby/irb
map{}.compact select{|a|}.map{|a|} がfilter_mapなどを使って今風に書き直されました。
Replace gsub with rstrip by Maumagnaguagno · Pull Request #1095 · ruby/irb
rstripで良い gsub(/\s*\z/, '') があり、rstripに置き換えられました。
厳密にはrstriptと一致しない("\0"などの扱いが違う)んですが、そこを区別する意図で書かれたものではないのでrstripが良いですね。
2025/05/09
Fix nil error on debugger prompt by muno92 · Pull Request #1097 · ruby/irb
IRBではpromptの一部(irb(この部分):001>)に self.to_s を使っています。
to_sが定義されていないケースについては以前から対応済みなんですが、to_sがString以外を返すケースでIRBがクラッシュする問題があり、それが修正されました。