Echo shell command within vim - vim

I am writing some map commands that run external commands. For example, I may have the following map command to compile the working project.
nnoremap <F5> :!mvn compile test<CR>
However, when vim switches to a shell, it's not clear what command is running. Is there a way for the command to show up on the shell, short of echoing it? It seems tedious to need to write the following each time, but it would do what I want.
nnoremap <F5> :!echo "mvn compile test"<CR>:!mvn compile test<CR>

If your external command processor is a UNIX style shell, it has an echo feature, and you need only to pass the x option to it:
map <F5> :!sh -xc 'mvn compile test'<CR>

Related

redirecting vim :make output to file

Rather than having vim print the output of the :make command, I want to read the output in a file (which gets updated automatically in vim); so that my compiled file can run right away without having to see the output of the :make command.
I'm using the following makefile
all: compile run
compile: file.cc
g++ -o file file.cc
run: file
./file
How does one redirect the output of the :make command in a way that it isn't also printed to the screen by vim?
First of all we have https://vi.stackexchange.com/ , you can get better answers about Vim in there.
Second, I'll argue that a Makefile is no place to run a program, the idea behind make is to catch compilation errors. But assuming you have your reasons (e.g. ./file opens a graphical display) there are a couple of ways to perform this in Vim:
For a start you can set makeprg to perform the redirection:
:set makeprg=make\ >/dev/null\ 2>&1
(You can change /dev/null to an actual file)
But that still leaves the line:
Press ENTER or type command to continue
And asks for confirmation, which may be annoying when you know that there is no output.
To get rid of the confirmation line you can use silent as follows:
set makeprg=make\ >/dev/null\ 2>&1
function! MyMake()
silent make
redraw!
endfunction
command Mm call MyMake()
And now you can do:
:Mm
To perform the make and go back to straight to Vim. (the redraw! is needed only in some terminals)
You can execute this command:
:silent exec "!make >Output" | :redraw!
The file Output contains the last output of the executed make command.
Use :silent to remove the output and "press enter" prompt. I suggest a nice mapping or command:
command! -nargs=* Smake silent make <args>
nnoremap <f5> :silent make<cr>
:make will populate the quickfix list with the results from :make. Use :copen to open the quickfix window.
For more help see:
:h :command
:h silent
:h :make
:h 'makeprg'
:h quickfix

Run command from within vi / vim

As part of learning Haskell, for fun I'm attempting to use Raspberry PI. Having encountered a myriad of issues installing ghci on the PI I've resolved to using just ghc.
So to create, compile & run a new Haskell file :
vi first.hs
i
main = putStrLn "First"
Esc
:w
:q
ghc -o first first.hs
./first
Output is : "First"
I would like to automate the commands :
Esc
:w
:q
ghc -o first first.hs
./first
Can these be added as new command from within vi / vim, something like :
:mycustomcommands
And run from within the vi / vim editor ?
Maybe you could try adding something like this to your vimrc:
function! ExecuteHS()
w
!ghc -o first %
!./first
endfunction
And to use this function you just have to call it like that :call ExecuteHS(). Vim will be put on background during the execution of your file and will then come back on foreground at the end of the execution.
As a bonus you can add the folowing line to your vimrc
nnoremap <key> :call ExecuteHS()<CR>
Replacing <key> with your prefered key combination <Leader>e for example. This way you'll simply have to hit ,e (if you didn't changed your leader key) in normal mode to call the function.
That's probably not the cleanest way to do it but it should work for what you want.
Absolutely in vim, though not necessarily in other vi flavors. See this tutorial on defining custom commands. Put the custom command in your vimrc and it will always be available as :Customcmd or whatever you call it. For one-button access, you can use :remap to assign a hotkey to your custom command or the sequence of built-in commands you want to run. This is a tutorial on keymappings that will give you more information.
I second #statox's referral to https://vi.stackexchange.com :)
I use vim-haskell, which includes a couple nice things. In particular, it includes a file for setting up cabal-install as the compiler, which is a very nice way of working. Dump this in ~/.vim/compiler/cabal-build.vim:
CompilerSet makeprg=cabal\ build
CompilerSet errorformat=
\%W%f:%l:%c:\ Warning:%m,
\%W%f:%l:%c:\ Warning:,
\%E%f:%l:%c:%m,
\%E%f:%l:%c:,
\%C\ \ %#%m,
\%-G%.%#,
\%-G%.%#
And this in ~/.vim/ftplugin/haskell.vim:
compiler cabal-build
(The argument to compiler should match the name of the file you put in ~/.vim/compiler.) Then you can run :make in vim and it will save any changed buffers (assuming autowrite is set) and build your project. When there are errors, it will populate the quick-fix list, which lets you jump to the specific file and line numbers of each error or warning with a key. Read more about this feature with :help quickfix. Once everything is working, you can :!cabal run to run it.

