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
);
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
);
92 case CONTROL('@'): /* ctrl + space */
93 action_print_selection(buffer
, 1, opt
);
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 * Remove the last word from the buffer's input
174 action_remove_word_input(Buffer
*buffer
)
176 size_t length
= strlen(buffer
->input
) - 1;
179 for (i
= length
; i
>= 0 && isspace(buffer
->input
[i
]); i
--)
180 buffer
->input
[i
] = '\0';
182 length
= strlen(buffer
->input
) - 1;
183 for (i
= length
; i
>= 0 && !isspace(buffer
->input
[i
]); i
--)
184 buffer
->input
[i
] = '\0';
189 * Add a character to the buffer input and filter lines again.
192 action_add_character(Buffer
*buffer
, char key
)
194 size_t length
= strlen(buffer
->input
);
197 buffer
->input
[length
] = key
;
198 buffer
->input
[length
+ 1] = '\0';
201 filter_lines(buffer
, 1);
203 action_jump(buffer
, 0);
208 * Send the selection to stdout.
211 action_print_selection(Buffer
*buffer
, int return_input
, Opt
*opt
)
215 fputs("\r\033[K", stderr
);
217 if (opt
->print_header
) {
218 for (line
= buffer
->current
; line
; line
= line
->prev
) {
220 fputs(line
->comment
, stdout
);
224 fputc((int) '\t', stdout
);
227 if (opt
->print_number
) {
228 if (buffer
->matching
> 0)
229 printf("%d\n", buffer
->current
->number
);
231 } else if (return_input
|| !buffer
->matching
) {
234 } else if (buffer
->matching
> 0) {
235 puts(buffer
->current
->content
);