2017-12-15 22:09 GMT+03:00 Bram Moolenaar <b...@moolenaar.net>:
>
> Many plugins set options to a different value.  To be able to restore
> the original value very often the old value needs to be saved.
>
> Not only is this a bit of a hassle, especially for local options, it is
> also incomplete, since the location where the option was originally set
> can't be restored.
>
> I have been thinking of adding two functions to make this work better:
>
> option_save({list})                                     *option_save()*
>                 Saves the options named in {list}.  The returned value can be
>                 passed to option_restore().  Example: >
>                         let s:saved_options = option_save([
>                             \ 'ignorecase',
>                             \ 'iskeyword',
>                             \ ])
>                          au <buffer> BufLeave *
>                             \ call option_restore(s:saved_options)
> <               The advantage over using `:let` is that global and local
>                 values are handled and the script ID is restored, so that
>                 `:verbose set` will show where the option was originally set,
>                 not where it was restored.
>
>
> option_restore({list})                                  *option_restore()*
>                 Restore options previously saved by option_save().
>                 When buffer-local options have been saved, this function must
>                 be called when the same buffer is the current buffer.
>                 When window-local options have been saved, this function must
>                 be called when the same window is the current window.
>                 When in the wrong buffer and/or window an error is given and
>                 the local options won't be restored.
>
> Does that sound useful?

AFAIK it was discussed before. Functions are too easy to forget to
call, especially given existence of excetpions and I don’t think that
“must be called when the same buffer … the same window …” is a good
idea either. Using context managers is a better option for the first
problem: you can forget ending `:with` block no more then you can
forget ending `:try`: i.e. forgetting will spawn an error at the point
where VimL does end the block even if `:endtry` was forgotten. Second
is nothing more then an annoing unnecessary nuisance, both buffers and
windows do have a unique identifiers and I do not see anything which
may prevent code from using them to find buffer/window to restore
option in, it is only needed to agree on behaviour in case that
buffer/window no longer exists.

Context managers are also not limited to just options, they are
frequently used in Python for user code as well because this syntax is
in many cases more pleasant then `try … finally`.

Also something like `:with setlocal iskeyword&vim|…|endwith` is much
nicer syntax then anything you can come up with based on VimL
expressions, with your proposal that would be

    let saved_options = option_save(['iskeyword'])
    try
        setlocal iskeyword&vim
        …
    finally
        " Restore buffer/window here if needed.
        " Do not forget to check if it is.
        " Do not forget :try/finally if `…` is anything which may
throw an exception.
        " Do not forget :try/finally if `…` may throw an error as well
and user may have
        " a reason to call your function inside a `:try` block.
Basically do not forget it ever,
        " you may never know whether last statement is true.
        call option_restore(saved_options)
    endtry

Putting my comments aside this is +2 lines for try/finally (endtry is
endwith, `let` line is `with` line), +1 line for `setlocal` (may be
good idea to devise different syntax, AFAIR I had something better
then `with setlocal iskeyword&vim`, i.e. more suitable for setting to
a value of an expression) and +1 line for `option_restore`, totalling
+4 lines.

The only downside (from the user POV) I see is that you can’t split
calls up: i.e. have option_save() in one function and option_restore()
in another. From the developer POV I understand that context managers
are significantly harder to implement.

>
> --
> hundred-and-one symptoms of being an internet addict:
> 100. The most exciting sporting events you noticed during summer 1996
>     was Netscape vs. Microsoft.
>
>  /// Bram Moolenaar -- b...@moolenaar.net -- http://www.Moolenaar.net   \\\
> ///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
> \\\  an exciting new programming language -- http://www.Zimbu.org        ///
>  \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///
>
> --
> --
> You received this message from the "vim_dev" maillist.
> Do not top-post! Type your reply below the text you are replying to.
> For more information, visit http://www.vim.org/maillist.php
>
> ---
> You received this message because you are subscribed to the Google Groups 
> "vim_dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to vim_dev+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui