Rhinocs
Rhinocs
そのうち作りたいものの構想をメモする。
作りたいもの
キーボード前提(必須)のAndroidのエディタを作りたい。
AndroidのIME周辺のキーボードの扱いが好きになれないので、全部キーコードを自前でハンドルするエディタを作りたい。 テキスト入力専用で快適に長文が入力出来る感じの。タッチでは全く使えない代わりにキーボードで快適、という風にしたい。 自分のBOOXをポメラっぽく使いたい。 ソフトキーのIMEは使わずにキーボード専用のものを自作したい。
Rhinoをバックエンドにしたemacsみたいなエディタをぼんやりと考えている。 ということで名前はRhino backendのemacsっぽいAndroid用エディタ、Rhinocsとした。
日本語入力はSKKを移植する感じで。
上記を満たしつつ、ちゃんとAndroidのアプリとして正しく振る舞うエディタが欲しい。PCのアプリの移植系ではなく。 Activityのリサイクル、SAFなどを考えたエディタであって欲しい。
最初の目標
考えないといけない事は無限にあって永遠に前に進めない気がするので、一番最初の目標を決めてそれに必要な事だけをやる感じにしたい。
やりたいのはこのWikiなどを書きたい。それに必要最低限のものから始めたい。
- SAFでのファイルの読み書き
- 日本語入力
- SKK
- ダイアログでEditText
- キーマップと基本的な入力
- カット、コピー、ヤンク
日本語入力は必須なので、最初から半角-全角の扱いはしたい。逆にこの枠組みに収まらない言語はやらない。
SKKはちゃんとやると結構いろいろな機能が必要になってしまうので、とりあえず複数windowが無くても出来るような範囲だけをやりたい。 ミニバッファ絡みの機能も最初はやらない。
その代わりEditTextで普通にタッチ入力する逃げ道は作っておきたい。
ウィンドウのsplitは無しでもまずはいけるか?ミニバッファとウィンドウのsplitがなければだいぶ話は楽そうだが。 switch-bufferは必要だろうが、最初の目標としては無しの状態でとりあえず動く所までを目指すか。
最初の最初の目標はSKKの実装を開始するまでの最低限
SKKを必要最低限に実装するのは結構大変ではある。 これが最初の目標というのは遠すぎる。
そして作り始めないと何が必要かは完全には分からないので、最初に作り始める所を最初の最初の目標とするか。
SKKを作り始めるのが最初の最初の目標とすると、必要なのはなんだろう?
- SAFでのファイルの読み書き
- Rhinoのキーマップ経由のローマ字の入力
- Rhinoによるjsのロード
モードとかを最初に整備するのは避けたいので、単純にSAFでskk.jsをロードしてしまって良いとは思っている。 このくらいが動けばjsの作業を開始出来るか。
ここまでを最初の最初の目標とするか。
SKKを書き始めるのにとりあえず必要なのは以下か?
- Rhinoからのバッファの操作
- Rhinoからの辞書のロード
- Rhinoからのread-key的な処理
この辺を揃え始めるのが最初の最初の目標かな。ドッグフードはまだまだだいぶ先だが。
作業ログ
とりあえず何をやったかを書いておく所。
作り始め 2026-05-13 (水)
とりあえずバッファを画面に描く機能はなんとなく書いた。 ファイルをロードしてスクロールもなんとなく動いている。 カーソルも描いた。
リサイクルとenv
Androidはプロセスが殺されるので、インタープリタをずっと活かしておく、という事が出来ない。 だから殺されて再生成された時にまぁまぁの速度で動く必要がある。
emacsのようにすべてをメモリ上にずっと置いておく、という前提は難しいので、恐らく現在のバッファに対して読み込まなくてはいけないものをある程度は限定する必要はありそう。
また、再生されてから動き出すまでと、その裏でいろいろやるのは分離したい。SKKの初期化などはいかにも分離したいよなぁ。
Viewについての雑記
下の方に書いたように初期はスクロールを真面目にやろうと考えていたが、それはドッグフードまでが遠すぎてやる気が出ない。 もっと単純にしよう。
Viewはバッファのある範囲を書くが、コンソールっぽく単純化したい。 Viewのうち文字を書く領域をPaneと呼ぶ事にする。
Paneは縦横の文字のグリッドで、文字は幅が1か2のどちらかとする。フォントは等幅フォント固定。 文字の描画は文字ごとに書く。くっついたりする言語とかはサポートしないし、文字の幅を足したものが文字列の幅になるようにする。
バッファに対してある行の範囲を指定すると、その範囲でのGrid情報を計算して、rowとcolを指定すると文字が取り出せる(または前のcolが2幅なら無しが取り出せる)。 この情報はGridと呼ぶ事にするか。
PaneはGridの通りに文字を描くだけとする。スクロールとかもとりあえずは考えずに全部redrawとする。
GUIスレッドとRhinoのスレッド
とりあえずGUIスレッドでRhinoも動かす。これでは駄目なのは少し考えればわかるが、Bufferの更新とUIのレンダリングの同期がちょっと面倒なので、まずは同一スレッドで始める。
最終的にはRhinoは専用の一つのスレッドでいつも動かし、GUI側にはイベントで変更を通知し、Gridを生成する時にはBufferをロックする感じにしたい。
パッケージについて
最初にホームディレクトリを指定させる。これはSAFで。とりあえずそこにjsのスクリプト置いて、それをロードする感じでいってみたい。 本当にそれでエディタになるのかは少し自信が無い所もあるが、 カスタマイズしたい訳では無いので、既存のパッケージの関数の上書きとかはまずは出来なくてもいいだろう。 どちらかといえば途中からは実装をRhino側でやるようにしたいなぁ、という気持ちが強い。
ただActivityのリサイクルがあるので、あまり大きな初期化を最初にやる、というモデルは厳しいかもしれない。
バッファについて
バッファは行のリストで。ギャップは入れないで単純に毎回コピーする。 バッファ周りはAPIは割と真面目に作る。 StringBuilderのArrayListくらいから始めるか。
古くなった話
考えているうちに変わったものなどをとりあえず残しておく場所。
最初はStarlarkバックエンドにしようと思ってStarlarcsと呼んでいたが、今はRhinoバックエンドのRhinocsにしたいと思っている。
Viewについての雑記(初期、やっぱり変える)
一行一TextViewで、RecyclerViewを使いたいが、厳しいかなぁ。 内部的には対応する行に合わせたグリフ情報を構成して、それを書く。 各TextViewは前に書いたグリフ情報はキャッシュし、、、ってそこまでやるならTextViewよりも自分で書く方がいいかなぁ。
View側と内部の両方を一気につくると永遠に完成しないのでViewは手抜きで始めたい気もするな。 そうすると一番単純にはスクロールとかは無視して、画面に表示している範囲の文字をdrawするだけの方が楽か。 まぁ最初はそこからか。
そう考えるならZipSourceCodeReadingと同じ感じでいいか。 ZipSourceCodeReadingはスクロールがいまいちだったので、将来的には各行を表示するViewを作ってRecyclerViewに任せたい気もするが、 キーボード中心と割り切れば別にスクロールがいまいちでも我慢出来るかもしれない。 なんにせよ最初は単に配列を画面に表示するだけの方がいいな。
とりあえず、内部で画面に表示する文字の一覧を作る。これはグリフの配列とする。 Viewはそれを表示するだけで、スクロールとかは一切サポートしない。 こんな感じで始めるか。 グリフを作る所まではどうせ一緒なので、そこから先は真面目に書きたくなったら書けばいいだろう。