multi-line copy/paste, more copy/paste

fix C and D in nimbus romono
This commit is contained in:
stjet
2025-04-26 05:17:06 +00:00
parent 7c6a7d6b6d
commit 724ffbd494
12 changed files with 78 additions and 19 deletions

View File

@@ -11,7 +11,7 @@ use std::fmt;
use pty_process::blocking;
use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLikeType };
use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse, ShortcutType };
use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse, WindowManagerRequest, ShortcutType };
use ming_wm_lib::framebuffer_types::Dimensions;
use ming_wm_lib::themes::ThemeInfo;
use ming_wm_lib::utils::{ concat_paths, path_autocomplete, Substring };
@@ -46,6 +46,11 @@ fn strip_ansi_escape_codes(line: String) -> String {
new_line
}
fn bytes_to_string(bytes: Vec<u8>) -> String {
let bytes_len = bytes.len();
String::from_utf8(bytes).unwrap_or("?".repeat(bytes_len))
}
#[derive(Default, PartialEq)]
enum Mode {
#[default]
@@ -78,6 +83,7 @@ pub struct Terminal {
current_path: String,
running_process: Option<Child>,
process_current_line: Vec<u8>, //bytes of line
output: String, //current or previous running output of command
pty_outerr_rx: Option<Receiver<u8>>,
pty_in_tx: Option<Sender<String>>,
history: Vec<String>,
@@ -116,6 +122,7 @@ impl WindowLike for Terminal {
self.history_index = None;
self.mode = self.process_command();
self.current_input = String::new();
self.output = String::new();
} else if key_press.key == '\t' { //tab
//autocomplete assuming it's a file system path
//...mostly working
@@ -144,8 +151,10 @@ impl WindowLike for Terminal {
loop {
if let Ok(ci) = self.pty_outerr_rx.as_mut().unwrap().recv_timeout(Duration::from_millis(5)) {
if char::from(ci) == '\n' {
let pcl_len = self.process_current_line.len();
self.lines.push(strip_ansi_escape_codes(String::from_utf8(self.process_current_line.clone()).unwrap_or("?".repeat(pcl_len))));
let append_line = strip_ansi_escape_codes(bytes_to_string(self.process_current_line.clone()));
self.output += &append_line;
self.output += "\n";
self.lines.push(append_line);
self.process_current_line = Vec::new();
} else if char::from(ci) == '\r' {
//for now, ignore
@@ -166,7 +175,14 @@ impl WindowLike for Terminal {
//process exited
self.pty_outerr_rx = None;
self.mode = Mode::Input;
self.process_current_line = Vec::new();
if self.process_current_line.len() > 0 {
//add to lines
let append_line = strip_ansi_escape_codes(bytes_to_string(self.process_current_line.clone()));
self.output += &append_line;
self.lines.push(append_line);
//only need to reset if not empty
self.process_current_line = Vec::new();
}
changed = true;
} else {
if key_press.key == 'i' {
@@ -187,8 +203,9 @@ impl WindowLike for Terminal {
} else if key_press.is_enter() {
let _ = self.pty_in_tx.as_mut().unwrap().send(self.current_stdin_input.clone());
self.mode = Mode::Running;
let pcl_len = self.process_current_line.len();
self.lines.push(strip_ansi_escape_codes(String::from_utf8(self.process_current_line.clone()).unwrap_or("?".repeat(pcl_len))) + &self.current_stdin_input);
let append_line = strip_ansi_escape_codes(bytes_to_string(self.process_current_line.clone()) + &self.current_stdin_input);
self.output += &append_line;
self.lines.push(append_line);
self.current_stdin_input = String::new();
self.process_current_line = Vec::new();
} else if key_press.is_backspace() {
@@ -210,6 +227,12 @@ impl WindowLike for Terminal {
//kills and running_process is now None
let _ = self.running_process.take().unwrap().kill();
self.mode = Mode::Input;
if self.process_current_line.len() > 0 {
let append_line = strip_ansi_escape_codes(bytes_to_string(self.process_current_line.clone()));
self.output += &append_line;
self.lines.push(append_line);
self.process_current_line = Vec::new();
}
WindowMessageResponse::JustRedraw
} else if self.mode == Mode::Input && (key_press.key == 'p' || key_press.key == 'n') {
//only the last command is saved unlike other terminals. good enough for me
@@ -231,6 +254,7 @@ impl WindowLike for Terminal {
},
WindowMessage::Shortcut(shortcut) => {
match shortcut {
ShortcutType::ClipboardCopy => WindowMessageResponse::Request(WindowManagerRequest::ClipboardCopy(self.output.clone())),
ShortcutType::ClipboardPaste(copy_string) => {
if self.mode == Mode::Input || self.mode == Mode::Stdin {
if self.mode == Mode::Input {
@@ -381,8 +405,7 @@ impl Terminal {
//must_add_current_line will be false
"$ ".to_string() + &self.current_input + ""
} else {
let pcl_len = self.process_current_line.len();
strip_ansi_escape_codes(String::from_utf8(self.process_current_line.clone()).unwrap_or("?".repeat(pcl_len))) + &self.current_stdin_input.clone() + ""
strip_ansi_escape_codes(bytes_to_string(self.process_current_line.clone()) + &self.current_stdin_input.clone() + "")
}
} else {
self.lines[line_num].clone()