Open SevereOverfl0w opened 7 years ago
The problem here is that (for the default case) nvim's stdin is already in use, because nvim-qt starts nvim as nvim --embed
, the --embed option uses stdin/stdout as an rpc channel between nvim and nvim-qt.
So simply passing the stdin is not an option, unless we somehow change the startup sequence (like https://github.com/equalsraf/neovim-qt/issues/50 suggests) e.g. it is possible to write a vimscript to start the gui
" start-nvim-qt.vim
let job = rpcstart('./nvim-qt', ['--embed', '--nofork'])
and then, this should work
echo hello | nvim --cmd "source start-nvim-qt.vim" --headless -
Bear in mind that this example is lacking in that it does not ensure the GUI shim is loaded and so GuiFont/ginit.vim and other features will not work properly as is.
Have been considered the case of having other sockets to RPC on?
Like, starting (for example nvim --embed --rpc-sockets=foo,bar
, and then communicate with nvim through those sockets, not stdin/stdout.
Of course, nvim would need to grow support for this, but it shouldn't be too hard (at least in POSIX systems).
Thanks!
@facundobatista Nvim already supports that, so I don't understand the question?
@justinmk hola! So you say that nvim already supports RPC on different channels than stdin/stdout? If that's the case, we only need to improve neovim-qt to use other channels, leaving stdin free?
:help serverstart()
@equalsraf is it possible to make nvim-qt to use other socket, as @justinmk is indicating, so we release stdin to be used as text input for the buffer?
@equalsraf is it possible to make nvim-qt to use other socket
Probably not anymore. Some things changed since this issue was opened.
nvim is called by nvim-qt using the --embed
flag which changes how neovim starts up - in particular it delays startup until the ui connects to avoid other issues. If we switched to using a different socket and allowing nvim to take in stdin input directly then the --embed behaviour would no longer be used (which would bring back past issues about error handling and startup). Right now I dont think this can be resolved this way and i dont think that is the main issue.
There is also another problem here in how exactly stdin would be passed to nvim (lets ignore the fork problem for now)
echo hi | nvim-qt -
# nvim-qt calls nvim, which means stdin needs to passed to the child
# if **-** is one of the file arguments.
what i suggested earlier was to simply invert this. Calling nvim (where test.vim starts nvim-qt via vimscript)
dmesg | nvim --cmd "source test.vim" --headless -
In either of these cases there are side effects
I am leaning away from any of the proposed solutions so far. Worst case scenario nvim-qt will have to handle stdin reading before starting up nvim and find a way to load it into a buffer - i'm not sure what is the best way to do this though.
Worst case scenario nvim-qt will have to handle stdin reading before starting up nvim and find a way to load it into a buffer - i'm not sure what is the best way to do this though.
Read from stdlin and write into a temp file? Not everything at once, of course, chunk by chunk. Shouldn't be too hard.
And then tell nvim to open that temp file, of course.
And then tell nvim to open that temp file, of course.
This last bit is more like load all data into an empty buffer. Otherwise nvim will open the file which is not what you want.
Yes, probably, this is too subtle for me.
I was just doing some tests with gVim: head -c 1223 /dev/urandom | gvim -
... when I do that, it creates an empty temp directory (e.g. /tmp/vuSVP4h
), I'm not sure what for.
Also checking what file descriptors has the process...
23:36:52|facundo@blackfx:/proc/15351$ ll fd
total 0
lrwx------ 1 facundo facundo 64 feb 20 23:36 0 -> /dev/pts/13
lrwx------ 1 facundo facundo 64 feb 20 23:36 1 -> /dev/pts/13
lrwx------ 1 facundo facundo 64 feb 20 23:36 10 -> socket:[20391476]
lrwx------ 1 facundo facundo 64 feb 20 23:36 11 -> anon_inode:[eventfd]
lrwx------ 1 facundo facundo 64 feb 20 23:36 2 -> /dev/pts/13
lrwx------ 1 facundo facundo 64 feb 20 23:36 20 -> socket:[2482947]
lrwx------ 1 facundo facundo 64 feb 20 23:36 3 -> socket:[20399638]
lrwx------ 1 facundo facundo 64 feb 20 23:36 4 -> anon_inode:[eventfd]
lrwx------ 1 facundo facundo 64 feb 20 23:36 5 -> /home/facundo/.svz
lrwx------ 1 facundo facundo 64 feb 20 23:36 6 -> socket:[20400350]
lrwx------ 1 facundo facundo 64 feb 20 23:36 7 -> anon_inode:[eventfd]
lrwx------ 1 facundo facundo 64 feb 20 23:36 8 -> socket:[20397377]
lrwx------ 1 facundo facundo 64 feb 20 23:36 9 -> anon_inode:[eventfd]
I found that temp buffer one:
23:37:16|facundo@blackfx:~$ stat .svz
Fichero: .svz
Tamaño: 12288 Bloques: 24 Bloque E/S: 4096 fichero regular
Dispositivo: 803h/2051d Nodo-i: 70214387 Enlaces: 1
Acceso: (0600/-rw-------) Uid: ( 1000/ facundo) Gid: ( 1000/ facundo)
Acceso: 2020-02-20 23:36:13.129432736 -0300
Modificación: 2020-02-20 23:36:22.217320163 -0300
Cambio: 2020-02-20 23:36:22.217320163 -0300
Creación: -
But I don't really understand what's going on here...
This issue has been a major hurdle for me, coming from gvim
(which is able to read stdin just fine).
I have multiple things that depend on this:
jq
) and showing that in VIM, with syntax highlightingPlease fix this.
In the mean time, there is a workaround, at least on Linux. The idea is this: if nvim-qt
cannot read from stdin/pipes, and can read from files, why not give it a file, which is a pipe - a named pipe?
Create an nv-
file (make it executable & put in your $PATH), with the following content:
#!/usr/bin/env bash
function mk_tmp_fifo() {
local temp_path
temp_path="$(mktemp --dry-run)"
local temp_full_path
temp_full_path="$(readlink -f "${temp_path}")"
mkfifo --mode=600 "${temp_full_path}"
printf '%s' "${temp_full_path}"
}
function nv_from_stdin() {
local nvim_pipe
nvim_pipe="$(mk_tmp_fifo)"
local cleanup_wait_pipe
cleanup_wait_pipe="$(mk_tmp_fifo)"
(
nvim-qt \
--spawn \
-- \
nvim \
--cmd "let old_undolevels = &undolevels" \
--cmd "set undolevels=-1" \
--cmd "0read ${nvim_pipe}" \
--cmd "let &undolevels = old_undolevels" \
--cmd "unlet old_undolevels" \
--cmd 'set nomodified' \
"${@}"
# signal cleanup process that it's ok to start cleaning up
printf '' > "${cleanup_wait_pipe}"
)&
# pass stdin to the nvim_pipe
cat /dev/stdin > "${nvim_pipe}"
(
cat "${cleanup_wait_pipe}" # wait for nvim to read the stdin
rm "${nvim_pipe}"
rm "${cleanup_wait_pipe}"
)&
}
nv_from_stdin "${@}"
You can use it like this:
</path/to/my/file nv-
Or like this:
echo '<root></root>' | nv- --cmd 'set ft=xml'
To use this as a PAGER, add export PAGER='/path/to/nv-'
to your shell's startup file.
Unfortunately this can't be used as a pager for man, since neovim displays unescaped BACKSPACE (^H
) characters.
To fix this, create a nv-manpager
file (make it executable), with the following content:
#!/usr/bin/env bash
col -bx | NO_AT_BRIDGE=1 /home/cvmocanu/Dropbox/Configuration/bin/nv- --cmd "set ft=man"
To explain the script:
NO_AT_BRIDGE
env var prevents QT from printing some error message about not being able to register with the accessibility busThen add this to your shell startup script: export MANPAGER='/path/to/nv-manpager'
.
Improving the above shell script by people more knowledgeable with bash than me is appreciated.
Is there any Neovim GUI variants which supports stdin without external scripts?
echo hi | nvim -
openshi
in nvim buffer.echo hi | nvim-qt -
errors. Alsoecho hi | nvim-qt --nofork -
errors. Error with nofork is:I think nvim-qt needs to pass through stdin to nvim.