Here I will list all incompatibilities between old and new VimL implementations. Some may be fixed, so it is also a place for discussion. Please discuss incompatibilities with separate issues in separate issues.
- Dot subscripts are not always read correctly (#240).
- E15 errors are not not just “E15: Invalid expression”: there are (invalid
expressions)
- “E15: expected variable name” (
\x80\xFD\x52) - “E15: expected expr7 (value)” (
+) - “E15: missing closing curly brace” (
a{1)
- “E15: expected variable name” (
- E116 error was renamed: “E116: expected closing parenthesis”.
- No nested expr errors:
function(a{})will produce one “E15: expected expr7 (value)”, not E15, E15, E116 and E15 errors at once (only E15 can be caught though). - Positions of error may differ.
- Environment variable name is determined on the parsing stage. But what part of
a string is environment variable name depends on &isident option which may be
different on the stage where expression is actually run. (I really would
rather prefer to remove dependency completely: say work like if value is
non-standard
@,48-57,_,128-255effectively including all UTF-8 characters (just in case), but not things like/. Standard ones are@,48-57,_,128-167,224-235(MS-DOS, Win32, OS/2) and@,48-57,_,192-255(otherwise) which means that e.g.$ENV«»is parsed as($ENV<c2>)<ab>: pretty useless.) ++optE474 was split into- “E474: Expected ++[no]bin or ++[no]binary” (
e ++binxxx) - “E474: Unknown ++opt” (
e ++unknown) - “E474: Option requires argument: use ++opt=arg” (
e ++enc) - “E474: Invalid ++bad argument: use "keep", "drop" or a single-byte
character” (
e ++bad=xxx) - “E474: Invalid ++ff argument” (
e ++ff=ttt)
- “E474: Expected ++[no]bin or ++[no]binary” (
-
appendworks slightly different:append abc .is always correct with my parser, but it may be not correct with old vim parser: depends on context. I failed to comprehend why, but inside functions append with indented first line and same indented dot does not work, while it works correctly inside files.
-
If you mix tabs and spaces in indentation
appenduses the value of&tabstopoption to deduce whether dot is on its place (which is very strange because code suggests it uses 8-wide tabs: I must have missed something (like fgetline transforming tabs to spaces)). My parser uses only 8-wide tabs. -
endfunctionin vim is a marker that is read byex_function()which is the reason whyfunction A()|endfunctiondoes not work. In my parser it is a separate command that ends a:functionblock, so there is no requirement for:endfunctionto be the first command in the line. -
:callaccepts any function calls, not necessary calls in the formfuncname(args)(funcnamemay actually be something likedic{"tionary"}['name'], but not(function("tr"))). I.e. it will work as long as top node is function call node. -
“E129: Function name required” was renamed to “E129: :call accepts only function calls”.
-
“E117: Unknown function” may be replaced with “E117: Attempt to call a non-function” when using
:call. -
:for/:letmessages are different:E475was split into- “E475: Expected variable name or a list of variable names” (
for 1 in []) (was “E690: Missing "in" after :for” for for) - “E475: Expected non-empty list of variable names” (
for [] in []) - “E475: Expected variable name” (
for [1] in [])
- “E475: Expected variable name or a list of variable names” (
-
:letE474 is now “E474: To list multiple variables use "let var|let var2", not ":let [var, var2]"”. -
:let 1will show “E475: Expected variable name or a list of variable names”, not “E121: Undefined variable”. -
“E125: Illegal argument” was split into
- “E125: Argument expected, got nothing” (
:function Abc(,)) - “E125: Function argument cannot start with a digit” (
:function Abc(1)) - “E125: Names "firstline" and "lastline" are reserved” (
:function Abc(firstline))
- “E125: Argument expected, got nothing” (
-
“E475” for
:functionnow looks either like “E475: Expected end of arguments list” or “E475: Expected end of arguments list or comma”. -
“E475” for
:behavenow looks like “E475: :behave command currently only supports mswin and xterm”. -
For debug commands “E475” was split into
- “E475: :profile only accepts
func' andfile' as its first argument” (for:profile foo), - “E475: Debug commands only accept
func',file' andhere'” (for:break… foo`), - “E475: Expecting function name or pattern” (for
:break… func,:break… func 123or:profile… funcwithout further arguments) and - “E475: Expecting file name or pattern” (for
:break… file,:break… file 123or:profile… filewithout further arguments).
- “E475: :profile only accepts
-
“E474” from
:cbufferand friends is now “E474: Expected buffer number”. -
:fu Abc()|echo1|endfis parsed as a correct function definition. Used to produce missing endfunction errors. -
Certain function definitions cannot be parsed. See #425.
-
ilist /inslashes/afterslasheswill complain about trailing characters, but not run anything (in Vim it will first search then complain). Same for similar commands. -
“E216” is always “No such event” (in Vim this may have been “No such group or event”). Any string that does not start with a star and contains no whitespaces is treated like an autocmd group name. Note:
augroupaccepts any sequence of characters as an autocmd group, includingBufWritePreandthis is a group name with spaces and \| bar. I cannot do anything with groups with whitespaces, but anything else is accepted. -
Leading autocmd group name which is identical to some autocmd event name (e.g.
BufWritePre),*or a list of event names (e.g.BufWritePre,BufReadPre) is not parsed as an autocmd group name when parsing:audefinition (I really have no idea why this should be allowed, but even if I thought having group name likeBufWritePreis a good idea I cannot do anything with this at the parsing stage). -
“E474” from
:delmarkswas split into- “E474: :delmarks must be called either without bang or without arguments”
(
:delmarks! some_argument). - “E474: Trying to construct range out of marks from different sets”
(
:delmarks 0-A). - “E474: Upper range bound is less then lower range bound” (
:delmarks z-a). - “E474: Unknown mark” (
:delmarks @).
- “E474: :delmarks must be called either without bang or without arguments”
(
-
“E471” from
:delmarksis now “E471: You must specify register(s)”. -
“E474” from
:digraphswas split into- “E474: Expected second digraph character, but got nothing” (
:digraphs a). - “E104: Escape not allowed in digraph” (
:execute "digraphs a\e 10").
- “E474: Expected second digraph character, but got nothing” (
-
:digraphsaccepts two characters in the digraph definition (was: two bytes, which I consider a bug). -
“E475” from
:later/:earlierwas split into- “E475: Expected 's', 'm', 'h', 'd', 'f' or nothing after number” (
:later 10x). - “E475: Trailing characters” (
:later 10mx). - “E475: Expected numeric argument” (
:later x).
- “E475: Expected 's', 'm', 'h', 'd', 'f' or nothing after number” (
-
Parser errors out on the parsing stage in many cases, without leaving neovim a chance to evaluate any code. But vim errors out on the execution stage (as it does not have any other stages), evaluating whatever was placed before the error. E.g. in the following code:
let list = [system('echo abc > def'),my parser is just going to complain about missing
], Vim is going to create filedefand then complain about missing]. -
In
E119/E118messages (not enough/too many arguments for function) in user functions function name are used exactly as they were defined. E.g. for the following function:let d = {} function d.Abc(a, b, c) endfunction call Abc(1)It will show
E119: Not enough arguments for function: d.Abc, not
E119: Not enough arguments for function: 42. I am planning to use this variant everywhere I need a function name: numbers are not descriptive at all.
-
Functions defined inside a dictionary are no longer dictionary functions (see below about relations between regular functions and
self). Reasoning: I have lots of non-dictionary dictionary functions just because I have a reason to define them inside a dictionary in place of using regulars:functions. I do not like having to always care about{}as a third argument tocall()in this case.
-
E15 errors are not not just “E15: Invalid expression”: there are (invalid expressions)
- “E15: Can only call a Funcref” (
let d={'a':1}|let i=d.a(1))
- “E15: Can only call a Funcref” (
-
string[{}],string[[]]andstring[function('tr')]will complain about using Dictionary/List/Funcref as a Number, not as a String. Same forlist[...]. Not the case fordictionary[...]. -
string[0.0]will not raiseE806: Using Float as a String. Same forlist[0.0]. Not the case fordictionary[...]. -
[] == {}and{} == []in Vim both complain about lists that can only be compared with lists. After translation first complains about comparing lists, second about comparing dictionaries. -
Trying to define function inside a dictionary if corresponding key already exists may throw “E718: Funcref required” if existing value is not a function and “E717: Dictionary entry already exists” if existing value is a function. I think that first error is a bug and always raise “E717”.
-
Using
:delfunctionacts like:unlet, but also deletes global function if it exists. The difference is that if you put function reference into a dictionary this reference will be removed from the dictionary when you rundelfunction. But it will not be removed at least from a) scope variables and b) lists. Code:execute "function S()\nendfunction" execute "function L()\nendfunction" let Funcref = function('S') let l = [function('L')] delfunction Funcref echo Funcref " Will complain about undefined variable in my branch and show S in Vim delfunction l echo l " Will output [function('L')] in Vim, [] in my translator.
-
Trying to delete a slice with
:delfunctionwill emit “E475: Expecting function reference, not List” in place of “E475: Invalid argument”. -
Trying to add two dictionaries (
{} + {}) will result in “E728: Using Dictionary as a Number” and not “E731: Using Dictionary as a String”. Same for{} + []. -
Trying to represent recursive containers will result in lots of brackets and a error. I do not have explicit recursion limit (lua(jit) may have one though) and do not use iterative version of
string(), but bothstring()and:echocheck for recursive containers resulting in the former emitting error earlier:let l = [] call add(l, l) echo string(l) " Vim: echoes “E724: Variable nested too deep for displaying” and " [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{E724}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] " (One hundred of opening brackets, exactly. Same for closing, of course.) " My translator: echoes “E724: Recursive data type detected” and " [{E724}]
-
Trying to change the value of the variable never raises E706. Reasoning: I never saw this error making me do anything useful, but constantly saw it as a source of bugs when processing heterogenous lists.
-
“E710” error message changed: “List value has too many items” (in Vim: “List value has more items than target”). Reason: consistency with “E711: List value has not enough items”.
-
“E684: List index out of range” is sometimes seen as “E684: First index is greater than the second”. Specifically this happens when trying to (un)lock or unlet
[1:0]. -
When deleting variable with
:unletlocks are ignored, but not if:unlet g:.varsyntax is used (i.e. locks are ignored only when using:unlet g:var). Current implementation ignores locks always when deleting from scope dictionaries, no matter how they are accessed. -
string()always uses%eformat for floating-point values.
- Dictionary and non-dictionary user functions have the only difference of
requiring to have self dictionary for calling them. E.g. calling dictionary
function without a dictionary will fail, but one may
- Call non-dictionary function with a dictionary and observe
selfvariable set to this dictionary. Since E706 is out it only makes difference for the case when one tries to accessselfwithout setting it which should be rare (usually this name is not used anywhere, but in dictionary functions). - Set
selfin a dictionary function to a different value (in Vim it raises E46).
- Call non-dictionary function with a dictionary and observe
- Due to the nature of the idea of having a parser it currently needs to parse
the whole block before executing something. I.e. if in Vim you type
:while 1<CR>echo 1you will immediately see1, but it will not repeat untilendwhile. I can add some hacks to preserve this behavior, but do not see any sense in doing this right now and see not very much sense in doing this later.