Skip to content

Commit

Permalink
vis: add new :set savemethod auto|atomic|inplace option
Browse files Browse the repository at this point in the history
Specifies how the current file should be saved, `atomic` which uses
rename(2) to atomically replace the file, `inplace` which truncates the
file and then rewrites it or `auto` which tries the former before falling
back to the latter. The rename method fails for symlinks, hardlinks,
in case of insufficient directory permissions or when either the file
owner, group, POSIX ACL or SELinux labels can not be restored.

The option defaults to `auto`.
  • Loading branch information
martanne committed Dec 14, 2016
1 parent e80d859 commit b531213
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 2 deletions.
13 changes: 13 additions & 0 deletions man/vis.1
Original file line number Diff line number Diff line change
Expand Up @@ -1111,6 +1111,19 @@ Whether to display replacement symbol instead of tabs.
Whether to display replacement symbol instead of newlines.
.It Cm show-spaces Bq off
Whether to display replacement symbol instead of blank cells.
.It Cm savemethod Bq auto
How the current file should be saved,
.Sy atomic
which uses
.Xr rename 2
to atomically replace the file,
.Sy inplace
which truncates the file and then rewrites it or
.Sy auto
which tries the former before falling back to the latter. The rename
method fails for symlinks, hardlinks, in case of insufficient directory
permissions or when either the file owner, group, POSIX ACL or SELinux
labels can not be restored.
.El
.
.Sh CONFIGURATION
Expand Down
11 changes: 9 additions & 2 deletions sam.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ enum {
OPTION_CURSOR_LINE,
OPTION_COLOR_COLUMN,
OPTION_HORIZON,
OPTION_SAVE_METHOD,
};

static const OptionDef options[] = {
Expand Down Expand Up @@ -372,6 +373,11 @@ static const OptionDef options[] = {
OPTION_TYPE_NUMBER, OPTION_FLAG_WINDOW,
"Number of bytes to consider for syntax highlighting",
},
[OPTION_SAVE_METHOD] = {
{ "savemethod" },
OPTION_TYPE_STRING, OPTION_FLAG_WINDOW,
"Save method to use for current file 'auto', 'atomic' or 'inplace'",
},
};

bool sam_init(Vis *vis) {
Expand Down Expand Up @@ -1349,9 +1355,10 @@ static bool cmd_write(Vis *vis, Win *win, Command *cmd, const char *argv[], Curs
return false;
}

TextSave *ctx = text_save_begin(text, *name, TEXT_SAVE_AUTO);
TextSave *ctx = text_save_begin(text, *name, file->save_method);
if (!ctx) {
vis_info_show(vis, "Can't write `%s': %s", *name, strerror(errno));
const char *msg = errno ? strerror(errno) : "try changing `:set savemethod`";
vis_info_show(vis, "Can't write `%s': %s", *name, msg);
return false;
}

Expand Down
15 changes: 15 additions & 0 deletions vis-cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,21 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor
case OPTION_HORIZON:
win->horizon = arg.i;
break;
case OPTION_SAVE_METHOD:
if (strcmp("auto", arg.s) == 0) {
win->file->save_method = TEXT_SAVE_AUTO;
} else if (strcmp("atomic", arg.s) == 0) {
win->file->save_method = TEXT_SAVE_ATOMIC;
} else if (strcmp("inplace", arg.s) == 0) {
win->file->save_method = TEXT_SAVE_INPLACE;
} else {
vis_info_show(vis, "Invalid save method `%s', expected "
"'auto', 'atomic' or 'inplace'", arg.s);
return false;
}
break;
default:
return false;
}

return true;
Expand Down
1 change: 1 addition & 0 deletions vis-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ struct File { /* shared state among windows displaying the same file */
struct stat stat; /* filesystem information when loaded/saved, used to detect changes outside the editor */
int refcount; /* how many windows are displaying this file? (always >= 1) */
Mark marks[VIS_MARK_INVALID]; /* marks which are shared across windows */
enum TextSaveMethod save_method; /* whether the file is saved using rename(2) or overwritten */
File *next, *prev;
};

Expand Down

0 comments on commit b531213

Please sign in to comment.