Vim :make, :grep making shell fg first [duplicate] - vim

I've been trying to experiment with using :make recently but I don't like that vim has to switch to showing the shell output first and require one enter keypress, then it shows me what I think is a list of the collected errors based on 'errorformat' which I also need to confirm by pressing enter. I would prefer to just have a short "OK" message that does not require confirmation by a keypress, or that vim would open the :cwindow if there were any errors.

I'm using next line just for exact purpose you wrote:
nnoremap <leader>m :silent make\|redraw!\|cc<CR>
cc in the end shows first error or No errors message if this is the case.

You can map for example F9 to use gcc for small C snippets that don't require libraries, linking, etc:
map <F9> :!gcc -o %< % <enter><CR><C-w>
This will produce for the file foo.c the binary foo. I know that's not exactly what you want, but this doesn't show any shell and is useful for small c snippet.

Try:
:silent make
To automatically open the quickfix window after you run make, you can put this into your .vimrc:
autocmd QuickFixCmdPost * :copen

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.

display 'make' output in 'vim'

I want to :make and display output from it only if it fails.
I map to
:wa<cr>:make<cr><cr>
and only when it fails I want to see the results. Notice the
<cr><cr>
sequence, which closes the output because usually it's success and nothing to read. And it's much faster.
You want to use :silent to stop the output and use :cwindow to open the quickfix window when there is something to see.
:wa|silent make|cwindow<cr>
Note: you will want to use <bar> instead of | if this is inside a mapping. Example of a mapping below:
nnoremap <f9> :wa<bar>silent make<bar>cwindow<cr>
See the following for more information:
:h :silent
:h :cw

Can I use cppcheck when I execute :wq in Vim editor for c/c++

I want to override wq/q/w!/w/q! to user defined command along with its functionality.
Example :
If I use :wq to exit, the command should do static code check of that particular c/c++ file and exit.
Please help me in this case.
Thanks in advance.
The built in solution to your problem is called an "autocommand" in Vim.
It is a way to invoke a command at a specific time like opening, saving or closing a buffer.
See :help autocmd for the full list
In your case, you should add to your .vimrc the following command
autocmd BufWritePre *.cpp,*.hpp !cppcheck %
BufWritePre means 'before writing the buffer' (You can also use BufWrite or BufWritePost)
*.cpp,*.hpp means the auto command will only be applied when saving cpp or hpp files. You can add c and h files if you want.
% means 'path of the current buffer'
cppcheck must be in your path
You are not overriding the defaut behaviour of 'w' but you are using 'hooks' to add custom commands.
I wouldn't do that. It obliges us (well, you actually) to save only when the file is really compilable -- which make no sense when we have to abort the current editing because an urging meeting that we've forget about is about to begin; saving the file in that situation is the normal way to proceed.
Moreover, what is the purpose of running cppcheck on a :wq? How can we exploit the result?
Instead, I'd have a mapping that run cppcheck, though :make in order to exploit the vim quickfix feature (:h quickfix)
function s:Check()
try
let save_makeprg=&makeprg
set makeprg=cppcheck
" you may have to specify other files/extensions
:make *.cpp *.hpp
finally
let &makeprg=save_makeprg
endtry
endfunction
nnoremap <buffer> <c-f7> :call <sid>Check()<cr>
<block>
function FunForQuickfix(makeprgIn, makeefmIn)
try
let save_makeprg=&makeprg
let save_makeefm=&efm
let &makeprg=a:makeprgIn
let &efm=a:makeefmIn
:wa
:make
:cw
finally
let &makeprg=save_makeprg
let &efm=save_makeefm
endtry
endfunction
function CompileAndRunTestCodeByScons()
call FunForQuickfix('scons . -j8 -u', '%f:%l:%c:\ %m,%f:%l:\ %m,build/release64/%f:%l:%c:\ %m,build/release64/%f:%l:\ %m,%f\|%l\|,build/release64/%f:%s,%m:%l:Assertion,%sExpression:\ false,scons:\ building\ terminated\ because\ of\ errors,%sError%m')
endfunction
function CppCheck()
call FunForQuickfix("cppcheck *.cpp -j 8 --enable=all", "\[%f:%l\]:\ %m")
endfunction
nmap ma :wa<CR>:call CompileAndRunTestCodeByScons()<CR>
nmap mc :wa<CR>:call CppCheck()<CR>
nmap <F3> :cp<cr>
nmap <F4> :cn<cr>
</block>
add this in ~/.vimrc, then use ma to compile code and mc to run cppcheck
this code is copy from Luc Hermitte, and i chang it
You might want some things even better, use cppcheck and other checkes while you are developing in vim.
Install and use that vim plugin: https://github.com/scrooloose/syntastic

