【问题标题】:Colorized output breaks linewrapping with readline彩色输出用 readline 打破换行
【发布时间】:2012-02-07 01:31:27
【问题描述】:

我正在使用 Ruby 中的 readline 为一些输出着色,但我没有任何运气让换行正常工作。例如:

"\e[01;32mThis prompt is green and bold\e[00m > "

期望的结果是:

This prompt is green and bold > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

我实际得到的是:

aaaaaaaaaaa is green and bold > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

如果我删除颜色代码,换行将正常工作。我知道使用 bash,如果颜色代码被错误地终止,就会发生这种情况,但我已经尝试了我能想到的一切,包括一些不同的 gem,并且行为是相同的。它也发生在具有不同版本 Readline 的多个系统上。这个特定的项目使用 rb-readline 而不是 C readline

【问题讨论】:

  • 您是否尝试过使用rubygems.org/gems/colored 为您的输出着色?
  • 是的,我尝试了那个以及着色。输出工作正常,但在使用 readline 提示符时,它会中断换行。

标签: ruby readline


【解决方案1】:

好的,sunkencity 得到了复选标记,因为我最终使用了他的大部分解决方案,但我不得不修改如下:

# encoding: utf-8
class String
    def console_red;          colorize(self, "\001\e[1m\e[31m\002");  end
    def console_dark_red;     colorize(self, "\001\e[31m\002");       end
    def console_green;        colorize(self, "\001\e[1m\e[32m\002");  end
    def console_dark_green;   colorize(self, "\001\e[32m\002");       end
    def console_yellow;       colorize(self, "\001\e[1m\e[33m\002");  end
    def console_dark_yellow;  colorize(self, "\001\e[33m\002");       end
    def console_blue;         colorize(self, "\001\e[1m\e[34m\002");  end
    def console_dark_blue;    colorize(self, "\001\e[34m\002");       end
    def console_purple;       colorize(self, "\001\e[1m\e[35m\002");  end

    def console_def;          colorize(self, "\001\e[1m\002");  end
    def console_bold;         colorize(self, "\001\e[1m\002");  end
    def console_blink;        colorize(self, "\001\e[5m\002");  end

    def colorize(text, color_code)  "#{color_code}#{text}\001\e[0m\002" end
end

每个序列都需要包含在 \001..\002 中,以便 Readline 知道忽略非打印字符。

【讨论】:

【解决方案2】:

这个问题不是 ruby​​ 特有的——它也发生在 bash 中。如果你放入一个 bash shell

PS1="\e[01;32mThis prompt is green and bold\e[00m > "

您将看到与上述相同的结果。但是如果你把

PS1="\[\e[01;32m\]This prompt is green and bold\[\e[00m\] > "

你会得到你想要的结果。

【讨论】:

  • 顺便说一句,如果您对它的工作原理感到好奇:它看起来像 \[blah\] 告诉 bash/readline/whatever ,为了估计行中的字符数,您应该忽略 \[ 和 \] 之间的任何内容。对于给定的终端,一行中的字符数被猜测/计算/猜测,并且只有在填充了所有未忽略的字符后才会下推到下一行。
  • 我同意这应该是修复,但是当我这样做时,我的输出变成这样:“[]This prompt is green and bold[] >”并且换行仍然是问题。这可以通过这里的简单测试脚本来证明:gist.github.com/1622119
  • "bash 特有的 [ 和 ] 实际上被翻译成 \001 和 \002..." --answer from SuperUser.
【解决方案3】:

当我需要为控制台着色字符串时,我总是抛出这个字符串扩展。您的代码中的问题似乎是终止符,应该只有一个零 "\e[0m"。

# encoding: utf-8
class String
    def console_red;          colorize(self, "\e[1m\e[31m");  end
    def console_dark_red;     colorize(self, "\e[31m");       end
    def console_green;        colorize(self, "\e[1m\e[32m");  end
    def console_dark_green;   colorize(self, "\e[32m");       end
    def console_yellow;       colorize(self, "\e[1m\e[33m");  end
    def console_dark_yellow;  colorize(self, "\e[33m");       end
    def console_blue;         colorize(self, "\e[1m\e[34m");  end
    def console_dark_blue;    colorize(self, "\e[34m");       end
    def console_purple;       colorize(self, "\e[1m\e[35m");  end

    def console_def;          colorize(self, "\e[1m");  end
    def console_bold;         colorize(self, "\e[1m");  end
    def console_blink;        colorize(self, "\e[5m");  end

    def colorize(text, color_code)  "#{color_code}#{text}\e[0m" end
end

puts "foo\nbar".console_dark_red

【讨论】:

  • 谢谢。 2 0 或 1,没关系,它做同样的事情。对我来说,这看起来像是 readline 中的一个错误。
  • 嗯,你开头有"\e[01;32m" 我有"\e[1m\e[32m"。
  • 签出这个:hintsforums.macworld.com/showthread.php?t=17068 显然你可以添加额外的转义,让 shell 在计算行长时忽略颜色代码。
  • sunkencity:两种格式都有效。无论哪种方式,无论我使用什么代码/代码组合,我都会遇到换行问题。至于那篇文章,忽略括号一定是一件很糟糕的事情。我用这个试过了,它不起作用,它所做的只是打印出括号。 Fwiw,我正在用 Ruby 编写一个 shell,所以这将允许在 shell 中显示彩色提示。
猜你喜欢
  • 2015-09-28
  • 2023-03-08
  • 2020-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-20
  • 2011-11-05
相关资源
最近更新 更多