nvim-ctrl icon indicating copy to clipboard operation
nvim-ctrl copied to clipboard

Not working anymore

Open fritzrehde opened this issue 3 years ago • 15 comments
trafficstars

This cli tool doesn't seem to work for me any more. Is it still supposed to work? Or did you find another way to achieve the same goal?

fritzrehde avatar Oct 14 '22 22:10 fritzrehde

check out nvim-remote

richardhttps avatar Oct 23 '22 07:10 richardhttps

It seems nvim 0.8.0 doesn't create a socket anymore.

You can have it working again by starting nvim with the following command:

nvim --listen $(mktemp --directory /tmp/nvimXXXXXX)/0 $@

(edit: missing $@ in command line)

pipoprods avatar Oct 25 '22 13:10 pipoprods

This script is what I use now (with nvim 0.8.0 as well);

#!/bin/sh

# send command to all nvim instances

ls $XDG_RUNTIME_DIR/nvim.*.0 \
	| xargs -I {} nvim --server {} --remote-send "$1"

fritzrehde avatar Oct 25 '22 14:10 fritzrehde

i've managed to make it work without any tool with a bash script trigged with a hotkey and a bash function in bashrc the function is just an nvim command with added parameters to initiate a server every time you launch nvim and save each server to a seperate file with a unique filename. the script consists of a for loop to go through each of those files and send a nvim --remote-send to all of them

works very smoothly

Edit: now using OP's solution below

richardhttps avatar Oct 25 '22 14:10 richardhttps

i've managed to make it work without any tool with a bash script trigged with a hotkey and a bash function in bashrc the function is just an nvim command with added parameters to initiate a server every time you launch nvim and save each server to a seperate file with a unique filename. the script consists of a for loop to go through each of those files and send a nvim --remote-send to all of them

works very smoothly

Yeah, I thought of doing that too, but I didn't want an nvim wrapper starting a server each time, so I used the above script and it works perfectly without any nvim wrapper (i.e. I just call nvim normally and it still works). Maybe give it a try! It's literally a one line script!

fritzrehde avatar Oct 25 '22 14:10 fritzrehde

This script is what I use now (with nvim 0.8.0 as well);

Working perfectly for me as well :)

I just had to surround the commands I used to send through nvim-ctrl between a <esc>: and a <cr>.

Thanks for sharing this!

pipoprods avatar Oct 25 '22 14:10 pipoprods

Yeah, I do something like that too. Here's the snippet I use to change the color theme in all open nvim instances:

nvim-ctl.sh ":colorscheme nord | source ~/.config/nvim/statusline.vim<cr>" &

The | allows you to execute multiple commands at once, that's more efficient than executing the script multiple times due to the lengthy for loop/xargs.

fritzrehde avatar Oct 25 '22 14:10 fritzrehde

This script is what I use now (with nvim 0.8.0 as well);

#!/bin/sh

# send command to all nvim instances

ls $XDG_RUNTIME_DIR/nvim.*.0 \
	| xargs -I {} nvim --server {} --remote-send "$1"

This doesn't work as nvim-ctrl did when the other instances are not in command mode. As someone else said, you can use : and <CR> to get to command mode from normal mode, but then this relies on your nvim instances being in normal mode. The advantage to using the neovim API is that you can run a command (a command-mode command) even when the editor is in insert mode.

Furthermore, neovim does still use sockets in 0.8.0 (that's what the script is lsing). I think they've just moved location. Unfortunately, on macOS, there is no $XDG_RUNTIME_DIR, so I've resorted to fd "nvim\..*\.0" /private/var to find them. Then we need to try and use the API to control them rather than --remote-keys, so that it works when the instances are not in normal mode. Here's an adaptation of the source code for this package that does what I want:

use std::path::PathBuf;

use anyhow::Result;
use neovim_lib::{Neovim, NeovimApi, Session};
use structopt::StructOpt;

#[derive(StructOpt)]
#[structopt(about = "Control nvim from the CLI!")]
struct Control {
    socket: String,
    cmd: String,
}

fn main() -> Result<()> {
    let args = Control::from_args();
    let mut s = Session::new_unix_socket(args.socket).ok().unwrap();
    s.start_event_loop();
    Neovim::new(s).command(&args.cmd);
    Ok(())
}

Then you can have this script:

fd "nvim\..*\.0" /private/var/ | xargs -I {} /path/to/executable {} "$1"

and it should work even when in insert mode

If you have $XDG_RUNTIME_DIR correctly working on your machine, the Rust code may still be useful if you want to be able to execute commands when other nvim instances are in insert mode.

Samasaur1 avatar Nov 12 '22 02:11 Samasaur1

That looks cool! But I don't really want a whole (Rust) program as a dependency, for my simple use-case adding a simple <esc> to the beginning of the command (e.g. nvim-ctl.sh "<esc>:colorscheme nord | source ~/.config/nvim/statusline.vim<cr>" &) works just fine for exiting either insert or command mode first.

fritzrehde avatar Nov 12 '22 16:11 fritzrehde

Yeah, I definitely agree! I'd like to have the functionality of fd built into this tool, but there doesn't appear to be a library for using fd and I couldn't get other file searching libraries to work. And as you said, it still would require you to have a Rust program, but I think it may mean that this tool can become functional again if it simply changes where it searches for sockets.

Samasaur1 avatar Nov 14 '22 09:11 Samasaur1

Really, I don't think fd is a requirement for such a task. I don't even use it in my script anymore, I use ls instead (I like fd a lot, but ls is obviously installed on any system and therefore more portable). My current script is just

ls $XDG_RUNTIME_DIR/nvim.*.0 | xargs -I {} nvim --server {} --remote-send "$1"

fritzrehde avatar Nov 15 '22 19:11 fritzrehde

Really, I don't think fd is a requirement for such a task. I don't even use it in my script anymore, I use ls instead (I like fd a lot, but ls is obviously installed on any system and therefore more portable). My current script is just


ls $XDG_RUNTIME_DIR/nvim.*.0 | xargs -I {} nvim --server {} --remote-send "$1"

I tried that, but macOS is being stupid as usual and there's no single directory where all the sockets are placed (it's like three nested temporary directories), so I resorted to fd. I could probably use ls if I set $XDG_RUNTIME_DIR manually, but as it is some find/fd equivalent is required

Samasaur1 avatar Nov 26 '22 18:11 Samasaur1

Thanks for the great script. I adapted it to use --remote-expr together with "excecute(' ... ' )" instead of --remote-send. This works independent of the current mode and does not require a rust program. E.g. I use the following snippets to trigger automatic light/dark mode switching of my nvim colorsheme via the gnome night-theme-switcher extension.

ls $XDG_RUNTIME_DIR/nvim.*.0 | xargs -I {} nvim --server {} --remote-expr "execute('set background=light')"

ls $XDG_RUNTIME_DIR/nvim.*.0 | xargs -I {} nvim --server {} --remote-expr "execute('set background=dark')"

bejuba avatar Dec 12 '22 11:12 bejuba

Nice! Do you know if the | still works to execute two commands at once. I use <esc>:colorscheme nord | source ~/.config/nvim/statusline.vim<cr> currently. But your solution looks less hacky than mine, maybe I have to try it as well.

fritzrehde avatar Dec 12 '22 17:12 fritzrehde

Yes, you can use | to send multiple commands. Everything in the single quotes gets executed. No need for the : at the beginning.

bejuba avatar Dec 12 '22 17:12 bejuba