ESP32とLuaで日本語入力
- 日本語入力の大部分をLuaに移動させる
- なぜか動かない
{ } shellをさらにshellっぽくする
- スクロールするようにする
- 子プロセスっぽくLuaスクリプトを実行できるようにする
- なんちゃって標準出力
{ } ファイル保存機能をつける
- 今のエディタだとどうするのが良いか?
- 保存するファイル名をどうしようか問題がある
- 前みたいにWiki形式にすると自然とファイル名が決まって良さそう
- ブラウザから実行するやつ、データを永続化できると楽しそう
- File System API?
- リモートに送るとしてもコンフリクトの問題がある
- 初めはindex.txtを勝手に開く、みたいな仕様にする
- 拡張子をどうするか問題
- 拡張子なしをデフォルトにすることでluaファイルの編集もできるようになるか?
- なるが、微妙か?
- 生ファイルを指す専用の記法があったらよい?
- 保存時にファイル名を入力させる仕組みはいずれ必要そう
- 検索とか
- 一旦オブジェクト指向に書き直そう
- グローバルを汚染しないことが目的
- アプリ内でモードを切り替えることも目的
- モジュールを使うでもよい?
- 複数のエディタコンポーネントを扱う可能性がある?
- テキスト入力を受け付けるだけでも面倒なコードが必要になるのがつらいな
- コンポーネント?
- { } オフセット機能付きの描画命令が欲しい
- { } クリッピング付きの描画命令が欲しい
- {x} 変換候補画面を消すのが難しい
- 全部再描画することは出来るが、ポップアップウインドウの時などは裏面の再描画が難しいケースがある
- ポップアップの時も重なっているウインドウ全部に再描画命令を出すべき
- そのようにしてみた、ESP32で速度が出るかは別問題
- {x} ESP32側で動作確認
- 何も手を加えずに動いた!すごい
プロジェクト名
- 案
- kaguya
- taketori
- fude, enpitu
- type
- ogi
- o-bakoの親戚としては良さそう
- Luaに縛られていない
- 文字入力とか感じかな変換とか関係ないなぁ
- 【決定】susu-ki
- susukiもパピルスみたいになるらしい
- o-bakoの親戚としてもよさそう
- 漢字感は少ないけどまぁよからろう
- ススキ→月見 というところからLuaを連想させるのもよかろう
中で暮らしたい
- Luaのプログラムの開発と実行ができるとよさそう
- ゲーム開発?(タイマー割込みがないけど・・)
- バージョン管理したい
- 作ればいいか・・?
- Wikiみたいなものを作って、ナレッジベースを作る
- ナレッジベース
- 日記
- Wikipediaの記事を検索する?
- ファイルシステムのサイズとかに引っかかる?
そろそろ公開する
- 辞書はダウンロードしてもらうことにする
- 分割するツールを同梱する
- esp32-lua-keyboardのbatにありそう
- conv.py
- 候補の最初の1文字目のUTF8文字をhexにしたもの.txtというファイルに分割する
- utf8に変換されたSKK辞書を使っているっぽい
- 直した
- {x} runが見ているのはSPIFFSで、それ以外はSDなのは微妙な気がする
- 実行時にSPIFFSにあるLuaファイルをSDにコピーするようにして、すべてSDカードを見るようにしたほうが良いかも
- なぜか初回にSDカードにアクセスできない
- delayではないようだ
- 2回Openもだめ
- openの返り値を見てterminateしてリトライする
- SDの初期化の前に読み込んでいた・・なるほど
- ブラウザ版のほうは公開できた
- ESP32版
- {x} conv.pyの使い方を説明する
https://inline.inajob.freeddns.org/img/twitter-5643382/2024-11-14/1bc0ba8c-a269-11ef-82e3-ee4d2584ab9e#.png
https://inline.inajob.freeddns.org/img/twitter-5643382/2024-11-14/1d107eef-a269-11ef-82e3-ee4d2584ab9e#.png
https://inline.inajob.freeddns.org/img/twitter-5643382/2024-11-14/dc321a0d-a269-11ef-82e3-ee4d2584ab9e#.png
細かい修正
- {x} ESP32でテキストの背景に違和感がある
- {x} ESP32でテキストの位置がWebとずれている
- {x} ESP32でシェルの画面の書き直しがやや遅い?
- { } ESP32でrunするときに固まったみたいになるので、クッション画面を入れたい
- { } WebでESP32の遅さを再現したい
- {x} Webでgetfreeheapを実装
font
- u8g2のフォントが使えるようだが、、豆腐になるな・・
- efontの中にフルセット入っていないものがある
- 命名からわかりそうだが、どういうルールだ?
- そもそもefontの中に複数の書体があるけど、どれがどれだ?
- とりあえずできたっぽい
- 変換の「換」の字が出ないほどフォントが少ない
- u8g2_font_b12_t_japanese3 なら出た。最後の数字が大事っぽい
- ヒープメモリを確認したい
- shell.lua
- 1の時 210,000以上
- 3の時 210,000以上
- そんな変わらないかも
{x} シェルを作る
- まあ結局CLIがよさそう
- CLIをLuaで作る
- ここでIME的な仕組みをCLIにも利用できるかなと思う
- まぁCLIに日本語は求められていないが・・
- IMEを外部ファイルにして読み込む
- タスクバーみたいなのを作って見栄えをよくするのもアリ
- 別のLuaスクリプトを動かす仕組みを作る
- 欲しいコマンド
- ls
- cat
- cd
- edit
- スクロールするようにするか、コマンドが1行目に書けるだけにするか
- 一旦後者で作るのが簡単そう
- execの仕組み
- runで別のLuaのコマンドをexecするような仕組みにしてみた
- 「戻る」を実現したい
- 前のLuaエンジンは捨ててしまっているので、厳密に戻ることができない
- ファイル名だけスタックで保持しておく作戦
{x} ファイルIO
- {x} ブラウザ側
- {できたかな?} ESP32側
- シェルが欲しい
- コマンドラインでも良いし GUIっぽいものでもよい
- getFiles(path)
- 今はSPIFFS
- saveFile(filename, body)
- SD
- readFile(filename)
- SD
- exists(filename)
- SD
{x} SDカードアクセス(辞書)
- 辞書をSDカードに入れることができ、さらに大きなものが利用できる
- 今後の展開でSDカードでPCとやり取りができるようになる
- 少し工夫すればできそう
- main.luaはSPIFFSのままにしたい
- IDEからSDカードを直接書き換える方法がない
- SPIFFSにあるファイルでSDを上書きするようにすれば全部SDから読む体にもできる
- 意図せず上書きされることもありそうだが
IME部分を別ファイルにする
- 前はどうやったっけ?
- requireで普通にロードできてるっぽい
{x} web側
- 関係がありそう
{x} ESP32側
- ほぼそのままで動きそう
- パスの書き方がwebと違う問題がある
- o-bakoのときはrequireを自前で作っていた
- できた、パスの書き方もOK
ヒープの確認
- 適当に1画面分書いて
- 234,568ということで234KBの空きということかな?
- 520KB RAMがあるということなので、それっぽい気がする
- PSRAMがあればまだまだ大きくできる
{x} screenサイズ取得APIの実装
- screenWidth, screenHeight
- を取得する関数
作りこみ
- {x} カタカナ
- {x} 半角英数
- {x} スクロール
- {x} フォールド
英字モード
カタカナモード
ファーストコミット
- Luaの内部をいじっているのでsubmoduleにはできない
- MITライセンスなので問題ない
- v5.4.7
- リポジトリの名前を考える
- o-bakoっぽいのが良い
- o-bakoのサブプロジェクトっぽい感じがある
- スプライト周りが貧弱、バッファをあえて設けていない
- o-bako的アイデアだが互換性を持たせるつもりがない
- o-bakoはゲームプラットフォームを意識していた
- SKKの辞書のライセンス
- GPLっぽい、ちょっと気になる、分離しておいたほうが良いかも
1文字目で辞書ファイルを分ける
ファイル名にマルチバイト文字が使える?
- その場合ソースコードからどうやってアクセスする?
- 普通に文字リテラルに日本語を書いたらアクセスできない
- u8を前置してUTF8にしたらどうか?
- だめ
- ShiftJISの可能性があるが面倒だな・・
- luaから来た文字列の1文字目が何かを考える
- ひらがなだと決め打ちできれば簡単そう
- 16進数にばらしてみるか
- あ=e38a82
辞書を前処理する
- 雑にPythonでつくった
動いた!
- M辞書余裕
- 1Mが上限とすると、ML、L辞書は入らない
- これ以上はSDカードを使わないとダメ
PoC
ブロックしないキーボード入力スキャン
> url
<<
キューも必要
> url
<<
TODO
- {x} 打ち込んだ文字が出るものを作る
- {たぶんできてる} あえて表示処理にウェイトを入れて、キューに残ったキー入力をちゃんと拾えるか確認する
- {x} 日本語フォントの実験
- {x} wasmoonで試したときに使った描画命令と同じものを用意
- color, print, measureText, fillrect, ksearch
- {x} 表示の最適化
- 変更のない行は再描画しない?
- ポップアップがあるので、オフスクリーンバッファがないと難しい
更新の最適化
- 変更のあった行だけ再描画するのはどうか?
- ポップアップの裏側も再描画が必要
- オフスクリーンバッファを用意するのは面倒
- 候補を画面下に固定で出すなどの対応はどうか?
- 1文字ごとの不要な再描画をやめたら普通に早くなったので、気にしなくてよさそう
- ひらがな確定後は再描画はしなくてよい気がする
- 行ごとにdirtyフラグを持たせるようにした
- 変換が確定するときは全画面を消すことでごまかしている
エディタを移植
- {x} FEPにエディタのカーソル位置を返す
- {x} 画面描画の整合性を合わせる
APIを合わせる
- ESP32側
- debug
- キーの名前がキーコード
- setcolor
- setcursor
- fillrect
- putstring
- gettextwidth
- fillrect
- Web側
- color
- fillrect
- print
- measureText
- 統一する
- debug
- color
- text(s, x, y)
- textwidth
- fillrect
日本語入力部分のLuaエンジンを分ける?
- メモリ食いそう
- ここを分離しておくと日本語入力周りだけ別のプログラムに切り替えたりできる
- Luaエンジンを分けたときのヒープの空きを調べたい
- 分ける意味を感じなくなったので統一させた
ksearchの実装
- さて、ここが鬼門
- ナイーブに全部舐めて結果を返す、でも良いか確認したい
- 今みたいにインクリメンタルに表示するのはできない
- 行頭区切り文字までの単語が、マッチするかを調べるとかで良さそう
- ナイーブにまずは実装する
- 1文字目でファイルを分けるなどもできるか?
- 辞書ファイルを作る
- 一旦SKK式にする
- 1行目が辞書形式になってそう
- 一旦初めのスペースの手前まで読めばよさそう
- 14406行のデータ
- 一応動いた、Luaだと楽だね
- ただ、ものすごく遅い
- 割り込みはうまいこと動いている
- どんなに早くしても限界がありそう
- SKKのSの辞書はエントリどのくらいあるの?=3412, 1/5くらい
- 一応動かしてみたが、まぁ毎回検索はだめだね
- 高速化の余地はある?
- 初めの文字でファイルを分ける?
- 1/50くらい高速化できるか?
- それでも毎回検索は厳しそう
- 非同期変換にする
- 待っていると検索結果が増える
- キャンセルをどうするかが悩み
SKK的なIMEの実装
- Luaで実装するので、ネイティブよりは気軽にできそう
- SKK的な実装
- 何も指示がないとひらがながどんどん確定していく
- 大文字が入ると変換モードに入る
- その後スペースキーか、再度の大文字で変換処理が走る
- 変換候補を出しているうちは、スペースキーで次の候補に切り替える
- 確定キーで文字を打ち込み通常モードに戻る
- 大体できた
- json版のSKK辞書を作る
- SKK辞書をそのまま読めたほうが便利か?
- フェッチして検索か・・そっちでもよいか
- アセットを文字として読み込むのが便利
- ESP32のほうでも動いたぞ
- 前と同じくらいところまできた
- S辞書なら実用的な速度に見える
大きな辞書への対応
- L辞書は 240274 語入っているらしい
- M辞書にしてみる 8379行
- 先頭文字でインデックスにする作戦はどうか?
- となるとひらがな
- ひらがなファイル名はいやだな・・
- 先頭文字とそのバイト数みたいなデータを持つ?
- 1/50くらいの早さになる?
- 特定の文字に偏ってそうだから、それでも1/10くらいにはなりそう
スマートフォンから使えるように
- キー入力をうまく取れれば行けそう
- カーソルキーとかがない問題
800*480とかの画面で足りるのか?
- 左右画面欲しい気持ちがある
- 相対座標で描画できる命令が欲しい
- lua側でラップすればいいか
- 今なら text, fillrectの2つだけ
- offset(x, y)などでずらすことができそう
- save(), restore()で戻れると便利そう、入れ子にもできるし
- 描画contextを用意する
- color
- offset
- 480あれば30~40行表示できる
- 縦が320と考えると・・20行
- 縦が240と考えると・・15行
- 動きそう
12pxの扱いやすいフォントを探す
- これは8px
- adobex11profont
- profont
- efontに12pxもある
画面がそれっぽいことは重要だと思う
- アイコンが並んでいていかにもOSのシェル!みたいな