2019-12-25 (Wed) [長年日記]
_ Textbringer 1.0.2リリース
※Textbringer Advent Calendar 2019の参加記事です。
Ruby 2.7.0がリリースされたので、Textbringer 1.0.2をリリースした。
変更点:
- isearch_quoted_insertの追加(インクリメントサーチ中にC-qで次に入力した特殊文字を検索できるようにするため)
- define_keyやヘルプでESCの代わりにM-記法を使うようにした
- indent_new_comment_line_commandの追加(平成Ruby会議01でライブコーディングした機能)
- find_alternate_fileの追加(ただしEmacsと違って現在のバッファはkillせず残す)
- Rubyモードのインデントのバグの修正
最後のが一番つらいやつで、平成Ruby会議の時も当日の朝にライブコーディングの練習をしていたらバグに気づいて修正していた。
デモの練習しようと思ったらTextbringerバグってるんだけど……
— Shugo Maeda (@shugomaeda) December 13, 2019
TextbringerのRubyモードでは、インデントの計算をする時にまず最初にカーソル位置から一番近いclassやdef、ifなどを探してそこからカーソル位置までのトークンをRipperで切り出す。例えば、
module Foo
class Bar
def foo
if bar
end
end
end
の最後のendの行でC-iすると
if bar
end
end
end
の部分のトークンを切り出し、ifの行のインデント位置からendの対応関係を見てインデントを計算する。 ところが、Ripper.lexは2番目のendで文法エラーを検出して最後のendはトークンとして返してくれない。
そこでTextbringer 1.0.2では途中で文法エラーになったら残りの部分を繰り返しRipperに食わせて最後までトークンを切り出すようにした。
また、
if bar
end
}
のように {
との対応が取れていない }
があると、 :on_rbrace
ではなく :on_embexpr_end
として返ってくるのでそのあたりも修正した。
Ripperは正しいRubyプログラムを先頭から食わせるような使い方では便利だが、テキストエディタのように正しくないかもしれないRubyプログラムを一部分だけ処理するようなケースではちょっと工夫が必要になる。