Re: [vim/vim] patch 9.2.0959: multiline dictionaries in :command and :autocmd cause E488 (PR #21073)
h_east (Vim Github Repository) <[email protected]>
| Newsgroups | gmane.editors.vim.devel |
|---|---|
| Message-ID | <vim/vim/pull/21073/[email protected]> |
h-east left a comment (vim/vim#21073)
### Nested braces are not collected
`may_get_cmd_block()` stops reading at the first line whose first non-blank
character is `}`:
```c
if (*skipwhite(line) == '}')
break;
```
The comment above the loop states this: "Does not support nesting or here-doc
constructs". That limitation is acceptable for a command block, where the
closing `}` is on its own line. A dictionary is different, because a nested
dictionary is ordinary:
```vim
vim9script
command! Foo call Bar('x', {
'a': {
'b': 1,
},
})
```
The line ` },` ends the collection, so `})` is never read and the argument is
left unbalanced. A list inside the dictionary works, since `],` does not
start with `}`, which makes the failure hard to predict from the outside.
Counting the brace depth instead of matching the first `}` would handle this,
and would fix the same limitation for command blocks. It changes existing
behaviour, so it deserves its own patch, but extending this collector to
dictionaries without it moves the limitation into a construct where nesting is
common.
### Detecting the opener
`find_cmd_dict_start()` requires the line to end exactly with `{`:
```c
char_u *p = line + STRLEN(line);
if (p == line || p[-1] != '{')
return NULL;
```
A trailing white space after `{` makes the detection fail. The existing
`find_cmd_block_start()` uses `ends_excmd2()` and does not have that problem,
so the two paths disagree on what "ends with a curly" means.
The set of characters accepted before `{` is `(`, `,`, `=` and `:`. `[` is
missing, and a list of dictionaries is a normal thing to write:
```vim
command! Foo call Bar('x', [{
'key': 'value',
}])
```
### version.c
The patch number is assigned when the change is committed. Including a
`version.c` bump in the pull request will conflict with whatever number is
current at that time.
### Line length
```c
if (p == line || (p[-1] != '(' && p[-1] != ',' && p[-1] != '='
&& p[-1] != ':'))
```
The continuation line is 89 columns wide. Aligning it under the first
condition keeps it within 80.
### Tests
The two new tests cover the flat case. Since `CheckScriptSuccess()` already
fails on E488, the `assert_match()` calls add little; checking that the
dictionary body was collected, not only the first line, would say more. A
case with a nested dictionary and one with `[{` would cover what is discussed
above.
--
Reply to this email directly or view it on GitHub:
https://github.com/vim/vim/pull/21073#issuecomment-5317781470
You are receiving this because you are subscribed to this thread.
Message ID: <vim/vim/pull/21073/[email protected]>
--
--
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].
To view this discussion visit https://groups.google.com/d/msgid/vim_dev/vim/vim/pull/21073/c5317781470%40github.com.