Hide the output of shell commands in Vim - 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')

Related

Vim Running Terminal Command Automatically

I am trying to write a command (in vim rc) that automatically creates a new split and starts a terminal (i.e by executing :Term) and then automatically executing some bash commands on that terminal (specifically 'conda activate')
This is how far I got:
command CustomTerminal execute "vsplit ." <bar> execute "Term"
How to I extended this command such that, it pipes and executes some bash commands on this terminal?
I see the following issues with your command definition:
you don't need :execute here; also <Bar> is only needed in mappings
the vsplit . creates a directory listing; is that intended?
have you defined a custom :Term command? The build-in command to open a terminal is :terminal
:term performs a (horizontal) split on its own; its :help :terminal mentions
If you want to split the window vertically, use:
:vertical terminal
The :terminal command accepts optional shell commands already. If that's what you need, you can easily extend your custom command to take and pass this argument:
:command -nargs=? CustomTerminal vertical terminal <args>
See :help :command-nargs and :help <args>.
Additionally, you can add :help :command-completion via -complete=shellcmd.
Keeping the terminal and feeding commands to it
If you want to run more than one command and then close the terminal, so to reuse a single terminal session, you have to follow :help terminal-to-job to send commands from Vim to the terminal (received by the interactive shell or whatever application currently is running). It looks like this:
call term_sendkeys(buf, "ls *.java\<CR>")

vim command line editting

is there a way to use vim/vi in the vim command line? Sometimes I write a long
command in vim such as:
:!./script /home/user/pet --flag=1
and I want to change for instance "user" by "other". What I usually do is to
navigate the command line with right arrow which is time consuming and even more
when I want to go to the beginning of the line. I would like to have something
like "0" to go there or w/b to move by words. Or use j/k to go to the next/previous
command.
Thanks.
:h cedit
in command line, type ctrl-F(default) to enter command window.
or in normal mode type q:
(for search, type q/)
Vim has a feature called the "commandline window". You can enter it with Control-F by default when you're already on the commandline, or q: from normal mode, edit the commandline using vim commands, and press enter to execute. It also contains your command history so that you can yank previous commands if you like. See :help cmdline-window for more information.
I'm not aware how you can use Vim commands to edit a command directly on the command line, but if you enter the command window q: you get can use regular Vim editing to edit commands.
From there you can execute commands by hitting <CR> or use Ctrl-C to copy the command to the regular command line.
If you run set -o vi you will have vim capabilities in your command line. Just put 'set -o vi' in your .bashrc file or equivalent to have it by default.

How to run Vim commands from Terminal

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>'

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
}

How to show the output from the last shell command run in vim? (e.g., :!echo foo)

