简体   繁体   中英

Building a very simple wrapper for ANSI escape sequences

Maybe a mission impossible. Once upon a time I wrote a Ruby module SimpleDialog for text coloring in DOS windows. It does so by talking to the Windows APIs. Now I want to make it suitable for Mac OS as well, or even for the entire unix universe. Okay, just Terminal and xterm would satisfy my needs for the moment. ANSI escape sequences seem to be the appropriate weapons for the job. But using them I cannot always handle things as I would like to. Here is the functionality I try to realize:

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

The "\\e[H\\e[2J" part is the same as the clear command (that's how I've found this sequence [edit next day after some experiments: "\\e[2J" does not erase any text sent before the "\\e[H" sequence, even when it's visible on the screen]). Terminal and xterm only clear the visible part of the screen [issue 1] . The "\\ec" part doesn't make sense for Terminal anymore, but this time xterm does succeed to clear the entire screen buffer. At doing so, it rings the bell [issue 2] , while Terminal keeps silent. Since the "\\ec" sequence resets the colors, the last settings have to be restored again. Not very elegant, altogether. The clear command submitted from the command line normally clears the entire screen buffer of xterm. However, it cannot wipe out the part that's left by my attempt to clear the screen by just sending "\\e[H\\e[2J" from Ruby.

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

The color method works almost fine, there's only one disappointment. In Windows, I can change the color of a rectangle without modifying the text that is already placed within it. I see no way how to do this by ANSI escape sequences [issue 3] . As a workaround I could memorize the text involved and restore it afterwards, of course. And this one is really puzzling me: the respons to "\\e[6n" (report cursor position) is printed to the screen, with the last few characters repeated after the command prompt. Can it be intercepted by Ruby [issue 4] ?

The other methods are a piece of cake:

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 allows me to get the current window title too, but I don't see real use for that (xterm doesn't listen at all when the title argument is an empty string, btw). The write method makes use of the color method. No problems here. So, in the end, four obstacles to overcome. Or to live with?

If you want help with all of these Mac OS and Unix terminal UI issues, try using the curses/ncurses libraries, through the Curses gem .

Since you already have a working Windows solution for this, you can create two classes that drive your dialog boxes. I suggest this because the presence of a curses library on Windows isn't always reliable or easy to install ( see this question and its answers for examples of that problem in action). Keep your DOS implementation, then make an alternate that uses curses/ncurses. Then your code can chose which implementation to go with based on operating system or based on whether a working curses/ncurses library exists. Naturally, this path also simplifies adding even more methods of user interface later, too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM