Add basic auto completion

This commit is contained in:
savalet
2025-05-22 20:46:34 +02:00
parent 8a435ee798
commit f0f5dfa7f0
6 changed files with 116 additions and 24 deletions

3
FIX.md
View File

@@ -4,8 +4,7 @@
- [ ] !x no args
- [x] Conditional jump/ invalid read with cd (PWD env var set)
- [x] Alias loop
- [ ] All AFL crashes
- [ ] Fix CTRL+E and ->
- [x] Fix CTRL+E and ->
- [x] Multi line editing
- [ ] Foreach in if
- [x] Output flushing when open an other shell with 42sh

View File

@@ -1,7 +1,7 @@
# TODO
- [x] Add job control in main branch
- [ ] Add auto complete
- [ ] Finish line editing
- [x] Add auto complete
- [ ] Syntax highlighting
- [ ] CTRL+R
- [x] CTRL+R
- [x] Git integration
- [x] Finish line editing

View File

@@ -0,0 +1,61 @@
/*
** EPITECH PROJECT, 2025
** __
** File description:
** _
*/
#include <ctype.h>
#include <glob.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "readline.h"
static
buff_t get_current_word(readline_helper_t *rh, buff_t *buff)
{
buff_t word = {buff->str, .sz = rh->cursor};
for (size_t i = rh->cursor; i; i--) {
if (isblank(buff->str[i])) {
word.str = &buff->str[i + 1];
word.sz = rh->cursor - (i + 1);
break;
}
}
return word;
}
bool handle_key_tab(readline_helper_t *rh, exec_ctx_t *ec, buff_t *buff)
{
buff_t word;
glob_t globs;
char *pattern;
if (!rh->cursor || !buff->sz)
return false;
printf("TAB\n");
word = get_current_word(rh, buff);
printf("Current word [%.*s]\n", (int)word.sz, word.str);
pattern = malloc(sizeof *pattern * (word.sz + 2));
if (pattern == nullptr)
return true;
strncpy(pattern, word.str, word.sz);
strcpy(pattern + word.sz, "*\0");
printf("Gen pattern [%s]\n", pattern);
if (glob(pattern, GLOB_ERR, nullptr, &globs) != 0)
return false;
for (size_t i = 0; i < globs.gl_pathc; i++) {
printf("Path v [%s] [%zu]\n", globs.gl_pathv[i], i);
}
if (!ensure_buff_av_capacity(buff, strlen(globs.gl_pathv[0])))
return true;
strcpy(word.str, globs.gl_pathv[0]);
buff->sz += strlen(globs.gl_pathv[0]) - word.sz;
rh->cursor = buff->sz;
refresh_line(rh);
free(pattern);
return false;
}

View File

@@ -31,6 +31,7 @@ bool handle_key_ctrl_y(readline_helper_t *rh, exec_ctx_t *, buff_t *buff);
bool handle_key_ctrl_r(readline_helper_t *rh, exec_ctx_t *ec, buff_t *buff);
bool handle_backspace(readline_helper_t *rh, exec_ctx_t *ec, buff_t *buff);
bool handle_delete(readline_helper_t *rh, exec_ctx_t *, buff_t *buff);
bool handle_key_tab(readline_helper_t *rh, exec_ctx_t *ec, buff_t *buff);
// Arrows
bool handle_key_arrow_up(readline_helper_t *rh, exec_ctx_t *ec, buff_t *buff);

View File

@@ -34,6 +34,7 @@ const key_handler_t KEY_HANDLERS[] = {
{ESC "[B", handle_key_arrow_down},
{ESC "[C", handle_key_arrow_right},
{ESC "[D", handle_key_arrow_left},
{"\t", handle_key_tab},
{"\x7f", handle_backspace},
{"\x1b[3~", handle_delete},
};
@@ -62,6 +63,10 @@ void print_git_prompt(git_status_t *gs)
{
if (!gs->ahead && !gs->behind)
printf(BLUE " [" RED "%s" BLUE "] " RESET "-", gs->branch);
if (gs->ahead)
printf(BLUE " [" RED "%s" GREEN " +" BLUE "] " RESET "-", gs->branch);
else if (gs->behind)
printf(BLUE " [" RED "%s" RED " -" BLUE "] " RESET "-", gs->branch);
}
static
@@ -105,26 +110,14 @@ void print_shell_prompt(exec_ctx_t *ec)
}
}
void init_shell_repl(exec_ctx_t *ec)
bool is_sequence(char *read_buff)
{
struct termios new_settings = ec->saved_term_settings;
ec->is_running = true;
if (ec->isatty) {
setvbuf(stdout, nullptr, _IONBF, 0);
WRITE_CONST(STDOUT_FILENO, BLINKING_VERTICAL_CURSOR);
new_settings.c_iflag &= ~IXON;
new_settings.c_lflag &= ~(ECHO | ICANON | ISIG);
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;
tcsetattr(ec->read_fd, TCSANOW, &new_settings);
for (size_t i = 0; i < sizeof KEY_HANDLERS / sizeof *KEY_HANDLERS; i++) {
if (strncmp(read_buff, KEY_HANDLERS[i].name,
strlen(KEY_HANDLERS[i].name)) == 0)
return true;
}
}
void restore_term_flags(exec_ctx_t *exec_ctx)
{
if (exec_ctx->isatty)
tcsetattr(exec_ctx->read_fd, TCSANOW, &exec_ctx->saved_term_settings);
return false;
}
ssize_t handle_keys(
@@ -133,6 +126,8 @@ ssize_t handle_keys(
char const *read_buff,
size_t len)
{
if (!rh->ec->isatty)
return 0;
for (size_t i = 0; i < sizeof KEY_HANDLERS / sizeof *KEY_HANDLERS; i++) {
if (strncmp(read_buff, KEY_HANDLERS[i].name,
strlen(KEY_HANDLERS[i].name)) != 0)
@@ -143,5 +138,5 @@ ssize_t handle_keys(
}
for (size_t i = 0; i < len; i++)
U_DEBUG("<- [%d]\n", read_buff[i]);
return 1;
return 0;
}

36
src/repl/term.c Normal file
View File

@@ -0,0 +1,36 @@
/*
** EPITECH PROJECT, 2025
** __
** File description:
** _
*/
#include <stdio.h>
#include <unistd.h>
#include "builtins_handler.h"
#include "u_str.h"
#include "vt100_esc_codes.h"
void init_shell_repl(exec_ctx_t *ec)
{
struct termios new_settings = ec->saved_term_settings;
ec->is_running = true;
if (ec->isatty) {
setvbuf(stdout, nullptr, _IONBF, 0);
WRITE_CONST(STDOUT_FILENO, BLINKING_VERTICAL_CURSOR);
new_settings.c_iflag &= ~IXON;
new_settings.c_lflag &= ~(ECHO | ICANON | ISIG);
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;
tcsetattr(ec->read_fd, TCSANOW, &new_settings);
}
}
void restore_term_flags(exec_ctx_t *exec_ctx)
{
if (exec_ctx->isatty)
tcsetattr(exec_ctx->read_fd, TCSANOW, &exec_ctx->saved_term_settings);
}