views:

1104

answers:

2

Hello im using curses to develop a small console application.

I have a main loop section wich waits for user input, it uses the getstr function, of course this waits for the user to press enter.

I would like to capture the up and down and tab keypresses. I suppose this can't be done with getstr.

Anyone have any idea how to do this?

EDIT: i've tried using STDIN.getc wich blocks the application from running, and getch doesnt catch the arrow keys

EDIT #2 : im trying this code on windows. It seems that Curses.getch works for linux, but on windows i get no key sent for the up arrow.

+3  A: 

You need to set the "cbreak" mode of the tty so that you get keypresses immediately. If you don't do this, the Unix terminal-handling system will buffer the input until a newline is received (i.e., the user hits ENTER), and the input will all be handed to the process at that point.

This isn't actually Ruby- or even curses-specific; this is the way all applications work that run through a Unix tty.

Try using the curses library cbreak() function to turn on this mode. Don't forget to call nocbreak() to turn it off before you exit!

For reading a single character, STDIN.getc will return a Fixnum of the ASCII code of the character. Quite possibly you'll find STDIN.read(1) to be more convenient, since it returns a one-character string of the next character.

However, you'll find that the "up/down" keys,if by that you mean the arrow keys, are actually a sequence of characters. On most ANSI-like terminal emulators these days (such as xterm), the up arrow will be "\e[A" (that \e is an escape character) for example. There are termcap (terminal capability) databases to deal with this sort of thing, and you can access them through curses, but intially you may find it easiest just to experiment with interpreting these directly; you're not very likely to run into a terminal using anything other than ANSI codes these days.

Curt Sampson
thx for the answer im going to try that now, btw can you tell me what crmode function does?
Nuno Furtado
I'd not heard of crmode and nocrmode, but according to http://redmine.ruby-lang.org/issues/show/916 , they're just aliases for cbreak and nocbreak (now that the bug is fixed).
Curt Sampson
then using crmode or cbrak would be the same thing?!.
Nuno Furtado
For some reason when i use STDIN.getc my ruby program wont run, just sits idly there and wont start the application
Nuno Furtado
A: 

you want getch rather than getstr. also see curt sampson's comment about the arrow keys not being a single character.

Martin DeMello
getch doesnt catch the arrows, only the TAB
Nuno Furtado
Does it catch an ESC when you press an arrow? If so, you're probably not reading all three characters that get sent when you press an arrow key.
Curt Sampson
It doesn't catch the arrows, no value is sent on the input
Nuno Furtado
this worked for me, under linux: require 'curses' while true puts Curses.getch end
Martin DeMello
(okay, looks like comments don't format code at all. you get the general idea though)
Martin DeMello
I haven't been able to test your solution , my system wacked it self up the last few days. Note that im running windows and im using the cmd prompt
Nuno Furtado
I've just tested your code in windows and the up arrows dont work. If i try using the num pad with numlock off it doesn't work eiter. No key gets sent over.
Nuno Furtado
okay, i guess it only works under linux, then :(
Martin DeMello