Permitting file as argument
[iomenu.git] / input.c
blob61f8e5e92db6950a5ed9f284a5556e48831d03f1
1 #include <ctype.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <termios.h>
7 #include "main.h"
11 * Listen for the user input and call the appropriate functions.
13 int
14 input_get(Buffer *buffer, int tty_fd, Opt *opt)
16 FILE *tty_fp = fopen("/dev/tty", "r");
17 int exit_code;
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);
29 fclose(tty_fp);
31 return exit_code;
36 * Perform action associated with key
38 int
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);
45 return EXIT_SUCCESS;
48 switch (key) {
50 case CONTROL('C'):
51 draw_clear(opt->lines);
52 return EXIT_FAILURE;
54 case CONTROL('U'):
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);
60 break;
62 case CONTROL('W'):
63 action_remove_word_input(buffer);
64 filter_lines(buffer, 0);
65 break;
67 case 127:
68 case CONTROL('H'): /* backspace */
69 buffer->input[strlen(buffer->input) - 1] = '\0';
70 filter_lines(buffer, 0);
71 action_jump(buffer, 0);
72 break;
74 case CONTROL('N'):
75 action_jump(buffer, 1);
76 break;
78 case CONTROL('P'):
79 action_jump(buffer, -1);
80 break;
82 case CONTROL('I'): /* tab */
83 strcpy(buffer->input, buffer->current->content);
84 filter_lines(buffer, 1);
85 break;
87 case CONTROL('J'):
88 case CONTROL('M'): /* enter */
89 action_print_selection(buffer, 0, opt);
90 return EXIT_SUCCESS;
92 case CONTROL('@'): /* ctrl + space */
93 action_print_selection(buffer, 1, opt);
94 return EXIT_SUCCESS;
96 case CONTROL('['): /* escape */
97 switch (fgetc(tty_fp)) {
99 case 'O': /* arrow keys */
100 switch (fgetc(tty_fp)) {
102 case 'A': /* up */
103 action_jump(buffer, -1);
104 break;
106 case 'B': /* Down */
107 action_jump(buffer, 1);
108 break;
110 break;
112 case '[': /* page control */
113 key = fgetc(tty_fp);
114 switch(fgetc(tty_fp)) {
116 case '~':
117 switch (key) {
119 case '5': /* page up */
120 action_jump(buffer, -10);
121 break;
123 case '6': /* page down */
124 action_jump(buffer, 10);
125 break;
127 break;
129 break;
131 break;
133 default:
134 action_add_character(buffer, key);
137 return CONTINUE;
142 * Set the current line to next/previous/any matching line.
144 void
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
173 void
174 action_remove_word_input(Buffer *buffer)
176 size_t length = strlen(buffer->input) - 1;
177 int i;
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.
191 void
192 action_add_character(Buffer *buffer, char key)
194 size_t length = strlen(buffer->input);
196 if (isprint(key)) {
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.
210 void
211 action_print_selection(Buffer *buffer, int return_input, Opt *opt)
213 Line *line = NULL;
215 fputs("\r\033[K", stderr);
217 if (opt->print_header) {
218 for (line = buffer->current; line; line = line->prev) {
219 if (line->header) {
220 fputs(line->comment, stdout);
221 break;
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) {
232 puts(buffer->input);
234 } else if (buffer->matching > 0) {
235 puts(buffer->current->content);