summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRory Dudley2024-09-12 15:27:08 -0600
committerRory Dudley2024-09-12 15:27:08 -0600
commitfd245ce1561fe5a6e71c5a359436e8ead01a977d (patch)
treeca7812478e9be2c64407707188f87061b4e38ca7
parent51fcf2efdaae8bdd5270cfe64de1522eadd1775f (diff)
downloaddwarvish-fd245ce1561fe5a6e71c5a359436e8ead01a977d.tar.gz
Fixed a bug introduced with termios
When at the prompt, ICANON and ECHO should be turned off, since all the output logic is handled via getline()/getchar(). However, they need to be turned back on (alongside ECHOE, which allows for backspace characters to work properly with ICANON), in case other programs need to get user input, their input will echo to the terminal.
-rw-r--r--src/main.rs14
1 files changed, 9 insertions, 5 deletions
diff --git a/src/main.rs b/src/main.rs
index 527fb8c..8cfd680 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -8,7 +8,7 @@ use poem::{read::Readable, recite::Reciteable, Poem};
mod compose;
use buffer::{getline, STDIN};
use compose::Environment;
-use termios::{tcsetattr, Termios, ECHO, ICANON, TCSANOW};
+use termios::{tcsetattr, Termios, ECHO, ECHOE, ICANON, TCSANOW};
/// Starts the main shell loop
///
@@ -33,16 +33,12 @@ fn repl(
) {
// Setup termios flags
let mut termios = Termios::from_fd(STDIN).unwrap();
- termios.c_lflag &= !(ICANON | ECHO);
// Initial path refresh on startup
env.bins = path::refresh();
// Main shell loop
loop {
- // Reset terminal using proper termios flags
- tcsetattr(STDIN, TCSANOW, &mut termios).unwrap();
-
// Clear the buffer
buffer.lock().unwrap().clear();
@@ -59,6 +55,10 @@ fn repl(
// At the prompt
*away.lock().unwrap() = false;
+ // Unset ICANON and ECHO before the prompt
+ termios.c_lflag &= !(ICANON | ECHO);
+ tcsetattr(STDIN, TCSANOW, &mut termios).unwrap();
+
// Wait for user input
let bytes = getline(buffer, pos);
@@ -78,6 +78,10 @@ fn repl(
continue;
}
+ // Set ICANON and ECHO for other programs after the prompt
+ termios.c_lflag |= ICANON | ECHO | ECHOE;
+ tcsetattr(STDIN, TCSANOW, &mut termios).unwrap();
+
// Not at the prompt
*away.lock().unwrap() = true;