In Vim script, a dictionary function can be defined as:
function obj.func() (dot notation)function obj['func']() (bracket notation)When using bracket notation, the expression inside [] was required to match function naming rules (identifier: letters, digits, underscore). So for example:
function obj['foo-bar']() dict return self.x endfunction
failed with E475: Invalid argument.
However, once a dictionary function exists, it can be assigned and called with any key:
let obj['foo-bar'] = obj.func workscall obj['foo-bar']() worksSo only the definition was incorrectly restricted.
This PR resolves this issue and brings consistency to the behavior.
This change may also be useful when creating DSLs in Vim script, for example.
In userfunc.c, when handling :function name(...) or :function dict[key](...), the code validated the name with eval_isnamec1 / eval_isnamec. For the bracket form, the key (e.g. 'foo-bar') is stored in fudi.fd_newkey. That key was validated as if it were a function name, even though it is just a dictionary key. Dictionary keys in Vim are arbitrary strings.
When the "name" being checked is fudi.fd_newkey (i.e. we are defining a dictionary function with bracket notation), skip the identifier check. The key is a dictionary key and does not need to follow function naming rules.
I was helped by AI for this work.
https://github.com/vim/vim/pull/19833
(2 files)
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
With this change, you could do something like a web API route handler in Vim script:
let routes = {} function routes['/api/hello']() dict return {'status': 200, 'body': 'Hello, World!'} endfunction function routes['/api/users']() dict return {'status': 200, 'body': self.get_users()} endfunction " Dispatch a request function! HandleRequest(path) abort if has_key(g:routes, a:path) return g:routes[a:path]() endif return {'status': 404, 'body': 'Not Found'} endfunction
Nice use case for dictionary keys as route paths. 👍
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Thanks, I think this makes sense.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
@yegappan approved this pull request.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()