How to run Vim commands from Terminal - vim

My questions is one that I haven't seen answered, the usual question is how to run certain commands to a file.
My question is how to run Vim commands or functions, from outside Vim (i.e. Terminal), these wouldn't affect any file, just Vim itself. Is this is even possible? If so, how?
If this is not possible like this, is there a way to go into Vim, run a command automatically, and then exit when that ends? Or run another command and then exit?
Thanks for your help!

Use
vim --cmd 'Command launched before vimrc' \
-c 'Command launched after vimrc' \
-c 'qa!' # Quit vim
. For running a command in an existing vim session you have to use +clientserver feature: run one vim with
vim --servername vim
and others with
vim --remote-send '<C-\><C-n>:Command<CR>'

Related

vim -s in command line without opening vim

I run vim scripts on a regular base. Is it possible to run a script e.g.
vim -s script.vim file.txt without opening vim and returning possible error messages to the terminal?

Hide the output of shell commands in Vim

How can I hide the output of any command in the form :!command in Vim. I don't want to get any messages from Vim after running this command (like Press ENTER or type command to continue) also. I want shell commands to run in background completely.
"I want shell commands to run in background completely." --- This is not about Vim. It is about how to run commands in background.
To not print any output, you can run command like this: yourCmd >/dev/null 2>&1, if it doesn't work, use nohup (https://www.computerhope.com/unix/unohup.htm).
To not print Press ENTER or type command to continue, you can execute commands in Vim like this:
:silent !<command>
silent blank-issue:
https://vi.stackexchange.com/questions/2809/silent-makes-my-vim-go-blank
Vim grep causes characters to temporarily disappear
As explained here, you can also do:
:call system('command')

How to run scripts in background in Neovim?

I wish I could mimic original VIM behaviour by running scripts in the background and not in the internal Neovim terminal emulator.
Basically the reason is that I cannot seem to get colors to work properly, plus, I like to Ctrl+Z (put the editor in the background) and check what was the output of the last command.
Anyway I can configure nvim to do the same as vim in this regard?
Here is the comparison:
EDIT: My tests are run by using :! ./vendor/bin/phpunit {file}
VIM
NVIM
EDIT
By "Background" I mean, not async, in the background while Neovim is on the "top". I mean, to place the editor in the background (like when we do ctrl+z, and then run the tests "on top". Then I hit a key and Neovim comes back to the top.
In other words, I want to configure nvim in a way that when I run a test, it is the same as doing CTRL-Z; execute test.
Sorry, this may be super confusing :D
Instead of using :!{cmd}, I'd encourage you to experiment with running the tests via the :te[rminal] {cmd} command:
:te ./vendor/bin/phpunit {file}
That way the output from phpunit will be captured in a terminal buffer. You can switch between the terminal buffer and the test file using <C-^> (or :b#). Or you can open the terminal buffer and the test file side by side in separate windows. When you're finished with the terminal buffer, you can delete it using :bwipeout {num}.
One cool feature of terminal buffers is that if you place your cursor on a filepath and press gf, Vim will open the specified file. Better still, you use gF, then Vim will open the file at the specified line/column number, if those are present.
For more info, look up :help terminal in Neovim.
In newest version(HEAD version in github repo) of vim with terminal feature enabled.
You can run current file in background with following command:
:terminal ++hidden ./%
for neovim
You may need to install some plugin like:
https://github.com/tracyone/neomake-multiprocess
or
https://github.com/skywind3000/asyncrun.vim
If you are using tmux, you can
https://gist.github.com/tracyone/65cffd685fc9b9308e50c1a1783d1fb0
You could use :silent !./vendor/bin/phpunit {file} to run the script background.

run :!command in a real terminal

I can use pudb (an ncurses Python debugger) in vim, because, for instance, :!python % runs in an actual terminal window. I prefer to use gvim, but gvim runs :!python % in the vim "dumb terminal."
Is there a way to change this behavior so gvim opens a separate terminal for commands? I think I recall having it work this way in the past.
You can tell Vim to run a terminal, and run python in the terminal:
:!xterm -e 'python %; read'
read is there to let you see the output of your script before exiting the terminal.

How to open another file in background Vim from Bash command-line?

I am transitioning from using Gvim to console Vim.
I open a file in Vim, and then suspend Vim, run a few commands on the command-line and then want to return to Vim.
Ctrl+Z (in normal mode) suspends Vim and drops back to the console
fg can be used to return focus to Vim
jobs lists background jobs and can be used to get the job number to
bring a given job to the foreground (e.g., fg %2 to bring job 2 to the
foreground).
However, when Vim is in the background and I issue vim file, the file opens in a new instance of Vim.
I'm used to using the --remote option with Gvim to open a file in an existing Gvim instance.
Question:
How can I open another file in a background Vim from the command-line?
Is this a reasonable workflow for moving between console and Vim?
Update:
I just read this answer by #jamessan which provides a few ideas. He shows the following code snippet:
vim --servername foo somefile.txt
:shell
<do stuff in your shell>
vim --servername foo --remote otherfile.txt
fg
However, I'd have to think about how to make it easier to use perhaps with some aliases.
Would this be a good approach?
How could it be made efficient to use?
This is also what I need. I found this thread, though no satisfying approach, happy to see people having same requirement like me.
My approach is
add below to .bashrc
v() {
vim_id=`jobs|sed -n "/vim/s/\[\([0-9]\)\]+.*/\1/p"`
if [ -n "$vim_id" ]; then
echo "tabedit $#" > ~/.vim_swap/e.vim && fg $vim_id
else
vim $#
fi
}
add below to .vimrc
nnoremap <silent> <space>e :source $HOME/.vim_swap/e.vim<Bar>:call writefile([], $HOME."/.vim_swap/e.vim")<CR>
Then v foo.c to open first file, editing..., ctrl-z to suspend vim, do shell stuff, v bar.h to bring vim foreground.
And in VIM, press <Space>e to tabedit bar.h.
So the idea is to generate vim command from shell command, save them to a temp .vim file. In VIM, map key to source the .vim file and clear it.
Instead of running vim again, you need to bring your current vim process to the foreground (with fg) and open the file in vim.
I have not used it much, but you may find the "vim server" feature (see --remote*, --servername, etc. options) lets you open the file from your shell into an existing, backgrounded vim. However, ctrl-z suspends the process instead of allowing it to continue to run in the background, and you will need to put that vim into the background so it can respond as a "vim server". Use the shell's bg command to do that.
I would just call vim from fg and open new file inside vim since its just seems to be faster (although it may be just faster to me). To work with multiple files inside vim you need to use command edit (in vim): :e [filepath/]filename and you walk true buffers (all files will be as vim buffers) with ^I (ctrl+I) and ^O (ctrl+o)
It works on both GTK and shell versions. There is no such a huge difference on workflow. I prefer shell version since i do most of commands there (compiling launching etc.).
If you use tmux, and if you always have your vim instance running as the first job in background, you can setup alias like below in csh.
alias v 'tmux send-keys fg Space +1 Enter :e Space `realpath \!:1` Enter'
then you can call it like this
v myfile.txt
If your vim instance is not the first background job, enrich the alias with jobs output.
In Bash, this can be done with a function.
function v() {
local job=$(jobs | perl -ne 'print $1 if /\[(\d+)\].*vim/')
if [[ -n $job ]]; then
tmux send-keys fg Space $job Enter
for f in $*; do
tmux send-keys :e Space `realpath $f` Enter
done
else
vim $*
fi
}

Resources