This commit is contained in:
Jack Halford 2017-03-22 13:09:07 +01:00
commit 8e4a3c17a8
7 changed files with 97 additions and 54 deletions

View file

@ -6,7 +6,7 @@
/* By: gwojda <gwojda@student.42.fr> +#+ +:+ +#+ */ /* By: gwojda <gwojda@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2017/03/09 15:50:24 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; char **env;
int i; int i;
int m_len;
i = 0; i = 0;
env = data_singleton()->env; env = data_singleton()->env;
c->match = ft_strdupi_w(current_word + 1); c->match = ft_strdupi_w(current_word + 1);
m_len = ft_strlen(c->match);
while (env[i]) while (env[i])
{ {
if (!ft_strncmp(c->match, env[i], ft_strlen(c->match)) && if (!ft_strncmp(c->match, env[i], m_len) && env[i][m_len] != '=')
env[i][ft_strlen(c->match)] != '=')
c_addnode(c, ft_strndup(env[i], ft_strchr(env[i], '=') - env[i])); c_addnode(c, ft_strndup(env[i], ft_strchr(env[i], '=') - env[i]));
++i; ++i;
} }

View file

@ -6,7 +6,7 @@
/* By: alao <alao@student.42.fr> +#+ +:+ +#+ */ /* By: alao <alao@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/09 13:31:21 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] == '.') if (c->rcmd[0] == '.')
{ {
c->cpath = ft_strdup("./"); c->cpath = ft_strdup("./");
c->match = ft_strdup("."); c->match = ft_strdup(current_word);
} }
if (c->cpath == NULL) if (c->cpath == NULL)
{ {

View file

@ -6,7 +6,7 @@
/* By: alao <alao@student.42.fr> +#+ +:+ +#+ */ /* By: alao <alao@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2016/10/15 13:27:14 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:58:21 by gwojda ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -15,15 +15,16 @@
/* /*
** Failsafe by checking if the nearby char are not a < or > for aggregation. ** Failsafe by checking if the nearby char are not a < or > for aggregation.
*/ */
/*
static int c_chevron(t_comp *c) static int c_chevron(t_comp *c)
{ {
size_t pos; size_t pos;
size_t input_len;
pos = c->ircmd; pos = c->ircmd;
input_len = ft_strlen(data_singleton()->line.input);
if (pos >= ft_strlen(c->rcmd)) if (pos >= ft_strlen(c->rcmd))
pos = ft_strlen(c->rcmd) - (ft_strlen(data_singleton()->line.input) pos = ft_strlen(c->rcmd) - (input_len - pos);
- pos);
while (pos) while (pos)
{ {
if (c->rcmd[pos] == '<' || c->rcmd[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] == '>') if (c->rcmd[pos] == '<' || c->rcmd[pos] == '>')
return (1); return (1);
return (0); return (0);
} }*/
/* /*
** Seek the current word. ** Seek the current word.
@ -42,14 +43,17 @@ static int c_chevron(t_comp *c)
static char *c_current_words(t_comp *c) static char *c_current_words(t_comp *c)
{ {
size_t pos; size_t pos;
size_t input_len;
pos = c->ircmd; pos = c->ircmd;
input_len = ft_strlen(data_singleton()->line.input);
if (pos >= ft_strlen(c->rcmd)) if (pos >= ft_strlen(c->rcmd))
pos = ft_strlen(c->rcmd) - pos = ft_strlen(c->rcmd) - (input_len - pos + 1);
(ft_strlen(data_singleton()->line.input) - pos + 1); while (pos && c->rcmd[pos] != ' ' && c->rcmd[pos] != '<'
while (pos && c->rcmd[pos] != ' ') && c->rcmd[pos] != '>' && c->rcmd[pos] != '\n')
--pos; --pos;
if (c->rcmd[pos] == ' ') if (c->rcmd[pos] == ' ' || c->rcmd[pos] == '<'
|| c->rcmd[pos] == '>' || c->rcmd[pos] == '\n')
++pos; ++pos;
return (c->rcmd + pos); return (c->rcmd + pos);
} }
@ -67,7 +71,8 @@ int c_matching(t_data *s, t_comp *c)
c_seek_abs_path(c, current_word); c_seek_abs_path(c, current_word);
else if (ft_strchr(c->rcmd, '$')) else if (ft_strchr(c->rcmd, '$'))
c_seek_env(c, current_word); 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); c_seek_binary(s, c);
else else
c_seek_files(s, c, current_word); c_seek_files(s, c, current_word);

View file

@ -6,7 +6,7 @@
/* By: gwojda <gwojda@student.42.fr> +#+ +:+ +#+ */ /* By: gwojda <gwojda@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2017/03/08 17:20:01 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. ** 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_next;
char *ref_mid; char *ref_mid;
char *ref_prev; char *ref_prev;
char *str; char *str;
size_t pos;
str = data_singleton()->line.input; str = data_singleton()->line.input;
pos = data_singleton()->line.pos;
while (str[pos] && str[pos] != ' ') while (str[pos] && str[pos] != ' ')
++pos; ++pos;
while (str[pos] && str[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); ss_glob = glob(current_word, glob_echap, glob_echap, 1);
if (c_check_glob(ss_glob, current_word, glob_echap, pos)) if (c_check_glob(ss_glob, current_word, glob_echap, pos))
return (0); return (0);
c_replace_globbing(ss_glob, pos); c_replace_globbing(ss_glob, pos, data_singleton()->line.pos);
return (1); return (1);
} }

View file

@ -6,7 +6,7 @@
/* By: alao <alao@student.42.fr> +#+ +:+ +#+ */ /* By: alao <alao@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2017/02/15 12:03:30 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) int c_rematch(t_comp *c, long int keypress)
{ {
t_data *s;
s = data_singleton();
if (ft_isascii(keypress)) if (ft_isascii(keypress))
{ {
c->isrematch = 1; c->isrematch = 1;
c_term_clear(c); c_term_clear(c);
c_refresh_match(c, keypress); c_refresh_match(c, keypress);
c_clear_lst(c); c_clear_lst(c);
c_matching(data_singleton(), c); c_matching(s, c);
if (data_singleton()->comp && c->lst == NULL) if (s->comp && c->lst == NULL)
c_clear(data_singleton()); c_clear(s);
else if (data_singleton()->comp && c->lst == c->lst->next) else if (s->comp && c->lst == c->lst->next)
return (1); return (1);
ft_print(keypress, &data_singleton()->line.input, ft_print(keypress, &s->line.input, &s->line.pos);
&data_singleton()->line.pos);
return (1); return (1);
} }
else else
{ {
c_term_clear(c); c_term_clear(c);
c_clear(data_singleton()); c_clear(s);
} }
return (0); return (0);
} }

View file

@ -6,28 +6,31 @@
/* By: alao <alao@student.42.fr> +#+ +:+ +#+ */ /* By: alao <alao@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2016/10/11 10:44:40 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" #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) void c_term_clear(t_comp *c)
{ {
int i; int i;
int lcmd; int lcmd;
t_data *s;
s = data_singleton();
ft_putstr(tgetstr("do", NULL)); ft_putstr(tgetstr("do", NULL));
ft_putstr(tgetstr("cd", NULL)); ft_putstr(tgetstr("cd", NULL));
ft_putstr(tgetstr("up", NULL)); ft_putstr(tgetstr("up", NULL));
i = 0; i = 0;
lcmd = 0; lcmd = (c->rcmd) ? ft_nb_last_line(s->line.input, s->line.pos) : 0;
lcmd = (c->rcmd) ? ft_nb_last_line(data_singleton()->line.input,
data_singleton()->line.pos) : 0;
while (i < lcmd) while (i < lcmd)
{ {
ft_putstr(tgetstr("nd", NULL)); 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 ** Restore cursor position.
** the original 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) void c_term_mv_back(t_comp *c)
@ -45,7 +52,9 @@ void c_term_mv_back(t_comp *c)
int i; int i;
int lcmd; int lcmd;
int value; int value;
t_data *s;
s = data_singleton();
i = 0; i = 0;
if (c->c_line > c->win_y) if (c->c_line > c->win_y)
value = c->m_size; value = c->m_size;
@ -58,8 +67,7 @@ void c_term_mv_back(t_comp *c)
} }
ft_putstr(tgetstr("cr", NULL)); ft_putstr(tgetstr("cr", NULL));
i = 0; i = 0;
lcmd = (c->rcmd) ? ft_nb_last_line(data_singleton()->line.input, lcmd = (c->rcmd) ? ft_nb_last_line(s->line.input, s->line.pos) : 0;
data_singleton()->line.pos) : 0;
while (i < lcmd) while (i < lcmd)
{ {
ft_putstr(tgetstr("nd", NULL)); 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 ** Make room for the list.
** the first line under the prompt **
** 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) 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 ** If the terminal has changed in size, the function will refresh these values
** and clear the previous print list. ** and clear the previous print list.
*/ */

