コードリーディングメモ
autocompleteとtab completionの状態分離
tab completion は --noautocomplete
で使える
Reline::DEFAULT_DIALOG_PROC_AUTOCOMPLETE
最終的にDialogRenderInfo
を返す。表示のために必要な枠組みの情報
DialogRenderInfo.new( pos: cursor_pos_to_render, contents: result, scrollbar: true, height: [15, preferred_dialog_height].min, face: :completion_dialog )
journey_data
として completion_journey_data
から.DialogProcScope::CompletionJourneyData
をもらってくる。
これは @completion_journey_state
としてダイアログ遷移中の状態のときにどこにいるか、前後の行情報、ダイアログに何を表示すべきかのリスト、ポインタをもっている。
遷移中じゃなければ @completion_journey_state
は nil
になる。
移動を表すのにjourneyという単語を使っているの好き
def completion_journey_data @line_editor.dialog_proc_scope_completion_journey_data end def dialog_proc_scope_completion_journey_data return nil unless @completion_journey_state line_index = @completion_journey_state.line_index pre_lines = @buffer_of_lines[0...line_index].map { |line| line + "\n" } post_lines = @buffer_of_lines[(line_index + 1)..-1].map { |line| line + "\n" } DialogProcScope::CompletionJourneyData.new( pre_lines.join + @completion_journey_state.pre, @completion_journey_state.post + post_lines.join, @completion_journey_state.list, @completion_journey_state.pointer ) end
dialog_proc_scope_completion_journey_data
が呼ばれるのは Reline::DEFAULT_DIALOG_PROC_AUTOCOMPLETE
からのみ
@completion_journey_state
はこう。move_completed_list
で動いたときに CompletionJourneyState
が入る。それ以外はnil
@completion_journey_state = CompletionJourneyState.new( @line_index, pre, target, post, [target] + candidates, pointer )
pre
target
post
は入力中の line
を区切り文字などを考慮して切ったもの。例えば S
を入力すると target
は S
になる
call_completion_proc_with_checking_args
の返り値は STDERR
とかダイアログに表示すべき文字列が Array
に詰め込まれる
["STDERR", "STDIN", "STDOUT", "ScriptError", "SecurityError", "Set", "Shellwords", "Signal", "SignalException", "SimpleDelegator", "SingleForwardable", "Singleton", "SizedQueue", "S...
move_completed_list
ダイアログ表示中に tab
を押したときなど移動が発生したときに入る。移動だけのときはCompletionJourneyStateの作成はスキップし、@completion_journey_state
のポインタの位置更新とset_current_line
でカーソル位置の更新を行う。
if (delta = { up: -1, down: +1 }[direction])
これで direction
の存在チェックしながらdelta
に数字を代入するの、こう書けるんだ..!面白い。
preposing, target, postposing = retrieve_completion_block
でターゲットの文字列を前後に分割する。preposingが入力中の文字の手前、targetが入力中の文字、postposingが入力中の文字の後
list = call_completion_proc
で表示対象の文字列を Array
に詰め込んで返す。 call_completion_proc_with_checking_args
と大体同じ(何が違うんだろう)
@completion_journey_state
の更新が入るとこんな感じの状態を持つ
#<struct Reline::LineEditor::CompletionJourneyState line_index=0, pre="", target="S", post="", list=["S", "STDERR", "STDIN", "STDOUT", "ScriptError", "SecurityError", "Set", "Shellw...
list
の最初の要素は入力中の文字っぽい。
em_delete_or_list
delete_char_of_list
のalias
elsif !@config.autocompletion
になったのはautocompleteが有効なときには補完周りの処理をしないためかな
delete-char-or-list Deletes the character under the cursor if not at the beginning or end of the line (like delete-char). If at the end of the line, behaves identically to possible-completions.