From 723dd13aba0603323daebfffac709a37d3e53b0a Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Thu, 21 May 2020 18:23:50 +0200
Subject: [PATCH 1/8] Starting the autocompletion
---
Makefile | 3 ++-
include/key_functions.h | 2 ++
src/key_bindings/autocompletion.c | 16 ++++++++++++++++
src/key_bindings/default_bindings.c | 3 +++
4 files changed, 23 insertions(+), 1 deletion(-)
create mode 100644 src/key_bindings/autocompletion.c
diff --git a/Makefile b/Makefile
index 8980c7b..5977f96 100644
--- a/Makefile
+++ b/Makefile
@@ -44,7 +44,8 @@ SRC = src/shell.c \
src/key_bindings/move_commands.c \
src/my_ncurses/my_ncurses.c \
src/my_ncurses/string_utils.c \
- src/my_ncurses/pause_utils.c
+ src/my_ncurses/pause_utils.c \
+ src/key_bindings/autocompletion.c
OBJ = $(SRC:%.c=%.o)
OBJ += src/main.o
diff --git a/include/key_functions.h b/include/key_functions.h
index ff31335..467eb43 100644
--- a/include/key_functions.h
+++ b/include/key_functions.h
@@ -41,3 +41,5 @@ int end_of_line_command(int key, buffer_t *buffer, env_t *env);
int up_history_command(int key, buffer_t *buffer, env_t *env);
int down_history_command(int key, buffer_t *buffer, env_t *env);
+
+int complete_command(int key, buffer_t *buffer, env_t *env);
\ No newline at end of file
diff --git a/src/key_bindings/autocompletion.c b/src/key_bindings/autocompletion.c
new file mode 100644
index 0000000..4f6619b
--- /dev/null
+++ b/src/key_bindings/autocompletion.c
@@ -0,0 +1,16 @@
+/*
+** EPITECH PROJECT, 2020
+** ash
+** File description:
+** autocompletion
+*/
+
+#include "shell.h"
+
+int complete_command(int key, buffer_t *buffer, env_t *env)
+{
+ if (!buffer->buffer ||
+ (!strchr(buffer->buffer, ' ') && !strchr(buffer->buffer, '\t')))
+ return (0);
+ return (0);
+}
\ No newline at end of file
diff --git a/src/key_bindings/default_bindings.c b/src/key_bindings/default_bindings.c
index 91595af..406c350 100644
--- a/src/key_bindings/default_bindings.c
+++ b/src/key_bindings/default_bindings.c
@@ -20,6 +20,8 @@ const key_function_t key_functions[] = {
{"forward-char", &forward_char_command},
{"beginning-of-line", &beginning_of_line_command},
{"end-of-line", &end_of_line_command},
+ {"up-history", &up_history_command},
+ {"down-history", &down_history_command},
{NULL, NULL}
};
@@ -35,5 +37,6 @@ const binding_t emacs_bindings[] = {
{KEY_END, &end_of_line_command},
{KEY_UP, &up_history_command},
{KEY_DOWN, &down_history_command},
+ {'\t', &complete_command},
{0, NULL}
};
\ No newline at end of file
From 324be40b7ea5896e28c1b77603094ca12d16b3c5 Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Thu, 21 May 2020 23:44:44 +0200
Subject: [PATCH 2/8] Completing the command when only one file is available
---
include/utility.h | 4 +-
src/glob.c | 2 +-
src/key_bindings/autocompletion.c | 72 ++++++++++++++++++++++++++++++-
src/my_ncurses/my_ncurses.c | 1 +
src/shell.c | 2 +-
5 files changed, 76 insertions(+), 5 deletions(-)
diff --git a/include/utility.h b/include/utility.h
index 94fe99d..d8b2976 100644
--- a/include/utility.h
+++ b/include/utility.h
@@ -23,4 +23,6 @@ char **split_commands(char *cmd);
int *get_return_separator(char *cmd);
int split_is_invalid(char **cmds, int *return_values, int i);
int count_char(const char *str, char c);
-int ncount_char(const char *str, int end, char c);
\ No newline at end of file
+int ncount_char(const char *str, int end, char c);
+
+#define MAX(x, y) ((x) < (y) ? (y) : (x))
\ No newline at end of file
diff --git a/src/glob.c b/src/glob.c
index 8a7e113..6113b24 100644
--- a/src/glob.c
+++ b/src/glob.c
@@ -26,7 +26,7 @@ char **glob_error(char **argv, int err)
char **globbing(char **argv)
{
static glob_t results;
- int flags = GLOB_DOOFFS | GLOB_NOMAGIC;
+ int flags = GLOB_DOOFFS | GLOB_NOMAGIC | GLOB_TILDE;
int ret = 0;
for (int i = 0; argv[i] && ret == 0; i++) {
diff --git a/src/key_bindings/autocompletion.c b/src/key_bindings/autocompletion.c
index 4f6619b..2a28c27 100644
--- a/src/key_bindings/autocompletion.c
+++ b/src/key_bindings/autocompletion.c
@@ -5,12 +5,80 @@
** autocompletion
*/
+#define _GNU_SOURCE
#include "shell.h"
+#include "utility.h"
+#include
+#include
+#include
+#include
+
+char *get_start_of_current_arg(buffer_t *buffer)
+{
+ if (!buffer->buffer)
+ return (NULL);
+ return (memrchr(buffer->buffer, ' ', buffer->pos) + 1);
+}
+
+void print_results(unsigned count, char **results)
+{
+ unsigned size = 0;
+
+ putchar('\n');
+ my_clrtobot();
+ for (unsigned i = 0; i < count; i++)
+ size = MAX(size, strlen(results[i]));
+ size++;
+ for (unsigned i = 0; i < count; i++)
+ printf("%-*s", size, results[i]);
+}
+
+void buffer_replace(buffer_t *buffer, char *to_replace, int start, int end)
+{
+ int len = strlen(to_replace);
+ int total = len + (buffer->buffer ? strlen(buffer->buffer) : 0);
+
+ if (buffer->size < total) {
+ buffer->buffer = realloc(buffer->buffer, total + 50);
+ buffer->size = total + 50;
+ }
+ for (int i = strlen(buffer->buffer); i > end; i--)
+ buffer->buffer[i + len] = buffer->buffer[i];
+ memcpy(buffer->buffer + start, to_replace, len);
+}
+
+void complete_current(buffer_t *buffer, char *cmd)
+{
+ char *start = get_start_of_current_arg(buffer);
+ char *end;
+
+ if (!start)
+ return;
+ end = strchr(start, ' ');
+ if (!end)
+ end = buffer->buffer + strlen(buffer->buffer);
+ buffer_replace(buffer, cmd, start - buffer->buffer, end - buffer->buffer);
+ buffer->pos = start - buffer->buffer + strlen(cmd);
+}
int complete_command(int key, buffer_t *buffer, env_t *env)
{
- if (!buffer->buffer ||
- (!strchr(buffer->buffer, ' ') && !strchr(buffer->buffer, '\t')))
+ char *str;
+ char *p = get_start_of_current_arg(buffer);
+ glob_t result;
+
+ if (!buffer->buffer || !p)
return (0);
+ str = malloc(buffer->pos - (p - buffer->buffer) + 2);
+ strncpy(str, p, buffer->pos - (p - buffer->buffer) + 1);
+ strcat(str, "*");
+ if (!glob(str, GLOB_MARK | GLOB_BRACE, NULL, &result)) {
+ if (result.gl_pathc == 1)
+ complete_current(buffer, result.gl_pathv[0]);
+ else
+ print_results(result.gl_pathc, result.gl_pathv);
+ }
+ globfree(&result);
+ free(str);
return (0);
}
\ No newline at end of file
diff --git a/src/my_ncurses/my_ncurses.c b/src/my_ncurses/my_ncurses.c
index bc13b0c..9a9ede8 100644
--- a/src/my_ncurses/my_ncurses.c
+++ b/src/my_ncurses/my_ncurses.c
@@ -19,6 +19,7 @@ void on_resize(int sig, siginfo_t *info, void *context)
{
my_getmaxyx(&stdwin->h, &stdwin->w);
my_getcuryx(&stdwin->y, &stdwin->x);
+ my_clrtobot();
}
my_window *my_initwin(void)
diff --git a/src/shell.c b/src/shell.c
index bb722c6..debeff6 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -57,7 +57,7 @@ void shell_refresh(buffer_t *buffer, env_t *env)
if (buffer->buffer)
my_mvaddstr(env->window, y, buffer->startx, buffer->buffer);
- my_clrtobot();
+ my_clrtoeol();
my_move(env->window, newy, buf_getx(buffer, env));
my_refresh();
oldbuffer_pos = buffer->pos;
From 3e619f78bd4c62e05782d9dc08e520c9e6ed0dcd Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Fri, 22 May 2020 02:21:48 +0200
Subject: [PATCH 3/8] Handling middle autocompletion
---
src/key_bindings/autocompletion.c | 10 +++++++---
src/shell.c | 1 +
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/key_bindings/autocompletion.c b/src/key_bindings/autocompletion.c
index 2a28c27..31e7b31 100644
--- a/src/key_bindings/autocompletion.c
+++ b/src/key_bindings/autocompletion.c
@@ -42,9 +42,12 @@ void buffer_replace(buffer_t *buffer, char *to_replace, int start, int end)
buffer->buffer = realloc(buffer->buffer, total + 50);
buffer->size = total + 50;
}
- for (int i = strlen(buffer->buffer); i > end; i--)
- buffer->buffer[i + len] = buffer->buffer[i];
+ if (!buffer->buffer)
+ return;
+ for (int i = strlen(buffer->buffer); i >= end; i--)
+ buffer->buffer[i + len - 1] = buffer->buffer[i];
memcpy(buffer->buffer + start, to_replace, len);
+ buffer->buffer[total - (end - start)] = '\0';
}
void complete_current(buffer_t *buffer, char *cmd)
@@ -70,7 +73,8 @@ int complete_command(int key, buffer_t *buffer, env_t *env)
if (!buffer->buffer || !p)
return (0);
str = malloc(buffer->pos - (p - buffer->buffer) + 2);
- strncpy(str, p, buffer->pos - (p - buffer->buffer) + 1);
+ strncpy(str, p, buffer->pos - (p - buffer->buffer));
+ str[buffer->pos - (p - buffer->buffer)] = '\0';
strcat(str, "*");
if (!glob(str, GLOB_MARK | GLOB_BRACE, NULL, &result)) {
if (result.gl_pathc == 1)
diff --git a/src/shell.c b/src/shell.c
index debeff6..8f77e8f 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -23,6 +23,7 @@ int process_key(int key, buffer_t *buffer, env_t *env)
{
if (key <= 0)
return (0);
+ my_clrtobot();
for (int i = 0; env->bindings[i].func; i++)
if (key == env->bindings[i].key)
return (env->bindings[i].func(key, buffer, env));
From f86e694bc6a59b7c6179a266cd1d38e4197d599e Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Fri, 22 May 2020 21:06:21 +0200
Subject: [PATCH 4/8] =?UTF-8?q?Handling=20line=20overflow=20for=20autocomp?=
=?UTF-8?q?letions=C3=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/key_bindings/autocompletion.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/key_bindings/autocompletion.c b/src/key_bindings/autocompletion.c
index 31e7b31..572ace8 100644
--- a/src/key_bindings/autocompletion.c
+++ b/src/key_bindings/autocompletion.c
@@ -20,17 +20,22 @@ char *get_start_of_current_arg(buffer_t *buffer)
return (memrchr(buffer->buffer, ' ', buffer->pos) + 1);
}
-void print_results(unsigned count, char **results)
+void print_results(my_window *window, unsigned count, char **results)
{
unsigned size = 0;
+ int per_line;
putchar('\n');
my_clrtobot();
for (unsigned i = 0; i < count; i++)
size = MAX(size, strlen(results[i]));
size++;
- for (unsigned i = 0; i < count; i++)
- printf("%-*s", size, results[i]);
+ per_line = window->w / size;
+ for (unsigned i = 0; i < count; i += per_line) {
+ for (int j = 0; j < per_line && i + j < count; j++)
+ printf("%-*s", size, results[i + j]);
+ printf("\n");
+ }
}
void buffer_replace(buffer_t *buffer, char *to_replace, int start, int end)
@@ -80,7 +85,7 @@ int complete_command(int key, buffer_t *buffer, env_t *env)
if (result.gl_pathc == 1)
complete_current(buffer, result.gl_pathv[0]);
else
- print_results(result.gl_pathc, result.gl_pathv);
+ print_results(env->window, result.gl_pathc, result.gl_pathv);
}
globfree(&result);
free(str);
From ea3e6b30a497080eb3e846a344c748807f6815db Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Fri, 22 May 2020 21:26:32 +0200
Subject: [PATCH 5/8] Removing prefixs on subdirectory autocompletion listing
---
src/key_bindings/autocompletion.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/key_bindings/autocompletion.c b/src/key_bindings/autocompletion.c
index 572ace8..fec28f4 100644
--- a/src/key_bindings/autocompletion.c
+++ b/src/key_bindings/autocompletion.c
@@ -24,17 +24,21 @@ void print_results(my_window *window, unsigned count, char **results)
{
unsigned size = 0;
int per_line;
+ int prefix_length = 0;
+ char *p = memrchr(results[0], '/', strlen(results[0]) - 1);
+ if (p)
+ prefix_length = p - results[0] + 1;
putchar('\n');
my_clrtobot();
for (unsigned i = 0; i < count; i++)
- size = MAX(size, strlen(results[i]));
+ size = MAX(size, strlen(results[i]) - prefix_length);
size++;
per_line = window->w / size;
for (unsigned i = 0; i < count; i += per_line) {
for (int j = 0; j < per_line && i + j < count; j++)
- printf("%-*s", size, results[i + j]);
- printf("\n");
+ printf("%-*s", size, results[i + j] + prefix_length);
+ putchar('\n');
}
}
From 5578eff174488cb8e160ac9428a731c1d14923b5 Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Fri, 22 May 2020 23:18:42 +0200
Subject: [PATCH 6/8] Handling scroll on autocompletion
---
src/key_bindings/autocompletion.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/key_bindings/autocompletion.c b/src/key_bindings/autocompletion.c
index fec28f4..bcba818 100644
--- a/src/key_bindings/autocompletion.c
+++ b/src/key_bindings/autocompletion.c
@@ -40,6 +40,7 @@ void print_results(my_window *window, unsigned count, char **results)
printf("%-*s", size, results[i + j] + prefix_length);
putchar('\n');
}
+ window->y -= MAX(0, (window->y + 2 + ((int)count / per_line) + 1 - window->h));
}
void buffer_replace(buffer_t *buffer, char *to_replace, int start, int end)
From a9f67600767afd76daeccdd31f34d74cc33bc4c4 Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Fri, 22 May 2020 23:20:15 +0200
Subject: [PATCH 7/8] Cleaning up
---
src/key_bindings/autocompletion.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/key_bindings/autocompletion.c b/src/key_bindings/autocompletion.c
index bcba818..53d9e01 100644
--- a/src/key_bindings/autocompletion.c
+++ b/src/key_bindings/autocompletion.c
@@ -40,7 +40,7 @@ void print_results(my_window *window, unsigned count, char **results)
printf("%-*s", size, results[i + j] + prefix_length);
putchar('\n');
}
- window->y -= MAX(0, (window->y + 2 + ((int)count / per_line) + 1 - window->h));
+ window->y -= MAX(0, (window->y + ((int)count / per_line) + 3 - window->h));
}
void buffer_replace(buffer_t *buffer, char *to_replace, int start, int end)
@@ -49,7 +49,7 @@ void buffer_replace(buffer_t *buffer, char *to_replace, int start, int end)
int total = len + (buffer->buffer ? strlen(buffer->buffer) : 0);
if (buffer->size < total) {
- buffer->buffer = realloc(buffer->buffer, total + 50);
+ buffer->buffer = realloc(buffer->buffer, total + 50);
buffer->size = total + 50;
}
if (!buffer->buffer)
From 656054ec9ea91c281b5decbc3b9c8b817e3d099a Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Sat, 23 May 2020 14:41:57 +0200
Subject: [PATCH 8/8] Solving a segfault
---
src/key_bindings/autocompletion.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/key_bindings/autocompletion.c b/src/key_bindings/autocompletion.c
index 53d9e01..d53e156 100644
--- a/src/key_bindings/autocompletion.c
+++ b/src/key_bindings/autocompletion.c
@@ -15,9 +15,14 @@
char *get_start_of_current_arg(buffer_t *buffer)
{
+ char *p;
+
if (!buffer->buffer)
return (NULL);
- return (memrchr(buffer->buffer, ' ', buffer->pos) + 1);
+ p = memrchr(buffer->buffer, ' ', buffer->pos);
+ if (!p)
+ return (NULL);
+ return (p + 1);
}
void print_results(my_window *window, unsigned count, char **results)
@@ -83,6 +88,8 @@ int complete_command(int key, buffer_t *buffer, env_t *env)
if (!buffer->buffer || !p)
return (0);
str = malloc(buffer->pos - (p - buffer->buffer) + 2);
+ if (!str)
+ return (0);
strncpy(str, p, buffer->pos - (p - buffer->buffer));
str[buffer->pos - (p - buffer->buffer)] = '\0';
strcat(str, "*");