Archived
1
Fork 0

Do some work on the text editing

A little is left, and there are bugs
This commit is contained in:
Hadeed 2023-09-04 15:06:35 +05:00
parent 818ef8d40b
commit 165eea1844
6 changed files with 102 additions and 53 deletions

View file

@ -2,6 +2,7 @@
#define BUFFER_H #define BUFFER_H
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h>
#include "utils.h" #include "utils.h"
@ -22,13 +23,16 @@ struct buffer {
struct buffer *buffer_create(void); struct buffer *buffer_create(void);
void buffer_read_file(struct buffer *buffer, const char *filename); 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); ERRCODE buffer_write_file(struct buffer *buffer);
void erow_update_rendering(struct erow *erow); 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_insert_char(struct erow *erow, int at, char c);
void erow_delete_char(struct erow *erow, int at); void erow_delete_char(struct erow *erow, int at);
int erow_cx_to_rx(struct erow *erow, int cx); int erow_cx_to_rx(struct erow *erow, int cx);
int erow_rx_to_cx(struct erow *erow, int rx); int erow_rx_to_cx(struct erow *erow, int rx);
void erow_free(struct erow *erow);
#endif // BUFFER_H #endif // BUFFER_H

View file

@ -5,6 +5,7 @@
void command_quit(void); void command_quit(void);
void command_move_cursor(KEY key); void command_move_cursor(KEY key);
void command_insert_line(void);
void command_insert_char(char c); void command_insert_char(char c);
void command_delete_char(void); void command_delete_char(void);
void command_save_buffer(void); void command_save_buffer(void);

View file

@ -23,8 +23,7 @@ struct buffer *buffer_create(void) {
return buffer; return buffer;
} }
// TODO: Handle file not existing void buffer_read_file(struct buffer *buffer, const char *filename) { // TODO: Add error handling
void buffer_read_file(struct buffer *buffer, const char *filename) {
if (buffer->filename) if (buffer->filename)
free(buffer->filename); free(buffer->filename);
@ -53,7 +52,7 @@ void buffer_read_file(struct buffer *buffer, const char *filename) {
line_buffer[i] = c; 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); file_remaining = (c != EOF);
} }
@ -95,18 +94,31 @@ END:
return errcode; 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)); 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); erow->chars = malloc(n_chars);
memcpy(new_row->chars, chars, n_chars); memcpy(erow->chars, chars, n_chars);
new_row->n_chars = n_chars; erow->n_chars = n_chars;
new_row->rchars = NULL; erow->rchars = NULL;
new_row->n_rchars = 0; 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; buffer->modified = true;
} }
@ -117,10 +129,8 @@ void buffer_free(struct buffer *buffer) {
} }
static void buffer_free_rows(struct buffer *buffer) { static void buffer_free_rows(struct buffer *buffer) {
for (int i = 0; i < buffer->n_rows; i++) { for (int i = 0; i < buffer->n_rows; i++)
if (buffer->rows->chars) free(buffer->rows->chars); erow_free(buffer->rows + i);
if (buffer->rows->rchars) free(buffer->rows->rchars);
}
} }
static char *buffer_get_string(struct buffer *buffer, size_t *len_p) { 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); 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) { void erow_insert_char(struct erow *erow, int at, char c) {
if (at < 0) at = 0; if (!(0 <= at && at <= erow->n_chars))
if (at > erow->n_chars) at = erow->n_chars; return;
erow->chars = realloc(erow->chars, erow->n_chars + 1); erow->chars = realloc(erow->chars, erow->n_chars + 1);
memmove(erow->chars + at + 1, erow->chars + at, erow->n_chars - at); 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); erow_update_rendering(erow);
// TODO: Seems like a bad idea E.current_buf->modified = true; // TODO
E.current_buf->modified = true;
} }
void erow_delete_char(struct erow *erow, int at) { void erow_delete_char(struct erow *erow, int at) {
if (at < 0) at = 0; if (!(0 <= at && at < erow->n_chars))
if (at > erow->n_chars) at = erow->n_chars; return;
if (at != 0) { memmove(erow->chars + at, erow->chars + at + 1, erow->n_chars - at);
memmove(erow->chars + at, erow->chars + at + 1, erow->n_chars - at); erow->n_chars--;
erow->n_chars--; erow->chars = realloc(erow->chars, erow->n_chars);
erow->chars = realloc(erow->chars, erow->n_chars); E.cx--;
E.cx--; erow_update_rendering(erow);
erow_update_rendering(erow);
}
// TODO E.current_buf->modified = true; // TODO
E.current_buf->modified = true;
} }
int erow_cx_to_rx(struct erow *erow, int cx) { 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); 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);
}

