[vim/vim] Allow defining dictionary function with bracket key that is not a valid identifier (PR #19833)

7 views
Skip to first unread message

thinca

unread,
Mar 26, 2026, 12:04:03 PM (18 hours ago) Mar 26
to vim/vim, Subscribed

Problem

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 works
  • call obj['foo-bar']() works

So 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.

Cause

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.

Solution

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.

Others

I was helped by AI for this work.


You can view, comment on, or merge this pull request online at:

  https://github.com/vim/vim/pull/19833

Commit Summary

  • 9a7b31f Allow defining dict function with bracket key that is not a valid identifier

File Changes

(2 files)

Patch Links:


Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/19833@github.com>

mattn

unread,
Mar 26, 2026, 12:31:15 PM (18 hours ago) Mar 26
to vim/vim, Subscribed
mattn left a comment (vim/vim#19833)

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.Message ID: <vim/vim/pull/19833/c4136421237@github.com>

Christian Brabandt

unread,
Mar 26, 2026, 5:55:51 PM (12 hours ago) Mar 26
to vim/vim, Subscribed
chrisbra left a comment (vim/vim#19833)

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.Message ID: <vim/vim/pull/19833/c4138545639@github.com>

Yegappan Lakshmanan

unread,
1:03 AM (5 hours ago) 1:03 AM
to vim/vim, Subscribed

@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.Message ID: <vim/vim/pull/19833/review/4018891757@github.com>

Reply all
Reply to author
Forward
0 new messages