42-archive/42sh/src/completion/completion.c
2017-02-03 15:49:03 +01:00

139 lines
3.9 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* completion.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: alao <alao@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/09/20 14:50:33 by alao #+# #+# */
/* Updated: 2017/02/03 15:47:19 by alao ### ########.fr */
/* */
/* ************************************************************************** */
#include "completion.h"
/*
** DEBUG FUNCTION
*/
int test(t_comp *c)
{
t_clst *tmp;
int i;
DG("\tAutocompletion dump");
i = 1;
if (!(c->lst))
{
DG("Empty list");
return (0);
}
if (c->lst && c->lst->cursor)
DG("Node [x] ID [%d] [%s]", c->lst->id, c->lst->name);
else
DG("Node [ ] ID [%d] [%s]", c->lst->id, c->lst->name);
if (c->lst->prev != c->lst)
{
tmp = c->lst->next;
while (tmp != c->lst)
{
if (tmp->cursor)
DG("Node [x] ID [%d] [%s]", tmp->id, tmp->name);
else
DG("Node [ ] ID [%d] [%s]", tmp->id, tmp->name);
i++;
tmp = tmp->next;
}
}
DG("List configuration as:");
DG("Max value: Length (X) %d Number (Y) %d", c->c_sx, c->c_sy);
DG("Translated to [%d] Lines and [%d] Column", c->c_line, c->c_pline);
return (0);
}
/*
** 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;
ptr = c->lst;
while (!ptr->cursor)
ptr = ptr->next;
ptr->cursor = 0;
ptr->next->cursor = 1;
}
/*
** 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)
{
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)
return (c_updater(s->comp, s->comp->lst->name));
else if (s->comp && s->comp->lst != s->comp->lst->next)
{
c_term_mv_down(s->comp);
c_printer(s->comp);
c_term_mv_back(s->comp);
}
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);
return (c_dispatcher(s));
}