diff --git a/CMakeLists.txt b/CMakeLists.txt index ea5657e..03f2af2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.15) project(ke C) # Specify C language explicitly set(CMAKE_C_STANDARD 99) -set(KE_VERSION "2.0.0") +set(KE_VERSION "2.0.1") set(CMAKE_C_FLAGS "-Wall -Wextra -pedantic -Wshadow -Werror -std=c99 -g") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_DEFAULT_SOURCE -D_XOPEN_SOURCE") diff --git a/abuf.c b/abuf.c index 97ba0c3..2e18bf4 100644 --- a/abuf.c +++ b/abuf.c @@ -6,6 +6,15 @@ #include "core.h" +static void +abuf_grow(abuf *buf, size_t delta) +{ + if (buf->cap - buf->size < delta) { + ab_resize(buf, buf->cap + delta); + } +} + + void ab_init(abuf *buf) { @@ -38,6 +47,7 @@ ab_resize(abuf *buf, size_t cap) void ab_appendch(abuf *buf, char c) { + abuf_grow(buf, 1); ab_append(buf, &c, 1); } @@ -45,20 +55,10 @@ ab_appendch(abuf *buf, char c) void ab_append(abuf *buf, const char *s, size_t len) { - char *nc = buf->b; - size_t sz = buf->size + len; + char *nc = NULL; - if (sz >= buf->cap) { - while (sz > buf->cap) { - if (buf->cap == 0) { - buf->cap = 1; - } else { - buf->cap *= 2; - } - } - nc = realloc(nc, buf->cap); - assert(nc != NULL); - } + abuf_grow(buf, len); + nc = buf->b; memcpy(&nc[buf->size], s, len); buf->b = nc; @@ -69,6 +69,8 @@ ab_append(abuf *buf, const char *s, size_t len) void ab_prependch(abuf *buf, const char c) { + abuf_grow(buf, 1); + ab_prepend(buf, &c, 1); } @@ -76,7 +78,10 @@ ab_prependch(abuf *buf, const char c) void ab_prepend(abuf *buf, const char *s, const size_t len) { - char *nc = realloc(buf->b, buf->size + len); + char *nc = NULL; + + abuf_grow(buf, len); + nc = buf->b; assert(nc != NULL); memmove(nc + len, nc, buf->size); diff --git a/buffer.c b/buffer.c index cb1070f..9908412 100644 --- a/buffer.c +++ b/buffer.c @@ -71,6 +71,7 @@ buffer_collect_prefix_matches(const char *prefix, int *out_idx, const int max_ou size_t plen = (prefix ? strlen(prefix) : 0); for (int i = 0; i < editor.bufcount; i++) { + matched = 0; b = editor.buffers[i]; const char *cand1 = b->filename; @@ -267,21 +268,35 @@ buffers_init(void) editor.buffers = NULL; editor.bufcount = 0; editor.curbuf = -1; + editor.bufcap = 0; idx = buffer_add_empty(); buffer_switch(idx); } +static void +buffer_list_resize(void) +{ + buffer **newlist = NULL; + + if (editor.bufcount == (int)editor.bufcap) { + editor.bufcap = cap_growth((int)editor.bufcap, editor.bufcount + 1); + + newlist = realloc(editor.buffers, sizeof(buffer *) * editor.bufcap); + assert(newlist != NULL); + editor.buffers = newlist; + } +} + + int buffer_add_empty(void) { buffer *buf = NULL; - buffer **newlist = realloc(editor.buffers, sizeof(buffer *) * (editor.bufcount + 1)); int idx = 0; - assert(newlist != NULL); - editor.buffers = newlist; + buffer_list_resize(); buf = calloc(1, sizeof(buffer)); assert(buf != NULL); diff --git a/editor.c b/editor.c index 1760f98..401d44e 100644 --- a/editor.c +++ b/editor.c @@ -92,6 +92,7 @@ init_editor(void) /* initialize buffer system on first init */ if (editor.buffers == NULL && editor.bufcount == 0) { + editor.bufcap = 0; buffers_init(); } } diff --git a/editor.h b/editor.h index d066835..8d24969 100644 --- a/editor.h +++ b/editor.h @@ -32,9 +32,10 @@ struct editor { time_t msgtm; /* Multi-buffer support */ - struct buffer **buffers; /* array of buffers */ + struct buffer **buffers; /* array of buffers */ int bufcount; /* number of buffers */ - int curbuf; /* current buffer index */ + int curbuf; /* current buffer index */ + size_t bufcap; /* current buffer capacity */ }; diff --git a/main.c b/main.c index 00247ca..cb44fc5 100644 --- a/main.c +++ b/main.c @@ -842,23 +842,37 @@ delete_region(void) void jump_to_position(int col, int row) { - /* clamp position */ - if (row < 0) { - row = 0; - } else if (row > editor.nrows) { - row = editor.nrows - 1; - } + /* Handle empty buffer safely */ + if (ENROWS <= 0) { + ECURX = 0; + ECURY = 0; + /* Keep legacy globals in sync with per-buffer fields for rendering */ + editor.curx = ECURX; + editor.cury = ECURY; + display_refresh(); + return; + } - if (col < 0) { - col = 0; - } else if (row >= 0 && row < ENROWS && col > (int) EROW[row].size) { - col = (int) EROW[row].size; - } + /* clamp position using per-buffer dimensions */ + if (row < 0) { + row = 0; + } else if (row >= ENROWS) { + row = ENROWS - 1; + } - ECURX = col; - ECURY = row; + if (col < 0) { + col = 0; + } else if (col > (int) EROW[row].size) { + col = (int) EROW[row].size; + } - display_refresh(); + ECURX = col; + ECURY = row; + /* Keep legacy globals in sync with per-buffer fields for rendering */ + editor.curx = ECURX; + editor.cury = ECURY; + + display_refresh(); } @@ -872,13 +886,13 @@ goto_line(void) return; } - lineno = atoi(query); - if (lineno < 1 || lineno >= ENROWS) { - editor_set_status("Line number must be between 1 and %d.", - ENROWS); - free(query); - return; - } + lineno = atoi(query); + if (lineno < 1 || lineno > ENROWS) { + editor_set_status("Line number must be between 1 and %d.", + ENROWS); + free(query); + return; + } jump_to_position(0, lineno - 1); free(query);