Vim - remove a file from quickfix - vim

Say I have 10 lines in quickfix coming from 3 files: 1.txt, 2.txt, and 3.txt.
1.txt - 3 lines
2.txt - 3 lines
3.txt - 4 lines
What I'd like to do is to set up a binding that would remove all entries from file under cursor from quickfix. I use Cfilter plugin, but it requires more typing, so at first I'd have to yank needed file name, and then run :Cfilter! <filename>, which is not very convenient.
Any ideas on how better to achieve this?
Thanks

You can use :help c_ctrl-r_ctrl-f to insert the filename under the cursor.
With it, your command:
:Cfilter! foo/bar/baz.txt<CR>
can become:
:Cfilter! <C-r><C-f><CR>
which can be mapped for convenience:
" in after/ftplugin/qf.vim
nnoremap <buffer> <key> :Cfilter! <C-r><C-f><CR>
All you have to do is move the cursor on an entry from the file you don't want and press <key>.

Related

Open file with :tag and jump to last edited position

When using ctags with Vim, it's possible to open a file as:
:tag <filename>
This is possible if the tags file was generated using the --extras=+qf flag, like in this code snippet:
$ find . -name "*.c" | xargs ctags-universal --extras=+qf -L -
This produces a line in the tags file such as this:
JPEGImageDecoder.cpp Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp 1;" F
This entry contains 4 elements: {tag name, path to file, line number, tag type}. Whenever Vim opens the tag, it goes to line number 1, despite I have configured Vim to remember the last edited position of a file and go back to it when the buffer is read.
if has("autocmd")
au BufReadPost * if line("'\"") > 0 && line("'\"") <= line("$") | exe "normal! g`\"" | endif
endif
Is there any way of opening a file with :tag <filename> and set the cursor to the last edited position?
Not an exact duplicate, but see this thread.
I'm not sure if you could do it with the :tag command. Consider making your own :Tag command that accomplishes this, maybe something like:
autocmd BufWinLeave * mkview
command -nargs=? Tag :tag <args> | loadview
This is essentially copypasta from the aforementioned thread. Make sure you also see :mksession; it's even more powerful.
I figured this out.
In Vim, :help tags-file-format shows information about a ctags entry format:
The lines in the tags file must have one of these three formats:
1. {tagname} {TAB} {tagfile} {TAB} {tagaddress}
2. {tagfile}:{tagname} {TAB} {tagfile} {TAB} {tagaddress}
3. {tagname} {TAB} {tagfile} {TAB} {tagaddress} {term} {field} ..
Somewhere below, it states the following about {tagaddress}:
{tagaddress} The Ex command that positions the cursor on the tag. It can
be any Ex command, although restrictions apply (see
tag-security). Posix only allows line numbers and search
commands, which are mostly used.
In most cases this {tagaddress} is a line number or a regular expression, but it should be possible to use other Vim mechanisms for positioning the cursor. If I replace 1 for '" (last edited position), it works.
So basically I need to produce a tags file that, for the indexed filenames, replaces the default 1 for '". Ideally that should be an argument in exuberant-ctags or universal-ctags, but basically I did that by postprocessing the tags file with sed:
# Replace 1 for "' (first line for last edited line).
sed -ri "s/1;\"\s+F$/'\";\"\tF/" .tags

How to move to end of a file upon opening it via a command in .vimrc using vim/MacVim?

I'm trying to open a file using a command I set in my .vimrc file. The relevant line in my .vimrc is similar to the following:
command Of so /Users/Dude/Working/open_file.txt
With open_file.txt containing the following:
tabnew /Users/Dude/Working/Project/config.txt
What I'd like to do when executing the 'Of' command is navigate to the end of config.txt. I've tried adding a large line number which is unlikely to exceed the number of lines in the file like so:
tabnew /Users/Dude/Working/Project/config.txt
250000
This takes me to the end of the file but doesn't seem like the right way to do it. Ideally, I'd also like to add a new line after the last line and navigate there too.
A few things:
I would suggest you use full names instead of short names. e.g. so -> source.
source is probably the wrong choice here as you can do everything with the right-hand-side of command
May want to use ! with command so you can resource your vimrc file. e.g. command! Of ...
$ represents the last line of the file. No need to choose a magic number
Create a new line can be done with :normal o or :put _
So with some tweaks we get the following command:
command! Of tabedit /Users/Dude/Working/Project/config.txt | $put_
For more help see:
:h :command
:h :put
:h :range
:h :bar
Have a look at :h :normal in your case just write :norm Go instead of your number there.
:tabnew, like most variants of :edit (and the command-line arguments when launching Vim), takes arbitrary Ex commands via the [+cmd] argument. The $ command will move to the end of the file:
tabnew +$ /Users/Dude/Working/Project/config.txt

Open next file in VIM

