How to autoupdate vimgrep search result in quickfix window? - vim

How to autoupdate search vimgrep results from quickfix window after file is autoudpated due to change?
I use :vim/pattern/% to search and put result in quickfix window.

You can always do <up> on the command line with a prefix of :vimgrep to make searching history easier. You may also want to check out q: and the use ?// to search for the command to re-execute.
Assuming the quickfix title is set correctly, you can use following the command:
:execute get(getqflist({'title':1}), 'title')
This however I am not certain this will work with all :grep/:make commands. You also need a newer Vim version to get the Quckfix list title (Vim 8+ I think).
If you find yourself doing this often you may want to bind a mapping or command.
command! -nargs=0 -bar QFRefresh execute get(getqflist({'title':1}), 'title')
Now how to add do this automatically? We can use FileChangedShellPost autocmd to run our QFRefresh command once a file change has been detected. Add the following to you vimrc file:
augroup QFRefresh
autocmd!
autocmd FileChangedShellPost * if get(b:, 'qfrefresh_auto', 0) | QFRefresh | endif
augroup END
command! -nargs=0 -bar QFAutoRefreshToggle let b:qfrefresh_auto = !get(b:, 'qfrefresh_auto', 0) | echo b:qfrefresh_auto ? 'Auto Refresh' : 'No Auto Refresh'
Now you can use :QFAutoRefreshToggle to toggle refreshing a file.
Note: As stated before QFRefresh uses the quickfix's title to get the quickfix command. If the title is not set correctly a refresh may not work correctly. Also I am not sure what guarantees Vim has on triggering FileChangedShellPost. You can force a check via :checktime command.
For more help see:
:h getqflist()
:h :execute
:h :get
:h q:
:h cmdwin
:h c_Up
:h FileChangedShellPost
:h :checktime

Related

How to Override/Redefine Vim Search Command

I need to override/redefine Vim's search operator "/" to also execute "zszH" after the search to center the search results on the screen horizontally.
For example, I want to enter: /varchar and have the search results (i.e., the string "varchar") displayed in the middle of the scren horizontally.
I can do that now by manually entering "zszH" after each search, but that is very tedious.
You can use the CmdlineLeave event. Add the following to your vimrc
augroup RecenterSearch
autocmd!
autocmd CmdlineLeave [/?] call feedkeys('zszH', 't')
augroup END
Note: CmdlineLeave requires Vim 8.1
Or you can map <cr>:
cnoremap <expr> <cr> "\<cr>" . (getcmdtype() =~ '[?/]' ? "zszH" : '')
Some mappings which might be helpful:
nnoremap n nzszH
nnoremap N NzszH
If you do not have a new enough version on Vim then maybe look into 'wrap' or create a mapping
For more help see:
:h CmdlineLeave
:h :autocmd
:h feedkeys()
:h expression-mapping
:h getcmdtype()

VIM: why do these bindings work only sometimes?

