First completion level is working (LSP connected)
This commit is contained in:
+56
-7
@@ -6,6 +6,8 @@
|
||||
#include "include/buffer.h"
|
||||
#include "include/data.h"
|
||||
#include "include/split_screen.h"
|
||||
#include "include/completion.h"
|
||||
#include "include/lsp_ui.h"
|
||||
#include <ctype.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
@@ -18,6 +20,7 @@
|
||||
|
||||
#include "include/terminal.h"
|
||||
#include "include/utf8.h"
|
||||
#include "include/utils.h"
|
||||
|
||||
extern struct editorConfig E;
|
||||
|
||||
@@ -37,7 +40,7 @@ extern struct editorConfig E;
|
||||
* - path ends with '/' (already a directory)
|
||||
* - no matching entries found
|
||||
* - directory cannot be opened
|
||||
* @note Caller is responsible for freeing the returned string
|
||||
* @note Caller is responsible for bFreeing the returned string
|
||||
* @note Uses static buffer internally; may return stale pointers across calls
|
||||
*/
|
||||
const char *fileCompletion(const char *path) {
|
||||
@@ -92,7 +95,7 @@ const char *fileCompletion(const char *path) {
|
||||
// Cleanup when no more entries
|
||||
closedir(dir);
|
||||
dir = NULL;
|
||||
free(entry);
|
||||
bFree(entry);
|
||||
appDebug("[FILE COMP] no entries\n");
|
||||
return strdup(path);
|
||||
}
|
||||
@@ -108,13 +111,13 @@ const char *fileCompletion(const char *path) {
|
||||
* @return Pointer to the user-entered text (dynamically allocated), or NULL if:
|
||||
* - User pressed ESC to cancel
|
||||
* - Input buffer is empty when Enter is pressed
|
||||
* @note Caller is responsible for freeing the returned string
|
||||
* @note Caller is responsible for bFreeing the returned string
|
||||
* @note Uses editorReadKey() for input and editorRefreshScreen() for display
|
||||
*/
|
||||
char *editorPrompt(char *prompt, char *placeHolder, char bPathMode) {
|
||||
size_t buf_size = 256;
|
||||
appDebug("[FILE COMP] %s %d\n", placeHolder, strlen(placeHolder));
|
||||
char *buf = malloc(buf_size);
|
||||
char *buf = bAlloc(buf_size);
|
||||
size_t buf_len = 0;
|
||||
int c = 0;
|
||||
buf[0] = '\0';
|
||||
@@ -131,7 +134,7 @@ char *editorPrompt(char *prompt, char *placeHolder, char bPathMode) {
|
||||
}
|
||||
} else if (c == ESCAPE) {
|
||||
editorSetStatusMessage("");
|
||||
free(buf);
|
||||
bFree(buf);
|
||||
return NULL;
|
||||
} else if (c == '\r') {
|
||||
if (buf_len != 0) {
|
||||
@@ -154,14 +157,14 @@ char *editorPrompt(char *prompt, char *placeHolder, char bPathMode) {
|
||||
buf_len = 0;
|
||||
char * buf_complete = (char *) fileCompletion(path);
|
||||
strcpy(buf, buf_complete);
|
||||
free(buf_complete);
|
||||
bFree(buf_complete);
|
||||
buf_len = strlen(buf);
|
||||
buf[buf_len] = '\0';
|
||||
|
||||
} else if (!iscntrl(c) && c < 256) {
|
||||
if (buf_len == buf_size - 1) {
|
||||
buf_size *= 2;
|
||||
buf = realloc(buf, buf_size);
|
||||
buf = bRealloc(buf, buf_size);
|
||||
}
|
||||
buf[buf_len++] = c;
|
||||
buf[buf_len] = '\0';
|
||||
@@ -213,6 +216,52 @@ void editorProcessKeypress() {
|
||||
int c = editorReadKey();
|
||||
char key_sequence[8];
|
||||
|
||||
if (E.lsp_client && E.lsp_completion.visible) {
|
||||
if (c == ARROW_UP || c == CTRL_KEY('p')) {
|
||||
if (E.lsp_completion.selected > 0)
|
||||
E.lsp_completion.selected--;
|
||||
return; // consumed, redraw on next loop
|
||||
}
|
||||
if (c == ARROW_DOWN || c == CTRL_KEY('n')) {
|
||||
if (E.lsp_completion.selected < E.lsp_completion.count - 1)
|
||||
E.lsp_completion.selected++;
|
||||
return;
|
||||
}
|
||||
if (c == '\r') {
|
||||
CompletionItem *item = &E.lsp_completion.items[E.lsp_completion.selected];
|
||||
EditorPane *active = splitScreenGetActivePane();
|
||||
struct buffer_t *buf = bufferFindById(active->buffer_id);
|
||||
|
||||
// Find how many chars the user already typed by looking at the
|
||||
// current word (chars before cursor on the same line)
|
||||
int file_col = active->cursor_x + active->x_offset;
|
||||
row_t *row = &buf->row[active->cursor_y + active->y_offset];
|
||||
|
||||
// Walk backwards from cursor to find start of current word
|
||||
int word_start = file_col;
|
||||
while (word_start > 0 &&
|
||||
(isalnum((unsigned char)row->chars[word_start - 1]) ||
|
||||
row->chars[word_start - 1] == '_'))
|
||||
word_start--;
|
||||
|
||||
int already_typed = file_col - word_start; // chars user already typed
|
||||
|
||||
// Insert only the suffix — what comes after what's already typed
|
||||
const char *suffix = item->label + already_typed;
|
||||
for (int i = 0; suffix[i]; i++)
|
||||
bufferInsertBytes(&suffix[i], 1);
|
||||
|
||||
E.lsp_completion.visible = 0;
|
||||
return;
|
||||
}
|
||||
if (c == ESCAPE) {
|
||||
E.lsp_completion.visible = 0;
|
||||
return;
|
||||
}
|
||||
// Any other key: dismiss popup and fall through to normal handling
|
||||
E.lsp_completion.visible = 0;
|
||||
}
|
||||
|
||||
if (executeKeyBind(keyToString(c))) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user