3

As title. I want to define an event via autocmd User MyEvent .... Then when some internal state of my plugin is reached, I will trigger the event with doautocmd User MyEvent. So, how to write the part ...?

3
  • 1
    autocmd User MyEvent does not define an event; it defines an autocommand to react to that event. However, there is a no-op command (:).
    – D. Ben Knoble
    Oct 19, 2022 at 20:03
  • @D.BenKnoble: I read the answer there, which said it did define the event. So how to define an event exactly? Oct 19, 2022 at 20:04
  • 1
    That answer is imprecise: there is no code that defines a User event. You simply invoke it when you wish, and autocommands established to react will fire.
    – D. Ben Knoble
    Oct 19, 2022 at 20:48

2 Answers 2

5

There is no API for defining custom events. What you define are autocommands that are meant to be executed explicitly. Executing those autocommands explicitly is the closest you can get from having custom events.

In their simplest form, autocommands look like this:

autocmd <event> <pattern> <command>

where:

  • <event> is the event that triggers the autocommand,
  • <pattern> is matched against the value of the event,
  • <command> is whatever you want to happen if <pattern> matches.

The User event can be understood as a generic event which is never triggered automatically by Vim. Instead, User autocommands are executed explicitly with :help :doautocmd and passed an arbitrary value. You mimic custom events, you don't "define" them.

Now, a User autocommand is defined the same way other autocommands are:

autocmd User MyThing echo 'foo'

where:

  • User is your <event>,
  • MyThing is your <pattern>,
  • and echo 'foo' is your <command>.

You would then execute that autocommand explicitly:

:doautocmd User MyThing
foo

where:

  • User is the dummy event you are triggering,
  • MyThing is its value.

Because you have defined a User autocommand with the pattern MyThing and you are triggering it with the value MyThing, the pattern matches the value and the command is executed.

--- EDIT ---

I don't use Neovim so I have no idea what the API you are mentioning in the comments does. If I were in your shoes, I would "probe" it with something like:

autocmd User * echomsg 'the value is ' .. expand('<amatch>')

which should echo the value of the event:

(do something with that API)
the value is foobar

which would then help me decide what pattern to use for my User autocommand:

autocmd User foobar ...

See :help <amatch>.

--- EDIT #2 ---

The value is a string. It is a file name for many events but not all of them (:help ColorScheme comes to mind) so the <pattern> can be any pattern that matches the particular value that comes with a particular event.

For a User event, it is up to the user to decide what value to send, how to match against it, and what to do with it. The following example shows the extent of what one can do with :help User. It is a bit contrived but it is all I could come up on the spot.

  1. Define an autocommand that evaluates the value and uses it to move the cursor:

    augroup MyAutocommands
        autocmd!
        autocmd User \[*\] call expand('<amatch>')->eval()->cursor()
    augroup END
    
  2. Trigger the autocommand with a list of coordinates as value:

    let myValue = [3, 20]->string()
    :execute 'doautocmd User ' .. myValue
    

    au

  3. Note the pattern \[*\]. It is a bit simplistic but it is useful for demonstrating how the whole thing works. If you do something like:

    :doautocmd User foobar
    

    then Vim will will say:

    No matching autocommands for: User foobar
    

    Another approach would be to use * as pattern and call a function where you can use a fancy regular expression to decide if the value matches or not.

One could imagine passing a serialized dictionary, the same way we use JSON, or any arbitrary syntax. It just has to be a string.

7
  • Well, this is very clear now. But say there is an official neovim API(vim.diagnostic.open_float) that accepts close_events. Then in this case if I add User to the list/table, then what <pattern> should I use in my plugin to make sure that the close event of that API will be triggered? Oct 19, 2022 at 21:42
  • @job_start, see my edit.
    – romainl
    Oct 20, 2022 at 5:45
  • Isn't that <pattern> should be a file pattern, e.g *.c? Why you said it can be any value. Nov 23, 2022 at 5:21
  • 1
    @job_start, see my edit.
    – romainl
    Nov 23, 2022 at 7:13
  • In neovim, run :h au gives :au[tocmd] [group] {event} {aupat} [++once] [++nested] {cmd}, where it is called {aupat}. And if you further run :h aupat you will see they describing things as The file pattern {aupat} .... This is the cause of my confusion: They implicitly mean {aupat} is a file-path. I found nowhere mentioning {aupat} can be any string. Nov 23, 2022 at 7:43
3

There is no code that defines a User event. You simply invoke it when you wish, and autocommands established to react will fire.

Note the caveat under :help doautocmd about <nomodeline>, and under :help User about what happens when no autocommands are "subscribed" to the event.

5
  • I still don't know how to achieve what I want vim to do. Oct 19, 2022 at 20:59
  • 1
    Write your code, and have it run doautocmd User MyEvent as needed (possibly guarded by an exists check as mentioned in :help User). That's it.
    – D. Ben Knoble
    Oct 19, 2022 at 21:01
  • In neovim there is an API vim diagnostic.open_float(...) where I can pass a lua table that contains a key close_events, which is lua table containing some built-in events. Now what I want to do is to add my custom event to the table/list but it caused some error. Oct 19, 2022 at 21:02
  • @job_start That isn’t what the question asks… but it is interesting. I would reach out to neovim devs.
    – D. Ben Knoble
    Oct 19, 2022 at 22:42
  • :help User doesn't explain what will happen when no autocmd are subscribed to the event. (I'm using neovim.) Nov 23, 2022 at 4:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.