From d251b54fe40f6f8f95261b4df65bced2fb728c63 Mon Sep 17 00:00:00 2001 From: salmonik Date: Sun, 1 Nov 2026 19:00:04 +0100 Subject: v4.0.6: move the prompt editor and key mapping out of the core --- src/bin/client/repl.rs | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) (limited to 'src/bin') diff --git a/src/bin/client/repl.rs b/src/bin/client/repl.rs index c13fc58..bc4238d 100644 --- a/src/bin/client/repl.rs +++ b/src/bin/client/repl.rs @@ -13,7 +13,8 @@ use crossterm::{ use sha2::{Digest, Sha256}; -use zagan_bet::client::core::{ClientCore, Effect, InteractiveCommand, Key}; +use zagan_bet::client::core::{ClientCore, Effect, InteractiveCommand}; +use zagan_bet::client::input::{game_input, GameInput, Input, Key, Editor}; use zagan_bet::client::database; use zagan_bet::client::ui::{ display_width, format_pong, host_lines, input_cursor_column, lines_to_move_up, @@ -30,6 +31,7 @@ pub struct ClientState { pub addr: Option, pub default_port: u16, core: ClientCore, + editor: Editor, cleanup_done: Arc>, /// Number of visual terminal lines currently occupied by the game board. game_lines: usize, @@ -59,6 +61,7 @@ impl ClientState { addr, default_port, core: ClientCore::new(), + editor: Editor::new(), cleanup_done: Arc::new(Mutex::new(false)), game_lines: 0, prompt_text: String::new(), @@ -112,9 +115,29 @@ impl ClientState { Event::Key(key) => { if key.kind == KeyEventKind::Press { if let Some(key) = map_key(key) { - let effects = self.core.handle_key(key); + let effects = if self.core.is_in_game() { + match game_input( + self.core.current_game_type().unwrap_or(""), + key, + ) { + GameInput::Quit => vec![Effect::Quit], + GameInput::Command(command) => { + self.core.command(command) + } + GameInput::None => Vec::new(), + } + } else { + match self.editor.handle(key) { + Input::Quit => vec![Effect::Quit], + Input::Submit(line) => self.core.submit_line(&line), + Input::Print(lines) => vec![Effect::Print(lines)], + Input::Prompt | Input::None => Vec::new(), + } + }; quit = self.apply_effects(effects); - self.apply_prompt(); + if !quit { + self.apply_prompt(); + } } } } @@ -222,7 +245,6 @@ impl ClientState { } } Effect::ClearRegion => self.clear_region(), - Effect::SetPrompt { text, cursor_col } => self.draw_prompt(&text, cursor_col), Effect::SendLine(line) => { let is_ping = line == "PING"; let started = Instant::now(); @@ -293,9 +315,12 @@ impl ClientState { } fn apply_prompt(&mut self) { - if let Some(prompt) = self.core.prompt_effect() { - let _ = self.apply_effects(vec![prompt]); + if self.core.is_in_game() { + return; } + let text = self.editor.input().to_string(); + let column = self.editor.cursor_column(); + self.draw_prompt(&text, column); } /// Leave the command currently on the prompt line visible in the -- cgit v1.2.3