redirection to a file of a search in Vim

My problem is simple. I search a specific pattern in a file (let's say label in a Tex file)
:g/label/#
but there are lots of occurrences. So I'd like to redirect this output to another file to be able to work easily with it.
Do you have a trick or a command that I don't know?
it's not clear from the original post what you mean by "work easily with it" but it's often useful to see and quickly jump between all of the matches in a buffer without "extracting" the matches to a separate buffer.
vim has an internal grep built in. your example would be something like this (in vim, % denotes the current file)
:vimgrep /label/ %
This will take you to the first occurrence and report how many matches there were. What's cool is that you can look at all of the matches listed by opening up the quickfix error list using
:cope
Now you can just scroll around and press enter on a line to jump to the exact position of the match.
The quickfix error list is exactly the same buffer you use if you run make from inside vim and your compiler throws errors: it gives you a list of what and where the errors are.
After you've jumped to one location pointed by quickfix, you can go to forwards and backwards in the list via :cn and :cp. :ccl closes the error list.
You can also expand your "error" list via :vimgrepa /newpattern/ % or :vimgrepadd
The (documented) caveat is that vim's internal grep is slower than most native grep implementations (but you do get it "for free" in windows, for example). If you do have a grep installed, you can use :grep instead of :vimgrep for similar results.
quoting :help grep
Vim has two ways to find matches for a
pattern: Internal and external. The
advantage of the internal grep is that
it works on all systems and uses the
powerful Vim search patterns. An
external grep program can be used when
the Vim grep does not do what you
want.
The internal method will be slower,
because files are read into memory.
The advantages are:
- Line separators and encoding are automatically recognized, as if a file
is being edited.
- Uses Vim search patterns. Multi-line patterns can be used.
- When plugins are enabled: compressed and remote files can be searched.
You can also use the location list if you're already using the error list for dealing with compilation errors. just add l (for location) to the beginning of the grep command (:lvimgrep,:lvimgrepa :lgrep, :lgrepa) and use :lopen :ln :lp :lcl instead of the :c* ones.
For more commands consult
:help grep
:help quickfix-window
:help quickfix
:help quickfix-error-lists
:redir > matches.txt|execute 'g/foo/#'|redir END
See :h :redir, you can also redirect to registers, variables, the clipboard etc.
What you're doing is essentially 'grep -n label file' from command line. So you can run that command and > it into a file easily enough.
The derivation of 'grep' is even from basically the same source.
I've gotten this of the net at some point:
function GoToLine(mainbuffer)
let linenumber = expand("<cword>")
silent bd!
silent execute "buffer" a:mainbuffer
silent execute ":"linenumber
silent nunmap <Enter>
endfunction
command -nargs=1 GoToLine :call GoToLine(<f-args>)
function GrepToBuffer(pattern)
let mainbuffer = bufnr("%")
silent %yank g
enew
silent put! g
execute "%!egrep -n" a:pattern "| cut -b1-80 | sed 's/:/ /'"
silent 1s/^/\="# Press Enter on a line to view it\n"/
silent :2
silent execute "nmap <Enter> 0:silent GoToLine" mainbuffer "<Enter>"
" silent nmap <C-G> <C-O>:bd!<Enter>
endfunction
command -nargs=+ Grep :call GrepToBuffer(<q-args>)
Put it in your .vimrc, then :Grep Foo
Requires external grep program to work properly.
(Just an idea -- untested.)
You can delete all the lines with your pattern in it, write to another file, and undo the delete.
:g/label/d
:w matches
u

Resources