I have the following files in directory:
" ============================================================================
" Netrw Directory Listing (netrw v149)
" /home/.../content
" Sorted by name
" Sort sequence: [\/]$,\<core\%(\.\d\+\)\=\>,\.h$,\.c$,\.cpp$,\~\=\*$,*,\.o$...
" Quick Help: <F1>:help -:go up dir D:delete R:rename s:sort-by x:exec
" ============================================================================
../
./
.swo
1
10-1
10-2
10-3
10-4
10-5
10-6
2
3
4
5
6
7
8-1
8-2
8-3
9-1
9-2
9-3
9-4
9-5
Having 10-2 buffer opened, how can I open for editing the next file (10-3)?
What about going back?
Right now I do :Ex and then go to the next file.
My EditSimilar plugin provides (among others) :EditNext and :EditPlus commands.
unimpaired.vim - Pairs of handy bracket mappings includes a pair of [f / ]f mappings to go to the previous / next file
You can load all the files:
:args *
Then use :bn and :bp to switch.
EDIT: Okay, macro time... use these mappings:
nmap <leader>[ :Ex<CR>k<CR>
nmap <leader>] :Ex<CR>j<CR>
Note that this kind of depends on <CR> mapping from netrw, so you can't use nnoremap.
You can try this mapping:
nnoremap <key> :setlocal bufhidden=wipe<CR>:edit<Space>
Action shot (the mapping is less polished but it does the same thing):
I think the straight forward way to go about this is to put all files that you will need while working on your project in a buffer and move to the next or the previous buffer as you see fit.
For example: if you need three files at this time in your project:
file1.txt
file2.txt
file3.txt
Put all three files in the vim buffer with the following command:
vim file1.txt file2.txt file3.txt
And open each buffer as you need with :bn to get the next buffer and :bp to get the previous buffer
:bn
:bp
(Optional) You can also open a new file in a buffer while you are editing a file in vim. The command is:
:e <name of the new file>
And then you can use :bn or :bp to get to the next or previous buffer

Move File within Vim

Is there a way to move a file within Vim? E.g. I opened a file foo/bar.txt in Vim. I know 2 ways to move this file:
First solution:
Delete the buffer with :bd bar.txt
Perform the move on the shell with mv foo/bar.txt foo/bar2.txt
Load the file in vim with :e foo/bar2.txt
Second solution:
Close Vim, so all buffer where closed.
Perform the move on the shell...
Start Vim and load the file.
But these two solutions are embarrassing. I know, there is a plugin for renaming files vim-enuch, but isn't there a Vim way for performing such basic functionality?
You could also use netrw (the default file explorer) rename functionality.
Open netrw with :E
Move your cursor to the line with the file you intend to rename, in this case bar.txt . You move to the file in question using h,j,k,l or you can search for it with / (e.g. /bar.txt)
Hit R. You will then be prompted for a new filepath. When done entering the filepath hit <CR>
Move your cursor to the new file and open it with <CR>
While this solution may not be as quick as using vim-eunch, it does allow you to see the project's structure as you rename the file. This will also allow you to move multiple files at once.
For further reading run :help netrw-move
There is no atomic way to move a file like that, but this should be close:
function! MoveFile(newspec)
let old = expand('%')
" could be improved:
if (old == a:newspec)
return 0
endif
exe 'sav' fnameescape(a:newspec)
call delete(old)
endfunction
command! -nargs=1 -complete=file -bar MoveFile call MoveFile('<args>')
Now you could say:
:MoveFile file2.txt
To rename to file2.txt
:MoveFile %.0
to move file2.txt to file2.txt.0
if you're in the bar.txt buffer:
:w bar2.txt
:!rm bar.txt
If bar2.txt already exists in the current directory, use :w!.

How do I make vim open all files matching a pattern in different tabs?

In a given working directory, if I do
:tabe **/test*.py
vim complains with E77: Too many file names. What if I want it to open every matching file in a separate tab? There must be a way to do it, but I can't find it.
You could use the args list and argdo like so:
:args **/test*.py
:argdo tabe %
However, the syntax event is turned off by argdo (to speed up the normal use case), so the files will be loaded without syntax at first. You could follow it up with a :syntax on to force the syntax event on all loaded buffers. Compressed into one line (need to wrap argdo in execute so it doesn't absorb the following |):
:args **/test*.py | execute 'argdo tabe %' | syntax on
Alternately, you can open vim from the command line via:
vim -p **/test*.py
But that will max out at 10 tabs.
You can use the following:
:next **/test*.py
It opens all the files.
To map it
nmap <c-d> :args **/*.tpl<bar>execute 'argdo tabe %'<bar>syntax on<cr>
But still it displays list of files, you have to press enter few times (depending of number of files).
This functionality can be included as a command in your .vimrc file:
"open all files in seperate tabs
command -nargs=1 OpenAll call <SID>openAll(<f-args>)
function! s:openAll(dir)
execute 'args ' . a:dir
silent argdo tabe %
syntax on
endfunction
With this function running :OpenAll **/*.py from vim will quickly open all files into new tabs
None of the other answers works for me, but this is fine:
find <path> -iname <pattrn> | xargs -o vim -p
all files are visible in different tabs
file lookup is recursive
Note, vim can limit tabs - to be changed by set tabpagemax=42.
Also, if you wonder how to close all tabs at once, use :qa

Resources