如何处理文件中的 ansi 转义序列?

问题描述 投票:0回答:1

我正在从头开始编写自己的 shell(

shark
- shell of ark)。 Ark 只是我名字的缩写。

大多数事情都运转良好,例如箭头/历史记录/命令执行,使用 VTIME 和 VMIN 输入缓冲区超时来处理 ascii esc 序列。

大多数时候我使用一个简单的硬编码提示,只是为了有一个,但带有颜色:

&tty.stdout.write(b"\x1b[1;32m[ shark ]\x1b[0m $");

这效果很好,但我想从 rc 文件中获取我的环境,

.sharkrc

在这个文件中我有简单的代码:

PS1='\x1b[1;32m[ shark ]\x1b[0m $ '

在 shell 开始时,读取并解析 rc 文件,然后提示符如下所示:

\x1b[1;32m[ shark ]\x1b[0m $

没有颜色,我知道问题实际上是什么:它是一个纯字符串,并且将打印为字符串,即使它是:

prompt.as_bytes()

没有

\x1b[..
序列,只有字符
\
然后
x
然后
1
然后
b
等等。

但问题是,我想从头开始执行此操作,因此我需要一些帮助,以在字符串来自文件时处理 ansi esc 代码。

我的最后一个想法是使用正则表达式并从字符串中查找所有 ansi 代码,然后单独编写。

但是有没有更简单的方法呢?

rust escaping ansi-escape
1个回答
0
投票

我自己解决了,代码还是有点乱,但是是通过尝试和错误。现在它可以工作了,我知道如何处理 ANSI EscCodes。

这里是代码:

pub fn parse_from_str( text: &str, tty: &Terminal ) {

    let mut ansi_code    = false;
    let mut ansi_blk     : Vec<char> = Vec::new();  
    let mut non_ansi_blk : Vec<char> = Vec::new();

    let ansi_scan : [char; 4 ] = [ '\\', 'x', 'b', 'm' ];

    for (index, byte) in text.chars().enumerate() {

        if byte == '\\' {
            ansi_code = true;
            //println!("\rfound \\");
            if !non_ansi_blk.is_empty() {
                write!(&tty.stdout, "{}", non_ansi_blk.iter().collect::<String>());
                non_ansi_blk.clear();
            }

        } else if ansi_code == true && !ansi_scan.contains(&byte)  {

            if text.as_bytes()[index - 1] == b'x' { continue; }

            //println!("\rPush ANSI: {}", byte);
            ansi_blk.push(byte);
        
        } else if ansi_code == true && byte == 'm' {
            ansi_code = false;
        
            write!(&tty.stdout, "\x1b{}m", ansi_blk.iter().collect::<String>());
            ansi_blk.clear();

        } else if ansi_code == false  {
            //println!("\rPush non ANSI: {}", byte);
            non_ansi_blk.push(byte);
        }
    }

    if !non_ansi_blk.is_empty() {
        write!(&tty.stdout, "{}", non_ansi_blk.iter().collect::<String>());
        non_ansi_blk.clear();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.