flèches, backspace, insertion fonctionnent

This commit is contained in:
Justine
2022-12-28 12:39:43 +01:00
parent e9d9db1f08
commit 4581d4f0f6
2 changed files with 96 additions and 38 deletions

View File

@ -8,7 +8,6 @@ pub mod shell {
use std::env;
use std::str;
use std::process::Stdio;
use std::num::Wrapping;
use users::{get_user_by_uid, get_current_uid};
use termion::event::Key;
use termion::input::TermRead;
@ -105,10 +104,7 @@ pub mod shell {
return resultat;
}
fn build_prompt(curr_number: &i32) -> (String, usize) {
let mut length: usize = 9;
length += curr_number.to_string().len();
fn build_prompt(curr_number: &i32) -> String {
let user = String::from(
get_user_by_uid(get_current_uid())
@ -118,16 +114,12 @@ pub mod shell {
.unwrap()
);
length += user.chars().count();
let host = String::from(
gethostname::gethostname()
.to_str()
.unwrap()
);
length += host.chars().count();
let current_dir = String::from(
env::current_dir()
.unwrap()
@ -141,15 +133,13 @@ pub mod shell {
.unwrap()
);
length += dir_last.chars().count();
let prompt = String::from(format!("{}{}{}[{}@{} in {}]{} ",
color::Fg(color::LightBlack),
curr_number,
color::Fg(color::LightCyan),
user, host, dir_last,
color::Fg(color::Reset)));
return (prompt, length);
return prompt;
}
fn replace_signs(line: &String) -> String {
@ -206,6 +196,28 @@ pub mod shell {
return String::new();
}
fn get_cmd_curs_pos(command: &String) -> (usize, usize) {
let mut max_pos: usize = 0;
let mut current_pos: usize = 0;
for _c in command.graphemes(true) {
max_pos += 1;
current_pos += 1;
}
return (max_pos, current_pos);
}
fn clear_line(max_pos: &usize) {
//clears currently written command from the screen
//...NOT from the variable !
let mut stdout = stdout().into_raw_mode().unwrap();
for i in 0..*max_pos {
write!(stdout, "{}", cursor::Left(1));
write!(stdout, "\x1b[K").unwrap();
}
}
pub fn run_raw() {
@ -216,7 +228,11 @@ pub mod shell {
//Used in conjunction with Up arrow to go back in history
//Resetted by pressing Enter
let mut current_number = get_curr_history_number();
let (mut prompt, mut pr_len) = build_prompt(&current_number);
let mut prompt = build_prompt(&current_number);
//Used to track the location of the cursor inside the command
let mut current_pos: usize = 0;
let mut max_pos: usize = 0;
//Initialize
write!(stdout, "\r\n SquiShell (sqish)--- \r\n{}", prompt);
@ -235,7 +251,9 @@ pub mod shell {
Key::Char('\n') => {
current_number = get_curr_history_number();
(prompt, pr_len) = build_prompt(&current_number);
prompt = build_prompt(&current_number);
current_pos = 0;
max_pos = 0;
if (mycommand != String::from("\n")) && (mycommand != String::from("exit")) {
let comm = replace_signs(&mycommand);
let res = handle_input(&comm);
@ -245,7 +263,7 @@ pub mod shell {
write!(stdout, "\r\n{}", line);
}
current_number = get_curr_history_number();
(prompt, pr_len) = build_prompt(&current_number);
prompt = build_prompt(&current_number);
write!(stdout, "{}", prompt).unwrap();
stdout.flush();
} else if mycommand == String::from("exit") {
@ -262,21 +280,63 @@ pub mod shell {
break;
},
Key::Ctrl('c') => {
continue;
},
Key::Ctrl('t') => {
clear_line(&max_pos);
max_pos = 0;
current_pos = 0;
mycommand.clear();
},
Key::Ctrl('a') => {
write!(stdout, "{}", cursor::Left(current_pos as u16));
current_pos = 0;
},
Key::Ctrl('e') => {
let chars_left = max_pos - current_pos;
write!(stdout, "{}", cursor::Right(chars_left as u16));
current_pos = max_pos;
},
Key::Char(c) => {
mycommand.push(c);
write!(stdout, "{}", c).unwrap();
//if at the end of the command...
if current_pos == max_pos {
mycommand.push(c);
current_pos += 1;
max_pos += 1;
write!(stdout, "{}", c).unwrap();
} else if current_pos < max_pos {
//Inserting a char inside the command...
write!(stdout, "{}", cursor::Save);
mycommand.insert(current_pos, c);
let command_piece = &mycommand[current_pos..];
write!(stdout, "{}", command_piece);
stdout.flush();
write!(stdout, "{}", cursor::Restore);
write!(stdout, "{}", cursor::Right(1));
max_pos += 1;
}
},
Key::Backspace => {
match mycommand.pop() {
Some(_) => {},
None => continue,
if current_pos > 0 {
max_pos -= 1;
current_pos -= 1;
mycommand.remove(current_pos);
write!(stdout, "{}", cursor::Left(1));
//Delete the end
write!(stdout, "\x1b[K").unwrap();
write!(stdout, "{}", cursor::Save);
clear_line(&max_pos);
write!(stdout, "{}", mycommand);
write!(stdout, "{}", cursor::Restore);
stdout.flush();
}
//Move cursor left
write!(stdout, "\x1b[D").unwrap();
//Delete one character there
write!(stdout, "\x1b[K").unwrap();
stdout.flush();
},
Key::Up => {
@ -287,6 +347,7 @@ pub mod shell {
None => continue
};
mycommand = lastcmd.trim().to_string();
(max_pos, current_pos) = get_cmd_curs_pos(&mycommand);
//let prompt = build_prompt();
write!(stdout, "{}", mycommand);
},
@ -299,21 +360,24 @@ pub mod shell {
None => continue
};
mycommand = lastcmd.trim().to_string();
(max_pos, current_pos) = get_cmd_curs_pos(&mycommand);
//let prompt = build_prompt();
write!(stdout, "{}", mycommand);
},
Key::Left => {
//La taille du prompt est incorrecte à cause des couleurs !
let curs_pos = stdout.cursor_pos().unwrap().0;
if usize::from(curs_pos) > pr_len {
if current_pos > 0 {
current_pos -= 1;
write!(stdout, "{}", cursor::Left(1));
stdout.flush();
}
}
},
Key::Right => {
print!("{}", cursor::Right(1));
if current_pos < max_pos {
print!("{}", cursor::Right(1));
current_pos += 1;
}
}
_ => (),