From e2f5ee9443b30b9a2cae8dff1f0b5f14b2db11bb Mon Sep 17 00:00:00 2001 From: josuah Date: Wed, 19 Oct 2016 17:55:34 -0400 Subject: [PATCH] It works! Only left the filtering to have core! --- complete.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++------------ complete.h | 25 +++++------ 2 files changed, 125 insertions(+), 38 deletions(-) diff --git a/complete.c b/complete.c index ca8fc1a..24b352c 100644 --- a/complete.c +++ b/complete.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -24,7 +25,7 @@ fill_buffer(char *separator) Buffer *buffer = malloc(sizeof(Buffer)); FILE *fp = fopen("complete.c", "r"); - if (! fp) { + if (!fp) { die("Can not open file for reading."); } @@ -50,7 +51,7 @@ parse_line(char *s, char *separator) { Line *line = malloc(sizeof(Line)); char *sep = strstr(s, separator); - int pos = ! sep ? (int) strlen(s) - 1 : (int) (sep - s); + int pos = !sep ? (int) strlen(s) - 1 : (int) (sep - s); /* strip trailing newline */ s[strlen(s) - 1] = '\0'; @@ -142,12 +143,31 @@ line_match_input(Line *line, char *input) * Print a line to stderr */ void -print_line(Line *line) +print_line(Line *line, int current) { - fprintf(stderr, "\033[K%-7d %-30s\033[1;30m%s\033[0m\n", - line->number, - line->content, - line->comment); + /* clean the line in case it was not empty */ + fputs("\033[K", stderr); + + /* line number if option set */ + if (TRUE) { + if (current) { + fputs("\033[1m", stderr); + } else { + fputs("\033[1;30m", stderr); + } + + fprintf(stderr, "%7d\033[0m", line->number); + } + + /* highlight current line */ + if (current) { + fputs("\033[1;33m", stderr); + } + + fprintf(stderr, " %-30s\033[1;30m%s", line->content, line->comment); + + fputs("\033[0m\n", stderr); + } /* @@ -167,19 +187,20 @@ void print_lines(Buffer *buffer, int count, int offset) { Line *line = buffer->current; - int i ,j; - i = j = 0; + int i = 0; + int j = 0; /* seek back from current line to the first line to print */ while (line && i < count - offset) { - i = line->matches? i + 1 : i; + i = line->matches ? i + 1 : i; line = line->prev; } + line = line ? line : buffer->first; /* print up to count lines that match the input */ while (line && j < count) { if (line->matches) { - print_line(line); + print_line(line, line == buffer->current); j++; } @@ -188,7 +209,7 @@ print_lines(Buffer *buffer, int count, int offset) /* continue up to the end of the screen clearing it */ for (; j < count; j++) { - fprintf(stderr, "\r\033[K-%d-\n", j); + fputs("\r\033[K\n", stderr); } } @@ -197,10 +218,11 @@ print_lines(Buffer *buffer, int count, int offset) * * This also has to clear the previous lines. */ -void update_screen(Buffer *buffer, int count) +void +update_screen(Buffer *buffer, int count, int offset) { fprintf(stderr, "\n"); - print_lines(buffer, count, 3); + print_lines(buffer, count, offset); /* go up to the prompt position and update it */ fprintf(stderr, "\033[%dA", count + 1); @@ -237,7 +259,7 @@ terminal_set() /* create a new modified state by switching the binary flags */ termio_new = termio_old; - termio_new.c_lflag &= ~(ICANON | ECHO); + termio_new.c_lflag &= ~(ICANON | ECHO | IGNBRK); /* apply this state to current terminal now (TCSANOW) */ tcsetattr(STDIN_FILENO, TCSANOW, &termio_new); @@ -249,20 +271,15 @@ terminal_set() * Listen for the user input and call the appropriate functions. */ void -get_input(Buffer *buffer, int count) +get_input(Buffer *buffer, int count, int offset) { - char key; + /* receive one character at a time from the terminal */ struct termios termio_old = terminal_set(); /* get input char by char from the keyboard. */ - while ((key = getchar())) { - - switch (key) { - case CONTROL('D'): return; - } - + while (do_key(getchar(), buffer)) { filter_lines(buffer); - update_screen(buffer, count); + update_screen(buffer, count, offset); } /* resets the terminal to the previous state. */ @@ -270,6 +287,73 @@ get_input(Buffer *buffer, int count) } /* + * Perform action associated with key + */ +int +do_key(char key, Buffer *buffer) +{ + size_t length; + int i; + + switch (key) { + + case CONTROL('C'): + return FALSE; + + case CONTROL('U'): + buffer->input[0] = '\0'; + break; + + case CONTROL('W'): + length = strlen(buffer->input) - 1; + + for (i = length; i >= 0 && isspace(buffer->input[i]); i--) { + buffer->input[i] = '\0'; + } + + length = strlen(buffer->input) - 1; + for (i = length; i >= 0 && !isspace(buffer->input[i]); i--) { + buffer->input[i] = '\0'; + } + + break; + + case CONTROL('H'): + case 127: /* backspace */ + buffer->input[strlen(buffer->input) - 1] = '\0'; + break; + + case CONTROL('N'): + if (buffer->current->next) { + buffer->current = buffer->current->next; + } + + break; + + case CONTROL('P'): + if (buffer->current->prev) { + buffer->current = buffer->current->prev; + } + break; + + case CONTROL('M'): + case CONTROL('J'): /* enter */ + fputs("\r\033[K", stderr); + puts(buffer->current->content); + return FALSE; + + default: + if (isprint(key)) { + length = strlen(buffer->input); + buffer->input[length] = key; + buffer->input[length + 1] = '\0'; + } + } + + return TRUE; +} + +/* * Print the prompt, before the input, with the number of candidates that * match. */ @@ -297,6 +381,7 @@ main(int argc, char *argv[]) Buffer *buffer = NULL; char *separator = "* "; int count = 30; + int offset = 3; /* command line arguments */ @@ -310,10 +395,11 @@ main(int argc, char *argv[]) buffer = fill_buffer(separator); /* set the interface */ - update_screen(buffer, count); + filter_lines(buffer); + update_screen(buffer, count, offset); /* listen and interact to input */ - get_input(buffer, count); + get_input(buffer, count, offset); clear_screen(count); diff --git a/complete.h b/complete.h index da36733..6dc5940 100644 --- a/complete.h +++ b/complete.h @@ -52,15 +52,16 @@ 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 *); -int line_match_input(Line *, char *); -void filter_lines(Buffer *); -void print_line(Line *); -void print_header(); -void print_lines(Buffer *, int, int); -void update_screen(Buffer *, int); -void get_input(Buffer *, int); -void print_prompt(int, int, char *); +void die(const char *); +Buffer * fill_buffer(char *); +Line * parse_line(char *, char *); +Line * add_line(Buffer *, int, char *, char *, Line *); +int line_match_input(Line *, char *); +void filter_lines(Buffer *); +void print_line(Line *, int); +void print_header(); +void print_lines(Buffer *, int, int); +void update_screen(Buffer *, int, int); +void get_input(Buffer *, int, int); +int do_key(char, Buffer *); +void print_prompt(int, int, char *); -- 2.11.4.GIT