daa84 / neovim-gtk

gtk ui for neovim
GNU General Public License v3.0
716 stars 57 forks source link

Pass arguments after `--` directly to Neovim #101

Closed idanarye closed 6 years ago

idanarye commented 6 years ago

This allows some more advanced workflows, such as:

idanarye commented 6 years ago

BTW - is there a reason why the files are set with :ar instead of just being passed to the headless nvim instance?

daa84 commented 6 years ago

For :ar think there is no reason, previously it was :e. I don't remember why it was implemented this way

idanarye commented 6 years ago

I can make this work without the need for --, but it will require two potentially-breaking changes:

  1. Pass the filenames to the headless nvim instance instead of running :ar in post_start_init. This could be a breaking change because the current implementation attaches the UI, runs ginit.vim, and then :ars the files. If we pass the files as command line arguments for the instance, the UI will have to be attached after adding the files, and we'll have to either:
    • Run ginit.vim before attaching the UI - which I doubt will work, because ginit.vim is usually the place to put initialization code that talks with the UI.
    • Run ginit.vim after Neovim had already opened the files. This should be OK, since initialization commands that need to run before the files are opened are usually in .vimrc/init.vim, but someone may want to put an autocmd FileType in ginit.vim so that it'll only run in GUI mode. These are just my predictions - I've tried neither of these options, so it is possible that I'm wrong.
  2. Remove the open signal handler, pass &[] to app.run to force it to always use activate, and in activate just pass all the arguments from std::env::args() (save for the ones we filter). This is needed to prevent GTK from treating all our arguments as files and translating them to absolute paths. The problem is that GTK won't be able to handle it's own arguments (like --display=). The official solution is to use the handle-local-options signal - but gtk-rs does not support it, so we'll have to either PR them or set it directly (unsafe and unstable code...)
idanarye commented 6 years ago

On second thought...

Run ginit.vim before attaching the UI - which I doubt will work, because ginit.vim is usually the place to put initialization code that talks with the UI.

Looking at the docs nvim_ui_attach is just making nvim start sending draw events to the UI. So commands in ginit.vim that talk to the UI should still work before calling nvim_ui_attach.

The official solution is to use the handle-local-options signal - but gtk-rs does not support it, so we'll have to either PR them or set it directly (unsafe and unstable code...)

This may not be so bad. It is only unsafe because we need to do glib stuff, and it's not really unstable because the signal is part of the stable GTK API.


Hold this PR - I'll try making another one, that does not require --.

daa84 commented 6 years ago

handle-local-options - can be problem as i think gtk do also validation of parsed arguments (not sure here). running ginit.vim before attach to ui have another todo: it can contains commands for enable/disable neovim options like tabline/ext_menu/ext_cmdline. In case it will call before ui_attach, this options must be saved and passed later to ui_attach as argument.

idanarye commented 6 years ago

What input validation do we need here? Why can't we leave it to nvim to do it's own validation?

As for tabline/ext_menu/ext_cmdline - is this really a problem? I mean, the UI already exists, and as far as I understand the RPC channel is already connected. All these commands are settings - I mean, they are settable from environment variables - so it shouldn't be a problem to set them before nvim_ui_attach.

Of course, I'll test it in the other PR I'll open.

daa84 commented 6 years ago

What input validation do we need here? Why can't we leave it to nvim to do it's own validation?

Not validation, i think gtk option parser will throw error if get unknown option, not sure handle-local-options will disable it

idanarye commented 6 years ago

I looked into it, and adding new signals from outside is not as easy as I thought - it requires way too many private stuff from gtk-rs. Also, handle-command-options requires registering the options in advance (and then we might as well parse them before passing them to GTK), so the signal we want is command-line - but both accept some complex object that we need to wrap.

From the docs, it looks like command-line can handle unknown options:

What happens next depends on the flags: if G_APPLICATION_HANDLES_COMMAND_LINE was specified then the remaining commandline arguments are sent to the primary instance, where a “command-line” signal is emitted. Otherwise, the remaining commandline arguments are assumed to be a list of files. If there are no files listed, the application is activated via the “activate” signal. If there are one or more files, and G_APPLICATION_HANDLES_OPEN was specified then the files are opened via the “open” signal.

As far as I understand, this means that command-line will not receive the flags specifically handled by GTK (seeing how it talks about "the remaining commandline arguments" - the previous sections talked about how some flags are handled earlier), and that it should be able to handle non-files arguments - namely, the options we want to pass to nvim.

As it turns out - gtk-rs already added connect_command_line. But... that commit happened three weeks after the latest release, so it'll be a while before we can use it.

So... the ability to do requires an update from the future and based on my unverified understanding that may or may not be correct. Meanwhile, the -- trick is available now, in the very PR, and not that uncommon (Neovim-QT does it) - so we might want to just do it.

It's your call.

daa84 commented 6 years ago

Ok, for me it's ok 👍