Yasuhiro Matsumoto wrote:

> My friends found weird behavior of vimscript.
> Try following code.
> ---------------------------------------------------------
> let dict = {}
> function! dict.func()
>   echo "fooooo"
>   return self
> endfunction
> 
> echo "=========== test1"
> if 1 | echo dict.func().func() | endif
> echo "=========== test2"
> if 1 | let a = dict.func().func() | endif
> echo "=========== test3"
> if 1 | call dict.func().func() | endif
> echo "=========== test4"
> if 0 | call dict.func().func() | endif
> ---------------------------------------------------------
> 
> You'll get following errors.
> ---------------------------------------------------------
> =========== test1
> fooooo
> fooooo
> {'func': function('18')}
> =========== test2
> fooooo
> fooooo
> =========== test3
> fooooo
> fooooo
> =========== test4
> Error detected while processing C:\temp\test.vim:
> line   14:
> E488: Trailing characters
> line   15:
> E171: Missing :endif
> Press ENTER or type command to continue
> ---------------------------------------------------------
> 
> Vimscript is treating letter '.' as two meanings.
> One of them is 'concat string'. Another is 'reference dictionary
> item'.
> Vim don't know that '.' is either one without evaluating script.
> 
> Thus, CURRENTLY, vim is evaluating subscript gracefully and doing no-
> performs.
> For example, When the code that blocked like 'if 0 | call dict.foo() |
> endif',
> 'foo()' return 1 instead of 'self'.
> i.e. Second time of calling func() is treating 'concat string'.
> If it is broked in 'if 1', then the result should be 'self' of course.
> 
> And, this problem happen only by 'call' command.
> This dont happend by 'echo', 'let'.
> 
> I think that 'if 0 / endif block' can be possible to skip until eol or
> '|'.
> Below is a patch to skip until that. And success to run above test
> code.
> Please check this way.
> If you accept this way, vim may have another commands turn of this
> case.
> 
> Thanks.
> - Yasuhiro Matsumoto
> 
> diff -r 94694351f592 src/eval.c
> --- a/src/eval.c      Fri Oct 15 20:20:05 2010 +0200
> +++ b/src/eval.c      Wed Oct 20 21:12:58 2010 +0900
> @@ -3337,6 +3337,11 @@
>      int              failed = FALSE;
>      funcdict_T       fudi;
> 
> +    if (eap->skip) {
> +     eap->nextcmd = find_nextcmd(eap->arg);
> +     return;
> +    }
> +
>      tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi);
>      if (fudi.fd_newkey != NULL)
>      {

Quickly skipping over the :call argument appears to work.  However,
find_nextcmd() does not understand expressions, it may fail.  E.g. for
this:

let dict = {}
function! dict.func(a)
  echo "fooooo"
  return self
endfunction

if 0 | call dict.func('|').func('|') | endif


-- 
Luxury. We used to have to get out of the lake at three o'clock in the 
morning, clean the lake, eat a handful of hot gravel, go to work at the 
mill every day for tuppence a month, come home, and Dad would beat us 
around the head and neck with a broken bottle, if we were LUCKY!

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\        download, build and distribute -- http://www.A-A-P.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

Raspunde prin e-mail lui