From 3d49a0e2ebd3537d73377bcfbc59f55c42706ca4 Mon Sep 17 00:00:00 2001 From: arthur barraux Date: Tue, 26 May 2026 08:28:38 +0200 Subject: [PATCH] copy paste functions --- config/init.lisp | 4 + include/buffer.h | 8 +- include/builtins.h | 8 +- include/data.h | 9 ++ include/define.h | 14 ++- include/editor_op.h | 7 +- include/file_io.h | 2 - include/input.h | 2 +- include/row_op.h | 9 +- include/syntax_highlighter.h | 2 - include/terminal.h | 4 +- main.c | 3 - meson.build | 3 +- src/buffer.c | 156 ++++++++++++++++++++++++++++++- src/builtins.c | 53 ++++++++++- src/editor_op.c | 174 ++++++++++++++++++----------------- src/file_io.c | 1 + src/init.c | 8 +- src/input.c | 65 +------------ src/output.c | 28 +++--- src/row_op.c | 90 +----------------- src/terminal.c | 6 +- src/utf8.c | 1 - 23 files changed, 369 insertions(+), 288 deletions(-) diff --git a/config/init.lisp b/config/init.lisp index d7bcab9..734fcea 100644 --- a/config/init.lisp +++ b/config/init.lisp @@ -86,3 +86,7 @@ (map-key "\"" editor-split-screen-vertical "user") (map-key "o" editor-switch-next-pane "user") (map-key "*" editor-unify-panes "user") +(map-key "CTRL-y" editor-paste "no-prefix") +(map-key "CTRL-k" editor-cut-end-line "no-prefix") +(map-key "a" editor-move-cursor-beg-buffer "user") +(map-key "z" editor-move-cursor-end-buffer "user") diff --git a/include/buffer.h b/include/buffer.h index fe13eba..818a80a 100644 --- a/include/buffer.h +++ b/include/buffer.h @@ -57,7 +57,13 @@ int bufferSaveAll(void); void bufferFind(struct buffer_t *buf); void bufferFindReverse(struct buffer_t* buf); - +void bufferInsertNewLine(); +void bufferInsertBytes(const char *src, int n); +void bufferDelBytes(); +void bufferRowInsertBytes(struct buffer_t *buffer, row_t *row, int at, const char *src, int n); +void bufferRowDelByte(struct buffer_t *buffer, row_t *row, int at, int n); +void bufferInsertRow(struct buffer_t *buffer, int at, char *s, size_t len); +void bufferFreeRow(row_t *row); #endif diff --git a/include/builtins.h b/include/builtins.h index e2de1cc..89c3fe7 100644 --- a/include/builtins.h +++ b/include/builtins.h @@ -45,12 +45,16 @@ Lisp editorSwitchNextPane(Lisp args, LispError *e, LispContext ctx); Lisp editorUnifiedPanes(Lisp args, LispError *e, LispContext ctx); +Lisp editorPaste(Lisp args, LispError *e, LispContext ctx); +Lisp editorCutEndLine(Lisp args, LispError *e, LispContext ctx); - - +Lisp editorMoveBegBuffer(Lisp args, LispError *e, LispContext ctx); +Lisp editorMoveEndBuffer(Lisp args, LispError *e, LispContext ctx); // Other + + void free_structs(void); #endif diff --git a/include/data.h b/include/data.h index 4f547dd..32dd6a0 100644 --- a/include/data.h +++ b/include/data.h @@ -19,6 +19,13 @@ typedef struct row { char *chars; /**< Characters of the line */ } row_t; +typedef struct context_buffer_t +{ + int editor_x, editor_y; + int width, height; + row_t *rows; +} ContextBuffer; + /** * @brief Split modes for screen layout */ @@ -113,6 +120,8 @@ struct editorConfig { row_t *rows; /**< Store all the rows printed */ + ContextBuffer* context_buffers; + int dirty; char *status_msg; diff --git a/include/define.h b/include/define.h index e31da55..e5aeab3 100644 --- a/include/define.h +++ b/include/define.h @@ -2,15 +2,17 @@ #define DEFINE_H_ #define CTRL_KEY(k) ((k) & 0x1f) +#define ALT(k) ((k) | 0x200) // set bit 9 to mark as Option combo + #define ESCAPE '\x1b' #define CURSOR_TOP_LEFT "\x1b[H" #define HIDE_CURSOR "\x1b[?25l" #define SHOW_CURSOR "\x1b[?25h" #define ERASE_END_LINE "\x1b[K" -#define TAB "\x9" +#define TAB "\t" #define SPACE "\x20" -// #define APP_DEBUG +#define APP_DEBUG enum editorKey_e { BACKSPACE = 127, @@ -29,4 +31,12 @@ enum editorKey_e { #define BELUGA_VERSION "2.4" +#ifdef __APPLE__ +#define CLIPBOARD_COPY_CMD "pbcopy" +#define CLIPBOARD_PASTE_CMD "pbpaste" +#else +#define CLIPBOARD_COPY_CMD "xclip -selection clipboard" +#define CLIPBOARD_PASTE_CMD "xclip -selection clipboard -o" +#endif + #endif // DEFINE_H_ diff --git a/include/editor_op.h b/include/editor_op.h index d174d27..0c9857d 100644 --- a/include/editor_op.h +++ b/include/editor_op.h @@ -3,10 +3,11 @@ #include "data.h" -void bufferInsertNewLine(); -void bufferInsertBytes(char *src, int n); void editorSetStatusMessage(const char *fmt, ...); -void bufferDelBytes(); +int editorRowCharCount(row_t *row, int x); +int editorRowCxToByte(const row_t *row, int cursor_x); +char *editorGetClipboard(void); +void editorSetClipboard(const char *text, int len); #endif // EDITOR_OP_H_ diff --git a/include/file_io.h b/include/file_io.h index abd7a3e..86d382a 100644 --- a/include/file_io.h +++ b/include/file_io.h @@ -2,8 +2,6 @@ #define FILE_IO_H_ #include "data.h" -#include "row_op.h" -#include "terminal.h" #include #include #include diff --git a/include/input.h b/include/input.h index af90923..5dc33c5 100644 --- a/include/input.h +++ b/include/input.h @@ -22,7 +22,7 @@ char *editorPrompt(char *prompt, char * PlaceHolder, char bPathMode); -const char *file_completion(const char *path); +const char *fileCompletion(const char *path); int editorMoveCursor(int key); diff --git a/include/row_op.h b/include/row_op.h index 3742b66..1af8f16 100644 --- a/include/row_op.h +++ b/include/row_op.h @@ -8,11 +8,8 @@ #include #include -void bufferInsertRow(struct buffer_t *buffer, int at, char *s, size_t len); -int editorRowCxToByte(const row_t *row, int cursor_x); -void bufferFreeRow(row_t *row); -int editorRowCharCount(row_t *row, int x); -void bufferRowInsertBytes(struct buffer_t *buffer, row_t *row, int at, char *src, int n); -void bufferRowDelByte(struct buffer_t *buffer, row_t *row, int at, int n); + + + #endif // ROW_OP_H_ diff --git a/include/syntax_highlighter.h b/include/syntax_highlighter.h index 294f294..d801539 100644 --- a/include/syntax_highlighter.h +++ b/include/syntax_highlighter.h @@ -1,7 +1,6 @@ #ifndef SYNTAX_HIGHLIGHTER_H_ #define SYNTAX_HIGHLIGHTER_H_ -#include "color.h" // Color codes that only affect foreground, preserving your background color #define COLOR_RESET "\x1b[39m" // Reset all (4 bytes) @@ -20,4 +19,3 @@ typedef enum { char *highlight_line(const char * line, int *length); #endif - diff --git a/include/terminal.h b/include/terminal.h index 6769379..86c6e79 100644 --- a/include/terminal.h +++ b/include/terminal.h @@ -4,8 +4,6 @@ /* includes */ -#include "data.h" -#include "define.h" #include #include #include @@ -31,7 +29,7 @@ int getCursorPosition(int *rows, int *cols); int getWindowSize(int *rows, int *cols); -char *key_to_string(int key); +char *keyToString(int key); void appDebug(const char *fmt, ...); diff --git a/main.c b/main.c index ae9f15f..954cce3 100644 --- a/main.c +++ b/main.c @@ -11,13 +11,10 @@ #include "include/buffer.h" #include "include/split_screen.h" -#include -#include #include #include #include "include/data.h" -#include "include/file_io.h" #include "include/init.h" #include "include/input.h" #include "include/editor_op.h" diff --git a/meson.build b/meson.build index 9fec757..a8ff411 100644 --- a/meson.build +++ b/meson.build @@ -23,7 +23,8 @@ src_files = files( 'src/builtins.c', 'src/buffer.c', 'src/split_screen.c', - 'src/utf8.c' + 'src/utf8.c', + 'src/completion.c' ) # Executable diff --git a/src/buffer.c b/src/buffer.c index dd4b099..a73b811 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -15,7 +15,6 @@ #include "include/input.h" -extern struct editorConfig E; /** * @brief Finds a buffer by filename @@ -284,7 +283,6 @@ void bufferFind(struct buffer_t* buf) { appDebug("searching\n"); char* query = editorPrompt("Search: %s (ESC to cancel)", "", 0); - EditorPane* active = splitScreenGetActivePane(); if (query == NULL) return; @@ -306,7 +304,6 @@ void bufferFindReverse(struct buffer_t* buf) { appDebug("searching\n"); char* query = editorPrompt("Reverse search: %s (ESC to cancel)", "", 0); - EditorPane* active = splitScreenGetActivePane(); if (query == NULL) return; @@ -325,3 +322,156 @@ void bufferFindReverse(struct buffer_t* buf) } free(query); } + +void bufferInsertRow(struct buffer_t *buffer, int at, char *s, size_t len) { + if (at < 0 || at > buffer->numrows) + return; + + row_t *tmp = realloc(buffer->row, sizeof(row_t) * (buffer->numrows + 1)); + if (!tmp) + return; + buffer->row = tmp; + + /* Shift existing rows to make room at 'at' — no at++ */ + if (at < buffer->numrows) { + memmove(&buffer->row[at + 1], &buffer->row[at], + sizeof(row_t) * (buffer->numrows - at)); /* not -at+1 */ + } + + buffer->row[at].size = len; + buffer->row[at].cap = len + 1; + buffer->row[at].chars = malloc(len + 1); + if (!buffer->row[at].chars) + return; + memcpy(buffer->row[at].chars, s, len); + buffer->row[at].chars[len] = '\0'; /* always NUL-terminate */ + + buffer->numrows++; + buffer->dirty++; +} + +void bufferFreeRow(row_t *row) { free(row->chars); } + +/** + * \fn editorRowInsertChar(erow *row, int at, int c) + * \param at Index of where we want to insert the char */ + +void bufferRowInsertBytes(struct buffer_t *buffer, row_t *row, int at, + const char *src, int n) { + if (buffer->state == READ_ONLY) + return; + if (row->size + n + 1 > row->cap) { + row->cap = (row->size + n + 1) * 2; + row->chars = realloc(row->chars, row->cap); + } + memmove(row->chars + at + n, row->chars + at, row->size - at); + memcpy(row->chars + at, src, n); + row->size += n; + row->chars = realloc(row->chars, row->size + 2); + ++buffer->dirty; +} + +/** + * \fn bufferRowDelChar(struct bufferConfig *E, frow *frow, int at) + * \brief Delete the a char at the chosen position on the given row + * \param at Index of the char to delete + * \param row Row on operation is made */ +void bufferRowDelByte(struct buffer_t *buffer, row_t *row, int at, int n) { + if (buffer->state == READ_ONLY) + return; + if (at < 0 || at >= row->size) + return; + memmove(row->chars + at, row->chars + at + n, row->size - at - n); + row->size -= n; + row->chars[row->size] = '\0'; + buffer->x -= n; + ++buffer->dirty; +} + + +void bufferInsertBytes(const char* src, int n) +{ + appDebug("bufferInsertBytes \r\n"); + EditorPane* active = splitScreenGetActivePane(); + struct buffer_t* buf = bufferFindById(active->buffer_id); + if (buf->y == buf->numrows) + { + bufferInsertRow(buf, buf->numrows, "", 0); + } + bufferRowInsertBytes(buf, &buf->row[buf->y], buf->x, src, n); + buf->x += n; +} + +void bufferDelBytes(void) +{ + EditorPane* active = splitScreenGetActivePane(); + struct buffer_t* buf = bufferFindById(active->buffer_id); + + /* Nothing to delete */ + if (buf->numrows == 0) return; + if (buf->x == 0 && buf->y == 0) return; + + /* Use row_offset, not col_offset, for row indexing */ + row_t* r = &buf->row[buf->y]; + + if (buf->x > 0) + { + int byte_end = editorRowCxToByte(r, buf->x); + int byte_start = editorRowCxToByte(r, buf->x - 1); + int char_width = byte_end - byte_start; /* byte width of the character */ + + bufferRowDelByte(buf, r, byte_start, char_width); + E.dirty = 1; + } + else + { + /* Merge current row into the previous one */ + row_t* prev = &buf->row[buf->y - 1]; // FIX: was buf->y (same as r) + int prev_char_count = editorRowCharCount(prev, prev->size); + + bufferRowInsertBytes(buf, prev, prev->size, r->chars, r->size); + free(r->chars); + r->chars = NULL; + + memmove(&buf->row[buf->y], + &buf->row[buf->y + 1], + sizeof(row_t) * (buf->numrows - buf->y - 1)); + buf->numrows--; + + active->cursor_x = prev_char_count; + buf->x = prev_char_count; + active->cursor_y--; + buf->y--; + E.dirty = 1; + } +} + +void bufferInsertNewLine(void) { + appDebug("Inserting new line\n"); + EditorPane *active = splitScreenGetActivePane(); + struct buffer_t *buf = bufferFindById(active->buffer_id); + + appDebug("buf x %d\n", buf->x); + + if (buf->y >= buf->numrows) { + /* Cursor is past the last row: just append a blank line */ + bufferInsertRow(buf, buf->numrows, "", 0); + } else { + row_t *row = &buf->row[buf->y]; + + /* Insert the tail (from cursor to end) as a new row below */ + bufferInsertRow(buf, buf->y + 1, &row->chars[buf->x], row->size - buf->x); + + /* Re-fetch: realloc inside bufferInsertRow may have moved the array */ + row = &buf->row[buf->y]; + + /* Truncate the current row at the cursor */ + row->size = buf->x; + row->chars[row->size] = '\0'; + /* Do NOT touch row->cap — the allocation is still valid */ + } + + buf->y++; + buf->x = 0; + appDebug("Insert new line done\n"); +} \ No newline at end of file diff --git a/src/builtins.c b/src/builtins.c index f54112f..049f6c2 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -13,8 +13,9 @@ #include "../include/editor_op.h" #include "../include/file_io.h" #include "../include/input.h" -#include "../include/row_op.h" +#include "../include/terminal.h" #include "../include/split_screen.h" +#include "../include/completion.h" #include #include @@ -223,8 +224,6 @@ Lisp l_editorInsertNewLine(Lisp args, LispError *e, LispContext ctx) { * @note Uses E.constantes.TAB_LENGTH for indentation width */ Lisp l_editorInserTab(Lisp args, LispError *e, LispContext ctx) { - EditorPane *active = splitScreenGetActivePane(); - struct buffer_t *buf = bufferFindById(active->buffer_id); for (int i = 0; i < E.constantes.TAB_LENGTH; ++i) { bufferInsertBytes(" ", 1); } @@ -359,7 +358,7 @@ Lisp editorOpenFile(Lisp args, LispError *e, LispContext ctx) { * @note Uses first character of the string argument */ Lisp editorPrintC(Lisp args, LispError *e, LispContext ctx) { - char *src = lisp_string(lisp_car(args)); + const char *src = lisp_string(lisp_car(args)); bufferInsertBytes(src, strlen(src)); return lisp_null(); } @@ -514,3 +513,49 @@ Lisp editorPrefix(Lisp args, LispError *e, LispContext ctx) { 64); return lisp_null(); } + +Lisp editorPaste(Lisp args, LispError *e, LispContext ctx) +{ + const char *char_to_paste = editorGetClipboard(); + appDebug("editor-paste, %s\n", char_to_paste); + bufferInsertBytes(char_to_paste, (int) strlen(char_to_paste)); + return lisp_null(); +} + +Lisp editorCutEndLine(Lisp args, LispError *e, LispContext ctx) +{ + EditorPane *active = splitScreenGetActivePane(); + struct buffer_t *buffer = bufferFindById(active->buffer_id); + int bytes_to_delete = buffer->row[buffer->y].size - buffer->x; + editorSetClipboard(&buffer->row[buffer->y].chars[buffer->x], bytes_to_delete); + buffer->x = buffer->row[buffer->y].size; + while (bytes_to_delete--) + { + bufferDelBytes(); + } + return lisp_null(); +} + +Lisp editorMoveBegBuffer(Lisp args, LispError *e, LispContext ctx) +{ + EditorPane *active = splitScreenGetActivePane(); + struct buffer_t *buffer = bufferFindById(active->buffer_id); + buffer->x = 0; + buffer->y = 0; + return lisp_null(); +} + +Lisp editorMoveEndBuffer(Lisp args, LispError *e, LispContext ctx) +{ + EditorPane *active = splitScreenGetActivePane(); + struct buffer_t *buffer = bufferFindById(active->buffer_id); + buffer->x = buffer->row[buffer->numrows-1].size; + buffer->y = buffer->numrows-1; + return lisp_null(); +} + +Lisp editorAutoComplete(Lisp args, LispError *e, LispContext ctx) +{ + createContextBuffer(E.cursor_x - 2, E.cursor_y + 1, "hello"); + return lisp_null(); +} \ No newline at end of file diff --git a/src/editor_op.c b/src/editor_op.c index 158f767..a028899 100644 --- a/src/editor_op.c +++ b/src/editor_op.c @@ -31,90 +31,100 @@ void editorSetStatusMessage(const char* fmt, ...) E.status_msg_time = time(NULL); } - -void bufferInsertBytes(char* src, int n) -{ - appDebug("bufferInsertBytes \r\n"); - EditorPane* active = splitScreenGetActivePane(); - struct buffer_t* buf = bufferFindById(active->buffer_id); - if (buf->y == buf->numrows) - { - bufferInsertRow(buf, buf->numrows, "", 0); - } - bufferRowInsertBytes(buf, &buf->row[buf->y], buf->x, src, n); - buf->x += n; -} - -void bufferDelBytes(void) -{ - EditorPane* active = splitScreenGetActivePane(); - struct buffer_t* buf = bufferFindById(active->buffer_id); - - /* Nothing to delete */ - if (buf->numrows == 0) return; - if (buf->x == 0 && buf->y == 0) return; - - /* Use row_offset, not col_offset, for row indexing */ - row_t* r = &buf->row[buf->y]; - - if (buf->x > 0) - { - int byte_end = editorRowCxToByte(r, buf->x); - int byte_start = editorRowCxToByte(r, buf->x - 1); - int char_width = byte_end - byte_start; /* byte width of the character */ - - bufferRowDelByte(buf, r, byte_start, char_width); - E.dirty = 1; - } - else - { - /* Merge current row into the previous one */ - row_t* prev = &buf->row[buf->y - 1]; // FIX: was buf->y (same as r) - int prev_char_count = editorRowCharCount(prev, prev->size); - - bufferRowInsertBytes(buf, prev, prev->size, r->chars, r->size); - free(r->chars); - r->chars = NULL; - - memmove(&buf->row[buf->y], - &buf->row[buf->y + 1], - sizeof(row_t) * (buf->numrows - buf->y - 1)); - buf->numrows--; - - active->cursor_x = prev_char_count; - buf->x = prev_char_count; - active->cursor_y--; - buf->y--; - E.dirty = 1; - } -} - -void bufferInsertNewLine(void) { - appDebug("Inserting new line\n"); +/** + * @brief Moves the cursor based on arrow key input + * @details Updates cursor position (E.cursor_x, E.cursor_y) based on the given + * key direction. Handles line wrapping and boundary conditions. Prevents cursor + * from exceeding line lengths. + * @param key The arrow key code (ARROW_UP, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT) + * @return 1 if cursor movement was valid, 0 if cursor was constrained to line boundary + * @note Updates global editor state E + */ +int editorMoveCursor(int key) { EditorPane *active = splitScreenGetActivePane(); struct buffer_t *buf = bufferFindById(active->buffer_id); + row_t *row = &buf->row[buf->y]; + switch (key) { + case ARROW_RIGHT: + if (row && buf->x < row->size) { + int len = utf8Seqlen(row->chars[buf->x]); + buf->x += len; + } else if (row && buf->y < buf->numrows) { + buf->y++; + buf->x = 0; + } + break; + case ARROW_DOWN: + if (buf->y < buf->numrows) { - appDebug("buf x %d\n", buf->x); - - if (buf->y >= buf->numrows) { - /* Cursor is past the last row: just append a blank line */ - bufferInsertRow(buf, buf->numrows, "", 0); - } else { - row_t *row = &buf->row[buf->y]; - - /* Insert the tail (from cursor to end) as a new row below */ - bufferInsertRow(buf, buf->y + 1, &row->chars[buf->x], row->size - buf->x); - - /* Re-fetch: realloc inside bufferInsertRow may have moved the array */ - row = &buf->row[buf->y]; - - /* Truncate the current row at the cursor */ - row->size = buf->x; - row->chars[row->size] = '\0'; - /* Do NOT touch row->cap — the allocation is still valid */ + buf->y++; + } + break; + case ARROW_UP: + if (buf->y != 0) { + --buf->y; + } + break; + case ARROW_LEFT: + if (buf->x != 0) { + --buf->x; + } else if (buf->y > 0) { + --buf->y; + buf->x = buf->row[buf->y].size; + } + break; } - - buf->y++; - buf->x = 0; - appDebug("Insert new line done\n"); + return 1; } + +char *editorGetClipboard(void) { + FILE *pipe = popen(CLIPBOARD_PASTE_CMD, "r"); + if (!pipe) return NULL; + + size_t cap = 4096; + size_t len = 0; + char *buf = malloc(cap); + + int c; + while ((c = fgetc(pipe)) != EOF) { + if (len + 1 >= cap) { + cap *= 2; + buf = realloc(buf, cap); + } + buf[len++] = (char)c; + } + buf[len] = '\0'; + pclose(pipe); + return buf; // caller must free +} + +void editorSetClipboard(const char *text, int len) { + FILE *pipe = popen(CLIPBOARD_COPY_CMD, "w"); + if (!pipe) return; + fwrite(text, 1, len, pipe); + pclose(pipe); +} + +int editorRowCxToByte(const row_t *row, int cursor_x) { + int i = 0, col = 0; + while (col < cursor_x && i < row->size) { + int sl = utf8Seqlen((unsigned char)row->chars[i]); + if (sl < 1) + sl = 1; + col++; + i += sl; + } + return i; +} + +int editorRowCharCount(row_t *row, int x) { + int n = 0, i = 0; + while (i < x && i < row->size) { + int sl = utf8Seqlen((unsigned char)row->chars[i]); + if (sl < 1) + sl = 1; + n++; + i += sl; + } + return n; +} \ No newline at end of file diff --git a/src/file_io.c b/src/file_io.c index 480a320..b1ac7d1 100644 --- a/src/file_io.c +++ b/src/file_io.c @@ -12,6 +12,7 @@ #include "../include/buffer.h" #include "../include/data.h" #include "../include/split_screen.h" +#include "../include/row_op.h" #include #include #include diff --git a/src/init.c b/src/init.c index 435e8f9..d380cfc 100644 --- a/src/init.c +++ b/src/init.c @@ -45,6 +45,10 @@ void initBuiltins() { registerBuiltin("editor-split-screen-vertical", l_editorSplitScreenVertical); registerBuiltin("editor-switch-next-pane", editorSwitchNextPane); registerBuiltin("editor-unify-panes", editorUnifiedPanes); + registerBuiltin("editor-paste", editorPaste); + registerBuiltin("editor-cut-end-line", editorCutEndLine); + registerBuiltin("editor-move-cursor-beg-buffer", editorMoveBegBuffer); + registerBuiltin("editor-move-cursor-end-buffer", editorMoveEndBuffer); } void initConfig() { @@ -64,7 +68,7 @@ void initConfig() { lisp_eval(E.ctx_data, &E.ctx_error, E.ctx); } -void init_theme() { +void initTheme() { E.constantes.THEME = (char *)lisp_string( lisp_eval(lisp_read("THEME", &E.ctx_error, E.ctx), &E.ctx_error, E.ctx)); if (strcmp(E.constantes.THEME, "dark") == 0) { @@ -130,7 +134,7 @@ void initEditor() { initConfig(); - init_theme(); + initTheme(); // To modify diff --git a/src/input.c b/src/input.c index 4ecd613..b1c51d6 100644 --- a/src/input.c +++ b/src/input.c @@ -5,7 +5,6 @@ #include "include/data.h" #include "include/buffer.h" #include "include/data.h" -#include "include/row_op.h" #include "include/split_screen.h" #include #include @@ -41,7 +40,7 @@ extern struct editorConfig E; * @note Caller is responsible for freeing the returned string * @note Uses static buffer internally; may return stale pointers across calls */ -const char *file_completion(const char *path) { +const char *fileCompletion(const char *path) { DIR *dir; struct dirent *entry; char directory[256]; @@ -153,7 +152,7 @@ char *editorPrompt(char *prompt, char *placeHolder, char bPathMode) { } memset(buf, 0, 256); buf_len = 0; - char * buf_complete = (char *) file_completion(path); + char * buf_complete = (char *) fileCompletion(path); strcpy(buf, buf_complete); free(buf_complete); buf_len = strlen(buf); @@ -170,65 +169,7 @@ char *editorPrompt(char *prompt, char *placeHolder, char bPathMode) { } } -/** - * @brief Moves the cursor based on arrow key input - * @details Updates cursor position (E.cursor_x, E.cursor_y) based on the given - * key direction. Handles line wrapping and boundary conditions. Prevents cursor - * from exceeding line lengths. - * @param key The arrow key code (ARROW_UP, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT) - * @return 1 if cursor movement was valid, 0 if cursor was constrained to line boundary - * @note Updates global editor state E - */ -int editorMoveCursor(int key) { - EditorPane *active = splitScreenGetActivePane(); - struct buffer_t *buf = bufferFindById(active->buffer_id); - row_t *row = &buf->row[buf->y]; - switch (key) { - case ARROW_RIGHT: - if (row && buf->x < row->size) { - int len = utf8Seqlen(row->chars[buf->x]); - buf->x += len; - } else if (row && buf->y < buf->numrows) { - buf->y++; - buf->x = 0; - } - break; - case ARROW_DOWN: - if (buf->y < buf->numrows) { - buf->y++; - } - break; - case ARROW_UP: - if (buf->y != 0) { - --buf->y; - } - break; - case ARROW_LEFT: - if (buf->x != 0) { - --buf->x; - } else if (buf->y > 0) { - --buf->y; - buf->x = buf->row[buf->y].size; - } - break; - } -/* - fprintf(stderr, "acx: %d acy %d aox %d aoy %d bx %d by %d ah %d aw %d\n", - active->cursor_x, - active->cursor_y, - active->x_offset, - active->y_offset, - buf->x, - buf->y, - active->height, - active->width - ); - */ - - - return 1; -} /** * @brief Executes the command bound to a key sequence @@ -272,7 +213,7 @@ void editorProcessKeypress() { int c = editorReadKey(); char key_sequence[8]; - if (executeKeyBind(key_to_string(c))) { + if (executeKeyBind(keyToString(c))) { return; } int seq_len = utf8Encode(c, key_sequence); diff --git a/src/output.c b/src/output.c index 35c323a..4a65a31 100644 --- a/src/output.c +++ b/src/output.c @@ -8,6 +8,7 @@ #include "../include/output.h" #include "../include/append_buffer.h" #include "../include/buffer.h" +#include "../include/editor_op.h" #include "../include/data.h" #include "../include/define.h" #include "../include/row_op.h" @@ -29,14 +30,9 @@ static void editorDrawPane(struct abuf* ab, EditorPane* pane) int file_row; char pos_buf[32]; int pos_len; - int chars_printed; - int start_offset; int byte_len_to_print; int bytes_to_print; char* highlighted; - char welcome[80]; - int welcome_len; - int padding; if (pane == NULL || pane->buffer_id < 0) return; @@ -56,9 +52,8 @@ static void editorDrawPane(struct abuf* ab, EditorPane* pane) abAppend(ab, pos_buf, pos_len); // Apply background color (6 bytes for RGB format) - abAppend(ab, E.theme.BACKGROUND_COLOR, strlen(E.theme.BACKGROUND_COLOR)); + abAppend(ab, E.theme.BACKGROUND_COLOR, (int) strlen(E.theme.BACKGROUND_COLOR)); - chars_printed = 0; // pane line is out of buffer if (file_row >= buf->numrows) @@ -75,7 +70,7 @@ static void editorDrawPane(struct abuf* ab, EditorPane* pane) } else { - start_offset = pane->x_offset; + if (buf->filename[strlen(buf->filename) - 1] == 'c' || buf->filename[strlen(buf->filename) - 1] == 'h') { @@ -135,7 +130,7 @@ static void editorDrawAllPanes(struct abuf* ab) { char pos_buf[32]; snprintf(pos_buf, sizeof(pos_buf), "\x1b[%d;%dH", y + 1, divider_col); - abAppend(ab, pos_buf, strlen(pos_buf)); + abAppend(ab, pos_buf, (int) strlen(pos_buf)); abAppend(ab, "\x1b[1m|\x1b[0m", 9); // Bold pipe divider } } @@ -145,7 +140,7 @@ static void editorDrawAllPanes(struct abuf* ab) int divider_row = layout->panes[0].height; char pos_buf[32]; snprintf(pos_buf, sizeof(pos_buf), "\x1b[%d;%dH", divider_row + 1, 1); - abAppend(ab, pos_buf, strlen(pos_buf)); + abAppend(ab, pos_buf, (int) strlen(pos_buf)); for (int x = 0; x < E.screencols; x++) { abAppend(ab, "\x1b[1m-\x1b[0m", 9); // Bold dash divider @@ -231,15 +226,13 @@ void editorScroll() char * basename(char *path) { - int len = strlen(path); - int flag=0; + int len = (int) strlen(path); for(int i=len-1; i>0; i--) { if(path[i]=='/' ) { - flag=1; path = path+i+1; break; } @@ -323,7 +316,7 @@ void editorDrawStatusBar(struct abuf* ab) */ void editorDrawMessageBar(struct abuf* ab) { - int msg_len = strlen(E.status_msg); + int msg_len = (int) strlen(E.status_msg); abAppend(ab, ERASE_END_LINE, 3); if (msg_len > E.screencols) { @@ -335,6 +328,7 @@ void editorDrawMessageBar(struct abuf* ab) } } + /** * @brief Performs complete screen refresh and buffer synchronization * @details Clears screen, redraws all visible content (rows, status bar, @@ -354,7 +348,7 @@ void editorRefreshScreen() abAppend(&ab, HIDE_CURSOR, 6); abAppend(&ab, CURSOR_TOP_LEFT, 3); abAppend(&ab, E.theme.BACKGROUND_COLOR, - strlen(E.theme.BACKGROUND_COLOR)); // RGB background is 12 bytes + (int) strlen(E.theme.BACKGROUND_COLOR)); // RGB background is 12 bytes // Draw all panes editorScroll(); @@ -363,16 +357,16 @@ void editorRefreshScreen() // Draw status bar and message bar editorDrawStatusBar(&ab); editorDrawMessageBar(&ab); + // editorDrawContextBuffer(&ab); // Position cursor in active pane EditorPane* active = splitScreenGetActivePane(); - struct buffer_t* buffer = bufferGetCurrent(); if (active != NULL) { snprintf(buf, sizeof(buf), "\x1b[%d;%dH", active->cursor_y + active->origin_y + 1, active->cursor_x + active->origin_x + 1); - abAppend(&ab, buf, strlen(buf)); + abAppend(&ab, buf, (int) strlen(buf)); } abAppend(&ab, SHOW_CURSOR, 6); diff --git a/src/row_op.c b/src/row_op.c index d930754..3142322 100644 --- a/src/row_op.c +++ b/src/row_op.c @@ -1,100 +1,12 @@ #include "../include/row_op.h" #include "../include/data.h" -#include "../include/define.h" +#include "../include/utf8.h" #include #include #include #include -#include "include/terminal.h" -#include "include/utf8.h" - extern struct editorConfig E; -void bufferInsertRow(struct buffer_t *buffer, int at, char *s, size_t len) { - if (at < 0 || at > buffer->numrows) - return; - row_t *tmp = realloc(buffer->row, sizeof(row_t) * (buffer->numrows + 1)); - if (!tmp) - return; - buffer->row = tmp; - /* Shift existing rows to make room at 'at' — no at++ */ - if (at < buffer->numrows) { - memmove(&buffer->row[at + 1], &buffer->row[at], - sizeof(row_t) * (buffer->numrows - at)); /* not -at+1 */ - } - - buffer->row[at].size = len; - buffer->row[at].cap = len + 1; - buffer->row[at].chars = malloc(len + 1); - if (!buffer->row[at].chars) - return; - memcpy(buffer->row[at].chars, s, len); - buffer->row[at].chars[len] = '\0'; /* always NUL-terminate */ - - buffer->numrows++; - buffer->dirty++; -} - -void bufferFreeRow(row_t *row) { free(row->chars); } - -int editorRowCxToByte(const row_t *row, int cursor_x) { - int i = 0, col = 0; - while (col < cursor_x && i < row->size) { - int sl = utf8Seqlen((unsigned char)row->chars[i]); - if (sl < 1) - sl = 1; - col++; - i += sl; - } - return i; -} - -/** - * \fn editorRowInsertChar(erow *row, int at, int c) - * \param at Index of where we want to insert the char */ - -void bufferRowInsertBytes(struct buffer_t *buffer, row_t *row, int at, - char *src, int n) { - if (buffer->state == READ_ONLY) - return; - if (row->size + n + 1 > row->cap) { - row->cap = (row->size + n + 1) * 2; - row->chars = realloc(row->chars, row->cap); - } - memmove(row->chars + at + n, row->chars + at, row->size - at); - memcpy(row->chars + at, src, n); - row->size += n; - row->chars = realloc(row->chars, row->size + 2); - ++buffer->dirty; -} - -/** - * \fn bufferRowDelChar(struct bufferConfig *E, frow *frow, int at) - * \brief Delete the a char at the chosen position on the given row - * \param at Index of the char to delete - * \param row Row on operation is made */ -void bufferRowDelByte(struct buffer_t *buffer, row_t *row, int at, int n) { - if (buffer->state == READ_ONLY) - return; - if (at < 0 || at >= row->size) - return; - memmove(row->chars + at, row->chars + at + n, row->size - at - n); - row->size -= n; - row->chars[row->size] = '\0'; - buffer->x -= n; - ++buffer->dirty; -} -int editorRowCharCount(row_t *row, int x) { - int n = 0, i = 0; - while (i < x && i < row->size) { - int sl = utf8Seqlen((unsigned char)row->chars[i]); - if (sl < 1) - sl = 1; - n++; - i += sl; - } - return n; -} diff --git a/src/terminal.c b/src/terminal.c index ab29e2b..5b42036 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -46,7 +46,7 @@ void enableRawMode() { #include /* isprint */ -char *key_to_string(int key) { +char *keyToString(int key) { static char key_str[32]; if (key == '\r') { @@ -111,7 +111,7 @@ int editorReadKey() { /* read first byte — may be start of UTF-8 or escape */ while (read(STDIN_FILENO, &c, 1) != 1) ; - appDebug("f : %X\r\n", c); + appDebug("f : %hhu %ld\r\n", c, 0x200); if (c == '\x1b') { char seq[6]; @@ -120,6 +120,8 @@ int editorReadKey() { return '\x1b'; if (read(STDIN_FILENO, &seq[1], 1) != 1) return '\x1b'; + appDebug("f2 : %s\r\n", seq); + if (seq[0] == '[') { if (seq[1] >= '0' && seq[1] <= '9') { if (read(STDIN_FILENO, &seq[2], 1) != 1) diff --git a/src/utf8.c b/src/utf8.c index 10db8b3..96e1af4 100644 --- a/src/utf8.c +++ b/src/utf8.c @@ -3,7 +3,6 @@ */ #include "../include/utf8.h" -#include "../include/data.h" #include #include