feat(protocol): add Paste request type for bracketed-paste events
feat(engine): summarize agent completion progress in UI notifications feat(main): enable and disable bracketed paste support in terminal fix(app_config): store API key from file as fallback for Claude provider refactor(workflow): remove unnecessary card separator in workflow panel
This commit is contained in:
+29
-1
@@ -118,6 +118,7 @@ fn run_single_process() -> Result<()> {
|
||||
enable_raw_mode()?;
|
||||
let mut stdout = io::stdout();
|
||||
execute!(stdout, EnterAlternateScreen)?;
|
||||
execute!(stdout, crossterm::event::EnableBracketedPaste)?;
|
||||
let backend = CrosstermBackend::new(stdout);
|
||||
let mut terminal = Terminal::new(backend)?;
|
||||
terminal.clear()?;
|
||||
@@ -125,6 +126,7 @@ fn run_single_process() -> Result<()> {
|
||||
let run_result = run_loop(&mut state, &mut terminal);
|
||||
|
||||
let mut restore_stdout = io::stdout();
|
||||
let _ = execute!(restore_stdout, crossterm::event::DisableBracketedPaste);
|
||||
let _ = execute!(restore_stdout, LeaveAlternateScreen);
|
||||
let _ = disable_raw_mode();
|
||||
|
||||
@@ -408,6 +410,12 @@ fn run_daemon() -> Result<()> {
|
||||
}
|
||||
apply_action(&mut state, Action::Tick);
|
||||
}
|
||||
ClientRequest::Paste(text) => {
|
||||
state.input.buffer.insert_str(state.input.cursor, &text);
|
||||
state.input.cursor += text.len();
|
||||
state.dirty = true;
|
||||
apply_action(&mut state, Action::Tick);
|
||||
}
|
||||
ClientRequest::Resize(w, h) => {
|
||||
apply_action(&mut state, Action::Resize(w, h));
|
||||
apply_action(&mut state, Action::Tick);
|
||||
@@ -468,6 +476,7 @@ fn run_attach(session_id: &str) -> Result<()> {
|
||||
enable_raw_mode()?;
|
||||
let mut stdout = io::stdout();
|
||||
execute!(stdout, EnterAlternateScreen)?;
|
||||
execute!(stdout, crossterm::event::EnableBracketedPaste)?;
|
||||
let backend = CrosstermBackend::new(stdout);
|
||||
let mut terminal = Terminal::new(backend)?;
|
||||
terminal.clear()?;
|
||||
@@ -516,6 +525,9 @@ fn run_attach(session_id: &str) -> Result<()> {
|
||||
}
|
||||
}
|
||||
}
|
||||
Event::Paste(text) => {
|
||||
client.send(&ClientRequest::Paste(text))?;
|
||||
}
|
||||
Event::Resize(w, h) => {
|
||||
client.send(&ClientRequest::Resize(w, h))?;
|
||||
}
|
||||
@@ -555,6 +567,7 @@ fn run_attach(session_id: &str) -> Result<()> {
|
||||
})?;
|
||||
}
|
||||
|
||||
let _ = execute!(io::stdout(), crossterm::event::DisableBracketedPaste);
|
||||
let _ = execute!(io::stdout(), LeaveAlternateScreen);
|
||||
let _ = disable_raw_mode();
|
||||
|
||||
@@ -578,8 +591,9 @@ fn run_loop(
|
||||
let result = run_loop_inner(state, terminal);
|
||||
if let Err(ref _e) = result {
|
||||
let _ = terminal.clear();
|
||||
|
||||
|
||||
let _ = disable_raw_mode();
|
||||
let _ = execute!(io::stdout(), crossterm::event::DisableBracketedPaste);
|
||||
let _ = execute!(io::stdout(), LeaveAlternateScreen);
|
||||
}
|
||||
result
|
||||
@@ -625,6 +639,20 @@ fn run_loop_inner(
|
||||
}
|
||||
}
|
||||
}
|
||||
Event::Paste(text) => {
|
||||
// Insert pasted text as a single bulk operation instead of
|
||||
// character-by-character, avoiding O(n^2) String::insert()
|
||||
// and preventing stray newline/control-byte misinterpretation.
|
||||
if state.input.autocomplete_visible {
|
||||
state.input.close_autocomplete();
|
||||
}
|
||||
state.input.buffer.insert_str(state.input.cursor, &text);
|
||||
state.input.cursor += text.len();
|
||||
if state.input.buffer.starts_with('/') {
|
||||
state.input.open_autocomplete();
|
||||
}
|
||||
state.dirty = true;
|
||||
}
|
||||
Event::Resize(w, h) => {
|
||||
apply_action(state, Action::Resize(w, h));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user