2017-06-23 21:52 GMT+03:00 Bram Moolenaar <[email protected]>:
>
> Nikolay Pavlov wrote:
>
>> 2017-06-22 20:12 GMT+03:00 Bram Moolenaar <[email protected]>:
>> >
>> > Patch 8.0.0654
>> > Problem: Text found after :endfunction is silently ignored.
>> > Solution: Give a warning if 'verbose' is set. When | or \n are used,
>> > execute the text as a command.
>> > Files: src/testdir/test_vimscript.vim, src/userfunc.c,
>> > runtime/doc/eval.txt
>>
>> [...]
>>
>> I am not much fond of the idea of conditionally making code stop
>> working. &verbose+&verbosefile combination is supposed to provide a
>> user with a log for debugging, not screw up the code (which will be
>> done should user e.g. be testing a SourceCmd that does `try | source |
>> finally`).
>
> Right. I used an error message to make the test work, but it's not a
> good solution. I'll make it a warning message.
>
>> Additionally `\n` is not supposed to occur inside an argument at all.
>> You are throwing an implementation detail of `:execute` into a face of
>> user and I do not remember it being actually documented. Not in `:h
>> :execute` for sure. There is some documentation at `:h :|` which talks
>> about replacing it with `<C-v><CR>`, but that’s all I found and it
>> does not mention `\n` or special treatment of a newline inside
>> `:execute`.
>
> The use of \n is required, as the code searching for :endfunction cannot
> parse commands and can easily handle | in a wrong way. This didn't
> change. I thought this was documented somewhere, but can't find it now.
> I'll add an example.
I am referring to `execute join(["normal! a", "insert", "."], "\n")`
vs `call writefile(["normal! a", "insert", "."], "/tmp/test.vim") |
source /tmp/test.vim`. The first takes `\ninsert\n.` as a part of the
`:normal!` argument due to how `:execute` is implemented, second
executes two commands. It is universal among commands which have a
habit of taking bar as their argument, so I would seek for the
description of the difference in `:h :execute` and `:h execute()`
(second only applicable for non-list form) since these are normally
the only commands which make difference in runtime. `-c` and `--cmd`
use the same variant of calling `do_cmdline` as well.
I saw this design flaw exploited in a number of places, including my
plugins (`:py << EOF` does not work inside `:execute`, so I have to
adapt). Mostly in a variant of “insert text via `:execute "normal!
i".multiline_text`”.
>
>
>> The third reason why I would actually proceed with my way is that
>> `:endfunction | next command` is not going to work reliably for a
>> pretty long period of time: e.g. debian jessie (oldstable) was there
>> for two years and it had 7.4.488, new stable was only released a
>> couple of days ago and contains 8.0.0197. These consideration could be
>> something to discard if `endfunction | cmd` was actually useful, but I
>> do not see it being such. At least not unless you want to allow
>> writing `:function Test() | echo 1 | endfunction | call Test()`: this
>> would prove handy for some of my one-liners, but in the current state
>> it does not work because of `:function` and not because of
>> `:endfunction`.
>
> The question came up with it didn't work and was silently ignored. Now,
> we could keep silently ignoring it, give an error or make it work.
> Giving an error is not reliable, since there are so many uses already
> where it gets in the way. Making it work appears to be the best
> long-term solution. And yeah, it will take a while until widely spread
> plugins can use it.
By “my solution” I refer to
1. Text after `:endfunction` which does not contain bar is always
allowed and silently ignored.
2. Comments after `:endfunction` are also always allowed, but they end
in `\n` in case of using `:execute` (BTW `:execute "\" {{{\nfunction
Foo()\nendfunction"` is actually executing a single comment line and
not defining function `Foo`, silently of course). Comments are
silently ignored.
3. Text which does contain bar not inside a comment is an error.
This way this is how the following examples work both inside and
outside `:execute`:
```VimL
" Defines function Foo
function Foo()
endfunction Foo
" {{{ Defines function Bar
function Bar()
endfunction " Bar | }}}
" Defines function Baz
function! Baz()
endfunction!
" Defines no functions due to errorring out
function FooBar()
endfunction | call FooBar()
" Defines and calls function FooBar
function FooBar()
endfunction
call FooBar()
```
This will not break any plugins my search found, give an error at code
which potentionally means user wanting to actually execute something
after `:endfunction`.
AND does not contain a memory leak or buffer overflow. At least it
looks like this: as `eap->nextcmd` is supposed to point to `eap->arg +
N` AFAIK I do not see it being freed anywhere, but I *do* see
```
STRMOVE(cmdline_copy, next_cmdline);
next_cmdline = cmdline_copy;
```
in do_cmdline(). This crashes or freezes Vim (for some reason crashes
regular Vim, freezes `-u NONE -i NONE -N` variant):
```VimL
call writefile([
\"function Foo()",
\"endfunction | echo " . string(repeat("x", 4096))],
\"/tmp/foo.vim")
source /tmp/foo.vim
```
>
> --
> hundred-and-one symptoms of being an internet addict:
> 71. You wonder how people walk
>
> /// Bram Moolenaar -- [email protected] -- 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 [email protected].
For more options, visit https://groups.google.com/d/optout.