Finish chapter 5
This commit is contained in:
parent
01dbed5e6c
commit
bfb47723af
9 changed files with 80 additions and 17 deletions
|
@ -25,7 +25,7 @@ struct buffer *buffer_create(void);
|
|||
void buffer_read_file(struct buffer *buffer, const char *filename);
|
||||
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, int *bytes_written);
|
||||
|
||||
void erow_update_rendering(struct erow *erow);
|
||||
void erow_append_string(struct erow *erow, const char *s, size_t s_len);
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
enum KEYS {
|
||||
TAB = 9,
|
||||
ENTER = 13,
|
||||
ESCAPE = 27,
|
||||
BACKSPACE = 127,
|
||||
HOME = 0x100,
|
||||
DEL,
|
||||
|
|
|
@ -21,6 +21,7 @@ struct editor_state {
|
|||
};
|
||||
extern struct editor_state E;
|
||||
|
||||
void editor_set_message(const char *, ...);
|
||||
void editor_set_message(const char *fmt, ...);
|
||||
char *editor_prompt(const char *prompt);
|
||||
|
||||
#endif // KILO_H
|
||||
|
|
5
progress_log.md
Normal file
5
progress_log.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Progress log
|
||||
- (4/9/2023) Finished 5 chapters out of 7, basic text editing is fully
|
||||
possible. It has fun been working on this, but semester is starting now and I
|
||||
might not get to work on this a lot anymore. It might have lots of bugs, and
|
||||
there's lots of things I don't like, there are TODOs everywhere.
|
|
@ -62,7 +62,7 @@ void buffer_read_file(struct buffer *buffer, const char *filename) { // TODO: Ad
|
|||
buffer->modified = false;
|
||||
}
|
||||
|
||||
ERRCODE buffer_write_file(struct buffer *buffer) {
|
||||
ERRCODE buffer_write_file(struct buffer *buffer, int *bytes_written) {
|
||||
ERRCODE errcode = 0;
|
||||
|
||||
int fd = -1;
|
||||
|
@ -78,7 +78,8 @@ ERRCODE buffer_write_file(struct buffer *buffer) {
|
|||
if (fd == -1)
|
||||
RETURN(-2);
|
||||
|
||||
if (write(fd, write_buffer, len) != (ssize_t) len)
|
||||
*bytes_written = write(fd, write_buffer, len);
|
||||
if (*bytes_written != (ssize_t) len)
|
||||
RETURN(-3);
|
||||
|
||||
END:
|
||||
|
|
|
@ -74,7 +74,6 @@ void command_move_cursor(KEY key) {
|
|||
void command_insert_line(void) {
|
||||
if (E.cy == E.current_buf->n_rows) {
|
||||
buffer_insert_row(E.current_buf, NULL, 0, E.cy);
|
||||
E.cy++;
|
||||
} else {
|
||||
buffer_insert_row(E.current_buf, NULL, 0, E.cy + 1);
|
||||
|
||||
|
@ -86,11 +85,12 @@ void command_insert_line(void) {
|
|||
c_row->chars = realloc(c_row->chars, E.cx);
|
||||
c_row->n_chars = E.cx;
|
||||
erow_update_rendering(c_row);
|
||||
|
||||
E.cx = 0;
|
||||
E.rx = 0;
|
||||
E.cy++;
|
||||
}
|
||||
|
||||
E.cx = E.rx = 0;
|
||||
E.cy++;
|
||||
|
||||
cursor_adjust_viewport();
|
||||
}
|
||||
|
||||
void command_insert_char(char c) {
|
||||
|
@ -99,6 +99,8 @@ void command_insert_char(char 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);
|
||||
|
||||
cursor_adjust_viewport();
|
||||
}
|
||||
|
||||
void command_delete_char(void) { // TODO
|
||||
|
@ -125,13 +127,24 @@ void command_delete_char(void) { // TODO
|
|||
}
|
||||
|
||||
E.rx = erow_cx_to_rx(E.current_buf->rows+E.cy, E.cx);
|
||||
|
||||
cursor_adjust_viewport();
|
||||
}
|
||||
|
||||
void command_save_buffer(void) {
|
||||
ERRCODE errcode = buffer_write_file(E.current_buf);
|
||||
if (E.current_buf->filename == NULL) {
|
||||
E.current_buf->filename = editor_prompt("Save as: %s (ESC to cancel)");
|
||||
if (E.current_buf->filename == NULL) {
|
||||
editor_set_message("Save aborted");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int bytes_written;
|
||||
ERRCODE errcode = buffer_write_file(E.current_buf, &bytes_written);
|
||||
|
||||
if (errcode == 0)
|
||||
editor_set_message("Saved file %s", E.current_buf->filename);
|
||||
editor_set_message("%d bytes written", bytes_written);
|
||||
else
|
||||
editor_set_message("Save failed: ERRCODE %d: %s", errcode, strerror(errno));
|
||||
}
|
||||
|
|
11
src/input.c
11
src/input.c
|
@ -21,15 +21,11 @@ void input_process_key(void) {
|
|||
command_move_cursor(c);
|
||||
break;
|
||||
|
||||
case CTRL_KEY('Q'):
|
||||
command_quit();
|
||||
return;
|
||||
|
||||
case CTRL_KEY('S'):
|
||||
command_save_buffer();
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
case ENTER:
|
||||
command_insert_line();
|
||||
break;
|
||||
|
||||
|
@ -46,6 +42,11 @@ void input_process_key(void) {
|
|||
|
||||
default:
|
||||
command_insert_char(c);
|
||||
break;
|
||||
|
||||
case CTRL_KEY('Q'):
|
||||
command_quit();
|
||||
return;
|
||||
}
|
||||
|
||||
E.quit_times = 3;
|
||||
|
|
37
src/kilo.c
37
src/kilo.c
|
@ -58,3 +58,40 @@ void editor_set_message(const char *fmt, ...) {
|
|||
|
||||
E.message_time = time(NULL);
|
||||
}
|
||||
|
||||
// TODO: Implement a fully featured line editor
|
||||
char *editor_prompt(const char *prompt) {
|
||||
size_t buffer_size = 64;
|
||||
char *buffer = malloc(buffer_size);
|
||||
|
||||
size_t buffer_len = 0;
|
||||
buffer[buffer_len] = '\0';
|
||||
|
||||
while (true) {
|
||||
editor_set_message(prompt, buffer);
|
||||
ui_draw_screen();
|
||||
|
||||
KEY key = terminal_read_key();
|
||||
if (key == ESCAPE) {
|
||||
editor_set_message("");
|
||||
free(buffer);
|
||||
return NULL;
|
||||
} else if (key == ENTER) {
|
||||
if (buffer_len > 0) {
|
||||
editor_set_message("");
|
||||
buffer = realloc(buffer, buffer_len + 1);
|
||||
return buffer;
|
||||
}
|
||||
} else if (isprint(key)) {
|
||||
if (buffer_len >= buffer_size - 1) {
|
||||
buffer_size *= 2;
|
||||
buffer = realloc(buffer, buffer_size);
|
||||
}
|
||||
|
||||
buffer[buffer_len++] = key;
|
||||
buffer[buffer_len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
|
|
@ -96,7 +96,10 @@ KEY terminal_read_key(void) {
|
|||
char buf[8] = { '\0' };
|
||||
|
||||
for (int i = 0; i < (int) sizeof(buf); i++) {
|
||||
if (read(STDIN_FILENO, buf+i, 1) == 0) break;
|
||||
if (read(STDIN_FILENO, buf+i, 1) == 0) {
|
||||
if (i == 0) return ESCAPE;
|
||||
else break;
|
||||
}
|
||||
|
||||
char escape_char;
|
||||
int escape_int;
|
||||
|
|
Reference in a new issue