aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2016-12-14 13:37:47 +0100
committerMarc André Tanner <mat@brain-dump.org>2016-12-14 14:44:49 +0100
commitb531213d198405ba0ff1a2982d8b258fb10d7697 (patch)
tree3bc3456b7fe4ddb9a66605e9c15a17457e7ec97f
parente80d859867e515d95492e61bf5dca08a1c325130 (diff)
downloadvis-b531213d198405ba0ff1a2982d8b258fb10d7697.tar.gz
vis-b531213d198405ba0ff1a2982d8b258fb10d7697.tar.xz
vis: add new :set savemethod auto|atomic|inplace option
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`.
-rw-r--r--man/vis.113
-rw-r--r--sam.c11
-rw-r--r--vis-cmds.c15
-rw-r--r--vis-core.h1
4 files changed, 38 insertions, 2 deletions
diff --git a/man/vis.1 b/man/vis.1
index 64d4c6a..76cfdfc 100644
--- a/man/vis.1
+++ b/man/vis.1
@@ -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
diff --git a/sam.c b/sam.c
index 960c670..dc4023c 100644
--- a/sam.c
+++ b/sam.c
@@ -294,6 +294,7 @@ enum {
OPTION_CURSOR_LINE,
OPTION_COLOR_COLUMN,
OPTION_HORIZON,
+ OPTION_SAVE_METHOD,
};
static const OptionDef options[] = {
@@ -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) {
@@ -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;
}
diff --git a/vis-cmds.c b/vis-cmds.c
index bc42268..a220c33 100644
--- a/vis-cmds.c
+++ b/vis-cmds.c
@@ -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;
diff --git a/vis-core.h b/vis-core.h
index 842c753..f6999dc 100644
--- a/vis-core.h
+++ b/vis-core.h
@@ -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;
};