11 * Listen for the user input and call the appropriate functions.
14 input_get(Buffer
*buffer
, int tty_fd
, Opt
*opt
)
16 FILE *tty_fp
= fopen("/dev/tty", "r");
19 /* receive one character at a time from the terminal */
20 struct termios termio_old
= set_terminal(tty_fd
);
22 /* get input char by char from the keyboard. */
23 while ((exit_code
= input_key(tty_fp
, buffer
, opt
)) == CONTINUE
)
24 draw_screen(buffer
, tty_fd
, opt
);
26 /* resets the terminal to the previous state. */
27 tcsetattr(tty_fd
, TCSANOW
, &termio_old
);
36 * Perform action associated with key
39 input_key(FILE *tty_fp
, Buffer
*buffer
, Opt
*opt
)
41 char key
= fgetc(tty_fp
);
43 if (key
== opt
->validate_key
) {
44 action_print_selection(buffer
, 0, opt
->print_number
);
51 draw_clear(opt
->lines
);
55 buffer
->input
[0] = '\0';
56 buffer
->current
= buffer
->first
;
57 filter_lines(buffer
, 0);
58 action_jump(buffer
, 1);
59 action_jump(buffer
, -1);
63 action_remove_word_input(buffer
);
64 filter_lines(buffer
, 0);
68 case CONTROL('H'): /* backspace */
69 buffer
->input
[strlen(buffer
->input
) - 1] = '\0';
70 filter_lines(buffer
, 0);
71 action_jump(buffer
, 0);
75 action_jump(buffer
, 1);
79 action_jump(buffer
, -1);
82 case CONTROL('I'): /* tab */
83 strcpy(buffer
->input
, buffer
->current
->content
);
84 filter_lines(buffer
, 1);
88 case CONTROL('M'): /* enter */
89 action_print_selection(buffer
, 0, opt
->print_number
);
92 case CONTROL('@'): /* ctrl + space */
93 action_print_selection(buffer
, 1, opt
->print_number
);
96 case CONTROL('['): /* escape */
97 switch (fgetc(tty_fp
)) {
99 case 'O': /* arrow keys */
100 switch (fgetc(tty_fp
)) {
103 action_jump(buffer
, -1);
107 action_jump(buffer
, 1);
112 case '[': /* page control */
114 switch(fgetc(tty_fp
)) {
119 case '5': /* page up */
120 action_jump(buffer
, -10);
123 case '6': /* page down */
124 action_jump(buffer
, 10);
134 action_add_character(buffer
, key
);
142 * Set the current line to next/previous/any matching line.
145 action_jump(Buffer
*buffer
, int direction
)
147 Line
* line
= buffer
->current
;
148 Line
* result
= line
;
150 if (direction
== 0 && !buffer
->current
->matches
) {
151 line
= matching_next(buffer
->current
);
152 line
= line
? line
: matching_prev(buffer
->current
);
153 result
= line
? line
: result
;
156 for (; direction
< 0 && line
; direction
++) {
157 line
= matching_prev(line
);
158 result
= line
? line
: result
;
161 for (; direction
> 0 && line
; direction
--) {
162 line
= matching_next(line
);
163 result
= line
? line
: result
;
166 buffer
->current
= result
;
171 * Send the selection to stdout.
174 action_print_selection(Buffer
*buffer
, int return_input
, int print_number
)
176 fputs("\r\033[K", stderr
);
179 if (buffer
->matching
> 0)
180 printf("%d\n", buffer
->current
->number
);
182 } else if (return_input
) {
185 } else if (buffer
->matching
> 0) {
186 puts(buffer
->current
->content
);
192 * Remove the last word from the buffer's input
195 action_remove_word_input(Buffer
*buffer
)
197 size_t length
= strlen(buffer
->input
) - 1;
200 for (i
= length
; i
>= 0 && isspace(buffer
->input
[i
]); i
--)
201 buffer
->input
[i
] = '\0';
203 length
= strlen(buffer
->input
) - 1;
204 for (i
= length
; i
>= 0 && !isspace(buffer
->input
[i
]); i
--)
205 buffer
->input
[i
] = '\0';
210 * Add a character to the buffer input and filter lines again.
213 action_add_character(Buffer
*buffer
, char key
)
215 size_t length
= strlen(buffer
->input
);
218 buffer
->input
[length
] = key
;
219 buffer
->input
[length
+ 1] = '\0';
222 filter_lines(buffer
, 1);
224 action_jump(buffer
, 0);