開発

[binllion] 編集用バッファに挿入機能を追加する

上書き、とくれば挿入も必要でしょう。挿入機能を追加しましょう。

現状は上書きのみを想定していたので、上書きと挿入を切り替えるようにする必要があります。

つまり、書き込みモードの管理と表示を実装していきます。

書き込みモードの管理

上書きと挿入の2パターンしかありませんが、これをコードとして表現するならば列挙型が便利でしょう。

enum WriteMode を下記のように定義してみました。

// 書き込みモード
pub(crate) enum WriteMode {
    OverWrite,
    Insert,
}Code language: JavaScript (javascript)
// 状態管理
pub(crate) struct Message {
    bin_data: BinData,
    cursor: CursorPosition,
    scroll: Scroll,
    write_mode: WriteMode,
    layout: [Rc<[Rect]>; 4], // main_layout, sub_layout, inner_main, inner_sub
}Code language: JavaScript (javascript)

関係ないですがMessage という名前を使っていますが状態管理をしているのでStateとか名前を変えたほうがいい気がしています。後ほどの検討項目としたいと思います。

書き込みモードの切り替え

            // 書き込みモード変更
            KeyCode::Char('i') => {
                message.toggle_mode();
            }

            // 数値データ入力
            KeyCode::Char(char_code @ ('0'..='9' | 'a'..='f' | 'A'..='F')) => {
                // 入力データをミニバッファへ書き込み
                self.input_buf.add(char_code);

                // 16進数へ変換が成功なら
                let res = self.input_buf.to_hex();
                if let Ok(val) = res {
                    use crate::message::WriteMode::*;

                    let index = message.cursor().index();
                    match message.write_mode() {
                        OverWrite => {
                            message.bin_data_mut().update(index, val);
                        }
                        Insert => {
                            // 最初の桁に入力あり
                            if self.input_buf.index() != 0 {
                                // 下の桁を0にしたい
                                self.input_buf.set_value(0);
                                self.input_buf.add(char_code);
                                let res = self.input_buf.to_hex();
                                if let Ok(val) = res {
                                    message.bin_data_mut().insert(index, val);
                                }
                            }

                            // 最後の桁に入力あり
                            if self.input_buf.index() == 0 {
                                message.bin_data_mut().update(index, val);
                            }
                        }
                    }
                }
            }Code language: PHP (php)
    // 書き込みモード変更
    pub(crate) fn toggle_mode(&mut self) -> &WriteMode {
        use WriteMode::*;
        let mode = &self.write_mode;
        self.write_mode = match mode {
            OverWrite => Insert,
            Insert => OverWrite,
        };
        &self.write_mode
    }Code language: PHP (php)

新しくKeyCode::Char('i')を追加して書き込みモードの切り替えキーとしました。

また、KeyCode::Char(char_code)の中の処理を書き込みモード別に処理するように変更しています。

挿入処理はちょっと複雑で、最初の桁(つまり2桁目)の入力があった場合は新しい値の挿入が行われます。ミニバッファは古い値が残っているので0でリセットしてから改めて値を追加して編集バッファにinsertしています。

最後の桁(つまり1桁目)の入力の場合は既に挿入が終わっているのでupdateの処理に切り替えています。

今見返してみると、if self.input_buf.index() != 0の条件式が良くないですね。コメントと合っていないです。if self.input_buf.index() – 1 == 0というような条件が良さそうです。

書き込みモードの表示

    let mode = {
        use crate::message::WriteMode::*;
        match message.write_mode() {
            OverWrite => " OVR ",
            Insert => " INT ",
        }
    };
    let status_bar_left = Line::from(vec![" Mode:".into(), mode.green().bold()]).left_aligned();
    let status_bar_mid = Line::from("").centered();
    let status_bar_right =
        Line::from(vec![" Quit ".into(), "<Ctrl+Q> ".blue().bold()]).right_aligned();

    // パネルブロック
    let block = Block::default()
        .title(title)
        .title_bottom(status_bar_left)
        .title_bottom(status_bar_mid)
        .title_bottom(status_bar_right)Code language: JavaScript (javascript)

書き込みモードをステータスバーに反映させるように表示処理もアップデートします。

モードによってOVR、INTを表示するように処理を変更しています。

表示ポジションによってstatus_bar_left 、status_bar_mid 、status_bar_right を分けました。status_bar_mid は使っていませんが将来の予約的な位置付けとしておきます。

GitHubにコードをアップロードしています。0.1.0バージョン

コードのコメントに書かれているfirst_stepなどをcargoコマンドに渡すと実行できます。

# Example
$ cargo run --example first_stepCode language: Bash (bash)
管理人

Recent Posts

情報セキュリティマネジメント試験取得への道

スキルアップを図るべく情報セキ…

2か月 ago

ファイナンシャルプランナー3級試験取得への道

スキルアップを図るべくファイナ…

2か月 ago

[rust] New Type Patternを使ってみる

DDDの考えを取り入れることで…

5か月 ago

RustでDDDの要素を取り入れてみる

前回SOLID原則というものを…

5か月 ago

期間限定!書籍無料キャンペーン2025

「mdBookではじめるKin…

5か月 ago