Simplifying and cleaning
[iomenu.git] / input.c
blobca996a7cda0d16d7d8a6ed0717ae84b70bdfc9e4
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 void
14 input_get(Buffer *buffer, int tty_fd, Opt *opt)
16 FILE *tty_fp = fopen("/dev/tty", "r");
18 /* receive one character at a time from the terminal */
19 struct termios termio_old = set_terminal(tty_fd);
21 /* get input char by char from the keyboard. */
22 while (input_key(fgetc(tty_fp), buffer, opt))
23 draw_screen(buffer, tty_fd, opt);
25 /* resets the terminal to the previous state. */
26 tcsetattr(tty_fd, TCSANOW, &termio_old);
28 fclose(tty_fp);
32 * Perform action associated with key
34 int
35 input_key(char key, Buffer *buffer, Opt *opt)
37 if (key == opt->validate_key) {
38 action_print_selection(buffer, opt);
39 return FALSE;
42 switch (key) {
44 case CONTROL('C'):
45 draw_clear(opt->lines);
46 return FALSE;
48 case CONTROL('U'):
49 buffer->input[0] = '\0';
50 buffer->current = buffer->first;
51 filter_lines(buffer, opt);
52 action_jump(buffer, ANY, opt);
53 break;
55 case CONTROL('W'):
56 action_remove_word_input(buffer);
57 filter_lines(buffer, opt);
58 break;
60 case 127:
61 case CONTROL('H'): /* backspace */
62 buffer->input[strlen(buffer->input) - 1] = '\0';
63 filter_lines(buffer, opt);
65 action_jump(buffer, ANY, opt);
66 break;
68 case CONTROL('N'):
69 action_jump(buffer, NEXT, opt);
70 break;
72 case CONTROL('P'):
73 action_jump(buffer, PREV, opt);
74 break;
76 case CONTROL('I'): /* tab */
77 strcpy(buffer->input, buffer->current->content);
78 filter_lines(buffer, opt);
79 break;
81 case CONTROL('M'):
82 case CONTROL('J'): /* enter */
83 action_print_selection(buffer, opt);
84 return FALSE;
86 default:
87 action_add_character(buffer, key, opt);
90 return TRUE;
94 * Set the current line to the next/previous/closest matching line.
96 void
97 action_jump(Buffer *buffer, int direction, Opt *opt)
99 Line * line = buffer->current;
101 if (direction == ANY && !buffer->current->matches) {
102 line = matching_next(buffer->current);
103 line = matching_prev(buffer->current);
104 } else if (direction == NEXT) {
105 line = matching_next(line);
106 } else if (direction == PREV) {
107 line = matching_prev(line);
110 buffer->current = line ? line : buffer->current;
112 if (opt->print_numbers)
113 action_print_selection(buffer, opt);
117 * Send the selection to stdout.
119 void
120 action_print_selection(Buffer *buffer, Opt *opt)
122 fputs("\r\033[K", stderr);
124 if (opt->print_numbers) {
125 printf("%d\n", buffer->current->number);
126 } else {
127 if (opt->complete) {
128 puts(buffer->input);
129 } else {
130 puts(buffer->current->content);
136 * Remove the last word from the buffer's input
138 void
139 action_remove_word_input(Buffer *buffer)
141 size_t length = strlen(buffer->input) - 1;
142 int i;
144 for (i = length; i >= 0 && isspace(buffer->input[i]); i--)
145 buffer->input[i] = '\0';
147 length = strlen(buffer->input) - 1;
148 for (i = length; i >= 0 && !isspace(buffer->input[i]); i--)
149 buffer->input[i] = '\0';
153 * Add a character to the buffer input and filter lines again.
155 void
156 action_add_character(Buffer *buffer, char key, Opt *opt)
158 size_t length = strlen(buffer->input);
160 if (isprint(key)) {
161 buffer->input[length] = key;
162 buffer->input[length + 1] = '\0';
165 filter_lines(buffer, opt);
167 action_jump(buffer, ANY, opt);