kkawakam / rustyline

Readline Implementation in Rust
https://crates.io/crates/rustyline/
MIT License
1.52k stars 175 forks source link

ExternalPrinter can't handle ASCII control character #692

Open yalikes opened 1 year ago

yalikes commented 1 year ago

I am using rustyline version 11.0.0

I want use ExternalPrinter to print string that contains some ASCII control character if I write the following code, it output a single character t. this make since because \x08 is a backspace.

fn main(){
    let mut rl = rustyline::DefaultEditor::new().unwrap();
    let mut printer = rl.create_external_printer().unwrap();
    printer.print("test\x08\x08\x08".to_owned()).unwrap();
}

but if I instead using the following code, ExternalPrintetr output all four character test. and I expect it output just a t

fn main(){
    let mut rl = rustyline::DefaultEditor::new().unwrap();
    let mut printer = rl.create_external_printer().unwrap();
    thread::spawn(move || {
        printer.print("test\x08\x08\x08".to_owned()).unwrap();
    });
    let line = rl.readline(">>").unwrap();
}

why ASCII control character didn't work in ExternalPrinter that I use it in another thread? and how can I make ExternalPrinter handle ASCII control character?

gwenn commented 1 year ago

Raw mode is activated only while reading / readline(">>") is called. And deactivated when readline(">>") returns. And some escape sequences are interpreted only in raw mode. I guess replxx behaves the same.

gwenn commented 1 year ago

Same behavior with linefeed:

diff --git a/examples/demo.rs b/examples/demo.rs
index a7ad87c..4754cac 100644
--- a/examples/demo.rs
+++ b/examples/demo.rs
@@ -90,8 +90,8 @@ fn main() -> io::Result<()> {
                     let mut rng = thread_rng();
                     let mut i = 0usize;
                     loop {
-                        writeln!(iface, "[#{}] Concurrent message #{}",
-                            my_thread_id, i).unwrap();
+                        writeln!(iface, "test\x08\x08\x08",
+                            ).unwrap();
                         let wait_ms = rng.gen_range(1, 500);
                         thread::sleep(Duration::from_millis(wait_ms));
                         i += 1;
linefeed % cargo run --example demo
demo> spawn-log-thread
Spawning log thread #0
test
test
test
test
test
demo>
Goodbye.

But if I add one character like "test\x08\x08\x08!" I get "t!st" with both rustyline and replxx...

yalikes commented 1 year ago

do we have any plan to add the feature that enable ASCII control character in external printer? or maybe I just misunderstanding the usage of external printer. because it by design to print plain text info...

gwenn commented 1 year ago

To print plain or styled text

michabs commented 1 year ago

tested with this bash script:

!/bin/bash

input="./test.txt" while IFS= read -r line do echo -e "$line" done < "$input"

test.txt is just one line: test\b\b\b!

yield (as rustyline): t!st