neovim / go-client

Nvim Go client
https://pkg.go.dev/github.com/neovim/go-client
Apache License 2.0
578 stars 36 forks source link

Question: How can you subscribe to events ? #68

Closed DenLilleMand closed 4 years ago

DenLilleMand commented 4 years ago

In the plug.Nvim.subscribe(event) i can subscribe to the events like CurrentLine or CurrentBuffer, but i don't think it is clear where i am going to receive the notifications about the changes?

E.g.

    plugin.Main(func(p *plugin.Plugin) error {
        err := p.Nvim.Subscribe("CurrentLine")
        }

The documentation on the Nvim Client API is very extensive, but i have not found a easy to follow tutorial or anything like that which indicates how exactly this can be used.

I was also looking at the Batch struct:

        b := p.Nvim.NewBatch()
        b.Subscribe("CurrentLine")

But it is hard to tell when looking at the remaining methods how to get the changes, i was hoping for a definition with a callback function like:

p.Nvim.Subscribe("CurrentLine", func(changes){
   // handle changes
}) 
DenLilleMand commented 4 years ago

I figured it out :)

justinmk commented 4 years ago

@DenLilleMand please share your solution here for others finding this via search.

DenLilleMand commented 4 years ago

Yeah, "figured it out' was an exaggeration, i actually gave up because it threw some undefined function error, but listening for the AutoCMD should be done with something like this i suppose:

package main

import (
    "github.com/neovim/go-client/nvim"
    "github.com/neovim/go-client/nvim/plugin"
)

func somethingChanged(vim *nvim.Nvim, fileName string) error {
    err := vim.WriteOut(fmt.Sprintf("File name:%s\n", fileName))
    if err != nil {
        return err
    }
    return nil
}

func main() {
    plugin.Main(func(p *plugin.Plugin) error {
        p.HandleAutocmd(&plugin.AutocmdOptions{Event: "BufEnter", Group: "", Pattern: "", Nested: false, Eval: "expand(\"<afile>\")"}, somethingChanged)
        return nil
    })
}

But when this event was triggered it threw a unknown function kind of error.

I was also trying to listen to the autocmd in vimscript, with something like:

autocmd BufEnter * :call rpcnotify(<channel id>, <method>, <args> )

I think that defining it in VimScript or in the Go code listening for a event is okay, but both at the same time is not necessary. I learned that from playing around with the pynvim plugin that just seemed to work with AutoCmd annotations, i had that one working pretty easily. So at the end of the day i actually dropped this one, and used pynvim instead.

What i especially found challenging trying to figure this out is which arguments my function 'someChanged' should take in as argument. I tried to look at the code, but the function given in to the AutoCmdHandler is just a fn interface{} so something happens with reflection, but i am not sure how it knows to give in *nvim.Nvim in my case, or if it doesn't and that is why my code fails.

EDIT: Arg yeah, and i never figured out why there is a SubscribeEvent method that seems like it does nothing.

filmil commented 8 months ago

In case this is still of interest to you, I managed to work out a way to subscribe to autocmds from within a go client, and using only the facilities offered by nvim.Nvim. No plugins.

The link below has an example for the LspAttach autocmd, but it should be fairly easy to make your own.

https://github.com/neovim/neovim/discussions/27371#discussioncomment-8405144