diff runtime/doc/eval.txt @ 30065:6cf788ab844c v9.0.0370

patch 9.0.0370: cleaning up afterwards can make a function messy Commit: https://github.com/vim/vim/commit/1d84f7608f1e41dad03b8cc7925895437775f7c0 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Sep 3 21:35:53 2022 +0100 patch 9.0.0370: cleaning up afterwards can make a function messy Problem: Cleaning up afterwards can make a function messy. Solution: Add the :defer command.
author Bram Moolenaar <Bram@vim.org>
date Sat, 03 Sep 2022 22:45:03 +0200
parents e37754a13778
children ebed259f919f
line wrap: on
line diff
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2979,6 +2979,62 @@ is used as a method: >
 	let y = GetList()->Filter()
 
 
+CLEANING UP IN A FUNCTION ~
+							*:defer*
+:defer {func}({args})	Call {func} when the current function is done.
+			{args} are evaluated here.
+
+Quite often a command in a function has a global effect, which must be undone
+when the function finishes.  Handling this in all kinds of situations can be a
+hassle.  Especially when an unexpected error is encountered.  This can be done
+with `try` / `finally` blocks, but this gets complicated when there is more
+than one.
+
+A much simpler solution is using `defer`.  It schedules a function call when
+the function is returning, no matter if there is an error.  Example: >
+	func Filter(text)
+	  call writefile(a:text, 'Tempfile')
+	  call system('filter < Tempfile > Outfile')
+	  call Handle('Outfile')
+	  call delete('Tempfile')
+	  call delete('Outfile')
+	endfunc
+
+Here 'Tempfile' and 'Outfile' will not be deleted if something causes the
+function to abort.  `:defer` can be used to avoid that: >
+	func Filter(text)
+	  call writefile(a:text, 'Tempfile')
+	  defer delete('Tempfile')
+	  defer delete('Outfile')
+	  call system('filter < Tempfile > Outfile')
+	  call Handle('Outfile')
+	endfunc
+
+Note that deleting "Outfile" is scheduled before calling system(), since it
+can be created even when `system()` fails.
+
+The defered functions are called in reverse order, the last one added is
+executed first.  A useless example: >
+	func Useless()
+	  for s in range(3)
+	    defer execute('echomsg "number ' .. s .. '"')
+	  endfor
+	endfunc
+
+Now `:messages` shows:
+	number 2
+	number 1
+	number 0
+
+Any return value of the deferred function is discarded.  The function cannot
+be followed by anything, such as "->func" or ".member".  Currently `:defer
+GetArg()->TheFunc()` does not work, it may work in a later version.
+
+Errors are reported but do not cause aborting execution of deferred functions.
+
+No range is accepted.
+
+
 AUTOMATICALLY LOADING FUNCTIONS ~
 							*autoload-functions*
 When using many or large functions, it's possible to automatically define them