Repository: neovim
Issue: events interface: event/autocmd, attach, provider, 'foofunc', nvim_on, vim.on
Labels: enhancement,documentation,api,code-standards,events,architecture

A lot of our standard plugins run into the question of how to allow consumers to handle an event without clobbering each other. We have things like `vim.paste()` where the idea is "you can choose exactly one way to do this", and things like Nvim LSP handlers where `vim.lsp.with()` tries to provide some composition.

# Paradigms

To avoid going in circles let's write down the current conventions ("paradigms"). Then when adding an interface or a feature, pick one from the list, and then use the existing mechanism for achieving that, instead of reinventing it. Also: do we actually need _all_ of these interfaces, can we eliminate any? 

1. "provider": single handler, may return a response
    - examples: `'tagfunc'`, `vim.paste`, clipboard, `:py`, etc.
    - aka "callback" in narrow ad-hoc contexts
    - mechanism: `vim.foo`
        - does not "fan out".
        - can compose by using the `old = vim.foo` trick.
1. "callback", "attach": multiple subscribers ("fan out" / multicast, no response)
    - mechanism: callbacks hooked into an ad-hoc registry
    - examples: `vim.on_foo()`, `vim.ui_attach()`, …
    - related:  multicast EventEmitter: [vscode](https://code.visualstudio.com/api/references/vscode-api#EventEmitter&lt;T&gt;), [C#](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/event)
1. "event handler": multiple subscribers ("fan out", no response)
    - mechanism: autocmds 
    - mechanism: callbacks associated with a namespace (see `nvim_set_decoration_provider`)
    - related:  multicast EventEmitter: [vscode](https://code.visualstudio.com/api/references/vscode-api#EventEmitter&lt;T&gt;), [C#](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/event)
1. "RPC notification": e.g. UI events
    - does it make sense to also use the autocmd system as the interface for RPC notifications?   e.g. instead of `nvim_buf_attach`, buf-update events would just be `nvim_create_autocmd('BufUpdate',...)`

# Discussion

What do we need in the autocmd system so that it fully solves the use-case of plugins or subsystems that want to support multiple subscribers to arbtirary plugin-defined events?

- performance
- usability
- visibility
- debuggability

`vim.on_key` implements its own quasi-event system by using namespaces (which is not a bad idea, but raises the question of whether we should try to make it easier to use the builtin event (autocmd) system instead of introducing these inner platforms). Using the event system (autocmds) allows us to focus on improving the performance, usability, visibility and debuggability of that one system instead of partially reinventing it over and over.

Plugins can "namespace" events via `augroup`. We could also allow `nvim_create_namespace()` there?

via @mfussenegger : 

> * With multiple clients it's often required to aggregate the results from all clients before doing something with the results, ... (E.g. vim.lsp.buf.references: gather all references, then set quickfix list _once_)
> * For high level functionality a simple request-response model is often not enough. Many LSP actions require multiple steps: code actions, rename, call hierarchy/incoming/outgoing calls.




# Done

- `nvim_get_autocmds()`
- `nvim_create_autocmd()`
- `nvim_create_autocmd()`

# Missing

1. Do we need a new event/autocmd similar to `User` ?
2. "Visibility":  add something like `nvim_inspect_ns`, which could list everything a particular namespace is used for.
3. use autocmd system as the interface for RPC notifications? 
    - e.g. instead of `nvim_buf_attach`, buf-update events would just be `nvim_create_autocmd('BufUpdate',...)`
4. Allow `nvim_create_namespace()` as an `augroup` ?
5. Ability to "compose" handlers? `vim.lsp.with()` or ...?
6. The _aggregation_ use-case mentioned by @mfussenegger above, implies that we might need _dependency modeling_ of events.
    - Could be done with a simple map-of-maps (disallow circular dependencies). But is it really needed?

# Proposal: `nvim_on`, `vim.on` ?

- TODO: gather coherent proposal from https://github.com/neovim/neovim/pull/21811#issuecomment-1383991552
- eliminate `nvim_create_augroup` by using `nvim_create_namespace` instead ?
- For "providers" or handlers, prefer `vim.handlers.foo()` and *deprecate* the following:
    - `'foofunc'` (example: 'tagfunc')
    - the old `:help provider` mechanism (example: `:help provider-clipboard`)

---

see also:

- https://github.com/neovim/neovim/issues/16810