1

Some time ago, I've made this question where I asked how to execute a file on the terminal with Neovim... The solution I found was the following :terminal bash % . Knowing that, I made the following configuration on my init.vim file:

function! ExecuteOnTerminal(type) range if (&ft=='javascript') if a:type == "V" :vert botright '<,'> terminal node % else :vert botright terminal node % endif elseif (&ft=='sh') if a:type == "V" :vert botright '<,'> terminal bash % else :vert botright terminal bash % endif elseif (&ft=='python') if a:type == "V" :vert botright '<,'> terminal python3 % else :vert botright terminal python3 % endif endif endfunction vnoremap <silent> <F6> :call ExecuteOnTerminal("V")<CR> nnoremap <silent> <F6> :call ExecuteOnTerminal("I")<CR> 

The above configuration works perfectly fine, it allows me to execute a file with bash, node.js and python when I press F6... And if I select some lines and press F6 it`ll execute only the selected lines.

The problem is that in my context, I need to execute files that are not stored on the disk. Let's say I have the following file.sh:

echo "Hello World" 

I need to open this file with cat file.sh | nvim - (not nvim file.sh)... When I do that, if I try using the command :vert botright terminal bash % I receive the error:

E499: Empty file name for '%' or '#', only works with ":p:h"

I tried using set ft=sh but it didn't work as well. Is there any workaround for this problem? In a way that I don't need to save this file on the disk to execute it with nvim?


Observation: With vim, I have a similar configuration in my vimrc file, the only difference is that I use the commands :vert botright '<,'> %terminal bash and vert botright %terminal bash instead. With vim it works perfectly fine to execute files opened from pipe. Like in cat file.sh | vi -. This issue only exists on NeoVim.

3
  • 2
    Depending on what you’re running, you can use term_start and a command with the text to execute or an in_buf if the command accepts stdin Commented Mar 22, 2022 at 13:48
  • 2
    You might want to check out the vim-slime plug-in. Commented Mar 22, 2022 at 14:28
  • ...or indeed the :make command. Commented Jan 31, 2024 at 10:43

1 Answer 1

1

I managed to solve this problem by creating the following vimscript:

function! ExecuteOnTerminal(type) range if (&ft=='javascript') if a:type == "V" '<,'>w! /tmp/file.js else :w! /tmp/file.js endif :vert sp | terminal node /tmp/file.js call system('xdotool key "Control_L+w" ; xdotool type r') elseif (&ft=='bash' || &ft=='sh') if a:type == "V" '<,'>w! /tmp/file.bash else :w! /tmp/file.bash endif :vert sp | terminal bash /tmp/file.bash call system('xdotool key "Control_L+w" ; xdotool type r') elseif (&ft=='python') if a:type == "V" '<,'>w! /tmp/file.py else :w! /tmp/file.py endif :vert sp | terminal python3 /tmp/file.py call system('xdotool key "Control_L+w" ; xdotool type r') endif endfunction vnoremap <silent> <F6> :call ExecuteOnTerminal("V")<CR> nnoremap <silent> <F6> :call ExecuteOnTerminal("I")<CR> 

In this solution, a temporary file with the content of the file was created.

I wanted to make NeoVim behavior exactly the same as Vim, so I've also used xdotool from the system to press Ctrl+w and r to switch sides of the terminal window. The logic here is writing a temporary file with its extension in /tmp and then executing it with terminal language /tmp/file.extension. The result on NeoVim after pressing F6 is:

enter image description here

1
  • 1
    check out :help wincmd instead of xdotool Commented May 31, 2024 at 19:51

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.