From 042528db340d309e4266e0b9a12d64daba85290f Mon Sep 17 00:00:00 2001 From: josuah Date: Tue, 18 Oct 2016 22:27:04 -0400 Subject: [PATCH] Added keyboard handling --- README | 35 +++++++++++++++++++--------- complete | Bin 0 -> 17984 bytes complete.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++----------- complete.h | 1 + 4 files changed, 88 insertions(+), 25 deletions(-) create mode 100755 complete diff --git a/README b/README index 60a569e..2216517 100644 --- a/README +++ b/README @@ -1,9 +1,8 @@ - /\ /\ - ____ ____ ________ ____ / / ___ / /_ ___ - / ___\ / __ \ / __ __ \ / __ \ / /.'__ \ / ___\.'__ \ - / /__ / /_/ // / / / / // /_/ // // ____// / / ____/ - \____\ \____/ \/ \/ \// ____/ \/ \___\ \/ \___\ 2016-09-20 -=========================\/===================================================== + ,--. | | + | ,--. --.-. ---. | ,--. |-- ,--. + | | | | | | | | | |--' | |--' + `--' `--' ' ' ' |--' ' `--' ' `--' 2016-10-18 +---------------- | ------------------------------------------------------------- Filter lines form stdin to print to stdout using user keyboard input I will hopefully write this in ANSI C some day... At least I @@ -13,7 +12,7 @@ Filter lines form stdin to print to stdout using user keyboard input interfaces like those of vimperator. -OPTIONS / FEATURES 2016-09-19 +OPTIONS / FEATURES -------------------------------------------------------------------------------- Description of the features I will possibly implement. @@ -78,7 +77,7 @@ Description of the features I will possibly implement. sections. -KEYBINDINGS 2016-09-18 +KEYBINDINGS -------------------------------------------------------------------------------- Ctrl + I @@ -103,7 +102,7 @@ KEYBINDINGS 2016-09-18 Ctrl + U Deletes the entire input. -MATCHING 2016-09-19 +MATCHING -------------------------------------------------------------------------------- I like the lines order to be preserved while matching. This can @@ -118,7 +117,7 @@ MATCHING 2016-09-19 the beginning of input match in priority these displayed numbers. -INTERFACE 2016-09-18 +INTERFACE -------------------------------------------------------------------------------- Differences and similarity with vimperator input. @@ -142,7 +141,7 @@ Differences and similarity with vimperator input. have to wait find on ~ to find a file to select it. -USAGE 2016-09-18 +USAGE -------------------------------------------------------------------------------- Example that can replicate advanced vimperator completion features @@ -165,3 +164,17 @@ Example that can replicate advanced vimperator completion features commands), then according to the command, select second level input different for each command (like flags or 'empty'), and then, select a third level input (like filename)... + + +RESOURCES +-------------------------------------------------------------------------------- + + These resources were very conveninent while making this software. + Thank you to the respective authors, that taught me C by writing + some: + + - https://github.com/martanne/vis/blob/master/vis-menu.c + - https://github.com/charles-l/pep/blob/master/pep.c + - http://git.suckless.org/sandy/tree/sandy.c + + diff --git a/complete b/complete new file mode 100755 index 0000000000000000000000000000000000000000..ca971f56fea8dbf84808432f0d362d66270ef92e GIT binary patch literal 17984 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 WjivSajn}ta?T #include +#include #include +#include +#include #include "complete.h" #include "config.h" +#define CONTROL(ch) (ch ^ 0x40) + /* * Fill the buffer apropriately with the lines and headers */ Buffer * fill_buffer(char *separator) { - /* Fill buffer with string */ + /* fill buffer with string */ char s[MAX_LINE_SIZE]; Line *last = NULL; Buffer *buffer = malloc(sizeof(Buffer)); FILE *fp = fopen("complete.c", "r"); buffer->count = 0; - /* Read the file into a doubly linked list of lines. */ + if (! fp) { + die("Can not open file for reading."); + } + + /* read the file into a doubly linked list of lines. */ while (fgets(s, MAX_LINE_SIZE, fp)) { buffer->count++; @@ -27,7 +35,7 @@ fill_buffer(char *separator) last = add_line(buffer, buffer->count, s, separator, last); } - /* Set the buffer stats. */ + /* set the buffer stats. */ buffer->current = buffer->first; return buffer; @@ -42,17 +50,17 @@ parse_line(char *s, char *separator) { Line *line = malloc(sizeof(Line)); char *sep = strstr(s, separator); - int pos = (sep == NULL ? strlen(s) - 1 : sep - s); + int pos = (! sep ? strlen(s) - 1 : sep - s); - /* Strip trailing newline */ + /* strip trailing newline */ s[strlen(s) - 1] = '\0'; - /* Fill line->content */ + /* fill line->content */ line->content = malloc((pos + 1) * sizeof(char)); strncpy(line->content, s, pos); - /* Fill line->comment */ - if (sep != NULL) { + /* fill line->comment */ + if (sep) { line->comment = malloc((strlen(s) - pos) * sizeof(char)); strcpy(line->comment, s + pos); } else { @@ -75,7 +83,7 @@ parse_line(char *s, char *separator) Line * add_line(Buffer *buffer, int number, char *string, char *separator, Line *prev) { - /* Allocate new line */ + /* allocate new line */ Line *line = malloc(sizeof(Line)); line = parse_line(string, separator); line->next = NULL; @@ -84,7 +92,7 @@ add_line(Buffer *buffer, int number, char *string, char *separator, Line *prev) printf("%s\n", line->content); - /* Interlink with previous line if exists */ + /* interlink with previous line if exists */ if (number == 1) { buffer->first = line; } else { @@ -139,7 +147,35 @@ print_lines() void get_input() { - + char key; + struct termios termio_old; + struct termios termio_new; + + /* set the terminal to send one key at a time. */ + + /* get the terminal's state */ + if (tcgetattr(0, &termio_old) < 0) { + die("Can not get terminal attributes with tcgetattr()."); + } + + /* create a new modified state and apply it */ + termio_new = termio_old; + termio_new.c_lflag &= ~(ICANON | ECHO); + tcsetattr(STDIN_FILENO, TCSANOW, &termio_new); + + /* get input char by char from the keyboard. */ + + while ((key = getchar())) { + printf("Key '%c' pressed.\n", key); + + switch (key) { + case CONTROL('D'): return; + } + } + + /* resets the terminal to the previous state. */ + + tcsetattr(STDIN_FILENO, TCSANOW, &termio_old); } /* @@ -159,6 +195,17 @@ print_input() { } +/* + * Reset the terminal state and exit with error. + */ +void die(const char *s) +{ +/* tcsetattr(STDIN_FILENO, TCSANOW, &termio_old); */ + fprintf(stderr, "%s\n", s); + exit(EXIT_FAILURE); + +} + int main(int argc, char *argv[]) { @@ -166,16 +213,18 @@ main(int argc, char *argv[]) Buffer *buffer = NULL; char *separator = "* "; - /* Command line arguments */ + /* command line arguments */ for (i = 0; i <= argc; i++) { if (argv[i][1] == '-') { ; } } - /* Command line arguments */ + /* command line arguments */ buffer = fill_buffer(separator); printf("%s\n", buffer->first->next->next->prev->prev->content); + get_input(); + return 0; } diff --git a/complete.h b/complete.h index 060a5f6..692650e 100644 --- a/complete.h +++ b/complete.h @@ -48,6 +48,7 @@ typedef struct Buffer { } Buffer; +void die(const char *); Buffer * fill_buffer(char *); Line * parse_line(char *, char *); Line * add_line(Buffer *, int, char *, char *, Line *); -- 2.11.4.GIT