From 165eea1844fe5805bcc6886f60e0859cf37e63f7 Mon Sep 17 00:00:00 2001 From: Hadeed Ahmad Date: Mon, 4 Sep 2023 15:06:35 +0500 Subject: [PATCH] Do some work on the text editing A little is left, and there are bugs --- include/buffer.h | 6 +++- include/commands.h | 1 + src/buffer.c | 81 +++++++++++++++++++++++++++++----------------- src/commands.c | 56 ++++++++++++++++++++++---------- src/input.c | 5 +-- src/ui.c | 6 ++-- 6 files changed, 102 insertions(+), 53 deletions(-) diff --git a/include/buffer.h b/include/buffer.h index 5f7a3ad..38cbfd3 100644 --- a/include/buffer.h +++ b/include/buffer.h @@ -2,6 +2,7 @@ #define BUFFER_H #include +#include #include "utils.h" @@ -22,13 +23,16 @@ struct buffer { struct buffer *buffer_create(void); void buffer_read_file(struct buffer *buffer, const char *filename); -void buffer_append_row(struct buffer *buffer, const char *chars, int n_chars); +void buffer_insert_row(struct buffer *buffer, const char *chars, int n_chars, int at); +void buffer_delete_row(struct buffer *buffer, int at); ERRCODE buffer_write_file(struct buffer *buffer); void erow_update_rendering(struct erow *erow); +void erow_append_string(struct erow *erow, const char *s, size_t s_len); void erow_insert_char(struct erow *erow, int at, char c); void erow_delete_char(struct erow *erow, int at); int erow_cx_to_rx(struct erow *erow, int cx); int erow_rx_to_cx(struct erow *erow, int rx); +void erow_free(struct erow *erow); #endif // BUFFER_H diff --git a/include/commands.h b/include/commands.h index 1292cce..111f64b 100644 --- a/include/commands.h +++ b/include/commands.h @@ -5,6 +5,7 @@ void command_quit(void); void command_move_cursor(KEY key); +void command_insert_line(void); void command_insert_char(char c); void command_delete_char(void); void command_save_buffer(void); diff --git a/src/buffer.c b/src/buffer.c index 2900052..5055047 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -23,8 +23,7 @@ struct buffer *buffer_create(void) { return buffer; } -// TODO: Handle file not existing -void buffer_read_file(struct buffer *buffer, const char *filename) { +void buffer_read_file(struct buffer *buffer, const char *filename) { // TODO: Add error handling if (buffer->filename) free(buffer->filename); @@ -53,7 +52,7 @@ void buffer_read_file(struct buffer *buffer, const char *filename) { line_buffer[i] = c; } - buffer_append_row(buffer, line_buffer, i); + buffer_insert_row(buffer, line_buffer, i, buffer->n_rows); file_remaining = (c != EOF); } @@ -95,18 +94,31 @@ END: return errcode; } -void buffer_append_row(struct buffer *buffer, const char *chars, int n_chars) { +void buffer_insert_row(struct buffer *buffer, const char *chars, int n_chars, int at) { // TODO: Make this take an erow buffer->rows = realloc(buffer->rows, sizeof(struct erow) * (buffer->n_rows + 1)); - struct erow *new_row = &buffer->rows[buffer->n_rows++]; + memmove(buffer->rows + at, buffer->rows + at + 1, sizeof(struct erow) * (buffer->n_rows - at)); + struct erow *erow = buffer->rows + at; - new_row->chars = malloc(n_chars); - memcpy(new_row->chars, chars, n_chars); - new_row->n_chars = n_chars; + erow->chars = malloc(n_chars); + memcpy(erow->chars, chars, n_chars); + erow->n_chars = n_chars; - new_row->rchars = NULL; - new_row->n_rchars = 0; + erow->rchars = NULL; + erow->n_rchars = 0; - erow_update_rendering(new_row); + erow_update_rendering(erow); + + buffer->modified = true; + buffer->n_rows++; +} + +void buffer_delete_row(struct buffer *buffer, int at) { + if (!(0 <= at && at < buffer->n_rows)) + return; + + erow_free(buffer->rows + at); + memmove(buffer->rows + at, buffer->rows + at + 1, sizeof(struct erow) * (buffer->n_rows - at - 1)); + buffer->n_rows--; buffer->modified = true; } @@ -117,10 +129,8 @@ void buffer_free(struct buffer *buffer) { } static void buffer_free_rows(struct buffer *buffer) { - for (int i = 0; i < buffer->n_rows; i++) { - if (buffer->rows->chars) free(buffer->rows->chars); - if (buffer->rows->rchars) free(buffer->rows->rchars); - } + for (int i = 0; i < buffer->n_rows; i++) + erow_free(buffer->rows + i); } static char *buffer_get_string(struct buffer *buffer, size_t *len_p) { @@ -179,9 +189,19 @@ void erow_update_rendering(struct erow *erow) { free(line_buffer); } +void erow_append_string(struct erow *erow, const char *s, size_t s_len) { + erow->n_chars = erow->n_chars + s_len; + erow->chars = realloc(erow->chars, erow->n_chars); + + memcpy(erow->chars + erow->n_chars - s_len, s, s_len); + erow_update_rendering(erow); + + E.current_buf->modified = true; // TODO +} + void erow_insert_char(struct erow *erow, int at, char c) { - if (at < 0) at = 0; - if (at > erow->n_chars) at = erow->n_chars; + if (!(0 <= at && at <= erow->n_chars)) + return; erow->chars = realloc(erow->chars, erow->n_chars + 1); memmove(erow->chars + at + 1, erow->chars + at, erow->n_chars - at); @@ -191,24 +211,20 @@ void erow_insert_char(struct erow *erow, int at, char c) { erow_update_rendering(erow); - // TODO: Seems like a bad idea - E.current_buf->modified = true; + E.current_buf->modified = true; // TODO } void erow_delete_char(struct erow *erow, int at) { - if (at < 0) at = 0; - if (at > erow->n_chars) at = erow->n_chars; + if (!(0 <= at && at < erow->n_chars)) + return; - if (at != 0) { - memmove(erow->chars + at, erow->chars + at + 1, erow->n_chars - at); - erow->n_chars--; - erow->chars = realloc(erow->chars, erow->n_chars); - E.cx--; - erow_update_rendering(erow); - } + memmove(erow->chars + at, erow->chars + at + 1, erow->n_chars - at); + erow->n_chars--; + erow->chars = realloc(erow->chars, erow->n_chars); + E.cx--; + erow_update_rendering(erow); - // TODO - E.current_buf->modified = true; + E.current_buf->modified = true; // TODO } int erow_cx_to_rx(struct erow *erow, int cx) { @@ -242,3 +258,8 @@ int erow_rx_to_cx(struct erow *erow, int rx) { return (_rx >= rx ? cx : erow->n_chars); } + +void erow_free(struct erow *erow) { + if (erow->chars) free(erow->chars); + if (erow->rchars) free(erow->rchars); +} diff --git a/src/commands.c b/src/commands.c index 8fab52c..031b602 100644 --- a/src/commands.c +++ b/src/commands.c @@ -28,8 +28,8 @@ void command_move_cursor(KEY key) { struct erow *rows = E.current_buf->rows; int n_rows = E.current_buf->n_rows; - struct erow *current_row = (rows && E.cy < n_rows ? rows + E.cy : NULL); - int max_x = (current_row ? current_row->n_chars : 0); + struct erow *erow = (rows && E.cy < n_rows ? rows + E.cy : NULL); + int max_x = (erow ? erow->n_chars : 0); switch (key) { case ARROW_LEFT: @@ -70,21 +70,43 @@ void command_move_cursor(KEY key) { cursor_adjust_viewport(); } +void command_insert_line(void) { + buffer_insert_row(E.current_buf, NULL, 0, ++E.cy); + + E.cx = 0; + E.rx = 0; +} + void command_insert_char(char c) { if (E.cy == E.current_buf->n_rows) - buffer_append_row(E.current_buf, NULL, 0); + buffer_insert_row(E.current_buf, NULL, 0, E.current_buf->n_rows); erow_insert_char(E.current_buf->rows+E.cy, E.cx++, c); E.rx = erow_cx_to_rx(E.current_buf->rows+E.cy, E.cx); } -void command_delete_char(void) { - struct erow *row = E.current_buf->rows + E.cy; +void command_delete_char(void) { // TODO + if (E.cx == 0 && E.cy == 0) return; + if (E.cy == E.current_buf->n_rows) { + E.cx = E.current_buf->rows[--E.cy].n_chars; + E.rx = erow_cx_to_rx(E.current_buf->rows+E.cy, E.cx); + return; + } - if (E.cx == 0) { - // TODO - } else - erow_delete_char(row, E.cx); + if (E.cx > 0) { + erow_delete_char(E.current_buf->rows+E.cy, E.cx - 1); + } + else { + struct erow *c_row = E.current_buf->rows + E.cy; + struct erow *p_row = E.current_buf->rows + E.cy - 1; + + E.cx = p_row->n_chars; + + erow_append_string(p_row, c_row->chars, c_row->n_chars); + buffer_delete_row(E.current_buf, E.cy); + + E.cy--; + } E.rx = erow_cx_to_rx(E.current_buf->rows+E.cy, E.cx); } @@ -102,8 +124,8 @@ static void cursor_check_file_bounds(bool horizontal) { struct erow *rows = E.current_buf->rows; int n_rows = E.current_buf->n_rows; - struct erow *current_row = (rows && E.cy < n_rows ? rows + E.cy : NULL); - int max_x = (current_row ? current_row->n_chars : 0); + struct erow *erow = (rows && E.cy < n_rows ? rows + E.cy : NULL); + int max_x = (erow ? erow->n_chars : 0); if (E.cy < 0) E.cy = 0; @@ -114,8 +136,8 @@ static void cursor_check_file_bounds(bool horizontal) { if (E.cx < 0) { if (E.cy > 0 && horizontal) { - current_row = &rows[--E.cy]; - max_x = current_row->n_chars; + erow = &rows[--E.cy]; + max_x = erow->n_chars; E.cx = max_x; } @@ -134,13 +156,13 @@ static void cursor_update_rx(bool horizontal) { struct erow *rows = E.current_buf->rows; int n_rows = E.current_buf->n_rows; - struct erow *current_row = (rows && E.cy < n_rows ? rows + E.cy : NULL); - int max_x = (current_row ? current_row->n_chars : 0); + struct erow *erow = (rows && E.cy < n_rows ? rows + E.cy : NULL); + int max_x = (erow ? erow->n_chars : 0); static int saved_rx = 0; - if (horizontal) saved_rx = erow_cx_to_rx(current_row, E.cx); + if (horizontal) saved_rx = erow_cx_to_rx(erow, E.cx); else { - E.cx = erow_rx_to_cx(current_row, saved_rx); + E.cx = erow_rx_to_cx(erow, saved_rx); if (E.cx > max_x) E.cx = max_x; } diff --git a/src/input.c b/src/input.c index d5502e9..37fec91 100644 --- a/src/input.c +++ b/src/input.c @@ -30,12 +30,13 @@ void input_process_key(void) { break; case '\r': - // TODO + command_insert_line(); break; + case DEL: + command_move_cursor(ARROW_RIGHT); case BACKSPACE: case CTRL_KEY('H'): - case DEL: command_delete_char(); break; diff --git a/src/ui.c b/src/ui.c index 2ca0151..6be551c 100644 --- a/src/ui.c +++ b/src/ui.c @@ -43,10 +43,10 @@ static void ui_draw_rows(struct append_buf *draw_buf) { bool no_file = (E.current_buf->n_rows == 0); if (in_file) { - struct erow curr_row = E.current_buf->rows[y + E.row_off]; - int max_len = MIN(curr_row.n_rchars - E.col_off, E.screencols); + struct erow erow = E.current_buf->rows[y + E.row_off]; + int max_len = MIN(erow.n_rchars - E.col_off, E.screencols); - ab_append(draw_buf, curr_row.rchars + E.col_off, MAX(max_len, 0)); + ab_append(draw_buf, erow.rchars + E.col_off, MAX(max_len, 0)); } else if (no_file && y == E.screenrows / 2) { char welcome[64]; int len = snprintf(welcome, sizeof(welcome),