From 29fe883aa9166bdbcae3f935523c75a8aa56fe45 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 4 Oct 2023 06:31:25 -0700 Subject: feat: ignore swapfile for running Nvim processes #25336 Problem: The swapfile "E325: ATTENTION" dialog is displayed when editing a file already open in another (running) Nvim. Usually this behavior is annoying and irrelevant: - "Recover" and the other options ("Open readonly", "Quit", "Abort") are almost never wanted. - swapfiles are less relevant for "multi-Nvim" since 'autoread' is enabled by default. - Even less relevant if user enables 'autowrite'. Solution: Define a default SwapExists handler which does the following: 1. If the swapfile is owned by a running Nvim process, automatically chooses "(E)dit anyway" (caveat: this creates a new, extra swapfile, which is mostly harmless and ignored except by `:recover` or `nvim -r`. 2. Shows a 1-line "ignoring swapfile..." message. 3. Users can disable the default SwapExists handler via `autocmd! nvim_swapfile`. --- runtime/doc/autocmd.txt | 2 +- runtime/doc/builtin.txt | 4 ++-- runtime/doc/editing.txt | 39 ++++++++++++++++----------------------- runtime/doc/eval.txt | 7 ++++--- runtime/doc/news.txt | 6 ++++++ runtime/doc/recover.txt | 9 +++++++++ runtime/doc/vim_diff.txt | 5 +++++ runtime/lua/vim/_editor.lua | 17 +++++++++++++++++ runtime/lua/vim/_meta/vimfn.lua | 4 ++-- 9 files changed, 62 insertions(+), 31 deletions(-) (limited to 'runtime') diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 90211fc5db..7ca9996e15 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -118,7 +118,7 @@ manually. Mostly the screen will not scroll up, thus there is no hit-enter prompt. When one command outputs two messages this can happen anyway. ============================================================================== -3. Removing autocommands *autocmd-remove* +3. Removing autocommands *autocmd!* *autocmd-remove* :au[tocmd]! [group] {event} {aupat} [++once] [++nested] {cmd} Remove all autocommands associated with {event} and diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index c5c941a4bf..6de7166f83 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -7843,8 +7843,8 @@ swapinfo({fname}) *swapinfo()* user user name host host name fname original file name - pid PID of the Vim process that created the swap - file + pid PID of the Nvim process that created the swap + file, or zero if not running. mtime last modification time in seconds inode Optional: INODE number of the file dirty 1 if file was modified, 0 if not diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt index 10b578fc73..7df2eb9742 100644 --- a/runtime/doc/editing.txt +++ b/runtime/doc/editing.txt @@ -169,33 +169,26 @@ If you want to keep the changed buffer without saving it, switch on the 2. Editing a file *edit-a-file* *:e* *:edit* *reload* -:e[dit] [++opt] [+cmd] Edit the current file. This is useful to re-edit the +:e[dit][!] [++opt] [+cmd] + Edit the current file. This is useful to re-edit the current file, when it has been changed outside of Vim. - This fails when changes have been made to the current - buffer and 'autowriteall' isn't set or the file can't - be written. - Also see |++opt| and |+cmd|. - *:edit!* *discard* -:e[dit]! [++opt] [+cmd] - Edit the current file always. Discard any changes to - the current buffer. This is useful if you want to - start all over again. + If [!] is given, unsaved changes in the current buffer + are discarded. Without [!] the command fails if there + are unsaved changes, unless 'autowriteall' is set and + the file can be written. Also see |++opt| and |+cmd|. *:edit_f* -:e[dit] [++opt] [+cmd] {file} +:e[dit][!] [++opt] [+cmd] {file} Edit {file}. - This fails when changes have been made to the current - buffer, unless 'hidden' is set or 'autowriteall' is - set and the file can be written. - Also see |++opt| and |+cmd|. - *:edit!_f* -:e[dit]! [++opt] [+cmd] {file} - Edit {file} always. Discard any changes to the - current buffer. + If [!] is given, unsaved changes in the current buffer + are discarded. Without [!] the command fails if there + are unsaved changes, unless 'hidden' is set or + 'autowriteall' is set and the file can be written. Also see |++opt| and |+cmd|. + *:edit_#* *:e#* :e[dit] [++opt] [+cmd] #[count] Edit the [count]th buffer (as shown by |:files|). @@ -1224,10 +1217,10 @@ MULTIPLE WINDOWS AND BUFFERS *window-exit* *:confirm* *:conf* :conf[irm] {command} Execute {command}, and use a dialog when an operation has to be confirmed. Can be used on the - |:q|, |:qa| and |:w| commands (the latter to override - a read-only setting), and any other command that can - fail in such a way, such as |:only|, |:buffer|, - |:bdelete|, etc. + |:edit|, |:q|, |:qa| and |:w| commands (the latter to + override a read-only setting), and any commands that + can fail because of unsaved changes, such as |:only|, + |:buffer|, |:bdelete|, etc. Examples: > :confirm w foo diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 3cd5ea13f6..c41237b862 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2276,12 +2276,13 @@ v:stderr |channel-id| corresponding to stderr. The value is always 2; :call chansend(v:stderr, "error: toaster empty\n") < *v:swapname* *swapname-variable* -v:swapname Only valid when executing |SwapExists| autocommands: Name of - the swap file found. Read-only. +v:swapname Name of the swapfile found. + Only valid during |SwapExists| event. + Read-only. *v:swapchoice* *swapchoice-variable* v:swapchoice |SwapExists| autocommands can set this to the selected choice - for handling an existing swap file: + for handling an existing swapfile: 'o' Open read-only 'e' Edit anyway 'r' Recover diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 3c20e52155..f0d01f92e7 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -114,6 +114,12 @@ The following new APIs and features were added. • Builtin TUI can now recognize "super" (|