Do some work on the text editing
A little is left, and there are bugs
This commit is contained in:
parent
818ef8d40b
commit
165eea1844
6 changed files with 102 additions and 53 deletions
|
@ -2,6 +2,7 @@
|
|||
#define BUFFER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#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
|
||||
|
|
|
@ -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);
|
||||
|
|
81
src/buffer.c
81
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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
6
src/ui.c
6
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),
|
||||
|
|
Reference in a new issue