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> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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;
}

View file

@ -6,7 +6,7 @@
/* By: alao <alao@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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)
{

View file

@ -6,7 +6,7 @@
/* By: alao <alao@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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.
*/
/*
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,14 +43,17 @@ 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);
while (pos && c->rcmd[pos] != ' ')
pos = ft_strlen(c->rcmd) - (input_len - pos + 1);
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);
}
@ -67,7 +71,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);

View file

@ -6,7 +6,7 @@
/* By: gwojda <gwojda@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

View file

@ -6,7 +6,7 @@
/* By: alao <alao@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

View file

@ -6,28 +6,31 @@
/* By: alao <alao@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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.
*/

View file

@ -6,7 +6,7 @@
/* By: alao <alao@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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)