tRecord and show if file is changed - ve - a minimal text editor (work in progress) (HTM) git clone git://src.adamsgaard.dk/ve (DIR) Log (DIR) Files (DIR) Refs (DIR) README (DIR) LICENSE --- (DIR) commit 42a8291950dcb96ec855afa221e71e06c6ef8e88 (DIR) parent f0699261a58f3c5e8e5eaff0e85553d4b7475fde (HTM) Author: Anders Damsgaard <anders@adamsgaard.dk> Date: Tue, 6 Aug 2019 16:36:59 +0200 Record and show if file is changed Diffstat: M byote.h | 1 + M input.c | 13 +++++++++++++ M io.c | 21 +++++++++++++++++---- M output.c | 4 +++- M row.c | 13 +++++++++++++ M row.h | 1 + M terminal.c | 1 + 7 files changed, 49 insertions(+), 5 deletions(-) --- (DIR) diff --git a/byote.h b/byote.h t@@ -30,6 +30,7 @@ struct editor_config { int show_status; char status_msg[80]; time_t status_msg_time; + int file_changed; }; extern struct editor_config E; (DIR) diff --git a/input.c b/input.c t@@ -3,6 +3,7 @@ #include "byote.h" #include "terminal.h" #include "edit.h" +#include "output.h" #include "io.h" #define CTRL_KEY(k) ((k) & 0x1f) t@@ -65,6 +66,18 @@ editor_process_keypress() break; case CTRL_KEY('q'): + if (E.file_changed) { + editor_set_status_message("error: " + "file has unsaved changes. " + "Press C-x to confirm quit"); + break; + } else { + write(STDOUT_FILENO, "\x1b[2J", 4); /* clear screen */ + write(STDOUT_FILENO, "\x1b[H", 3); + exit(0); + break; + } + case CTRL_KEY('x'): write(STDOUT_FILENO, "\x1b[2J", 4); /* clear screen */ write(STDOUT_FILENO, "\x1b[H", 3); exit(0); (DIR) diff --git a/io.c b/io.c t@@ -9,6 +9,7 @@ #include <string.h> #include <fcntl.h> #include <unistd.h> +#include <errno.h> #include "byote.h" #include "terminal.h" #include "row.h" t@@ -39,6 +40,7 @@ file_open(char *filename) } free(line); fclose(fp); + E.file_changed = 0; } /* convert rows to one long char array of length buflen */ t@@ -76,10 +78,21 @@ file_save(char *filename) } buf = editor_concatenate_rows(&len); + fd = open(filename, O_RDWR | O_CREAT, 0644); - ftruncate(fd, len); - write(fd, buf, len); - close(fd); + if (fd != -1) { + if (ftruncate(fd, len) != -1) { + if (write(fd, buf, len) == len) { + close(fd); + free(buf); + E.file_changed = 0; + editor_set_status_message("%d bytes written to disk", len); + return; + } + } + close(fd); + } free(buf); - editor_set_status_message("%s written", filename); + editor_set_status_message("error: can't save! I/O error %s", + strerror(errno)); } (DIR) diff --git a/output.c b/output.c t@@ -66,7 +66,9 @@ editor_draw_status(struct abuf *ab) } left_status_len += snprintf(left_status + left_status_len, sizeof(left_status), - E.filename ? E.filename : "[unnamed] "); + "%.20s %s", + E.filename ? E.filename : "[unnamed]", + E.file_changed ? "[+] " : ""); right_status_len = snprintf(right_status, sizeof(right_status), "%d%% < %d:%d", (DIR) diff --git a/row.c b/row.c t@@ -65,6 +65,7 @@ editor_append_row(char *s, size_t len) editor_update_row(&E.row[i]); ++E.num_rows; + E.file_changed = 1; } /* insert character to row, making sure to allocate memory accordingly */ t@@ -78,4 +79,16 @@ editor_row_insert_char(eRow *row, int i, int c) row->size++; row->chars[i] = c; editor_update_row(row); + E.file_changed = 1; +} + +void +editor_row_delete_char(eRow *row, int i) +{ + if (i<0 || i>row->size) + return; + memmove(&row->chars[i], &row->chars[i+1], row->size-i); + row->size--; + editor_update_row(row); + E.file_changed = 1; } (DIR) diff --git a/row.h b/row.h t@@ -6,5 +6,6 @@ int editor_row_cursor_x_to_rx(eRow *row, int cursor_x); void editor_append_row(char *s, size_t len); void editor_row_insert_char(eRow *row, int i, int c); +void editor_row_delete_char(eRow *row, int i); #endif (DIR) diff --git a/terminal.c b/terminal.c t@@ -121,6 +121,7 @@ init_editor() { E.status_msg[0] = '\0'; E.status_msg_time = 0; E.show_status = 0; + E.file_changed = 0; if (get_window_size(&E.screen_rows, &E.screen_columns) == -1) die("get_window_size");