Home Explore Blog CI



neovim

39th chunk of `runtime/doc/vimeval.txt`
5df91cce55c0acd3840debc91f4c19039959b920757e81ae0000000100000fa8
		*except-autocmd-Post*
For some commands, autocommands get executed after the main action of the
command has taken place.  If this main action fails and the command is inside
an active try conditional, the autocommands are skipped and an error exception
is thrown that can be caught by the caller of the command.
   Example: >

	:autocmd BufWritePost * echo "File successfully written!"
	:
	:try
	:  write /i/m/p/o/s/s/i/b/l/e
	:catch
	:  echo v:exception
	:endtry

This just displays: >

	Vim(write):E212: Can't open file for writing (/i/m/p/o/s/s/i/b/l/e)

If you really need to execute the autocommands even when the main action
fails, trigger the event from the catch clause.
   Example: >

	:autocmd BufWritePre  * set noreadonly
	:autocmd BufWritePost * set readonly
	:
	:try
	:  write /i/m/p/o/s/s/i/b/l/e
	:catch
	:  doautocmd BufWritePost /i/m/p/o/s/s/i/b/l/e
	:endtry
<
You can also use ":silent!": >

	:let x = "ok"
	:let v:errmsg = ""
	:autocmd BufWritePost * if v:errmsg != ""
	:autocmd BufWritePost *   let x = "after fail"
	:autocmd BufWritePost * endif
	:try
	:  silent! write /i/m/p/o/s/s/i/b/l/e
	:catch
	:endtry
	:echo x

This displays "after fail".

If the main action of the command does not fail, exceptions from the
autocommands will be catchable by the caller of the command:  >

	:autocmd BufWritePost * throw ":-("
	:autocmd BufWritePost * echo "Should not be displayed"
	:
	:try
	:  write
	:catch
	:  echo v:exception
	:endtry
<
							*except-autocmd-Cmd*
For some commands, the normal action can be replaced by a sequence of
autocommands.  Exceptions from that sequence will be catchable by the caller
of the command.
   Example:  For the ":write" command, the caller cannot know whether the file
had actually been written when the exception occurred.  You need to tell it in
some way. >

	:if !exists("cnt")
	:  let cnt = 0
	:
	:  autocmd BufWriteCmd * if &modified
	:  autocmd BufWriteCmd *   let cnt = cnt + 1
	:  autocmd BufWriteCmd *   if cnt % 3 == 2
	:  autocmd BufWriteCmd *     throw "BufWriteCmdError"
	:  autocmd BufWriteCmd *   endif
	:  autocmd BufWriteCmd *   write | set nomodified
	:  autocmd BufWriteCmd *   if cnt % 3 == 0
	:  autocmd BufWriteCmd *     throw "BufWriteCmdError"
	:  autocmd BufWriteCmd *   endif
	:  autocmd BufWriteCmd *   echo "File successfully written!"
	:  autocmd BufWriteCmd * endif
	:endif
	:
	:try
	:	write
	:catch /^BufWriteCmdError$/
	:  if &modified
	:    echo "Error on writing (file contents not changed)"
	:  else
	:    echo "Error after writing"
	:  endif
	:catch /^Vim(write):/
	:    echo "Error on writing"
	:endtry

When this script is sourced several times after making changes, it displays
first >
	File successfully written!
then >
	Error on writing (file contents not changed)
then >
	Error after writing
etc.

							*except-autocmd-ill*
You cannot spread a try conditional over autocommands for different events.
The following code is ill-formed: >

	:autocmd BufWritePre  * try
	:
	:autocmd BufWritePost * catch
	:autocmd BufWritePost *   echo v:exception
	:autocmd BufWritePost * endtry
	:
	:write


EXCEPTION HIERARCHIES AND PARAMETERIZED EXCEPTIONS	*except-hier-param*

Some programming languages allow to use hierarchies of exception classes or to
pass additional information with the object of an exception class.  You can do
similar things in Vim.
   In order to throw an exception from a hierarchy, just throw the complete
class name with the components separated by a colon, for instance throw the
string "EXCEPT:MATHERR:OVERFLOW" for an overflow in a mathematical library.
   When you want to pass additional information with your exception class, add
it in parentheses, for instance throw the string "EXCEPT:IO:WRITEERR(myfile)"
for an error when writing "myfile".
   With the appropriate patterns in the ":catch" command, you can catch for
base classes or derived classes of your hierarchy.  Additional information in
parentheses can be cut out from |v:exception| with the ":substitute" command.
   Example:

Title: Exception Handling with Autocommands (Post and Cmd) and Parameterized Exceptions
Summary
This section explains how autocommands executed after a command ('Post') interact with exceptions. If the main command fails within a 'try' block, 'Post' autocommands are skipped, and an exception is thrown. To ensure 'Post' autocommands always run, the event can be triggered in the 'catch' block or using `:silent!`. It also discusses autocommands that replace the normal command action ('Cmd') and how their exceptions are handled. Finally, it touches on simulating exception hierarchies and passing additional information with exceptions using strings, which can be parsed using regular expressions.