为ANSI转义序列构建一个非常简单的包装器

时间:2014-02-11 20:09:58

标签: ruby macos terminal ansi-escape

也许一项任务无法完成。曾几何时,我在DOS窗口中编写了一个用于文本着色的Ruby模块SimpleDialog。它是通过与Windows API交谈来实现的。现在我想让它适用于Mac OS,甚至适用于整个unix世界。好的,只是终端和xterm将满足我当前的需求。 ANSI转义序列似乎是适合这项工作的武器。但是使用它们我不能总是像我想的那样处理事情。以下是我尝试实现的功能:

def clear_screen
  print "\e[H\e[2J\ec"
  color( ... old colors stored in an instance variable ... )
end

"\e[H\e[2J"部分与clear命令相同(这就是我发现此序列的方式[经过一些实验后第二天编辑:"\e[2J"不会删除任何发送的文字< em>在 "\e[H"序列之前,即使它在屏幕上可见])。终端和xterm仅清除屏幕的可见部分 [问题1] "\ec"部分对终端没有意义,但这次xterm确实成功清除了整个屏幕缓冲区。在这样做时,它响铃 [问题2] ,而终端保持沉默。由于"\ec"序列重置颜色,因此必须再次恢复最后的设置。完全不是很优雅。从命令行提交的clear命令通常会清除xterm的整个屏幕缓冲区。但是,它不能通过从Ruby发送"\e[H\e[2J"来消除我尝试清除屏幕所留下的部分。

def color( ... )
  ... too big to show here ...
end

color方法工作得很好,只有一个令人失望。在Windows中,我可以更改矩形的颜色,而无需修改已放置在其中的文本。我看不出如何通过ANSI转义序列 [问题3] 来做到这一点。作为一种解决方法,我可以记住所涉及的文本,然后将其恢复。而这个让我很困惑:"\e[6n"(报告光标位置)的响应被打印到屏幕上,最后几个 命令提示符后重复的字符。它可以被Ruby [问题4] 拦截吗?

其他方法是小菜一碟:

def shrink_window # to its original size
  print "\e[9;0t"
end

def stretch_window # to the maximum size that fits on the screen
  print "\e[9;1t"
end

def title(title = nil)
  print "\e]2;#{title}\a"
end

def write(... text containing human-friendly color codes ...)
  ... trivial ...
end

MS-Windows允许我获取当前的窗口标题,但是我没有看到真正的用途(当title参数是write时,xterm根本不听一个空字符串,顺便说一句。 color方法使用{{1}}方法。这里没问题。所以,最终要克服四个障碍。还是和谁一起生活?

1 个答案:

答案 0 :(得分:0)

如果您需要有关所有这些Mac OS和Unix终端UI问题的帮助,请尝试使用curses / ncurses库,通过Curses gem

由于您已经有了一个可用的Windows解决方案,因此您可以创建两个驱动对话框的类。我建议这样做是因为Windows上存在的curses库并不总是可靠或易于安装(see this question and its answers用于解决该问题的示例)。保持你的DOS实现,然后创建一个使用curses / ncurses的替代。然后,您的代码可以根据操作系统或基于是否存在正在运行的curses / ncurses库来选择要使用的实现。当然,这条路径也简化了以后添加更多用户界面的方法。