mirror of
https://github.com/Savapitech/42sh.git
synced 2026-01-18 16:57:28 +01:00
Add basic auto completion
This commit is contained in:
3
FIX.md
3
FIX.md
@@ -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
|
||||
|
||||
6
TODO.md
6
TODO.md
@@ -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
|
||||
|
||||
61
src/repl/auto_completion.c
Normal file
61
src/repl/auto_completion.c
Normal 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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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
36
src/repl/term.c
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user