I'm trying to write a shell in Ruby, and to implement tab completion I am using the WinAPI function getch
to read in a character at a time from the user, checking for tabs.
The problem with this is the backspace key:
hello>
, the user can backspace the cursor on to the h
. I would like it to stop at the final space.(I know both of these behaviours are by design.)
My imagined solution to these problems involve controlling the cursor movement; I need to know where the cursor is, and be able to move it.
On Linux, I would use ANSI escape sequences, but these aren't supported by the Windows console.
I have looked into the WinAPI and tried to find functions that would let me do this, but all I could find was GetConsoleCursorInfo
function, which only returns the size and visibility of the cursor.
Examples would be appreciated, as I am hopeless at using the Win32API class for anything other than primitive functions.
Thanks.
You're probably better off using readline. It is included in the Ruby One-Click installer. A basic setup is:
require 'readline'
while line = Readline.readline('hello> ', true)
#do something with line
break if line == 'quit'
end
Already you'll have standard readline capabilities such as backspacing, Alt+backspace to delete a word, history, and tab completion. There's good documentation on how to customize it for your needs here.
If you don't have readline installed, you can get it and other external libraries here. You'll want the readline-4.3-2-mswin32 package. Copy the readline.dll file (located in the bin
directory) to your ruby\bin
directory. That should do it.
Although it isn't documented on the Ruby homepage, it looks as if you can also use readline 5, available here. Specifically, you need the binaries distribution. Copy readline5.dll (in the bin
directory) to your ruby\bin
directory, and rename it to readline.dll
.
Also, as a side note, don't be alarmed if require 'readline'
returns false when using irb, since it appears to pre-load it.