Skip to content

Commit

Permalink
Warn when saving a file which has been changed outside the editor
Browse files Browse the repository at this point in the history
  • Loading branch information
martanne committed Jul 6, 2015
1 parent 071b5f3 commit 22d843e
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 2 deletions.
1 change: 1 addition & 0 deletions editor.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
9 changes: 8 additions & 1 deletion text.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1043,6 +1046,10 @@ Text *text_load(const char *filename) {
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.
Expand Down
4 changes: 4 additions & 0 deletions text.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down Expand Up @@ -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*);
Expand Down
11 changes: 10 additions & 1 deletion vis.c
Original file line number Diff line number Diff line change
Expand Up @@ -1683,19 +1683,28 @@ 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;
}

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;
Expand Down

0 comments on commit 22d843e

Please sign in to comment.