I know that I can close all opened buffers in vim by :qall.
I want to close event to pending opening buffers.
I have problem while reviewing my changes in P4 sandbox. When I have changes in multiple files and I try to review my code with "P4 diff" and set my P4DIFF to vimdiff.
It opens one by one vimdiff of all changed files. Now if I have 10 opened files and after reviewing 2 files I want to close diff for remaining 8 files. How can I do that?
Thanks,
This sounds like a job for hastily learnt Vimscript!
Particularly, the :bufdo, if, and match statements!
Try out the following:
:bufdo if match(expand("%"), ".vim") >= 0 | bw | endif
bw is for buffer wipe in Ex-mode (the : operator)
expand("%") returns the name of the current buffer
match(string, pattern) finds the index of a pattern in string
|'s separate lines if you're in Ex-mode
This matches buffers that contain .vim in their filenames and closes those buffers.
I'm guessing if these are temp buffers that are fed into vimdiff, they wouldn't have file names to begin with. Maybe you can use bufnr(".") to output the number of the current buffer. Then you can close all buffers past or before a certain number.
You can probably do even more buffer manipulation with certain plugins. I've been considering adopting one of the following three plugins that help manage plugins:
LustyExplorer
FuzzyFinder
minibufexpl
I can't speak for any merits, but I've heard them mentioned several times over the internet and on IRC.
I'm assuming you open vim with a number of arguments (known as... the argument list).
You should probably reset it:
:args %
You can also selectively manage the list (:argdelete). More information: :he arglist
DISCLAIMER: I've not used perforce, so I've had to make an assumption: that when multiple files have uncommitted changes, it will behave like a lot of VCS's and run the configured diff command (in this case, vimdiff) on each changed file in turn (I'm thinking this is what you meant by "opens one by one vimdiff of all changed files").
If this is the case, then vim won't have any references to any of the remaining files when viewing the changes for any particular file, so no amount of trickery within a single vim session is going to help you.
If you are willing to change your workflow at all, you may be able to do something with this vim script I found: http://www.vim.org/scripts/script.php?script_id=240
It claims to be modelled after the P4 GUI, so hopefully could fit neatly into your usage. From the overview of the script, it sounds like it should be able to show you a summary of which files have changed and allow you to view the changes.
If none of this is suitable for you, you could always try the old favourite Ctrl-C immediately after closing a vimdiff session for a file.
This is a bad hack but putting it here as no other answers worked for me.
Add "qall" without qoutes on top of your .vimrc .
:e ~/.vimrc
:source ~/.vimrc
:q
All files will close automatically after opening.
Then open vimrc in emacs or sed and remove qall.
Related
I'm brand new in the Vim game, and I'm looking for the best tips and shorcuts to manage multiple files projects.
I saw people on the internet having a window with all the directory they have in there projects, and I'm really interested to find how they do that.
So feel free to put all your tips here.
Thanks
One tip I can give you on making changes in a bunch of files is (based on vimcasts):
Let' say you have many markdown files and want to substitute the word ISSUE for SOLVED...
vim *.md
At this point you have all markdown files as arguments...
:args
So you have the argdo command, but in order to use it you have to set the hidden option (it allows you to go to the next file without saving the current one)
:set hidden
Now
:argdo %s/ISSUE/SOLVED/ge
The g flag makes the substitution in all occurrences at each line
the e flag makes vim ignore files where the pattern does not appear
Another good thing is avoiding messeges during substitution of each file, we can add silent at the beggining
:silent argdo %s/ISSUE/SOLVED/ge
If you realize you made a mistake
:silent argdo edit!
Because the command edit! with exclamation makes the file get back to its original state
If you are sure you made it all correct
:argdo update
There are tons of good tips about dealing with many files on vim, you can visit the vimcasts original tip here.
More about the arglist here.
Another great tool to combine with vim is FZF, you can see a good video about it here.
When you have a couple of files opened you can also use the buffer list easily with this mapping (on your ~/.vimrc or ~/.cofig/nvim/init.vim)
" list buffers and jump to a chosen one
nnoremap <Leader>b :buffers<CR>:b<Space>
A shortcut you can use to get back to the last edited file is Ctrl-6.
In order to open you vim on the last edited file add this alias to your ~/.bashrc or ~/.zshrc
alias lvim='vim -c "normal '\''0"'
Open a new terminal and run
lvim
In Vim, I know I can do this to see a list of recently opened files and select one for editing:
:browse old
But is there a way to choose several at once in one go? And bonus: can I open them into tabs instead of buffers?
I'd prefer a native (non-plugin) way if possible.
UPDATE: I finally settled for a plugin called MRU that's actually pretty good. It lets me browse and open multiple recent files into tabs, which matches my workflow perfectly.
UPDATE #2: I just learned that vim lets you save your current work state, including all the opened tabs/buffers, into a "session" which you can then reload the next time you open vim (saves by default into Session.vim, you can optionally append a filename to change that).
To create/save your current workstate:
:mks
Then later to restore from your session:
vim -S
Note that vim creates the Session.vim file in the current dir, not ~
The files are also stored as a List in the v:oldfiles variable. From there, you could loop over them and query for multiple files. That could be a custom mapping or command that you write.
Opening just the last N (here: 3) in tabs can for example be achieved with
:for file in v:oldfiles[0:2] | execute 'tabedit' fnameescape(file) | endfor
When I have many vim files open in different tmux panes, it becomes difficult to keep track of where they all are. I would love to see a list of open tmux panes labeled with the filename of the vim file being edited. Does such a plugin exist? Is it possible to create one?
For such a plugin to work you would need all your vim instances to run as servers on the same machine in order to query all the visible instances for their bufferlist. This sounds like a pathetically complex solution to a really dumb problem, IMO.
Unless you have a very specific need you shouldn't run multiple vim instances. Vim is perfectly able to deal with dozens of files and has many plugins designed to make buffer management easier.
Start with :help buffers.
Also, tmux is a fine piece of software but you should probably take a moment to weight the complexity it adds to your setup and workflow against its actual benefits.
tmux choose-window
will show the name of current directories of all buffers.
(0) 0: ssh "u35#localhost:~"
(1) 1: vim- "u0_a105#android:~/K/20081121"
(2) 2: vim "u0_a105#android:~/K/2014"
(3) 3: vim "u0_a105#android:~/K/20120430"
(4) 4: bash* "u0_a105#android:~/K/20081121"
I personnaly use
bind-key '"' choose-window
so that ^A" gives this list like screen did.
If you want to see the name of current file, you might configure vim to change the buffer name, as bash is doing.
I've opened a file and modified it - now I want to do :Explore without splitting.
It splits - because I have an unsaved buffer. By default this is nice, becasuse Vim generally doesn't allow to switch files, until you do something with the modified buffer (save or discard changes).
But I have set hidden option, so I can jump from buffer to buffer, switch files and everything - and save or not when I feel I want to. It seems Netrw doesn't follow this policy. How could I help it?
One way I know of is to map netrw explore to save & explore, but I'm not sure if autowriting is a good way of doing things... I am actually using other autowriting settings now, but I was just rethinking to maybe get rid of them.
So here is the function, that does just that:
function! ExploreWithHidden()
let s:cw = getcwd()
lcd %:p:h
enew
Explore
cd `=s:cw`
endfunction
Seems to work like expected.
You could use :Texplore instead. This is the same as explore except in a new tab (and will have no splits).
:h Texplore
Another thing you could do is use :lcd %:p:h to change the current working directory to the directory of the file. Then use :enew to create another buffer then open explore. (Make sure hidden is on if the buffer is modified)
:command! BExplore :lcd %:p:h | enew | Explore
To run the command use :BExplore.
The old buffer will be sitting in the background and the explore window is pointing at the directory the file was in.
You could just upgrade your netrw -- its up to v153s at http://www.drchip.org/astronaut/vim/index.html#NETRW, and it does avoid the split if the modified buffer is hidden.
tpope's vim-vinegar operates like this. It maps - to Explore the current file's directory. (That's the same key netrw uses to go up one directory.) It uses the current window instead of splitting.
When the current file is modified:
If you have 'hidden' set, it will not split and Explore from the current window.
If you do not have 'hidden' set, it will issue an error and do nothing.
If I'm editing a file in Vim, then some external program changes the file, Vim tells me:
W11: Warning: File "test.erl" has changed since editing started
See ":help W11" for more info.
[O]K, (L)oad File:
If I Load the file, though, all the undo history is lost.
Is there any way to avoid that?
Update: it appears that this is one of the new features in Vim 7.3: https://groups.google.com/group/vim_announce/browse_thread/thread/66c02efd1523554b
I don't believe this is possible.
There is a very useful patch available for the vim source code available here that keeps the undo history after exiting vim and restarting. However, I've just tried it and it seems to fail when the file is edited externally. It might be worth contacting the author or reporting a bug on the patch website to see if this can be overcome.
G'day,
I'm not sure but does setting autoread, i.e. entering :set autoread leave the undo history for the file when it changes?
Hmmmm. I'm thinking probably not because the change history is maintained as line numbers and vim doesn't know if those line numbers are still relevant to the changed file.
BTW WTF are you editing a file that is being changed by external forces anyway? Sounds dangerous to me. (-:
This is a workaround I used before Vim 7.3:
" :e usually clears undo history, so we don't really do :e any more.
" Instead we delete the contents of the buffer, then read the file in, which
" is an operation we can undo. We must delete the top (empty) line also.
:map :e<Enter> :%d<Enter>:r<Enter>:0<Enter>dd
When you see the warning prompt, you would have to hit ok instead of load, and then perform the load yourself: :e<Enter>
There are two disadvantages (although I found the tradeoff acceptable):
You lose the line you were on. Your cursor is left sitting at the top of the file.
Vim still thinks the buffer is out of sync with the file, so when you next save, you may need to do :w! instead of the normal :w, and you will need to hit y to confirm the overwrite.
Edit: There might be a workaround for the second problem.
Edit: The first problem could be addressed with a bit more scripting (see :h line.)
I don't see how vim could keep track of something it didn't do.
So, as to the question, I would suggest - source control ... but that's probably not the answer you're looking for.