View file

@ -28,8 +28,8 @@ void command_move_cursor(KEY key) {
struct erow *rows = E.current_buf->rows; struct erow *rows = E.current_buf->rows;
int n_rows = E.current_buf->n_rows; int n_rows = E.current_buf->n_rows;
struct erow *current_row = (rows && E.cy < n_rows ? rows + E.cy : NULL); struct erow *erow = (rows && E.cy < n_rows ? rows + E.cy : NULL);
int max_x = (current_row ? current_row->n_chars : 0); int max_x = (erow ? erow->n_chars : 0);
switch (key) { switch (key) {
case ARROW_LEFT: case ARROW_LEFT:
@ -70,21 +70,43 @@ void command_move_cursor(KEY key) {
cursor_adjust_viewport(); 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) { void command_insert_char(char c) {
if (E.cy == E.current_buf->n_rows) 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); 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); E.rx = erow_cx_to_rx(E.current_buf->rows+E.cy, E.cx);
} }
void command_delete_char(void) { void command_delete_char(void) { // TODO
struct erow *row = E.current_buf->rows + E.cy; 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) { if (E.cx > 0) {
// TODO erow_delete_char(E.current_buf->rows+E.cy, E.cx - 1);
} else }
erow_delete_char(row, E.cx); 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); 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; struct erow *rows = E.current_buf->rows;
int n_rows = E.current_buf->n_rows; int n_rows = E.current_buf->n_rows;
struct erow *current_row = (rows && E.cy < n_rows ? rows + E.cy : NULL); struct erow *erow = (rows && E.cy < n_rows ? rows + E.cy : NULL);
int max_x = (current_row ? current_row->n_chars : 0); int max_x = (erow ? erow->n_chars : 0);
if (E.cy < 0) if (E.cy < 0)
E.cy = 0; E.cy = 0;
@ -114,8 +136,8 @@ static void cursor_check_file_bounds(bool horizontal) {
if (E.cx < 0) { if (E.cx < 0) {
if (E.cy > 0 && horizontal) if (E.cy > 0 && horizontal)
{ {
current_row = &rows[--E.cy]; erow = &rows[--E.cy];
max_x = current_row->n_chars; max_x = erow->n_chars;
E.cx = max_x; E.cx = max_x;
} }
@ -134,13 +156,13 @@ static void cursor_update_rx(bool horizontal) {
struct erow *rows = E.current_buf->rows; struct erow *rows = E.current_buf->rows;
int n_rows = E.current_buf->n_rows; int n_rows = E.current_buf->n_rows;
struct erow *current_row = (rows && E.cy < n_rows ? rows + E.cy : NULL); struct erow *erow = (rows && E.cy < n_rows ? rows + E.cy : NULL);
int max_x = (current_row ? current_row->n_chars : 0); int max_x = (erow ? erow->n_chars : 0);
static int saved_rx = 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 { 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) if (E.cx > max_x)
E.cx = max_x; E.cx = max_x;
} }

View file

@ -30,12 +30,13 @@ void input_process_key(void) {
break; break;
case '\r': case '\r':
// TODO command_insert_line();
break; break;
case DEL:
command_move_cursor(ARROW_RIGHT);
case BACKSPACE: case BACKSPACE:
case CTRL_KEY('H'): case CTRL_KEY('H'):
case DEL:
command_delete_char(); command_delete_char();
break; break;

View file

@ -43,10 +43,10 @@ static void ui_draw_rows(struct append_buf *draw_buf) {
bool no_file = (E.current_buf->n_rows == 0); bool no_file = (E.current_buf->n_rows == 0);
if (in_file) { if (in_file) {
struct erow curr_row = E.current_buf->rows[y + E.row_off]; struct erow erow = E.current_buf->rows[y + E.row_off];
int max_len = MIN(curr_row.n_rchars - E.col_off, E.screencols); 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) { } else if (no_file && y == E.screenrows / 2) {
char welcome[64]; char welcome[64];
int len = snprintf(welcome, sizeof(welcome), int len = snprintf(welcome, sizeof(welcome),