views:

464

answers:

4

I'm trying to determine how the system prints characters to standard input -- that is, how it prints characters which the user can delete and which are considered input if the user hits "Enter."

I happen to be using C, but I would be very surprised if the solution were language-dependent.

Thanks for any insights! : D

+1  A: 

It uses readline library to handle the input and readline provides the history and the completion.

To actually implement completion, access to the keyboard input handling is needed. The completion must be able to modify the buffer used by it. After that it is just about looking at the current input and checking what completions is found. The actual completion logic can work in many ways.

iny
+2  A: 

As iny says, bash uses readline for its input. The source is available here, and there's a file called complete.c.

To answer your question, I don't think they're actually printed to standard input. Readline contains some kind of buffer for the contents of the line the user is editing, and completion prints into this. When the user presses enter, the contents of the buffer are sent to whatever program wanted to read a line, and in the case of bash, passed along into standard input. (Readline doesn't do this - other programs which use readline might simply store the value into a string for later use.)

Jefromi
Thanks, that makes sense!Thanks also to iny.
Zack
+2  A: 

Several people have pointed out that bash uses readline, which is true, but I think what you're really asking is how is it able to see what you've typed before you hit enter.

The answer is that ttys (ie: terminals) can be switched into "raw mode", where input processing of the terminal is disabled, and then you'll see every character as it comes in. This also disables automatic echoing of typed characters.

See this guide on Reading a single character from a file or a terminal for more info.

Laurence Gonsalves
Is the "raw mode" of ttys what permits a program to write the suggestion to the screen in such a way that when you hit "enter" it's included as though the user had typed it him or herself? If so, how does one get access to a tty for reading and writing? Is it a simple open('/dev/tty') type of call?
Zack
In raw mode the program sees the keystrokes even before the user hits enter. When you type a printable key (eg: letter, number symbol), the program echoes it back. When you press enter it's already been keeping track of what you typed, and it just "accepts" the buffer in response to the enter key.
Laurence Gonsalves
In "cooked mode", the terminal will instead echo everything you type, but doesn't send what you typed to the program until you hit enter. bash switches the tty back to cooked mode just before running other programs. You can get an idea of how cooked mode behaves differently from raw mode by running "sleep 300" and then typing while the sleep command is running. Note that you can type lines and even have *very* basic editing facilities (eg: backspace). Once you hit enter that line will be committed and when sleep command completes, bash will try to execute those lines (so be careful!).
Laurence Gonsalves
A: 

Here's a C snippet that implements tab completion via readline:

http://github.com/rupa/el

2morecnts