lucc / nvimpager

Use nvim as a pager to view manpages, diffs, etc with nvim's syntax highlighting
Other
372 stars 20 forks source link

Being able to use an already running nvim process via RPC #39

Closed eugene-babichenko closed 1 year ago

eugene-babichenko commented 3 years ago

The application of this would be to make syntax highlighting in https://github.com/junegunn/fzf.vim preview window look exactly the same (or, at least, as close as possible) as in nvim.

By default nvim exposes an RPC socket which is available to subprocesses via $NVIM_LISTEN_ADDRESS. This API could be used for running Lua scripts as well, so nvimpager would require very little modification for that.

What would be a good approach to implement that? This would be hard to do in bash because of RPC message format. There are client libraries for multiple languages, but the Lua library is not well documented, so I am leaning towards Python.

lucc commented 3 years ago

Ok lets try to get clear what you want here but first some assumptions that I have coded into nvimpager:

  1. Nvimpager currently is a command line program. It follows the Unix philosophy for cli programs, meaning you can execute it with or without filenames on the command line and it will read stdin if no files are given. Especially it is not a nvim plugin, it is not designed to be loaded.
  2. nvimpager tries to use a separate init file and config dir from normal nvim as I am assuming that users have many plugins installed that are useful for editing files but not needed for pageing. They might slow down nvimpager and I think one does not want to wait for a plugin with an external process in python/rust/nodejs/... to start up just to view a git diff or a man page.
  3. currently nvimpager only requires nvim and bash and one of the reasons I started a new program and did not continue development of https://github.com/rkitover/vimpager was to reduce dependencies.

I will try to summarise your idea to make sure I get it right (please correct me):

  1. you are running nvim to edit some files
  2. you use fzf to switch files and do not want to use bat to highlight the preview window of fzf but nvimpager.
  3. you want nvimpager to use the same colorscheme and other visual settings to get the highlight of the preview window as similar to the highlight of open buffers as possible.
    • did you try to use your default nvim config for nvimpager? That should select your colorscheme etc
    • or is it important to you to not start extra processes for fzf highlighting?

So what is the thing you want to have in technical terms. I want to write down kind of an algorithm or the requirements of sort. Please correct me if I am mislead:

  1. I assume fzf will start a command line application for the preview
  2. you want this command to connect to the nvim socket of the parent nvim process (lets call it "nvim-cat")
  3. it should probably send over the filename or file contents that need to be highlighted
  4. the parent process (an nvim process started with your normal config file) should use some code from nvimpager to highlight the given file and send this data back through the socket.
  5. the nvim-cat process should output the data
    • I have never worked with the neovim socket interface but I assume here that the nvim-cat process can not tell the parent nvim process to :echo l:data because that would echo in the command line of the parent process, so I assume it has to retrieve the data and echo (not :echo!) it itself.
lucc commented 3 years ago

If my above assumptions are correct there would be two steps that would be neccessary:

  1. enable the nvimpager lua code to run in normal nvim and return instead of echo the data (currently cat mode uses io.write in lua)
  2. one of the following a. write a small executable that only handles the RPC case and uses the same lua code as nvimpager under the hood b. rework the main nvimpager script to handle the normal command line case as well as the rpc case. This entails that we have to think about some more possible cases where the NVIM_LISTEN_ADDRESS might be visible and what to do in these cases (eg. running man man inside a terminal in nvim when export PAGER=nvimpager is set)
eugene-babichenko commented 3 years ago

did you try to use your default nvim config for nvimpager? That should select your colorscheme etc

It is quite heavy. For example, it automatically starts a language server if available for the current file format.

or is it important to you to not start extra processes for fzf highlighting?

Not really. The idea is to just reuse what is already running given that the config is quite heavy and not everybody want to maintain two separate configurations.

I have never worked with the neovim socket interface but I assume here that the nvim-cat process can not tell the parent nvim process to :echo l:data because that would echo in the command line of the parent process, so I assume it has to retrieve the data and echo (not :echo!) it itself.

Yes, this is the exact problem. We would need a function to return a string/byte array.

eg. running man man inside a terminal in nvim when export PAGER=nvimpager is set

I only care about the cat mode actually.


I think I will follow your advice and start with making nvimpager being usable as a Vim plugin with a function that outputs the highlighted code. When this is done, the RPC program is trivial.

lucc commented 3 years ago

did you try to use your default nvim config for nvimpager? That should select your colorscheme etc

It is quite heavy. For example, it automatically starts a language server if available for the current file format.

or is it important to you to not start extra processes for fzf highlighting?

Not really. The idea is to just reuse what is already running given that the config is quite heavy and not everybody want to maintain two separate configurations.

Alternative solution for your special use case: You could modularize your init.vim file and put the stuff for colors in a file that you can :source from the default nvim and the nvimpager init files.

Yes, this is the exact problem. We would need a function to return a string/byte array.

If you want to try that have a look at the highlight function in nvimpager.lua. The outer for loop builds the outline variable. Maybe it is easy to refactor the code into a highlight_line function that returns the outline. This could then be reused be the current (maybe renamed to highlight_write) function and your new highlight_return function.

eg. running man man inside a terminal in nvim when export PAGER=nvimpager is set

I only care about the cat mode actually.

What I meant here is that if we change the default behaviour of nvimpager we have to think a little deeper then "I care about this" because I do not want nnvimpager to be a program that acumulates random features. It is foremost a pager.

lucc commented 3 years ago

I just had a look at the docs and it seems that you can use a new nvim instance as a n rpc client to send commands to the nvim process behind $NVIM_LISTEN_ADDRESS. Check the help for sockconnect() and rpcrequest().

lucc commented 1 year ago

I will close this because I do not consider it important enough to track it. If somebody is interested in implementing it they can start a new discussion about some more concrete aspect.