diff --git a/include/buffer.h b/include/buffer.h index 06ad1e7..10695e0 100644 --- a/include/buffer.h +++ b/include/buffer.h @@ -1,6 +1,8 @@ #ifndef BUFFER_H #define BUFFER_H +#include "utils.h" + struct erow { char *chars; int n_chars; @@ -18,6 +20,7 @@ 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); +ERRCODE buffer_write_file(struct buffer *buffer); void erow_update_rendering(struct erow *erow); void erow_insert_char(struct erow *erow, int at, char c); diff --git a/include/commands.h b/include/commands.h index 03c1a08..0b2881e 100644 --- a/include/commands.h +++ b/include/commands.h @@ -5,5 +5,6 @@ void command_move_cursor(KEY key); void command_insert_char(char c); +void command_save_buffer(void); #endif // COMMANDS_H diff --git a/include/input.h b/include/input.h index 39a3676..6ed4d55 100644 --- a/include/input.h +++ b/include/input.h @@ -5,6 +5,7 @@ enum KEYS { TAB = 9, + BACKSPACE = 127, HOME = 0x100, DEL, PG_UP, diff --git a/src/buffer.c b/src/buffer.c index b9bdef3..9423a31 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1,7 +1,9 @@ +#include #include #include #include #include +#include #include "buffer.h" #include "kilo.h" @@ -19,6 +21,7 @@ struct buffer *buffer_create(void) { return buf; } +// TODO: Handle file not existing void buffer_read_file(struct buffer *buffer, const char *filename) { if (buffer->filename) free(buffer->filename); @@ -56,6 +59,33 @@ void buffer_read_file(struct buffer *buffer, const char *filename) { fclose(file); } +ERRCODE buffer_write_file(struct buffer *buffer) { + if (buffer->filename == NULL) + return -1; + + size_t len = 0; + + for (int i = 0; i < buffer->n_rows; i++) + len += buffer->rows[i].n_chars + 1; + + char *write_buffer = malloc(len); + char *p = write_buffer; + for (int i = 0; i < buffer->n_rows; i++) { + struct erow *row = buffer->rows+i; + memcpy(p, row->chars, row->n_chars); + p += row->n_chars; + *p = '\n'; + p++; + } + + int fd = open(buffer->filename, O_RDWR | O_TRUNC | O_CREAT, 0644); + write(fd, write_buffer, len); + close(fd); + free(write_buffer); + + return 0; +} + void buffer_append_row(struct buffer *buffer, const char *chars, int n_chars) { buffer->rows = realloc(buffer->rows, sizeof(struct erow) * (buffer->n_rows + 1)); struct erow *new_row = &buffer->rows[buffer->n_rows++]; diff --git a/src/commands.c b/src/commands.c index 2fc4f29..792443b 100644 --- a/src/commands.c +++ b/src/commands.c @@ -4,6 +4,7 @@ #include "input.h" #include "kilo.h" #include "buffer.h" +#include "utils.h" static void cursor_adjust_viewport(void); static void cursor_check_file_bounds(bool horizontal); @@ -63,6 +64,15 @@ void command_insert_char(char c) { E.rx = erow_cx_to_rx(E.current_buf->rows+E.cy, E.cx); } +void command_save_buffer(void) { + ERRCODE errcode = buffer_write_file(E.current_buf); + + if (errcode == 0) + editor_set_message("Saved file %s", E.current_buf->filename); + else if (errcode == -1) + editor_set_message("Save failed, no filename"); +} + static void cursor_check_file_bounds(bool horizontal) { struct erow *rows = E.current_buf->rows; int n_rows = E.current_buf->n_rows; diff --git a/src/input.c b/src/input.c index 29fb2bc..f0e7f41 100644 --- a/src/input.c +++ b/src/input.c @@ -20,6 +20,10 @@ void input_process_key(void) { command_move_cursor(c); break; + case CTRL_KEY('S'): + command_save_buffer(); + break; + case CTRL_KEY('Q'): terminal_clear(); exit(0); @@ -28,9 +32,13 @@ void input_process_key(void) { case '\r': break; - case 127: - case DEL: + case BACKSPACE: case CTRL_KEY('H'): + case DEL: + break; + + case CTRL_KEY('L'): + // case NOP: break; default: diff --git a/src/kilo.c b/src/kilo.c index c3e61bc..10953fc 100644 --- a/src/kilo.c +++ b/src/kilo.c @@ -45,7 +45,7 @@ void editor_init(char *filename) { if (filename) buffer_read_file(E.current_buf, filename); - editor_set_message("Welcome to kilo. Press CTRL-Q to quit."); + editor_set_message("Welcome to kilo! | CTRL-Q: Quit | CTRL-S: SAVE"); terminal_clear(); }