Whenever I make a new directory, copy, a file, etc. using netrw's mt mf mc commands (for example), or just d, my vim gets into a state where it will absolutely, by no means (known to me) be exited from.
Even if I try to type q! from the netrw directory view, I get:
E37: No write since last change
E162: No write since last change for buffer
Literally all I am left with doing is killing my terminal process.
Assuming I can't change the permissions in this environment. What options am I left with? Completely avoiding netrw for managing directories?
And I'm always seeing this kind of thing after editing files:
"NetrwTreeListing 1" [Not edited][readonly]
netrw creates and modifies hidden buffers.
A way out of the situation might be
autocmd FileType netrw setlocal bufhidden=delete
That can be placed in ~/.vimrc, then q! will let you out after netrw work.
This is via Tim Pope, https://github.com/tpope/vim-vinegar/issues/13#issuecomment-47133890 but there are other comments in that thread that that setting may not always work. Works here, but that is probably luck, very light newrw usage, and not bumping into some bufhidden on/off edge case yet.
That autocmd setting might delete a hidden modified buffer that means something someday, so take this as unexpert sledge hammer advice, no warranty expressed or implied.
Related
I want to:
Automaticaly close Lexpore after opening a file for better experience but I don't know vim script.
It shouldn't be hard, I suppose.
I will appreciate any comment!
I'm now learning vim script and trying to do it.
here is where I've got by now:
:autocmd <Lexplore> * :<Lexplore-exit>
or
if <command-mode> == "Lexplore *.*"
excute \\close last buffer. (because now I am in new buffer)
I just need to know how to say "RUN" / "RUNED" in script
then i use regex for anyfile and i need to say "CLOSE".
The truth is
I'm actually Hopeless! :)))))))))))))
There are other avenues to try before going full-on with VimScript. In this case, a simple mapping would probably be enough.
Basically, the right-hand side of a mapping is just a macro, a sequence of commands that you would type yourself, which makes mappings a very good and approchable way to discover Vim automation.
Assuming a simple layout, with only one window, how do you do what you describe manually?
You do :Lexplore and browse around.
In the Netrw window, you press <CR> to open the file.
Then you go back to the previous window (the Netrw window) with <C-w>p.
You close the window with <C-w>q.
Steps 2-4 above are easy to turn into a mapping (<key> is a placeholder, use what you want):
nmap <key> <CR><C-w>p<C-w>q
But that mapping will be available everywhere, which may not be a good idea. Enters the notion of filetype plugins:
Create these directories if they don't already exist:
~/.vim/after/ftplugin/ (Unix-like systems)
%userprofile%\vimfiles\after\ftplugin\ (Windows)
Create a netrw.vim file in the directory above:
~/.vim/after/ftplugin/netrw.vim (Unix-like systems)
%userprofile%\vimfiles\after\ftplugin\netrw.vim (Windows)
Put the mapping above in that file:
nmap <buffer> <key> <CR><C-w>p<C-w>q
The <buffer> tells Vim to only define that mapping in Netrw.
This is the simplest approach, which may or may not work for you.
A few notes regarding your comments…
Buffer numbers are implementation detail. They don't matter at all in your day-to-day work so you shouldn't think too much about them. Buffer names are far more useful and much easier to think about.
The "sidebar file explorer" UX pattern is a familiar one that newcomers like to transfer from their previous editor but it necessitates a lot of fighting against Vim itself to "work". Netrw's take on the pattern is different, yes, and it might take time to adjust to, but it fits much better within the overall experience. Hint: give up on :Lexplore. :Explore, :Sexplore, :Vexplore, and :Texplore are much more useful.
As you learn more, you will soon discover that file explorers, whatever UX pattern they follow, are not that useful to begin with.
Netrw already has a mapping for opening a file in a new tab page: :help netrw-t.
Is there any way to stop vim from automatically updating folds on the fly? I really love vim's folding, and I prefer having it in syntax mode so that folds are created as I type. But for instance when I code C++ and I write a bracket { it automatically closes all subsequent folds, and when I then close the bracket again with a }, vim automatically expands all subsequent folds, meaning that I have to refold everything.
Another related problem, if I have the same document open in a different buffer, say I have run ":split", then writing an open bracket { will nest all folds in the buffer under the fold in which I opened the bracket, and closing it will un-nest the folds but also close all of them. If I use either "." or "->" to access a member function/variable, it resets all folds in the buffer to be whatever the current foldlevel is, regardless of which folds I have opened/closed myself.
This is somewhat frustrating when I have the same document open in two buffers so I can read the contents of one function when writing another, as I constantly have to switch buffers and reopen my folds.
In my .vimrc I have
set foldmethod=syntax
and that is about it. For autocompletion I use clang-complete and supertab with:
let g:SuperTabDefaultCompletionType = "<c-x><c-u><c-p>"
I think that is everything which migh affect this.
Edit:
Added some pictures to help illustrate the problem
Both problems can be solved with the following two autocmds:
autocmd InsertLeave,WinEnter * setlocal foldmethod=syntax
autocmd InsertEnter,WinLeave * setlocal foldmethod=manual
This sets the buffer local 'foldmethod' to manual when insert mode is entered or its window (a buffer display) is left, and sets it to syntax when insert mode is left or its window is entered.
This works because setting 'foldmethod' to manual will keep the folds automatically created by syntax as if you set them yourself (manually), and manual folds are not updated based on the syntax of the file.
I've found two bugs with this solution:
When switching windows while in insert mode, the autocmd will set the 'foldmethod' to syntax for the new window, even though it's in insert mode and should be set to manual.
This isn't really a problem for me because I use Vim like a civilized person and operate in normal mode by default.
When
a new buffer is created (e.g. by reading a file)
and 'foldlevel' is 0
and a particular syntax is used (I'm able to duplicate the issue with a C file)
and the o or O command is used to enter insert mode for the first time in that buffer (doing i<esc>o does not duplicate the bug),
then all folds below the cursor will be opened.
I accidentally discovered this when testing the above solution, and now looking back I'm surprised I found it; it's almost not even worth mentioning. I don't intend on trying to write a test file that has the exact syntax necessary to duplicate the bug, so this may go unnoticed for another eon.
I actually discovered this question several months ago and used the solution Ben linked to for a while, before eventually being annoyed enough with the multiple window for one buffer issue (your second problem) to fix it.
So thanks to Ben for his solution, and you for asking this question!
I made a bit of a modification to user4830797's answer which helps deal with situations where the file you're editing doesn't use foldmethod=syntax (for example, a .vimrc file which might use foldmethod=marker):
autocmd InsertLeave,WinEnter * let &l:foldmethod=g:oldfoldmethod
autocmd InsertEnter,WinLeave * let g:oldfoldmethod=&l:foldmethod | setlocal foldmethod=manual
I think you need to check :h 'foldlevel. You should also perhaps use :mkview, probably in autocmd which restores manually open and closed folds.
Other then that you should perhaps set folding method differently on different file types (for instance on C you could set it to manual or marker)
If you temporarily set the foldmethod to manual, then Vim will keep all the folds currently defined by syntax, and keep them in the exact open/closed state you have them in now. This can be done automatically with an InsertEnter autocmd and restored on InsertLeave to protect your fold states in a single window. Unfortunately I have not yet spent time trying to get it working in split windows, but using window-local variables it is easy enough to even account for the user switching windows or something without leaving insert mode. See http://vim.wikia.com/wiki/Keep_folds_closed_while_inserting_text for details and discussion.
I've got the (Mac)Vim Syntastic plugin installed via Janus. When I open the :Errors window to view the reason for syntax errors, it shrinks the file with the errors to one line and uses the rest of the real estate for the Errors window.
Is there a way to make it hog less room for errors and more importantly, how do I close just the Errors window? The usual :q closes both the Errors window AND the original file, even if the cursor is in the Errors window. (That's not 100% correct -- it gratefully does not close the file if the file hasn't yet been saved).
Syntastic uses the location list (a window-local variant of the quickfix list), so a :lclose will close it, but keep the other buffers.
As per syntastic's help pages, the initial height can be configured:
:let g:syntastic_loc_list_height=5
But I suspect that your intrusive Janus distribution has a hand in that. Vim "distributions" like spf-13 and Janus lure you with a quick install and out of the box settings, but you pay the price with increased complexity (you need to understand both Vim's runtime loading scheme and the arbitrary conventions of the distribution) and inflexibility (the distribution may make some things easier, but other things very difficult). Vim is incredibly customizable, using someone else's customization makes no sense.
The command to close the Syntastic error window is:
:SyntasticReset
Syntastic gets confused when you're juggling multiple buffers on one screen so here's a script that will collect information about the situation, then do the right thing:
function JustCloseSyntasticWindow()
"Check which buffer we are in, and if not, return to the main one:
if &ft == "qf"
normal ZZ
endif
"Since different buffers have different command spaces, check if we've
"escaped the other buffer and then tell syntastic to stop.
if &ft != "qf"
SyntasticReset
" --- or ----
SyntasticToggleMode
endif
endfunction
au FileType buffer1_ft nnoremap :yourcmd<CR>:call JustCloseSyntasticWindow()<cr>
au FileType main_win_ft nnoremap :yourcmd<CR>:call JustCloseSyntasticWindow()<cr>
Don't be shy on the duct tape for this job, it's the only thing holding the unit together.
You can use :lclose to close it.
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.
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.