how to execute frequently run bash commands with less keystrokes?

I'm frequently running the following bash command from within vim:
! cordova emulate
What are my options for reducing the number of keystrokes? Please describe how to implement as well.
Note that I'd prefer NOT to create a bash alias for this command.
Bash aliases don't work in Vim by default anyway.
You could add this mapping in ~/.vimrc:
nnoremap <F5> :!cordova emulate<CR>

compile c++ project using vim

I a new vim user, so i am trying to modify vim in order to fit to my needs.
Let's say that i have the project/main.cpp and project/build. Where inside the project/build when i do "make -j5 install" my project is being build and installed correctly. But when i am trying to do that inside from the vim it doesn't work. Here is the code which i use....
map <F5> :call BuildGitRepo()<cr>
function! BuildGitRepo()
:cd %:p:h
let currentFileDir = :pw
:cd currentFileDir
:cd "build"
:!make -j5 install
endfunction
Vim script from a vimrc file functions a bit differently from the Vim window. Commands that begin with : become native in vim script, meaning that you don't need the colon. Also, using local variables is a bit different - you need to use exec.
Finally, you can't capture the output of : commands without buffer redirection, but you can use the getcwd() function to get the current working directory. But it looks like you're cding to the current file's directory twice, so I've made that a bit simpler.
Here's a version of your function that should work in a vimrc file:
map <F5> :call BuildGitRepo()<cr>
function! BuildGitRepo()
exec "cd " . expand("%:p:h") ."/build"
!make -j5 install
endfunction

Vim — running external command bound to F5 inserts result in source

I'm currently developing a webapp that need a "compilation" phase to be tested. For this, I have a simple shell script, which is designed to run from a precise directory.
So in Vim, when I enter command mode and issue this, it works:
:lcd /my/script/directory
:!./build debug
My build script writes some logs in the command window, everything is fine, and tells me to press return to go back editing my stuff. Fine.
Now I'd like to bind this to F5 to speed things up. In my ~/.vimrc, I have added this:
map <F5> :lcd /my/script/directory<CR>! ./build debug<CR>
But after source'ing my ~/.vimrc, when I press F5, my script runs correctly... but strangely Vim replaces the current line I'm on with the output of the script. The same if I do map <silent> <F5> …
If i change ./build debug with a simple ls, the problem arises too. The output of the ls is inserted in my current document, overwriting the current line.
Does anybody know where the problem comes from? I really need to see the output of my build script, so there's no way I could just add a "undo" command after my bind, that would simply erase the inserted output of my command.
FWIW, I'm running MacVim snapshot 63 on OSX 10.7.2, but it also occurs when I use the plain old command-line vim (v7.3) from iTerm2 (1.0.0.20111020).
Try
map <silent> <F5> :lcd /my/script/directory \| !./build debug<CR>
The escaped pipe is here to chain commands.
Use a colon before !, like:
map <F5> :lcd /my/script/directory<CR>:! ./build debug<CR>

Resources