myitcv / neovim

Go package for writing Neovim plugins (in Go!)
http://godoc.org/github.com/myitcv/neovim
MIT License
85 stars 4 forks source link

Complete implementation of plugin host #10

Open myitcv opened 9 years ago

myitcv commented 9 years ago

Needs to follow ideas laid out in https://github.com/neovim/neovim/pull/1335

Refer as a starting point to the Python provider

Also reference old conversation here

tarruda commented 9 years ago

Some concept of configuration file, that lists which Go-based plugins are active

That will be done by a "manifest" that is required for every plugin that implemented in an external host. This manifest will be nothing more than a vimscript file(eg: plugin/manifest.vim) that will use the vimscript library I'm implementing in #1335.

Here's an idea of how a plugin manifest can look like:

" Manifest for a go plugin implemented in the file 'x.go' 
call rpc#plugin#Register({
\  'github.com/myitcv/X': {
\      'host': 'Go',
\      'path': expand('<sfile>:p:h').'/x.go',  " assuming the plugin implementation is in x.go
\      'register': [
\         rpc#plugin#Command('XCommand1, {'implementation': 'XCmd1', 'nargs': 1, 'count': 2}),
\         rpc#plugin#Command('XCommand2, {'implementation': 'XCmd2', 'nargs': '*}),
\         rpc#plugin#AutoCommand('BufRead', {'pattern': '*.go', 'implementation': 'XBufRead'}),
\         rpc#plugin#AutoCommand('BufWrite', {'pattern': '*.go', 'implementation': 'XBufWrite'}),
\         rpc#plugin#Function('XFunction', {'implementation': 'XFunc'})
\      ]
})

what the rpc#plugin#Register function will do is define commands, autocommands and functions that have a lazy implementation: The real implementation is defined the first time it is called, and will load the host if it hasn't been loaded already.

Some nice things about this pattern of using vimscript as a manifest format:

So for example, here's an idea of what will happen when a user executes XCommand1 for the first time:

I also think it will be possible for us to design a scheme for automatically-generating this manifest when a plugin is installed(similar to help tags), this way the plugin author won't ever have to touch vimscript.

tarruda commented 9 years ago

I've been searching for a pattern of dynamically loading go code and found this SO answer.

While I will do my best add explicit support host reloading(which is required for static languages like go), perhaps an initial implementation of a go host could simply load the "real host"(containing all compiled plugins) as an external process and talk to it with the rpc/net package?

Here's a small chart showing the processes:

           Nvim                     
           ^  +                     
           |  |                     
           |  |                     
           +  v                     
 Golang host(handle communication between Nvim and the real host)      
           ^  +                     
           |  |                     
           |  |                     
           +  v                     
Real host(with the compiled plugins)

Loading/unloading golang plugins would be handled by the golang host by reloading the "real host" recompiled with the new plugin list.