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");