ScrapVim-lite-3
またscratchから作り直す
あと2,3回scrap & build繰り返しそうtakker.icon
設計をなんとかしたい
キー入力を解釈する部分
Vim comamndsと実際の命令とを結びつける部分
命令集
引数に規格を与える
modeごとにcommandを分けたほうが良いのかもしれない
Mode→KeyHandlerMode→NormalModeというふうに派生していた
Modeの下にStateを置く方法も考えていた
数字入力state
operater state
text objectの入力を受け付ける状態
いや、こっちの方が良いかも
delete({register, count,range})などの関数を用意して置く
diw/da[など、vim commandとして解決できる文字列が渡されたら、deleteなどに適切な引数を渡して実行する
ひとかたまりのcommandをparseする部分と、引数で対処方法を変えられる関数群とで分離させる
で、それぞれのmodeに対してそれぞれこのペアを用意する
下手にstateの切り替えとかを考えない分シンプルかも。
コマンド周り
Mode
モードの管理
ここから派生してNormalMode/InsertMode/VisualModeを作る
commandはmodeに持たせてもいいか
具体的なcommand, vim key bindの解決などの関数をもたせる
モードの切り替えごとに関数とコマンド解析をすげ替えるかんじ
modeの切り替えはModeChangerで行う
切り替え指示はイベント経由で行う
global関数として公開する
commandからmodeを切り替えたいときは、このglobal関数を使う
Parser
渡されたvim commandの文字列を解析する
1文字ずつ解析する
これちょっとややこしいか?
operatorとかrangeごとに文字集合を作っておいて
どの文字の次にどの文字が来るのかを決めておく必要がある
これもmodeごとにparserをまるごと交換する感じになるかな
やっぱなんかややこしくなってきたなあ。
一番簡単なのは、全てのコマンドの組み合わせ列挙してしまうことか?
いやいやそれも大変だろう
少なくとも繰り返しに関しては列挙不可能だ
いまparseしているcommandに関するデータを保存しておくことかかなあ?
{count: 0, command: delete, range:{count, command:moveLeft}}とか
実行するときに、command({count,range})と変数を組み立てて実行する
rangeは選択範囲を作る関数とその繰り返し数。返り値は選択範囲情報
range以下はcommandに応じて変えて良いかも
例えば{count: 0, command: replace, char: 'a'}など
一旦Vimの主要commandを全部洗い出して、それぞれに対して↑の形式でcommandを表現できるか確かめてみると良さそう
keyboard
キー入力をVIm用の文字に変換する
ModeからEvent伝播を止めるかどうか決めるcallback関数を設定する
Normal mode
<C-v>や<F5>など一部のキーを除いて横取りする
1文字ずつ入力されたものとみなす
editorに流し込まれたtextは全部消す
Visual mode
Normal modeと同じ
Insert Mode
事前に設定したkey以外はそのまま流す
一旦最低限度のprototypeを作ってみるかな
機能はhjklだけにする
とはいえ、コマンドの追加は簡単だろうけど
実際のコマンド実行とコマンドの解釈を切り分ける設計にしているから、コマンドの中身はそこまで関係ない
必要なクラスを羅列する
register
コマンドにしか関係しないのでいらない
ParseStateで文字列解析するときにいるかもしれないが
Mode
以下の派生クラスを作る
NormalMode
InsertMode
解析用クラス
解析用関数
コマンドと入力文字列との対応表を管理するクラス
KeyInput
ScrapVim
entry point
KeyInputとModeChangerを持つ
KeyInputで得た結果をModeChangerに渡す
モード変更を行う
うまい具合に、モード更新関数をコマンドに渡して使わせたいな
イベントを使う
図解
https://gyazo.com/42ca7e504987bc923ed37c36f96c4d84
Modeの中身
https://gyazo.com/ac32baa3aefd3cd72412092fd99b05d4
commandはModeではなくParseStateにもたせたほうがよさそう
commandとvim key mapが対応している
Modeはcommandとvim key mapとの対応を知る必要がない
vim key mapの解析は全てParseStateに任せている
commandの実行はするが、中に入っているcommandの種類にかかわらず同じ方法で実行できる
一方でParseStateは文字とcommandとの対応表が必須になる
特に、vim key mapの種類ごとに対応表を用意する必要がある
e.g. motion, text object, 数字, ...
対応表のデータ自体は別のファイルに書いておいても良いかも
全ての対応表を一つのファイルに書くのか、対応表ごとにファイルを分けるのかは、まあそのとき決めればいいだろう
コマンド追加がしやすい方でいい
まだ実装しないやつ
Settings
custom key bindや挙動の設定をするやつ
まだ後回し