When I run a shell command it asks to type ENTER at the end and once you do the output is hidden. Is there a way to see it again w/o running the command again?
Also some internal commands like make also run external commands, and those do not even stop for ENTER so if I have an error in my 'compiler' settings the command flashes on the screen too fast to see it. How do I see the command and its output? (quickfix is empty)
UPDATE
The output is DEFINITELY still there. at least on the terminal vim. if I type
:!cat
the output of the previous command is still there. the problem is a) it seems too much like a hack, I'm looking for a proper vim way b) it doesn't work in gui vim
just type :!
or you could try SingleCompile
Putting vim into the background normally works for me (hit Ctrl+Z).
This will show you the shell you started vim from and in my case I can see the output of all the commands that I ran in vim via ":!somecommand".
This is assuming that you ran vim from a shell, not the gui one (gvim).
Before executing a command, you can redirect output to a file, register, selection, clipboard or variable. For me, redirecting to a register is the most practical solution.
To start redirecting to register a, use
:redir #a
Then you run your commands, say
:!ls -l
And end redirecting with
:redir END
That's all, register a now contains the output from the redirected commands. You can view it with :reg a or put into a buffer with "ap, as you would do normally with a register.
Read the help for :redir to know more about the various ways of redirecting.
After months, I found a help file that you may be interested in taking a look: messages.txt.
Though incomplete, it helps a lot. There is a command (new to me) called g< that displays the last message given, but apparently only the Vim messages, like [No write since last change].
First, I suggest you to take a look in your settings for 'shm', and try to make your commands output more persistent (the "Hit ENTER" appearing more often). Then, check if this help file helps :-) I couldn't make it work 100%, but was a great advance.
Why I do not use :! anymore, and what is the alternative
I learn the :! from the currently chosen answer (and I upvoted it). It works, in a sense that it does show the previous screen.
However, the other day I learn another tip of using :!! to re-run the last command (which, by the way, is very useful when you are in a edit-test-edit-test-... cycle). And then I realize that, using :! somehow has a side effect of forgetting the last command, so that future :!! won't work. That is not cool.
I don't understand this, until I take a deep dive into vim's documentation.
:!{cmd} Execute {cmd} with the shell.
Any '!' in {cmd} is replaced with the previous
external command
Suddenly, everything starts to make sense. Let's examine it in this sequence:
Assuming you first run :!make foo bar baz tons of parameters and see its output, later come back to vim.
Now you can run :!!, the second ! will be replaced with the previous external command, so you will run make foo bar baz tons of parameters one more time.
Now if you run :!, vim will still treat it as "start a (new) external command", it is just that the command turns out to be EMPTY. So this is equivalent to you type an empty command (i.e. hitting ENTER once inside a normal shell). By switching the screen into shell, you happen to get a chance to see the previous screen output. That's it.
Now if you run :!!, vim will repeat the previous command, but this time, the previous command is an empty command. That's why your vim loses the memory for make foo bar baz tons of parameters so that next time you wanna make, you will have to type them again.
So, the next question will be, is there any other "pure vim command" to only show the previous shell output without messing up the last command memory? I don't know. But now I settle for using CTRL+Z to bring vim to background, therefore shows the shell console with the previous command output, and then I type fg and ENTER to switch back to vim. FWIW, the CTRL+Z solution actually needs one less key stroke than the :! solution (which requires shift+; shift+1 ENTER to show command screen, and a ENTER to come back).
I usually exit to the shell using :sh and that will show you the output from all commands that has been executed and did not have it's output redirected.
Simply close the shell and you will be back inside of vim.
Found this script -- which will open up a new tab
function! s:ExecuteInShell(command)
let command = join(map(split(a:command), 'expand(v:val)'))
let winnr = bufwinnr('^' . command . '$')
silent! execute winnr < 0 ? 'botright new ' . fnameescape(command) : winnr . 'wincmd w'
setlocal buftype=nowrite bufhidden=wipe nobuflisted noswapfile nowrap number
echo 'Execute ' . command . '...'
silent! execute 'silent %!'. command
silent! execute 'resize ' . line('$')
silent! redraw
silent! execute 'au BufUnload <buffer> execute bufwinnr(' . bufnr('#') . ') . ''wincmd w'''
silent! execute 'nnoremap <silent> <buffer> <LocalLeader>r :call <SID>ExecuteInShell(''' . command . ''')<CR>'
echo 'Shell command ' . command . ' executed.'
endfunction
command! -complete=shellcmd -nargs=+ Shell call s:ExecuteInShell(<q-args>)
Paste it in your .vimrc
It works on gui vim too..
Example Usage -- :Shell make
Scroll up (tested on iTerm 2). Note: this might not work depending on your vim configuration..
Example: I'm about to run !rspec --color % from my vim.
The buffer is filled with the output.
Now, after hitting ENTER, you can scroll up to see the previous output.
maybe the guys are forgetting about the :r
r !ls ~/
Put this where my cursor is:
bug_72440.html
bug_72440.vim
Desktop
dmtools
Docear
docear.sh
Documents
Downloads
examples.desktop
index.html
linux_home
Music
Pictures
Public
Templates
A simple u could get rid of the new text after I yank it or whatever;
Commands like make save their output to /tmp/vsoMething. The errorfile setting seems to be set to the file backing the quickfix/location list. If you want the output to be somewhere specific, see makeef. You can open the current errorfile like this:
:edit <C-r>=&errorfile<CR>
(Unfortunately, this doesn't seem to work for :grep.)
redir doesn't have to be tedious. See this plugin for simplifying it. (I have ftdetect and ftplugin scripts to make the output buffer not backed by a file.)
You see the output on the terminal when you type :!cat because of your terminal, not vim. You'd see the same thing if you used Ctrl-z which suspends vim so vim isn't actively doing anything.

Resources