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-255
effectively 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.)
-
append
works 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.
-
Missing block endings (
:endif
,:endfor
, etc) in:autocmd
do generate errors. -
Incomplete blocks (
:if
, etc) in:autocmd
definition are not supported. -
If you mix tabs and spaces in indentation
append
uses the value of&tabstop
option 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. -
endfunction
in vim is a marker that is read byex_function()
which is the reason whyfunction A()|endfunction
does not work. In my parser it is a separate command that ends a:function
block, so there is no requirement for:endfunction
to be the first command in the line. -
:call
accepts any function calls, not necessary calls in the formfuncname(args)
(funcname
may 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
/:let
messages are different:E475
was 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” (
-
:let
E474 is now “E474: To list multiple variables use "let var|let var2", not ":let [var, var2]"”. -
:let 1
will 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
:function
now looks either like “E475: Expected end of arguments list” or “E475: Expected end of arguments list or comma”. -
“E475” for
:behave
now looks like “E475: :behave command currently only supports mswin and xterm”. -
For debug commands “E475” was split into
- “E475: Profile commands only accept
func' and
file' as their 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 123
or:profile… func
without further arguments) and - “E475: Expecting file name or pattern” (for
:break… file
,:break… file 123
or:profile… file
without further arguments).
- “E475: Profile commands only accept
-
“E474” from
:cbuffer
and friends is now “E474: Expected buffer number”. -
:fu Abc()|echo1|endf
is parsed as a correct function definition. Used to produce missing endfunction errors. -
Certain function definitions cannot be parsed. See #425.
-
ilist /inslashes/afterslashes
will 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:
augroup
accepts any sequence of characters as an autocmd group, includingBufWritePre
andthis 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:au
definition (I really have no idea why this should be allowed, but even if I thought having group name likeBufWritePre
is a good idea I cannot do anything with this at the parsing stage). -
“E474” from
:delmarks
was transformed into “E474: :delmarks must be called either without bang or without arguments” (:delmarks! some_argument
). -
“E475” from
:delmarks
was split into- “E475: Trying to construct range out of marks from different sets”
(
:delmarks 0-A
). - “E475: Upper range bound is less then lower range bound” (
:delmarks z-a
). - “E475: Unknown mark” (
:delmarks @
).
- “E475: Trying to construct range out of marks from different sets”
(
-
“E471” from
:delmarks
is now “E471: You must specify register(s)”. -
“E474” from
:digraphs
was transformed into “E474: Expected second digraph character, but got nothing” (:digraphs a
) -
:digraphs
accepts two characters in the digraph definition (was: two bytes, which I consider a bug). -
“E475” from
:later
/:earlier
was 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” (
-
“E475” from
:filetype
is now “E475: Invalid syntax: expected `filetype[ [plugin|indent]... {on|off|detect}]'”. -
++opt
E474 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” (
-
“E488” from
:history
was split into- “E488: Expected history type name or nothing” (
:history garbage
) - “E488: Expected valid history lines range” (
:history ,
)
- “E488: Expected history type name or nothing” (
-
“E488” from
:clist
and friends is now “E488: Expected valid integer range”. -
“E471” from
:mark
/:k
is now “E471: Expected mark name”. -
:mark
no longer allows setting<
,>
,[
,]
and"
marks (according to the doc it never did). -
“E475” from
:redir
was split into- “E475: Expected `END', `>[>] {file}', `@{register}[>[>]]' or `=>
{variable}': redir!!!” (
:redir
without arguments or with invalid argument) - “E475: Expected
END'” (
:redir e`) - “E475: Expected register name; one of A-Z, a-z, ", * and +” (
:redir @?
) - “E475: Expected `>' and variable name”
- “E475: Expected `END', `>[>] {file}', `@{register}[>[>]]' or `=>
{variable}': redir!!!” (
-
“E475” from
:match
is now “E475: Expected regular expression” (:match HlGroup
without last argument). -
“E474” from
:set
was split into- “E474: Expected `>'” (
:set <C-a
). - “E474: Cannot set boolean options with `=' or `:'” (
:set number=0
). - “E474: Expected `=', `:', `&' or `<'” (
:set nocb-
). - “E474: Cannot invert or unset non-boolean option” (
:set noclipboard
). - “E474: Expected key definition” (
:set wcm=<C-a
).
- “E474: Expected `>'” (
-
“E475” from
:sleep
is now “E475: Expected `m' or nothing”. -
Any error in expression after
\=
in:substitute
will result in:substitute
command not executed at all, not in:substitute
command spamming error on each occurence of pattern it is to replace. -
Parser that has no way to know whether
:s
is going to occur inside another:s
and always parses expressions after\=
dictates allowing nested\=
expressions at least for:s
. -
“E474” from
:sort
is now “E474: Can only specify one kind of numeric sort”. -
“E475” from
:sort
is now “E475: Expected sort flag or non-ASCII regular expression delimiter”. -
“E475” from
:syntime
is now “E475: Expected one action of `on', `off', `clear' or `report'”. -
“E474” from
:wincmd
was split into- “E474: Expected extended window action (see help tags starting with
CTRL-W_g)” (
:wincmd g
). - “E474: Trailing characters” (
:wincmd ogarbage
).
- “E474: Expected extended window action (see help tags starting with
CTRL-W_g)” (
-
“E791” from
:loadkeymap
was split into- “E791: Empty LHS” (loading keymap line that starts with a blank).
- “E791: Empty RHS” (loading keymap line that has only one sequence of non-whitespace characters).
-
LHS+RHS length in
:loadkeymap
is no longer limited to 200 characters. -
“E474” from
:menutranslate
was split into- “E474: Expected translated string” (
:menutranslate Foo
). - “E474: Expected string that is to be translated” (
:menutranslate
). - “E474: Expected no submenus” (
:menutranslate Foo.Bar
).
- “E474: Expected translated string” (
-
“E475” from
:highlight
is now “E475: Missing closing quote”. -
“E239” from
:sign
was split into- “E239: Non-printable character in sign text” (
:exe "sign define Foo text=\e"
). - “E239: Failed to process complete sign text” (not sure whether this can happen at all).
- “E239: Sign text is too wide” (
:sign define Foo text=1
). - “E239: Sign text is too narrow” (
:sign define Foo text=123
).
- “E239: Non-printable character in sign text” (
-
“E475” from
:sign
is now “E475: Unknown sign property” (:sign define Foo xxx=>>
). -
“E474” from
:sign
was split into- “E474: Cannot use `*' when identifier was already given” (
:sign unplace 1 *
). - “E474: Unknown property” (
:sign place 1 foo
). - “E474: Must provide either buffer= or file= as the last argument” (
:sign place 1 line=10 name=Foo
). - “E474: Cannot use zero as sign id” (
:sign place 0
). - “E474: Cannot use line= and name= without a sign id” (
:sign place line=10 buffer=1
). - “E474: Cannot use line= and name= with :sign jump” (
:sign jump 10 line=10 buffer=1
). - “E474: Cannot use line= and name= with :sign unplace” (
:sign unplace 10 line=10 buffer=1
). - “E474: Missing sign name” (
:sign place 10 line=10 buffer=1
).
- “E474: Cannot use `*' when identifier was already given” (
-
“E488” from
:sign
may now be “E488: buffer= argument must be the last one”. -
“E158” from
:sign
is now only (it used to be emitted for any error regarding buffers failed to be found) “E158: Buffer number can only be positive” (:sign place 1 line=10 name=Foo buffer=-10
). -
“E885” from
:sign
is now only “E885: Can only use positive line numbers” (:sign place 1 line=-1
). -
Calling
:sign
with non-positive line number fails always (used to fail only if placed sign identifier is new identifier). -
“E390” from
:syntax case
is now “E390: Expected match or ignore”. -
“E390” from
:syntax conceal
is now “E390: Expected on or off”. -
:syn cluster Foo add=A,B,C remove=C add=C
or similar will probably not do what you want: such things are parsed intosyn cluster Foo add=A,B,C,C remove=C
(separate arguments are always parsed into one list and thus you will most likely end up withC
inFoo
cluster). -
:syn cluster
subarguments order is not preserved, executors are supposed to process them in order contains, add, remove. -
“E475” from
:syn cluster
is now “E475: Expecting group name followed by an argument”. -
“E402” from
:syn match
and others that accept patterns may be “E402: Expected offset anchor designator (`s' or `e')” (syn match Foo /e/ms=x
) or “E402: Garbage after pattern” like it was previously. -
“E399” from
:syn region
may either be “E399: Expected group name” (syn region Foo matchgroup=
) or “E399: Expected syntax pattern” (syn region Foo start=
). -
“E404” from
:syn sync
was split into- “E404: Expected `=number'” (
syntax sync lines=x
/syntax sync lines
). - “E404: Pattern end not found” (
syntax sync linecont /foo
). - “E404: Unknown argument” (
syntax sync xxx
).
- “E404: Expected `=number'” (
-
“E475” from
:syntax keyword
is now one of- “E475: Expected group name” (
syntax keyword
). - “E475: Expected keywords” (
syntax keyword Foo
).
- “E475: Expected group name” (
-
“E475” from
:syntax match
is now one of- “E475: Expected group name followed by an argument” (
syntax match Foo
andsyntax match
). - “E475: Trailing characters” (
syntax match Foo /bar/ /bar/
).
- “E475: Expected group name followed by an argument” (
-
Invalid range in glob pattern prevents pattern from being used, not emits an error and proceeds with treating this range literally.
-
“E16: Invalid range” is “E16: Invalid range: end is greater then start” in glob patterns.
-
Treatment of the “corner cases” like
[a-[:alnum:]]
differs. -
It is currently not possible to fall back to “treat the file name literally” variant if pattern matching failed in many cases because parser does not save this information (this will be a few lines fix to save this information, but I do not think this is a good idea: if user meant a pattern he should get a pattern, if user meant no pattern then there is backslash at his service).
-
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 filedef
and then complain about missing]
. -
In
E119
/E118
messages (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
:delfunction
acts 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
:delfunction
will 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:echo
check 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
:unlet
locks are ignored, but not if:unlet g:.var
syntax 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%e
format 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
self
variable set to this dictionary. Since E706 is out it only makes difference for the case when one tries to accessself
without setting it which should be rare (usually this name is not used anywhere, but in dictionary functions). - Set
self
in 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 1
you 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.