aboutsummaryrefslogtreecommitdiff
path: root/sam.c
diff options
context:
space:
mode:
authoralex <alex@cloudware.io>2020-02-21 18:12:28 +0100
committeralex <alex@cloudware.io>2020-02-22 18:04:33 +0100
commite824dd43eaa6969577b40694f71acde54f3a3f27 (patch)
tree761341357ab3581f5429acc05514c0f5c868dea9 /sam.c
parentd2407f9ebc089e11eb12054f614a37ba6dbcb1ef (diff)
downloadvis-e824dd43eaa6969577b40694f71acde54f3a3f27.tar.gz
vis-e824dd43eaa6969577b40694f71acde54f3a3f27.tar.xz
sam: re-take range after pre-save hooks are run
A vis.events.FILE_SAVE_PRE callback may mutate the file text, making the original range passed to cmd_write incorrect. It is unclear how to realign the range after the callback is done for the cases where an active selection in visual mode is present or an explicit range like :1,2w! was specified. However, this commit resolves the issue for the case where the whole file is expected to be written.
Diffstat (limited to 'sam.c')
-rw-r--r--sam.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/sam.c b/sam.c
index 38bbad8..3ea7aee 100644
--- a/sam.c
+++ b/sam.c
@@ -1573,6 +1573,10 @@ static bool cmd_substitute(Vis *vis, Win *win, Command *cmd, const char *argv[],
return false;
}
+/* cmd_write stores win->file's contents end emits pre/post events.
+ * If the range r covers the whole file, it is updated to account for
+ * potential file's text mutation by a FILE_SAVE_PRE callback.
+ */
static bool cmd_write(Vis *vis, Win *win, Command *cmd, const char *argv[], Selection *sel, Filerange *r) {
if (!win)
return false;
@@ -1582,6 +1586,9 @@ static bool cmd_write(Vis *vis, Win *win, Command *cmd, const char *argv[], Sele
return false;
Text *text = file->text;
+ Filerange range_all = text_range_new(0, text_size(text));
+ bool write_entire_file = text_range_equal(r, &range_all);
+
const char *filename = argv[1];
if (!filename)
filename = file->name;
@@ -1599,6 +1606,9 @@ static bool cmd_write(Vis *vis, Win *win, Command *cmd, const char *argv[], Sele
vis_info_show(vis, "Rejected write to stdout by pre-save hook");
return false;
}
+ /* a pre-save hook may have changed the text; need to re-take the range */
+ if (write_entire_file)
+ *r = text_range_new(0, text_size(text));
bool visual = vis->mode->visual;
@@ -1624,8 +1634,7 @@ static bool cmd_write(Vis *vis, Win *win, Command *cmd, const char *argv[], Sele
vis_info_show(vis, "WARNING: file will be reduced to active selection");
return false;
}
- Filerange all = text_range_new(0, text_size(text));
- if (!text_range_equal(r, &all)) {
+ if (!write_entire_file) {
vis_info_show(vis, "WARNING: file will be reduced to provided range");
return false;
}
@@ -1648,6 +1657,9 @@ static bool cmd_write(Vis *vis, Win *win, Command *cmd, const char *argv[], Sele
vis_info_show(vis, "Rejected write to `%s' by pre-save hook", path);
goto err;
}
+ /* a pre-save hook may have changed the text; need to re-take the range */
+ if (write_entire_file)
+ *r = text_range_new(0, text_size(text));
TextSave *ctx = text_save_begin(text, path, file->save_method);
if (!ctx) {