So I am using the gvim editor to program in C++, however when I open a .cpp file on the editor then type :!g++ -std=C++17 file.cpp -o file I get this error:
See attached file below:
C:\Windows\system32\cmd.exe /c(g++ -std=c++17 file.cpp - o file)
g++: error: file.cpp: No such file or directory
g++: fatal error: no input files
compilation terminated
Now is this related to vim, or to my command?
Thanks in advance.
It seems that you're unfortunately using gcc-mingw that doesn't come with gnumake properly configured (:let $CXXFLAGS='-std=c++17 -Wall -Werror'+ make %< would have been enough otherwise). Thus you'll have a do a few things manually. And don't misspell the parameters to g++. And forget :!{compilername}, this is want we had to do 25 years ago with vi. Unlike vi, vim permits to integrate compilation.
" to do once
:let &makeprg='g++ -std=c++17 -Wall -Werror % -o %<'
" to execute each time to compile
:make
:copen
" to navigate the errors
:cc " jump to error under cursor
:cnext " jump to next error
:cprev " jump to previous error
:cclose " close the quickfix window
-> :h quickfix
This shouldn't execute g++ from the wrong directory. If this still does, run :cd %:h.
The execution should work with :./%.
And if you wish to have hot keys for that...
nnoremap <silent> <F7> :<c-u>update<cr>:make<cr>
nnoremap <silent> <C-F5> :<c-u>./%<cr>
nnoremap <silent> <F3> :<c-u>cnext<cr>
nnoremap <silent> <S-F3> :<c-u>cprev<cr>
Automatically opening the quickfix windows only if there are errors or executing the result only if there are no errors requires a little more work.
Related
I am using vim for competitive programming and I am using this shell script to compile my c++ files.
g++ -static -DLOCAL -lm -s -x c++ -Wall -Wextra -O2 -std=c++17 -o $1 $1.cpp
When I use this script I get all the errors and warnings in the terminal and when I press ENTER everything is gone. Is there a way to modify this script to display errors and warnings in a separate buffer in vim without going to terminal or is there anything that I should add in my .vimrc file ??
I want my vim to show errors like this one below.
There are many ways of doing it. The best way, IMHO, would be to use the compiler plugins. Please read :help compiler. After that please read :help make. Here is an example from my .vimrc:
nnoremap <F6> :wa <bar> :compiler cargo <bar> :make build <CR>
The example is for Rust. In your case it would be like this
nnoremap <F6> :wa <bar> :compiler gcc <bar> :make<CR>
I fixed the problem by doing this
nnoremap <F9> :wa <bar> :compiler gcc <bar> :silent! make %:r <CR> :cw <CR>
But I don't know how to highlight errors of quickfix list.
I used to use vim/gvim at windows, and my old .vimrc part for compilation looked like this:
autocmd filetype cpp nnoremap <F5> :w <bar> !g++ -std=c++11 -Wall % -o %:r && %:r.exe <CR>
On windows when I pressed f5 a shell (windows cmd) would open and execute it.
However now I began using vim/gvim on linux and when I press f5 it runs on a built-in shell. Is there a way to run on a external shell? I just can open an external shell by typing :! gnome-terminal, but how can I automatically open a shell with the compiler command like g++ main.cpp -o main, javac Main.java && java Main (whatever)
I looking for a solution for a while haha
I'm still improving my english, any critiscism is welcome!!
autocmd filetype cpp nnoremap <F4> :w <bar> exec '!g++ '.shellescape('%').' -o '.shellescape('%:r').' && ./'.shellescape('%:r')<CR>
Try it out!
BTW, maybe here will u find useful information :)
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
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
I am learing Vim and I want have set it up as IDE by mapping F5 key to compilation command which is decided by the filetype.
My ~/.vim/ftplugin/c.vim:
map <F5> :w<CR>:!clang % -o %:r.out && ./%:r.out<CR>
My ~/.vim/ftplugin/cpp.vim:
map <F5> :w<CR>:!clang++ -ggdb -pthread -std=c++11 % -o %:r.out && ./%:r.out<CR>
When I open a C++ file (with .cpp extension) and hit F5, the command from c.vim is executed. Why is this happening?
When I remove the file c.vim, then Vim loads cpp.vim and works as expected.
The cpp ftplugin that comes with vim has the following line:
runtime! ftplugin/c.vim ftplugin/c_*.vim ftplugin/c/*.vim
Which means it is going to source the ~/.vim/ftplugin/c.vim.
A way to overcome this is to put your mappings in ~/.vim/after/ftplugin/cpp.vim and ~/.vim/after/ftplugin/c.vim files.
But your problems don't stop there:
You are using :map where you probably want to at least supply a mode. nmap
You also should probably be using noremap so it would become nnoremap
Your mapping is global so it will stomp over your <f5> everytime you open a cpp and switch to a c file. You should make it local to the specific buffer. nnoremap <buffer>
You should probably also be setting makeprg accordingly so you can take advantage of :make and the quickfix list. e.g. setlocal makprg clang\ %\ -o\ %:r.out
For more help see:
:h :map
:h :map-local
:h 'makeprg'
:h :make
:h quickfix
If you move your file into the /after/ftplugin/ folder, your C specific instructions will still be executed on your C++ files. But your C++ instructions will be executed after the C ones.
If you want to avoid this behaviour, add this at the beginning of your ~/.vim/ftplugin/c.vim file
if (&ft != 'c')
finish
endif