aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editor.c1
-rw-r--r--editor.h1
-rw-r--r--text.c9
-rw-r--r--text.h4
-rw-r--r--vis.c11
5 files changed, 24 insertions, 2 deletions
diff --git a/editor.c b/editor.c
index 87072a3..ad9bd4e 100644
--- a/editor.c
+++ b/editor.c
@@ -293,6 +293,7 @@ static File *file_new_text(Editor *ed, Text *text) {
if (!file)
return NULL;
file->text = text;
+ file->stat = text_stat(text);
file->refcount++;
if (ed->files)
ed->files->prev = file;
diff --git a/editor.h b/editor.h
index 5192d31..36f2829 100644
--- a/editor.h
+++ b/editor.h
@@ -195,6 +195,7 @@ struct File {
Text *text;
const char *name;
bool stdin;
+ struct stat stat;
int refcount;
Mark marks[MARK_LAST];
File *next, *prev;
diff --git a/text.c b/text.c
index 764d7cb..c5f3768 100644
--- a/text.c
+++ b/text.c
@@ -802,7 +802,7 @@ static bool preserve_selinux_context(int src, int dest) {
* - SELinux security context can not be preserved (if enabled)
*/
static bool text_range_save_atomic(Text *txt, Filerange *range, const char *filename) {
- struct stat meta;
+ struct stat meta = { 0 };
int fd = -1, oldfd = -1, saved_errno;
char *tmpname = NULL;
size_t size = text_range_size(range);
@@ -877,6 +877,8 @@ static bool text_range_save_atomic(Text *txt, Filerange *range, const char *file
if (rename(tmpname, filename) == -1)
goto err;
+ if (meta.st_mtime)
+ txt->info = meta;
free(tmpname);
return true;
err:
@@ -955,6 +957,7 @@ bool text_range_save(Text *txt, Filerange *range, const char *filename) {
goto err;
if (close(fd) == -1)
return false;
+ txt->info = meta;
ok:
txt->saved_action = txt->history;
text_snapshot(txt);
@@ -1043,6 +1046,10 @@ out:
return NULL;
}
+struct stat text_stat(Text *txt) {
+ return txt->info;
+}
+
/* A delete operation can either start/stop midway through a piece or at
* a boundry. In the former case a new piece is created to represent the
* remaining text before/after the modification point.
diff --git a/text.h b/text.h
index 725fa26..16b4a45 100644
--- a/text.h
+++ b/text.h
@@ -3,7 +3,9 @@
#include <stdbool.h>
#include <time.h>
+#include <unistd.h>
#include <sys/types.h>
+#include <sys/stat.h>
#define EPOS ((size_t)-1) /* invalid position */
@@ -35,6 +37,8 @@ typedef struct {
text_iterator_next(&it))
Text *text_load(const char *file);
+/* file information at time of load or last save */
+struct stat text_stat(Text*);
bool text_insert(Text*, size_t pos, const char *data, size_t len);
bool text_delete(Text*, size_t pos, size_t len);
void text_snapshot(Text*);
diff --git a/vis.c b/vis.c
index 076f0c7..4520fe3 100644
--- a/vis.c
+++ b/vis.c
@@ -1683,12 +1683,20 @@ static bool cmd_write(Filerange *range, enum CmdOpt opt, const char *argv[]) {
return false;
}
for (const char **name = &argv[1]; *name; name++) {
+ struct stat meta;
+ if (!(opt & CMD_OPT_FORCE) && file->stat.st_mtime && stat(*name, &meta) == 0 &&
+ file->stat.st_mtime < meta.st_mtime) {
+ editor_info_show(vis, "WARNING: file has been changed since reading it");
+ return false;
+ }
if (!text_range_save(text, range, *name)) {
editor_info_show(vis, "Can't write `%s'", *name);
return false;
}
- if (!file->name)
+ if (!file->name) {
editor_window_name(vis->win, *name);
+ file->stat = text_stat(text);
+ }
}
return true;
}
@@ -1696,6 +1704,7 @@ static bool cmd_write(Filerange *range, enum CmdOpt opt, const char *argv[]) {
static bool cmd_saveas(Filerange *range, enum CmdOpt opt, const char *argv[]) {
if (cmd_write(range, opt, argv)) {
editor_window_name(vis->win, argv[1]);
+ vis->win->file->stat = text_stat(vis->win->file->text);
return true;
}
return false;