diff options
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/doc/builtin.txt | 60 | ||||
-rw-r--r-- | runtime/doc/userfunc.txt | 60 |
2 files changed, 103 insertions, 17 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index cb05718ab9..15ccfd9b92 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -5572,8 +5572,24 @@ mkdir({name} [, {flags} [, {prot}]]) When {flags} is present it must be a string. An empty string has no effect. - If {flags} is "p" then intermediate directories are created as - necessary. + If {flags} contains "p" then intermediate directories are + created as necessary. + + If {flags} contains "D" then {name} is deleted at the end of + the current function, as with: > + defer delete({name}, 'd') +< + If {flags} contains "R" then {name} is deleted recursively at + the end of the current function, as with: > + defer delete({name}, 'rf') +< Note that when {name} has more than one part and "p" is used + some directories may already exist. Only the first one that + is created and what it contains is scheduled to be deleted. + E.g. when using: > + call mkdir('subdir/tmp/autoload', 'pR') +< and "subdir" already exists then "subdir/tmp" will be + scheduled for deletion, like with: > + defer delete('subdir/tmp', 'rf') If {prot} is given it is used to set the protection bits of the new directory. The default is 0o755 (rwxr-xr-x: r/w for @@ -9507,31 +9523,43 @@ writefile({object}, {fname} [, {flags}]) When {object} is a |List| write it to file {fname}. Each list item is separated with a NL. Each list item must be a String or Number. - When {flags} contains "b" then binary mode is used: There will - not be a NL after the last list item. An empty item at the - end does cause the last line in the file to end in a NL. + All NL characters are replaced with a NUL character. + Inserting CR characters needs to be done before passing {list} + to writefile(). When {object} is a |Blob| write the bytes to file {fname} - unmodified. + unmodified, also when binary mode is not specified. - When {flags} contains "a" then append mode is used, lines are - appended to the file: > + {flags} must be a String. These characters are recognized: + + 'b' Binary mode is used: There will not be a NL after the + last list item. An empty item at the end does cause the + last line in the file to end in a NL. + + 'a' Append mode is used, lines are appended to the file: > :call writefile(["foo"], "event.log", "a") :call writefile(["bar"], "event.log", "a") < - When {flags} contains "S" fsync() call is not used, with "s" - it is used, 'fsync' option applies by default. No fsync() - means that writefile() will finish faster, but writes may be - left in OS buffers and not yet written to disk. Such changes - will disappear if system crashes before OS does writing. + 'D' Delete the file when the current function ends. This + works like: > + :defer delete({fname}) +< Fails when not in a function. Also see |:defer|. + + 's' fsync() is called after writing the file. This flushes + the file to disk, if possible. This takes more time but + avoids losing the file if the system crashes. + + 'S' fsync() is not called, even when 'fsync' is set. + + When {flags} does not contain "S" or "s" then fsync() is + called if the 'fsync' option is set. - All NL characters are replaced with a NUL character. - Inserting CR characters needs to be done before passing {list} - to writefile(). An existing file is overwritten, if possible. + When the write fails -1 is returned, otherwise 0. There is an error message if the file can't be created or when writing fails. + Also see |readfile()|. To copy a file byte for byte: > :let fl = readfile("foo", "b") diff --git a/runtime/doc/userfunc.txt b/runtime/doc/userfunc.txt index ce6f2fc2e9..db0127df95 100644 --- a/runtime/doc/userfunc.txt +++ b/runtime/doc/userfunc.txt @@ -350,10 +350,68 @@ A function can also be called as part of evaluating an expression or when it is used as a method: > let x = GetList() let y = GetList()->Filter() +< +============================================================================== +3. 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) abort + 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) abort + 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 deferred functions are called in reverse order, the last one added is +executed first. A useless example: > + func Useless() abort + 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. The function can be a partial with extra arguments, but +not with a dictionary. *E1300* ============================================================================== -3. Automatically loading functions ~ + +4. Automatically loading functions ~ *autoload-functions* When using many or large functions, it's possible to automatically define them only when they are used. There are two methods: with an autocommand and with |