View file

@ -6,7 +6,7 @@
/* By: alao <alao@student.42.fr> +#+ +:+ +#+ */ /* By: alao <alao@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2016/09/20 14:50:33 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 ** 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) 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. ** Once the completion has been processed, this is the return point.
** if it detect a single item list, the command is directly updated. ** The three condition are as follow:
** If none of the above behavior is right, the terminal is dropped down by ** - If the completion list is empty (NULL), the screen is cleared and (1) is
** comp->c_line then the list is printed. Once that done, the previous position ** returned.
** of the cursor is restored. ** - 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) int c_dispatcher(t_data *s)
@ -60,17 +69,29 @@ int c_dispatcher(t_data *s)
/* /*
** Autocompletion feature. ** 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 ** 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 ** 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 ** cursor is not a space. If those condition are not met the comp struct is
** created using c_init(). ** created using c_init().
** **
** If the comp struct already exist at the call of the function, it will check ** If the comp struct already exist at the call of the function, the first
** which key has been pressed. If the tab key has been used, that mean an other ** thing done is checking if the terminal have been resized between call to
** item should be selected. This is done using c_next_item(). If the keypress ** update the corresponding var. Then it will check which key has been pressed.
** is not tab, c_gtfo() is called to know if the command should be updated or **
** simply delete all the memory. ** 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 ** The c_dispatcher() is called which will print or update the command
** depending on their respective condition. ** depending on their respective condition.
@ -79,14 +100,15 @@ int c_dispatcher(t_data *s)
int completion(long int keypress) int completion(long int keypress)
{ {
t_data *s; t_data *s;
int pos;
s = data_singleton(); s = data_singleton();
pos = s->line.pos;
if (c_glob_matching()) if (c_glob_matching())
return (1); return (1);
if (s->comp == NULL) if (s->comp == NULL)
{ {
if ((s->line.pos == 0) || (s->line.input[s->line.pos] != ' ' && if (!pos || (s->line.input[pos] != ' ' && s->line.input[pos] != '\0'))
s->line.input[s->line.pos] != '\0'))
return (0); return (0);
c_init(s, keypress); c_init(s, keypress);
if (s->comp == NULL) if (s->comp == NULL)