I've got these bindings in my .vimrc. They work most of the time, but sometimes they don't: they will just save the file but not run it.
Then I go into insert mode and exit it back to normal mode, and they work again. What could be the problem?
Thanks!
autocmd FileType python map <C-k> :write <CR> :! python % <CR>
autocmd FileType lisp map <C-k> :write <CR> :! clisp % <CR>
autocmd FileType scala map <C-k> :write <CR> :! scala % <CR>
There are many topics to discuss here so with out further ado:
Mappings
Your current mappings map <c-k> ... will only work in normal, visual, and operator-pending modes. However executing your mappings in visual mode or operator-pending modes would save the buffer with only a range of lines (read not good). I suggest you make your mappings for normal mode only.
Two general rules of thumb:
Always supply a mode like n for normal.
Always use noremp instead of map unless you are mapping to a <Plug> mapping.
So one of your mappings might look something similar to this:
nnoremap <c-k> :w<cr>:!python %<cr>
For more information:
:h :map-modes
:h map-overview
:h :nore
:h map-listing
:h map-verbose
Filetype based mappings
You need to do 2 things:
Create a mapping local to a specific buffer by using the <buffer> option for noremap.
Load the mappings for just a specific filetype.
This can be done via an autocmd and FileType event in your .vimrc like so:
autocmd FileType python nnoremap <buffer> <c-k> :w<cr>:!python %:p<cr>
The other way option is by creating a filetype plugin. (see :h ftplugin for more details)
A simple example is do create a file named, ~/.vim/ftplugin/python.vim and place your mappings inside like so:
nnoremap <buffer> <c-k> :w<cr>:!python %:p<cr>
I personally lean more towards the ftplugin approach but having a everything in your .vimrc file can be nice.
For more help see:
:h :au
:h FileType
:h map-local
:h ftplugin
:make
A more vim like way of doing this would be to use :make. (Assuming you want to lint vs execute your current buffer)
:make will execute the 'makeprg'. It defaults to make which is great of C projects
After running :make the quickfix list will be contain any errors.
Set your compiler via the :compiler command.
Extra parameter can be passed like so :make foo-command
Current filename can be represented by %. e.g. :make %
Often people set do :complier/'makeprg' in side of ftplugins e.g. ~/.vim/ftplugin/perl.vim or autocmd's e.g. autocmd FileType perl compiler perl.
Fop more help see:
:h :make
:h 'makeprg'
:h :compiler
:h c_%
quickfix list
Use :cnext and :cprev to move between your errors.
:copen to open up the quickfix list in a window (:cclose to close)
:cwindow to open quickfix list window only if there are errors
May want to use better mappings for :cnext and friends. I suggest Tim Pope's unimpaired plugin
For more help see the following:
:h quickfix
:h :cnext
:h :cope
Alternatives to using :make
Just use <c-z> to suspend vim and run your build system. (Cons: loose out on the quickfix list)
Use :! to compile. (Same cons as suspending) e.g. :!make
Syntastic is a syntax checking system that checks files on save
Ale (Asynchronous Lint Engine) is a plugin for providing linting in NeoVim and Vim 8 while you edit your text files
Dispatch can be used to run things in the background. Great for test suites
May want to consider terminal multiplexers like tmux or screen.
SingleComplile tries and takes some of the work out of using :make
Conclusion
Personally I would install ALE as this removes the need for your mappings. It is also a great idea to learn how to use the location (or quickfix) list. When you are ready to get your hands dirty then you can learn and use :make.
tl;dr
Install ALE.
The space inserted between <CR> and : could lead to errors, because this space is really entered during the execution of the mapping.
With :noremap or :nnoremap (which should be used most of the times, as Peter Rincker wrote in his answer), it wouldn't be a big problem, since it only would move the cursor one char to the right (see :h <space>).
But with :map, it could trigger a custom mapping (or a partial one).
Then, instead of:
autocmd FileType python map <C-k> :write <CR> :! python % <CR>
the following would be better:
autocmd FileType python map <C-k> :write <CR>:! python % <CR>
and this one, really better:
autocmd FileType python nnoremap <C-k> :write <CR>:! python % <CR>

Vim exec command with input() and nested command

I would like to create a vim command that is waiting for an input THEN that will execute ':cw' automatically after the first command.
Here is what I try:
noremap <C-p> :exec ":ProjectGrep /".input('Search: ')"/ src/**"<CR>:cw
But the ':cw' does not execute after the command, it complete the input().
Add the following snippet to your vimrc to make Vim open the quickfix/location window when there are valid errors/locations:
augroup qf
autocmd!
autocmd QuickFixCmdPost [^l]* cwindow
autocmd QuickFixCmdPost l* lwindow
augroup END
That snippet addresses what I believe is your underlying issue (having the quickfix window open automatically after your search command), though, not your actual question.
Anyway, cwindow should be the last command in the function called by your :ProjectGrep command; not at the mapping level.

How would you switch to the previous window using vim autocmd

I use NERDTree and have it set to automatically open when I open vim, but that causes the NERDTree window to be the one selected, which isn't what I want. I want to be able to go right into editing the file I opened, but autocmd vimenter * <c-w><c-p> just gives me an error on startup. Is there any way to do what I'm wanting to do, or is it impossible?
I'm not completely familiar with Vim and its configuration files, so excuse me if this is a simple question, but I haven't been able to find it anywhere.
:autocmd's execute ex-commands not normal mode commands. This means you can use :normal! or use :wincmd (method I prefer).
Your new command:
autocmd VimEnter * wincmd p
Note: wincmd p is the same as <c-w>p or <c-w><c-p> in normal mode.
For more help see:
:h :wincmd
:h :normal
:h :au

How do I open the quickfix window instead of displaying grep results?

I am searching through a large codebase and find vimgrep unusably slow, so I'm using :grep from within vim, which displays a list of files, then says Press ENTER or type command to continue.
After I press Enter I can then type :copen to get to the list of results. But I'm wondering if I could automate this process? Adding the -q flag to grep seems to have the effect of causing grep to do nothing and then copen to be blank, which, unless I'm doing something wrong here, isn't really desirable.
I am using vim 7.4
You could define such a command :
command! -bar -nargs=1 Grep silent grep <q-args> | redraw! | cw
This will allow you to call it like Grep pattern, and :cw which opens the quickfix list only if it isn't empty.
Use an autocommand. Here is the one suggested by Tim Pope for :Ggrep. It will work for your case as well:
autocmd QuickFixCmdPost *grep* cwindow
For more information see:
:h :au
:h QuickFixCmdPost
:h :cwindow

Resources