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