Archived
1
Fork 0

Finish chapter 5

This commit is contained in:
Hadeed 2023-09-04 20:53:43 +05:00
parent 01dbed5e6c
commit bfb47723af
9 changed files with 80 additions and 17 deletions

View file

@ -25,7 +25,7 @@ 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_insert_row(struct buffer *buffer, const char *chars, int n_chars, int at); void buffer_insert_row(struct buffer *buffer, const char *chars, int n_chars, int at);
void buffer_delete_row(struct buffer *buffer, 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_update_rendering(struct erow *erow);
void erow_append_string(struct erow *erow, const char *s, size_t s_len); void erow_append_string(struct erow *erow, const char *s, size_t s_len);

View file

@ -5,6 +5,8 @@
enum KEYS { enum KEYS {
TAB = 9, TAB = 9,
ENTER = 13,
ESCAPE = 27,
BACKSPACE = 127, BACKSPACE = 127,
HOME = 0x100, HOME = 0x100,
DEL, DEL,

View file

@ -21,6 +21,7 @@ struct editor_state {
}; };
extern struct editor_state E; 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 #endif // KILO_H

5
progress_log.md Normal file
View 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.

View file

@ -62,7 +62,7 @@ void buffer_read_file(struct buffer *buffer, const char *filename) { // TODO: Ad
buffer->modified = false; buffer->modified = false;
} }
ERRCODE buffer_write_file(struct buffer *buffer) { ERRCODE buffer_write_file(struct buffer *buffer, int *bytes_written) {
ERRCODE errcode = 0; ERRCODE errcode = 0;
int fd = -1; int fd = -1;
@ -78,7 +78,8 @@ ERRCODE buffer_write_file(struct buffer *buffer) {
if (fd == -1) if (fd == -1)
RETURN(-2); 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); RETURN(-3);
END: END:

View file

@ -74,7 +74,6 @@ void command_move_cursor(KEY key) {
void command_insert_line(void) { void command_insert_line(void) {
if (E.cy == E.current_buf->n_rows) { if (E.cy == E.current_buf->n_rows) {
buffer_insert_row(E.current_buf, NULL, 0, E.cy); buffer_insert_row(E.current_buf, NULL, 0, E.cy);
E.cy++;
} else { } else {
buffer_insert_row(E.current_buf, NULL, 0, E.cy + 1); 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->chars = realloc(c_row->chars, E.cx);
c_row->n_chars = E.cx; c_row->n_chars = E.cx;
erow_update_rendering(c_row); 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) { 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); 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);
cursor_adjust_viewport();
} }
void command_delete_char(void) { // TODO 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); E.rx = erow_cx_to_rx(E.current_buf->rows+E.cy, E.cx);
cursor_adjust_viewport();
} }
void command_save_buffer(void) { 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) if (errcode == 0)
editor_set_message("Saved file %s", E.current_buf->filename); editor_set_message("%d bytes written", bytes_written);
else else
editor_set_message("Save failed: ERRCODE %d: %s", errcode, strerror(errno)); editor_set_message("Save failed: ERRCODE %d: %s", errcode, strerror(errno));
} }

View file

@ -21,15 +21,11 @@ void input_process_key(void) {
command_move_cursor(c); command_move_cursor(c);
break; break;
case CTRL_KEY('Q'):
command_quit();
return;
case CTRL_KEY('S'): case CTRL_KEY('S'):
command_save_buffer(); command_save_buffer();
break; break;
case '\r': case ENTER:
command_insert_line(); command_insert_line();
break; break;
@ -46,6 +42,11 @@ void input_process_key(void) {
default: default:
command_insert_char(c); command_insert_char(c);
break;
case CTRL_KEY('Q'):
command_quit();
return;
} }
E.quit_times = 3; E.quit_times = 3;

View file

@ -58,3 +58,40 @@ void editor_set_message(const char *fmt, ...) {
E.message_time = time(NULL); 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;
}

View file

@ -96,7 +96,10 @@ KEY terminal_read_key(void) {
char buf[8] = { '\0' }; char buf[8] = { '\0' };
for (int i = 0; i < (int) sizeof(buf); i++) { 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; char escape_char;
int escape_int; int escape_int;