Install the man page in "$PREFIX/man"
[iomenu.git] / input.c
blobd6e6ab604c47ac922b16323008a6184a0e9c2554
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);
33 * Perform action associated with key
35 int
36 input_key(char key, Buffer *buffer, Opt *opt)
38 if (key == opt->validate_key) {
39 action_print_selection(buffer, opt);
40 return FALSE;
43 switch (key) {
45 case CONTROL('C'):
46 draw_clear(opt->lines);
47 return FALSE;
49 case CONTROL('U'):
50 buffer->input[0] = '\0';
51 buffer->current = buffer->first;
52 filter_lines(buffer, opt);
53 action_jump(buffer, NEXT);
54 action_jump(buffer, PREV);
55 break;
57 case CONTROL('W'):
58 action_remove_word_input(buffer);
59 filter_lines(buffer, opt);
60 break;
62 case 127:
63 case CONTROL('H'): /* backspace */
64 buffer->input[strlen(buffer->input) - 1] = '\0';
65 filter_lines(buffer, opt);
66 action_jump(buffer, ANY);
67 break;
69 case CONTROL('N'):
70 action_jump(buffer, NEXT);
71 break;
73 case CONTROL('P'):
74 action_jump(buffer, PREV);
75 break;
77 case CONTROL('I'): /* tab */
78 strcpy(buffer->input, buffer->current->content);
79 filter_lines(buffer, opt);
80 break;
82 case CONTROL('M'):
83 case CONTROL('J'): /* enter */
84 action_print_selection(buffer, opt);
85 return FALSE;
87 default:
88 action_add_character(buffer, key, opt);
91 return TRUE;
96 * Set the current line to next/previous/any matching line.
98 void
99 action_jump(Buffer *buffer, int direction)
101 Line * line = buffer->current;
103 if (direction == ANY && !buffer->current->matches) {
104 line = matching_next(buffer->current);
105 line = line ? line : matching_prev(buffer->current);
106 } else if (direction == NEXT) {
107 line = matching_next(line);
108 } else if (direction == PREV) {
109 line = matching_prev(line);
112 buffer->current = line && !line->header ? line : buffer->current;
117 * Send the selection to stdout.
119 void
120 action_print_selection(Buffer *buffer, Opt *opt)
122 fputs("\r\033[K", stderr);
124 if (buffer->matching > 0 || opt->complete) {
125 if (opt->print_number) {
126 printf("%d\n", buffer->current->number);
127 } else {
128 if (opt->complete) {
129 puts(buffer->input);
130 } else {
131 puts(buffer->current->content);
139 * Remove the last word from the buffer's input
141 void
142 action_remove_word_input(Buffer *buffer)
144 size_t length = strlen(buffer->input) - 1;
145 int i;
147 for (i = length; i >= 0 && isspace(buffer->input[i]); i--)
148 buffer->input[i] = '\0';
150 length = strlen(buffer->input) - 1;
151 for (i = length; i >= 0 && !isspace(buffer->input[i]); i--)
152 buffer->input[i] = '\0';
157 * Add a character to the buffer input and filter lines again.
159 void
160 action_add_character(Buffer *buffer, char key, Opt *opt)
162 size_t length = strlen(buffer->input);
164 if (isprint(key)) {
165 buffer->input[length] = key;
166 buffer->input[length + 1] = '\0';
169 filter_lines(buffer, opt);
171 action_jump(buffer, ANY);