Rust termion crate:如何清除单个字符?

3

我正在尝试使用 termion 库实现一个简单的文本编辑器。当用户按下Backspace键时,我想删除一个字符,但是我无法弄清楚如何实现。

这个库似乎只提供了这些选项

AfterCursor     Clear everything after the cursor.
All             Clear the entire screen.
BeforeCursor    Clear everything before the cursor.
CurrentLine     Clear the current line.
UntilNewline    Clear from cursor to newline.

这些选项都不太合适。UntilNewLine(直到换行) 算是比较适用的一个,除非用户将光标移动到左侧,在这种情况下它会删除超过一个字符(基本上是该行剩余的所有字符)。

我的当前代码:

fn main() {
    let stdin = io::stdin();
    let mut stdout = stdout().into_raw_mode().unwrap();

    write!(stdout, "{}{}", termion::clear::All, termion::cursor::Goto(1, 1));
    stdout.flush().unwrap();

    for c in stdin.keys() {
        match c.unwrap() {
            Key::Esc => break,
            Key::Left => {
                let (x, y) = stdout.cursor_pos().unwrap();
                write!(stdout, "{}", termion::cursor::Goto(x-1, y));
            },
            Key::Right => {
                let (x, y) = stdout.cursor_pos().unwrap();
                write!(stdout, "{}", termion::cursor::Goto(x+1, y));
            },
            Key::Up => {
                let (x, y) = stdout.cursor_pos().unwrap();
                write!(stdout, "{}", termion::cursor::Goto(x, y-1));
            },
            Key::Down => {
                let (x, y) = stdout.cursor_pos().unwrap();
                write!(stdout, "{}", termion::cursor::Goto(x, y+1));
            },
            Key::Backspace => {
                let (x, y) = stdout.cursor_pos().unwrap();
                write!(stdout, "{}{}", termion::cursor::Goto(x-1, y), termion::clear::UntilNewline );
            },
            Key::Char('\n') => { write!(stdout, "\r\n"); },
            Key::Char(x) => { write!(stdout, "{}", x); },
            _ => ()
        }
        stdout.flush().unwrap();
    }
}

我想我有一个双重问题:

  1. 如何解决这个特定的问题(清除单个字符)?
  2. 如果解决方案在文档中,我该如何找到它?我尝试搜索删除 / 回退 / 清除 - 但那没用。我在这里是否遇到了库的限制,还是有其他方法可以做到?

过去我是这样做的:https://github.com/peterjoel/inspector/blob/9d924e52862476b80fb143e6ef415e1f7878d7af/cli/src/console.rs#L299。也就是说,定义一个更抽象的模型,可以随意更新并在单独的步骤中呈现。 - Peter Hall
如果你想要实现更复杂的功能,比如多行选择或不同的编辑模式,你会发现这种方法更容易使用。 - Peter Hall
我没有尝试过tui,但它在termion的基础上提供了更多的抽象和功能。我猜它会做你想要的事情。 - Peter Hall
1个回答

3
为了删除单个字符,将光标定位到该字符之前,然后打印一个空格以覆盖该字符。

3
聪明!对于任何未来查看此代码的人,它是有效的:let (x, y) = stdout.cursor_pos().unwrap(); write!(stdout, "{}{}", " ", termion::cursor::Goto(x-1, y)); 感谢您的帮助。 - ilmoi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接