From 9f15e9b4c75cae3311736f4df70e84e2c97888ca Mon Sep 17 00:00:00 2001 From: m600x Date: Fri, 3 Feb 2017 14:15:46 +0100 Subject: [PATCH] Content of data->line.input and data->line.pos updated --- 42sh/Makefile | 4 +- 42sh/includes/completion.h | 24 +++++-- 42sh/src/completion/c_binary.c | 3 +- 42sh/src/completion/c_files.c | 7 +- 42sh/src/completion/c_init.c | 6 +- 42sh/src/completion/c_matching.c | 9 +-- 42sh/src/completion/c_output.c | 58 +++++++++++++++++ 42sh/src/completion/c_parser.c | 10 +-- 42sh/src/completion/c_single.c | 40 ------------ 42sh/src/completion/c_terminal.c | 6 +- 42sh/src/completion/completion.c | 102 ++++++++++++++++++++---------- 42sh/src/line-editing/get_touch.c | 6 +- 12 files changed, 170 insertions(+), 105 deletions(-) create mode 100644 42sh/src/completion/c_output.c delete mode 100644 42sh/src/completion/c_single.c diff --git a/42sh/Makefile b/42sh/Makefile index bd707f4a..65248d51 100644 --- a/42sh/Makefile +++ b/42sh/Makefile @@ -6,7 +6,7 @@ # By: wescande +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2016/08/29 21:32:58 by wescande #+# #+# # -# Updated: 2017/02/03 12:26:23 by alao ### ########.fr # +# Updated: 2017/02/03 13:53:09 by alao ### ########.fr # # # # **************************************************************************** # @@ -29,6 +29,7 @@ INC_DIR = includes/ OBJ_DIR = objs/ SRC_BASE = \ +completion/c_output.c\ completion/c_binary.c\ completion/c_clear.c\ completion/c_files.c\ @@ -37,7 +38,6 @@ completion/c_matching.c\ completion/c_parser.c\ completion/c_pathsolver.c\ completion/c_printer.c\ -completion/c_single.c\ completion/c_sizing.c\ completion/c_terminal.c\ completion/completion.c\ diff --git a/42sh/includes/completion.h b/42sh/includes/completion.h index 782e24d2..36902c8a 100644 --- a/42sh/includes/completion.h +++ b/42sh/includes/completion.h @@ -6,7 +6,7 @@ /* By: alao +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/02/18 11:13:04 by alao #+# #+# */ -/* Updated: 2017/02/03 12:23:05 by alao ### ########.fr */ +/* Updated: 2017/02/03 13:37:11 by alao ### ########.fr */ /* */ /* ************************************************************************** */ @@ -74,6 +74,10 @@ typedef struct s_comp t_clst *lst; } t_comp; +/* +** Main autocompletion engine +*/ + int completion(long int key); void c_init(t_data *s, long int input); int c_matching(t_data *s, t_comp *c); @@ -82,15 +86,27 @@ int c_seek_files(t_data *s, t_comp *c); int c_parser(t_comp *c, char *path, char *name); int c_sizing(t_comp *c); -int c_single(t_comp *c); +/* +** Output functions. +*/ + +int c_updater(t_comp *c); +int c_gtfo(t_comp *c, long int keypress); + +/* +** Terminal related function (moving and printing the list) +*/ void c_term_mv_down(t_comp *c); void c_term_mv_back(t_comp *c); void c_printer(t_comp *c); +/* +** Support functions +*/ + int c_clear(t_data *s); char *path_solver(t_comp *c, char *cmd, char *cwd); - -int test(t_comp *c); +int test(t_comp *c); #endif diff --git a/42sh/src/completion/c_binary.c b/42sh/src/completion/c_binary.c index fd46eb81..9aa4fb75 100644 --- a/42sh/src/completion/c_binary.c +++ b/42sh/src/completion/c_binary.c @@ -6,7 +6,7 @@ /* By: alao +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/09 13:30:57 by alao #+# #+# */ -/* Updated: 2017/01/11 14:08:08 by alao ### ########.fr */ +/* Updated: 2017/02/03 13:30:59 by alao ### ########.fr */ /* */ /* ************************************************************************** */ @@ -35,5 +35,6 @@ int c_seek_binary(t_data *s, t_comp *c) c_parser(c, paths[i++], c->rcmd); tmp ? ft_memdel((void *)&tmp) : (0); paths ? ft_sstrfree(paths) : (0); + DG("SB: End"); return (0); } diff --git a/42sh/src/completion/c_files.c b/42sh/src/completion/c_files.c index 98046317..005fb857 100644 --- a/42sh/src/completion/c_files.c +++ b/42sh/src/completion/c_files.c @@ -6,7 +6,7 @@ /* By: alao +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/09 13:31:21 by alao #+# #+# */ -/* Updated: 2017/01/11 14:06:50 by alao ### ########.fr */ +/* Updated: 2017/02/03 13:30:50 by alao ### ########.fr */ /* */ /* ************************************************************************** */ @@ -50,14 +50,15 @@ static char *c_slicer(t_comp *c) int c_seek_files(t_data *s, t_comp *c) { - DG("Seek Files"); - (void)s; char *path; + DG("SF: Start"); + (void)s; path = c_slicer(c); c->cpath = path_solver(c, path, NULL); DG("Solved as [%s]", c->cpath); path ? ft_memdel((void *)&path) : (0); c_parser(c, c->cpath, c->match); + DG("SF: End"); return (0); } diff --git a/42sh/src/completion/c_init.c b/42sh/src/completion/c_init.c index 36247c0c..f54a37a1 100644 --- a/42sh/src/completion/c_init.c +++ b/42sh/src/completion/c_init.c @@ -6,7 +6,7 @@ /* By: alao +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/09 11:21:16 by alao #+# #+# */ -/* Updated: 2017/02/03 12:28:49 by alao ### ########.fr */ +/* Updated: 2017/02/03 13:38:53 by alao ### ########.fr */ /* */ /* ************************************************************************** */ @@ -42,12 +42,14 @@ static char *c_trimmer(char *cmd, int st, int nd) void c_init(t_data *s, long int input) { struct winsize win; + int len_trail; if (!(s->comp = (t_comp *)malloc((sizeof(t_comp))))) return ; s->comp->rcmd = c_trimmer(s->line.input, s->line.pos, s->line.pos); + len_trail = ft_strlen(s->line.input) - s->line.pos; if (ft_strlen(s->line.input) > s->line.pos) - s->comp->trail = ft_strsub(s->line.input, s->line.pos, ft_strlen(s->line.input) - s->line.pos); + s->comp->trail = ft_strsub(s->line.input, s->line.pos, len_trail); else s->comp->trail = NULL; s->comp->ircmd = s->line.pos; diff --git a/42sh/src/completion/c_matching.c b/42sh/src/completion/c_matching.c index 43774657..72bcc01d 100644 --- a/42sh/src/completion/c_matching.c +++ b/42sh/src/completion/c_matching.c @@ -6,7 +6,7 @@ /* By: alao +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/10/15 13:27:14 by alao #+# #+# */ -/* Updated: 2017/02/03 12:06:23 by alao ### ########.fr */ +/* Updated: 2017/02/03 13:31:36 by alao ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,7 +17,6 @@ ** it will call c_seek_files() function. If not, it assume it will be a binary ** so the function c_seek_binary() is called instead. ** Once that done, the printing function should occur. -** NOT YET IMPLEMENTED */ int c_matching(t_data *s, t_comp *c) @@ -27,12 +26,6 @@ int c_matching(t_data *s, t_comp *c) else c_seek_files(s, c); if (c->lst) -// { c_sizing(c); -// DG("Seek Binary end [%d]", c->lst->prev->id); -// test(c); -// } -// else -// DG("Seek Binary end No result"); return (0); } diff --git a/42sh/src/completion/c_output.c b/42sh/src/completion/c_output.c new file mode 100644 index 00000000..f94317f7 --- /dev/null +++ b/42sh/src/completion/c_output.c @@ -0,0 +1,58 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* c_output.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: alao +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/03 13:10:38 by alao #+# #+# */ +/* Updated: 2017/02/03 13:52:01 by alao ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "completion.h" + +/* +** Output function. Will update the data->line.input along with the +** position of the cursor in data->line.pos. If the autocompletion occur in +** the middle of the command, it will join the trailing part of it. Therefor +** recreating the commands completed. +** Once that done, it will clear all the memory related and return zero. +*/ + +int c_updater(t_comp *c) +{ + char *tmp; + char *rt; + int new_pos; + + DG("\tUpdater"); + DG("RCMD [%s] match [%s] Candidat [%s]", c->rcmd, c->match, c->lst->name); + tmp = NULL; + rt = NULL; + new_pos = c->ircmd + (ft_strlen(c->lst->name) - ft_strlen(c->match)) + 1; + tmp = ft_strsub(c->rcmd, 0, ft_strlen(c->rcmd) - ft_strlen(c->match)); + rt = ft_strjoin(tmp, c->lst->name); + tmp ? ft_memdel((void *)&tmp) : (0); + if (c->trail) + data_singleton()->line.input = ft_strjoin(rt, c->trail); + else + data_singleton()->line.input = ft_strdup(rt); + data_singleton()->line.pos = new_pos; + DG("Resulting RCMD [%s] with pos [%d] from [%d]", rt, new_pos, c->ircmd); + rt ? ft_memdel((void *)&rt) : (0); + c_clear(data_singleton()); + return (0); +} + +/* +** Placeholder to clear the memory if an other key than tab is pressed to know +** if the command should be updated or not before clearing the memory. +*/ + +int c_gtfo(t_comp *c, long int keypress) +{ + DG("It's time to GTFO. Keypress [%d]", keypress); + (void)c; + return (0); +} diff --git a/42sh/src/completion/c_parser.c b/42sh/src/completion/c_parser.c index cf73b457..90d5c717 100644 --- a/42sh/src/completion/c_parser.c +++ b/42sh/src/completion/c_parser.c @@ -6,7 +6,7 @@ /* By: alao +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/09 13:52:07 by alao #+# #+# */ -/* Updated: 2017/01/31 18:34:54 by alao ### ########.fr */ +/* Updated: 2017/02/03 13:40:14 by alao ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,7 +16,7 @@ ** Add the matching element to the list */ -static void c_add_to_lst(t_comp *c, t_clst *node) +static void c_add_to_lst(t_comp *c, t_clst *node) { DG("PARSER: Adding node [%s]", node->name); if (c->lst == NULL) @@ -42,9 +42,9 @@ static void c_add_to_lst(t_comp *c, t_clst *node) ** created and the function above is called to add it. */ -static int c_storing(t_comp *c, char *value, unsigned char type) +static int c_storing(t_comp *c, char *value, unsigned char type) { - t_clst *tmp; + t_clst *tmp; if (ft_strncmp(".", value, 1) == 0 || ft_strncmp("..", value, 2) == 0) return (0); @@ -68,10 +68,10 @@ static int c_storing(t_comp *c, char *value, unsigned char type) int c_parser(t_comp *c, char *path, char *name) { - DG("PARSER: Search for [%s] in [%s]", name, path); DIR *rep; struct dirent *dirc; + DG("PARSER: Search for [%s] in [%s]", name, path); if (!(rep = opendir(path))) return (-1); while ((dirc = readdir(rep))) diff --git a/42sh/src/completion/c_single.c b/42sh/src/completion/c_single.c deleted file mode 100644 index d10227d8..00000000 --- a/42sh/src/completion/c_single.c +++ /dev/null @@ -1,40 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* c_single.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: alao +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2017/01/31 14:01:22 by alao #+# #+# */ -/* Updated: 2017/01/31 18:57:59 by alao ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "completion.h" - - -int c_single(t_comp *c) -{ - DG("SINGLE"); - DG("Containing [%s] match [%s] Candidat [%s]", c->rcmd, c->match, c->lst->name); - char *tmp; - char *rt; - int new_pos; - - tmp = NULL; - rt = NULL; - new_pos = c->ircmd + (ft_strlen(c->lst->name) - ft_strlen(c->match)) + 1; - tmp = ft_strsub(c->rcmd, 0, ft_strlen(c->rcmd) - ft_strlen(c->match)); - rt = ft_strjoin(tmp, c->lst->name); - tmp ? ft_memdel((void *)&tmp) : (0); - if (c->trail) - { - tmp = ft_strjoin(rt, " "); - rt ? ft_memdel((void *)&rt) : (0); - rt = ft_strjoin(tmp, c->trail); - } - DG("Resulting RCMD as [%s] with new position [%d] from [%d]", rt, new_pos, c->ircmd); - rt ? ft_memdel((void *)&rt) : (0); - c_clear(data_singleton()); - return (0); -} diff --git a/42sh/src/completion/c_terminal.c b/42sh/src/completion/c_terminal.c index f8c42c89..04b94f05 100644 --- a/42sh/src/completion/c_terminal.c +++ b/42sh/src/completion/c_terminal.c @@ -6,7 +6,7 @@ /* By: alao +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/10/11 10:44:40 by alao #+# #+# */ -/* Updated: 2017/01/31 13:24:50 by alao ### ########.fr */ +/* Updated: 2017/02/03 13:40:41 by alao ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,11 +19,11 @@ void c_term_mv_back(t_comp *c) { - DG("Terminal back up"); int i; int lcmd; i = 0; + DG("Terminal back up"); while (i != (c->c_line)) { ft_putstr(tgetstr("up", NULL)); @@ -47,10 +47,10 @@ void c_term_mv_back(t_comp *c) void c_term_mv_down(t_comp *c) { - DG("Terminal down"); int i; i = 0; + DG("Terminal down"); while (i < c->c_line) { ft_putstr(tgetstr("do", NULL)); diff --git a/42sh/src/completion/completion.c b/42sh/src/completion/completion.c index 87f93f32..284cca28 100644 --- a/42sh/src/completion/completion.c +++ b/42sh/src/completion/completion.c @@ -6,7 +6,7 @@ /* By: alao +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/09/20 14:50:33 by alao #+# #+# */ -/* Updated: 2017/02/03 12:30:54 by alao ### ########.fr */ +/* Updated: 2017/02/03 14:11:42 by alao ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,12 +16,13 @@ ** DEBUG FUNCTION */ -int test(t_comp *c) +int test(t_comp *c) { - DG("\tAutocompletion dump"); - int i = 1; - t_clst *tmp; + t_clst *tmp; + int i; + DG("\tAutocompletion dump"); + i = 1; if (!(c->lst)) { DG("Empty list"); @@ -50,9 +51,14 @@ int test(t_comp *c) return (0); } -static void c_next_item(t_comp *c) +/* +** Function to select the next item in the list if it has already been Created +** and if the keypressed is tab. +*/ + +static void c_next_item(t_comp *c) { - t_clst *ptr; + t_clst *ptr; ptr = c->lst; while (!ptr->cursor) @@ -61,40 +67,24 @@ static void c_next_item(t_comp *c) ptr->next->cursor = 1; } -int completion(long int input) +/* +** If the list is empty after the parsing, all memory is cleared. +** if it detect a single item list, the command is directly updated. +** If none of the above behavior is right, the terminal is dropped down by +** comp->c_line then the list is printed. Once that done, the previous position +** of the cursor is restored. +*/ + +static int c_dispatcher(t_data *s) { - t_data *s; - - s = data_singleton(); - - DG("\n\n\t\tAutocompletion input key [%d]\n", (int)input); - if (s->comp == NULL) - { - if (s->line.pos == 0) - return (0); - if (s->line.input[s->line.pos] != ' ' && s->line.input[s->line.pos] != '\0') - return (0); - c_init(s, input); - } - else - { - if (input == 9) - c_next_item(s->comp); - else - DG("Place holder to clear or put the selection in rcmd"); - } - test(s->comp); if (s->comp && s->comp->lst == NULL) { DG("Empty list, flushing autocompletion"); c_clear(s); } else if (s->comp && s->comp->lst == s->comp->lst->next) - { - c_single(s->comp); - return (1); - } - else if (s->comp && s->comp->lst != s->comp->lst->next ) + return (c_updater(s->comp)); + else if (s->comp && s->comp->lst != s->comp->lst->next) { c_term_mv_down(s->comp); c_printer(s->comp); @@ -102,3 +92,47 @@ int completion(long int input) } return (0); } + +/* +** Autocompletion feature. +** If the structure of the completion (later called comp) doesn't exist, the +** function will check for a few things. If the current position is zero, it +** will return immediately. Same thing apply if the current position of the +** cursor is not a space. If those condition are not met the comp struct is +** created using c_init(). +** If the comp struct already exist at the call of the function, it will check +** which key has been pressed. If the tab key has been used, that mean an other +** item should be selected. This is done using c_next_item(). If the keypress +** is not tab, c_gtfo() is called to know if the command should be updated or +** simply delete all the memory. +** +** The c_dispatcher() is called which will print or update the command +** depending on their respective condition. +*/ + +int completion(long int keypress) +{ + t_data *s; + + s = data_singleton(); + DG("\n\n\t\tAutocompletion input key [%d]\n", (int)keypress); + if (s->comp == NULL) + { + if (s->line.pos == 0) + return (0); + if (s->line.input[s->line.pos] != ' ' && + s->line.input[s->line.pos] != '\0') + return (0); + c_init(s, keypress); + } + else + { + if (keypress == TOUCHE_TAB) + c_next_item(s->comp); + else + return (c_gtfo(s->comp, keypress)); + } + test(s->comp); + c_dispatcher(s); + return (0); +} diff --git a/42sh/src/line-editing/get_touch.c b/42sh/src/line-editing/get_touch.c index 2edec968..f0f2d1de 100644 --- a/42sh/src/line-editing/get_touch.c +++ b/42sh/src/line-editing/get_touch.c @@ -6,7 +6,7 @@ /* By: gwojda +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/19 16:28:49 by gwojda #+# #+# */ -/* Updated: 2017/02/03 12:23:44 by alao ### ########.fr */ +/* Updated: 2017/02/03 13:05:41 by alao ### ########.fr */ /* */ /* ************************************************************************** */ @@ -54,10 +54,10 @@ char *ft_read_stdin(void) ret = 0; j = 0; read(0, &ret, sizeof(int)); +if (data_singleton()->comp || ret == TOUCHE_TAB) + completion(ret); while (g_key[j].value && g_key[j].value != ret) ++j; - if (data_singleton()->comp || ret == 9) - completion(ret); if (g_key[j].value) g_key[j].f(); else if (ft_isprint(ret))