From 5588b0a8d73698f1f45aaf8b8fc18ea076f1be93 Mon Sep 17 00:00:00 2001 From: arthur Date: Wed, 5 Nov 2025 15:49:01 +0100 Subject: [PATCH] add path autocomplete --- include/input.h | 2 +- src/builtins.c | 2 +- src/file_io.c | 6 ++-- src/input.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 76 insertions(+), 8 deletions(-) diff --git a/include/input.h b/include/input.h index 2a6c948..2c031ef 100644 --- a/include/input.h +++ b/include/input.h @@ -20,7 +20,7 @@ // END \x1b[4~ || [8~ || [F || OF // DELETE \x1b[3~ -char *editorPrompt(char *prompt); +char *editorPrompt(char *prompt, char * PlaceHolder, char bPathMode); char *key_to_string(int key); diff --git a/src/builtins.c b/src/builtins.c index 0403e19..7d930ed 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -125,7 +125,7 @@ Lisp editorMoveCursorPageDown(Lisp args, LispError* e, LispContext ctx) { } Lisp editorOpenFile(Lisp args, LispError *e, LispContext ctx) { - char *filename = editorPrompt("Path : %s"); + char *filename = editorPrompt("Open : %s", getenv("PWD"), 1); if (filename) editorOpen(filename); diff --git a/src/file_io.c b/src/file_io.c index 1f98d63..a0fb3a7 100644 --- a/src/file_io.c +++ b/src/file_io.c @@ -87,7 +87,7 @@ void editorSave() { char *buf; int fd; if (E.filename == NULL) { - E.filename = editorPrompt("Save as: %s (ESC to cancel)"); + E.filename = editorPrompt("Save as: %s (ESC to cancel)", "", 1); if (E.filename == NULL) { editorSetStatusMessage("Save aborted"); return; @@ -112,10 +112,10 @@ void editorSave() { } void editorFind() { - char *query = editorPrompt("Search: %s (ESC to cancel)"); + char *query = editorPrompt("Search: %s (ESC to cancel)", "", 0); if (query == NULL) return; int i; - for (i = 0; i < E.numrows; i++) { + for (i = E.cursor_y + 1; i < E.numrows; i++) { erow *row = &E.row[i]; char *match = strstr(row->render, query); if (match) { diff --git a/src/input.c b/src/input.c index dcb579e..808c72c 100644 --- a/src/input.c +++ b/src/input.c @@ -3,6 +3,8 @@ #include "../include/output.h" #include "../include/define.h" #include +#include +#include #include #include #include @@ -11,19 +13,67 @@ extern struct editorConfig E; +char * file_completion(const char *path) { + DIR * dir; + struct dirent *entry; + char directory[128]; + char predict[128]; + size_t predict_len; + + // Find dir name + char * last_slash = strrchr(path, '/'); + if (last_slash) { + size_t dir_len = last_slash - path + 1; // length of dir_path + strncpy(directory, path, dir_len); + predict_len = strlen(path) - dir_len - 1; + strncpy(predict, last_slash + 1, predict_len); + directory[dir_len] = '\0'; + fprintf(stderr, "%s %s\n", directory, predict); + predict[predict_len] = '\0'; + } else { + return NULL; + } + + dir = opendir(directory); + if (!dir) + return NULL; + + while ((entry = readdir(dir)) != NULL) { + if (strncmp(entry->d_name, predict, predict_len) == 0) { + static char full_path[128]; + snprintf(full_path, sizeof(full_path), "%s%s", directory, entry->d_name); + + struct stat st; + if (stat(full_path, &st) == 0 && S_ISDIR(st.st_mode)) { + strcat(full_path, "/"); // add slash for directories + } + + return strdup(full_path); + } + } + + // Cleanup when no more entries + closedir(dir); + dir = NULL; + return NULL; + +} + /** - * \fn char * editorPrompt(struct editorConfig *E, char *prompt) + * \fn char * editorPrompt(struct editorConfig *E, char *prompt, char bPathMode) * \brief Return user input in a prompt when enter is hit. */ -char *editorPrompt(char *prompt) { +char *editorPrompt(char *prompt, char * placeHolder, char bPathMode) { size_t buf_size = 128; char *buf = malloc(buf_size); size_t buf_len = 0; int c = 0; buf[0] = '\0'; + strcpy(buf, placeHolder); + buf_len = strlen(placeHolder); while (1) { - editorSetStatusMessage(prompt, buf); + editorSetStatusMessage(prompt, buf); editorRefreshScreen(); c = editorReadKey(); if (c == DEL_KEY || c == CTRL_KEY('h') || c == BACKSPACE) { @@ -39,6 +89,24 @@ char *editorPrompt(char *prompt) { editorSetStatusMessage(""); return buf; } + } else if (bPathMode && c == '\t') { + char path[128]; + char * pwd; + if (buf[0] != '/') { + pwd = getenv("PWD"); + fprintf(stderr, "%s\n", pwd); + memcpy(path, pwd, strlen(pwd)); + path[strlen(pwd)] = '/'; + strncat(path, buf, buf_len); + } else { + strcpy(path, buf); + } + memset(buf, 0, 128); + buf_len = 0; + strcpy(buf, file_completion(path)); + buf_len = strlen(buf); + buf[buf_len] = '\0'; + } else if (!iscntrl(c) && c < 128) { if (buf_len == buf_size - 1) { buf_size *= 2;