From 47d07aaa6de24116366dbe8b3225a5f1c9d267a4 Mon Sep 17 00:00:00 2001 From: m600x Date: Wed, 22 Mar 2017 12:45:25 +0100 Subject: [PATCH 1/2] Completion. Norme + c_chevron on hold --- 42sh/src/completion/c_find_env.c | 7 ++-- 42sh/src/completion/c_match.c | 19 +++++----- 42sh/src/completion/c_match_glob.c | 8 ++--- 42sh/src/completion/c_match_update.c | 18 +++++----- 42sh/src/completion/c_terminal.c | 37 ++++++++++++++------ 42sh/src/completion/completion.c | 52 ++++++++++++++++++++-------- 6 files changed, 91 insertions(+), 50 deletions(-) diff --git a/42sh/src/completion/c_find_env.c b/42sh/src/completion/c_find_env.c index 3d36ea24..f93297ff 100644 --- a/42sh/src/completion/c_find_env.c +++ b/42sh/src/completion/c_find_env.c @@ -6,7 +6,7 @@ /* By: gwojda +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/03/09 15:50:24 by gwojda #+# #+# */ -/* Updated: 2017/03/16 08:28:19 by alao ### ########.fr */ +/* Updated: 2017/03/22 12:29:40 by alao ### ########.fr */ /* */ /* ************************************************************************** */ @@ -38,14 +38,15 @@ int c_seek_env(t_comp *c, char *current_word) { char **env; int i; + int m_len; i = 0; env = data_singleton()->env; c->match = ft_strdupi_w(current_word + 1); + m_len = ft_strlen(c->match); while (env[i]) { - if (!ft_strncmp(c->match, env[i], ft_strlen(c->match)) && - env[i][ft_strlen(c->match)] != '=') + if (!ft_strncmp(c->match, env[i], m_len) && env[i][m_len] != '=') c_addnode(c, ft_strndup(env[i], ft_strchr(env[i], '=') - env[i])); ++i; } diff --git a/42sh/src/completion/c_match.c b/42sh/src/completion/c_match.c index 03b81a0b..09761b0f 100644 --- a/42sh/src/completion/c_match.c +++ b/42sh/src/completion/c_match.c @@ -6,7 +6,7 @@ /* By: alao +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/10/15 13:27:14 by alao #+# #+# */ -/* Updated: 2017/03/20 18:14:35 by gwojda ### ########.fr */ +/* Updated: 2017/03/22 12:44:00 by alao ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,15 +15,16 @@ /* ** Failsafe by checking if the nearby char are not a < or > for aggregation. */ - +/* static int c_chevron(t_comp *c) { size_t pos; + size_t input_len; pos = c->ircmd; + input_len = ft_strlen(data_singleton()->line.input); if (pos >= ft_strlen(c->rcmd)) - pos = ft_strlen(c->rcmd) - (ft_strlen(data_singleton()->line.input) - - pos); + pos = ft_strlen(c->rcmd) - (input_len - pos); while (pos) { if (c->rcmd[pos] == '<' || c->rcmd[pos] == '>') @@ -33,7 +34,7 @@ static int c_chevron(t_comp *c) if (c->rcmd[pos] == '<' || c->rcmd[pos] == '>') return (1); return (0); -} +}*/ /* ** Seek the current word. @@ -42,11 +43,12 @@ static int c_chevron(t_comp *c) static char *c_current_words(t_comp *c) { size_t pos; + size_t input_len; pos = c->ircmd; + input_len = ft_strlen(data_singleton()->line.input); if (pos >= ft_strlen(c->rcmd)) - pos = ft_strlen(c->rcmd) - - (ft_strlen(data_singleton()->line.input) - pos + 1); + pos = ft_strlen(c->rcmd) - (input_len - pos + 1); while (pos && c->rcmd[pos] != ' ') --pos; if (c->rcmd[pos] == ' ') @@ -67,7 +69,8 @@ int c_matching(t_data *s, t_comp *c) c_seek_abs_path(c, current_word); else if (ft_strchr(c->rcmd, '$')) c_seek_env(c, current_word); - else if (c->rcmd[0] != '.' && !(ft_strchr(c->rcmd, ' ')) && !c_chevron(c)) + else if (c->rcmd[0] != '.' && !(ft_strchr(c->rcmd, ' '))) +// else if (c->rcmd[0] != '.' && !(ft_strchr(c->rcmd, ' ')) && !c_chevron(c)) c_seek_binary(s, c); else c_seek_files(s, c, current_word); diff --git a/42sh/src/completion/c_match_glob.c b/42sh/src/completion/c_match_glob.c index d51a8a0c..078c5b12 100644 --- a/42sh/src/completion/c_match_glob.c +++ b/42sh/src/completion/c_match_glob.c @@ -6,7 +6,7 @@ /* By: gwojda +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/03/08 17:20:01 by gwojda #+# #+# */ -/* Updated: 2017/03/21 13:40:42 by gwojda ### ########.fr */ +/* Updated: 2017/03/22 11:52:18 by alao ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,16 +16,14 @@ ** Recreate the command from the globbing module responds. */ -static void c_replace_globbing(char **glob, size_t start) +static void c_replace_globbing(char **glob, size_t start, size_t pos) { char *ref_next; char *ref_mid; char *ref_prev; char *str; - size_t pos; str = data_singleton()->line.input; - pos = data_singleton()->line.pos; while (str[pos] && str[pos] != ' ') ++pos; while (str[pos] && str[pos] == ' ') @@ -113,6 +111,6 @@ int c_glob_matching(void) ss_glob = glob(current_word, glob_echap, glob_echap, 1); if (c_check_glob(ss_glob, current_word, glob_echap, pos)) return (0); - c_replace_globbing(ss_glob, pos); + c_replace_globbing(ss_glob, pos, data_singleton()->line.pos); return (1); } diff --git a/42sh/src/completion/c_match_update.c b/42sh/src/completion/c_match_update.c index 9fa54ace..e9195ea9 100644 --- a/42sh/src/completion/c_match_update.c +++ b/42sh/src/completion/c_match_update.c @@ -6,7 +6,7 @@ /* By: alao +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/02/15 12:03:30 by alao #+# #+# */ -/* Updated: 2017/03/21 15:03:37 by gwojda ### ########.fr */ +/* Updated: 2017/03/22 12:25:26 by alao ### ########.fr */ /* */ /* ************************************************************************** */ @@ -48,25 +48,27 @@ static int c_refresh_match(t_comp *c, long int keypress) int c_rematch(t_comp *c, long int keypress) { + t_data *s; + + s = data_singleton(); if (ft_isascii(keypress)) { c->isrematch = 1; c_term_clear(c); c_refresh_match(c, keypress); c_clear_lst(c); - c_matching(data_singleton(), c); - if (data_singleton()->comp && c->lst == NULL) - c_clear(data_singleton()); - else if (data_singleton()->comp && c->lst == c->lst->next) + c_matching(s, c); + if (s->comp && c->lst == NULL) + c_clear(s); + else if (s->comp && c->lst == c->lst->next) return (1); - ft_print(keypress, &data_singleton()->line.input, - &data_singleton()->line.pos); + ft_print(keypress, &s->line.input, &s->line.pos); return (1); } else { c_term_clear(c); - c_clear(data_singleton()); + c_clear(s); } return (0); } diff --git a/42sh/src/completion/c_terminal.c b/42sh/src/completion/c_terminal.c index 68d9359d..da7a0f05 100644 --- a/42sh/src/completion/c_terminal.c +++ b/42sh/src/completion/c_terminal.c @@ -6,28 +6,31 @@ /* By: alao +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/10/11 10:44:40 by alao #+# #+# */ -/* Updated: 2017/03/21 11:22:03 by gwojda ### ########.fr */ +/* Updated: 2017/03/22 12:14:53 by alao ### ########.fr */ /* */ /* ************************************************************************** */ #include "completion.h" /* -** Clear the previous list from the screen and restore the same position. +** Clear the screen and restore cursor position. +** +** First thing is the move the cursor down (do), clear the terminal (cd), back +** up (up) and then move back in position. */ void c_term_clear(t_comp *c) { int i; int lcmd; + t_data *s; + s = data_singleton(); ft_putstr(tgetstr("do", NULL)); ft_putstr(tgetstr("cd", NULL)); ft_putstr(tgetstr("up", NULL)); i = 0; - lcmd = 0; - lcmd = (c->rcmd) ? ft_nb_last_line(data_singleton()->line.input, - data_singleton()->line.pos) : 0; + lcmd = (c->rcmd) ? ft_nb_last_line(s->line.input, s->line.pos) : 0; while (i < lcmd) { ft_putstr(tgetstr("nd", NULL)); @@ -36,8 +39,12 @@ void c_term_clear(t_comp *c) } /* -** Move the terminal up by the number of line needed and move it back up to -** the original position. +** Restore cursor position. +** +** Move the cursor up as needed (up) then to the beginning of the line (cr). +** The value check if the current print is a rolling list (terminal too small to +** print the whole list at once). If so, m_size is used or c_line. +** The cursor is then moved to the right (nd) by restore the position. */ void c_term_mv_back(t_comp *c) @@ -45,7 +52,9 @@ void c_term_mv_back(t_comp *c) int i; int lcmd; int value; + t_data *s; + s = data_singleton(); i = 0; if (c->c_line > c->win_y) value = c->m_size; @@ -58,8 +67,7 @@ void c_term_mv_back(t_comp *c) } ft_putstr(tgetstr("cr", NULL)); i = 0; - lcmd = (c->rcmd) ? ft_nb_last_line(data_singleton()->line.input, - data_singleton()->line.pos) : 0; + lcmd = (c->rcmd) ? ft_nb_last_line(s->line.input, s->line.pos) : 0; while (i < lcmd) { ft_putstr(tgetstr("nd", NULL)); @@ -68,8 +76,13 @@ void c_term_mv_back(t_comp *c) } /* -** Move the terminal down by the number of line needed and move it back up to -** the first line under the prompt +** Make room for the list. +** +** Move the cursor down as needed (do) and clear them (cd). +** The value check if the current print is a rolling list (terminal too small to +** print the whole list at once). If so, m_size is used or c_line. +** The cursor is then moved back up to the line just below where it was to begin +** printing the list. */ void c_term_mv_down(t_comp *c) @@ -101,6 +114,8 @@ void c_term_mv_down(t_comp *c) } /* +** Retrieve new terminal size. +** ** If the terminal has changed in size, the function will refresh these values ** and clear the previous print list. */ diff --git a/42sh/src/completion/completion.c b/42sh/src/completion/completion.c index 3996ccff..d5f82ffa 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/03/16 09:17:11 by alao ### ########.fr */ +/* Updated: 2017/03/22 12:00:27 by alao ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,7 +14,7 @@ /* ** Function to select the next item in the list if it has already been created -** and if the keypressed is tab. +** and if the key pressed is tab. */ static void c_next_item(t_comp *c) @@ -29,11 +29,20 @@ static void c_next_item(t_comp *c) } /* -** 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. +** Once the completion has been processed, this is the return point. +** The three condition are as follow: +** - If the completion list is empty (NULL), the screen is cleared and (1) is +** returned. +** - If the list contain only one element, c_updater() is called to update the +** string in the struct data then (1) is returned. +** - If the list contain multiple element that mean the completion is not yet +** finished so the c_term_mv_down() drop the terminal to make room for the +** list to be printed using c_printer() and the position is restored by +** calling c_term_mv_back(). (0) s returned because the command doesn't need +** an update to be done. +** +** RETURN VALUE : +** If the function return (1), the line edition module will update the command. */ int c_dispatcher(t_data *s) @@ -60,17 +69,29 @@ int c_dispatcher(t_data *s) /* ** Autocompletion feature. ** -** If the structure of the completion (later called comp) doesn't exist, the +** The autocompletion module work like the one found in ZSH. Meaning you can +** select the element in a list and complet the command. You can also move in +** it using arrows. It can rematch and update the list of choice with a new +** input from the user. The globbing is also supported. It will also complete +** path (adding /) and solve dots path. +** The completion module work for relative, absolute path and binary from the +** PATH. The env completion is also supported ($[tab]). +** +** The module start by checking if a globbing should be done using +** c_glob_matching(). If so, (1) is returned which trigger an update. +** If the completion structure (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. +** If the comp struct already exist at the call of the function, the first +** thing done is checking if the terminal have been resized between call to +** update the corresponding var. Then 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_keypress() +** is called to process the new key. ** ** The c_dispatcher() is called which will print or update the command ** depending on their respective condition. @@ -79,14 +100,15 @@ int c_dispatcher(t_data *s) int completion(long int keypress) { t_data *s; + int pos; s = data_singleton(); + pos = s->line.pos; if (c_glob_matching()) return (1); if (s->comp == NULL) { - if ((s->line.pos == 0) || (s->line.input[s->line.pos] != ' ' && - s->line.input[s->line.pos] != '\0')) + if (!pos || (s->line.input[pos] != ' ' && s->line.input[pos] != '\0')) return (0); c_init(s, keypress); if (s->comp == NULL) From f0e931b44db33b570afd10149f9c2f99e58dc383 Mon Sep 17 00:00:00 2001 From: gwojda Date: Wed, 22 Mar 2017 13:00:01 +0100 Subject: [PATCH 2/2] correction match .> + tab --- 42sh/src/completion/c_find_files.c | 4 ++-- 42sh/src/completion/c_match.c | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/42sh/src/completion/c_find_files.c b/42sh/src/completion/c_find_files.c index ce521d43..bc621a50 100644 --- a/42sh/src/completion/c_find_files.c +++ b/42sh/src/completion/c_find_files.c @@ -6,7 +6,7 @@ /* By: alao +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/09 13:31:21 by alao #+# #+# */ -/* Updated: 2017/03/21 14:53:21 by gwojda ### ########.fr */ +/* Updated: 2017/03/22 12:57:02 by gwojda ### ########.fr */ /* */ /* ************************************************************************** */ @@ -88,7 +88,7 @@ int c_seek_files(t_data *s, t_comp *c, char *current_word) if (c->rcmd[0] == '.') { c->cpath = ft_strdup("./"); - c->match = ft_strdup("."); + c->match = ft_strdup(current_word); } if (c->cpath == NULL) { diff --git a/42sh/src/completion/c_match.c b/42sh/src/completion/c_match.c index 09761b0f..e3f7b7ba 100644 --- a/42sh/src/completion/c_match.c +++ b/42sh/src/completion/c_match.c @@ -6,7 +6,7 @@ /* By: alao +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/10/15 13:27:14 by alao #+# #+# */ -/* Updated: 2017/03/22 12:44:00 by alao ### ########.fr */ +/* Updated: 2017/03/22 12:58:21 by gwojda ### ########.fr */ /* */ /* ************************************************************************** */ @@ -49,9 +49,11 @@ static char *c_current_words(t_comp *c) input_len = ft_strlen(data_singleton()->line.input); if (pos >= ft_strlen(c->rcmd)) pos = ft_strlen(c->rcmd) - (input_len - pos + 1); - while (pos && c->rcmd[pos] != ' ') + while (pos && c->rcmd[pos] != ' ' && c->rcmd[pos] != '<' + && c->rcmd[pos] != '>' && c->rcmd[pos] != '\n') --pos; - if (c->rcmd[pos] == ' ') + if (c->rcmd[pos] == ' ' || c->rcmd[pos] == '<' + || c->rcmd[pos] == '>' || c->rcmd[pos] == '\n') ++pos; return (c->rcmd + pos); }