I can press ctrlO to go to the last jump point. However, if there are any changes in the current document it warns me with:
E37: No write since last change (add ! to override)
Is there a way to ignore that message and do ctrl-o and either (1) discard any changes; or (2) save any changes and do ctrl-o?
Discard any changes --- No.
Save any changes --- set autowrite or set autowriteall
Hide buffer but keep it in memory (can ask for saving it later) --- set hidden
Ask if you want to save a buffer --- set confirm
Note: (2), (3) and (4) are global options and change Vim behaviour for many(!) commands.
2) Here is a simple command for your .vimrc that will save the file before jumping:
noremap <C-O> :update<C-M><C-O>
EDIT: Use :update instead of :w to avoid re-writing the file when it was not previously modified.
1) I looked for the equivalent solution to discard the changes instead of saving them, using :e! instead of :w, but that modifies the list of jump points in a way that break <C-O> completely.
Related
I am using vim editor. I was writing a program and did some of the changes in the file after which I "undo" all the changes and by mistake closed the file. Later I realized that the approach that I was doing in the code is right, So I again opened the file and tried to do "redo" operation,but as I have closed the session I think I have lost all the history. Can somebody please tell me if I can do redo by some means as retyping the whole thing again is quite tedious.
Is there some way in which I can redo changes after opening a new session of Vim file
For that you need to have :help persistent-undo enabled:
When unloading a buffer Vim normally destroys the tree of undos created for
that buffer. By setting the 'undofile' option, Vim will automatically save
your undo history when you write a file and restore undo history when you edit
the file again.
Unfortunately, 'undofile' is off by default, so unless you've configured it (and if you've tried redo and failed, that looks like it's off), it's of no use for your current problem.
If the swap-file is still lying around (unlikely as there was a clean exit of Vim), you might be able to grab small incoherent bits of your edits from it.
soap box
To preempt the typical comments: You probably have to accept the loss right now, but take this as an opportunity to rethink your approach. Persistent undo is a really nice feature. With a modern revision control systems (like Git or Mercurial), you can commit often and only locally, and revising your edits is easy to do. Even if that's not an option, there are plugins for Vim (like my writebackup plugin) that make it very easy to frequently save "snapshots" of important editing states. Any of these could save you from the data loss next time!
Another approach, in case you have executed some commands, is recovering your command history by redirecting it into a register.
:redir #h
:history
:redir END
:set paste
"hp
:redir #h ............. start redirecting output to register "h"
:history .............. outputs all commands history
:redir END ............ stops redirecting
:set paste ............ to avoid wrong indentation
"hp ................... puts the "h" register in the current position
you can control where to put it by doing...
0put h .............. pastes the `h` register at the line zero
Once you have a series of commands into a file or register it makes easier to build a function like:
function! Helo()
echo "hello world"
endfunction
If by any change you have used a macro, let's say q, you can retrive it or even edite it, because macros are regular registers that you can reassign as you want. For example, on insert mode you can type:
Ctrl-r q .................... pastes register q
:let #q= ................... starts reassingning macro q
:let #q= ctrl-r q .......... pastes the q register on its reassignment
setting register q to "hello vim"
:let #q = "ihello\<Return>vim\<Esc>"
OBS: Using double quotes you can use control keys as seen above
Any complex command can be saved into the clipboard
:let #+ = #: .............. places last command on the clipboard
:#+ ......................... uses clipboard as command
I created a blank "scratch buffer" (i.e. not associated with a specific file) in vim, by using :vnew. Then I played around with some text, now I simply want to exit the editor - not keeping the contents of this "scratch buffer".
When I type the command:
:q!
Vim gives me:
[No Name][+]
E37: No write since last change (add ! to override)
E162: No write since last change for buffer "[No Name]"
Press ENTER or type command to continue
How can I quit vim from this state?
This happens when you have a modified hidden buffer. Use :qa! to exit anyway.
From :h :quit :
:q[uit]! Quit without writing, also when currently visible
buffers have changes. Does not exit when this is the
last window and there is a changed hidden buffer.
In this case, the first changed hidden buffer becomes
the current buffer.
Use ":qall!" to exit always.
In case someone wants to reproduce it:
Start vim and modify the unnamed buffer
Edit another file (you might need to :set hidden), ie :e README
Try to exit with :q!
At best you could call it a "transient" buffer (in memory but not associated with a specific file) but what you created with :vnew is not a "scratch" buffer.
In Vim, a "scratch" buffer is a normal buffer in which you set a bunch of local options. It can be done with a command like this:
:vnew | setlocal nobuflisted buftype=nofile bufhidden=wipe noswapfile
Suppose state A in my document, I make change to B, C then D.
Now I typed 'u', the state goes to C.
I type 'u' again it goes back to D. (the second undo looks like redo to me).
In my understanding, undo means that I undo it once it will return to C, then undo again to it will return to B then undo again it will return to A.
Also, I know 'u3' can work here but in most cases I have no way to keep track of the number of state changes.
How can I achieve unlimited undo in Vim?
You have only 1 level of undo if you are in Vi compatible mode. You are missing out on a number of features by being in 'compatible' mode. Just create a ~/.vimrc file and you will automatically disable 'compatible' mode.
What wonderful undo features do you get by using 'nocompatible'?
Unlimited undo
Persistent undo
Undo branches (like an undo tree)
I like the old vi undo/redo commands which allows undo (u) or redo (CTRL-R) to be pressed multiple times rather than browsing history to figure out the number of changes to undo.
The vi command uses the ~/.exrc file, not ~/.vimrc so just add "set nocompatible" to the file.
Note that I like using a single undo/redo to jump back to the last place in a file that I changed, and "u" followed by CTRL-R does the trick. And I can always hold down the "u" until all changes are undone including those I might have already saved.
I have a Vimscript function which is called on BufWritePre to check the integrity of the file. Typically this involves trimming whitespace and checking that the fold structure is "valid" (according to my company's conventions).
My problem is that if I edit a file and then save it, the undo tree contains the edits made by the checking function. Is there a simple way to say that I don't want a function to modify the undo tree? Or can I save its state at the start of the function and restore it at the end?
With :undojoin, you can join your changes with the last changes done by the user (though I would find that more confusing than having them separate). In general, undo is sequence of steps; you cannot simply omit steps in the middle, that would both be unintuitive and also difficult to implement in the undo engine.
Anyway, what's so bad about including your automatic reformatting in the undo history? As I understand it, it'll be re-applied on the next save when the user undoes his last edits.
If your BufWritePre action is performing manipulations that ultimately leave your file unchanged, you can:
:wundo <tmpfile>
...Make changes leaving file the same afterwards...
:rundo <tmpfile>
This will leave you with your undo history prior to the temporary change, however if the file doesn't match it's previous state you'll get the error File contents changed, cannot use undo info.
If you wish to make the changes done during the BufWritePre impossible to undo, you can:
:set noundofile
.. Perform changes ...
:set undofile
However, this will lose all history prior to the BufWritePre
I open several files in Vim by, for example, running
vim a/*.php
which opens 23 files.
I then make my edit and run the following twice
:q
which closes all my buffers.
How can you close only one buffer in Vim?
A word of caution: “the w in bw does not stand for write but for wipeout!”
More from manuals:
:bd
Unload buffer [N] (default: current
buffer) and delete it from
the buffer list. If the buffer was changed, this fails,
unless when [!] is specified, in which case changes are
lost.
The file remains unaffected.
If you know what you’re doing, you can also use :bw
:bw
Like |:bdelete|, but really delete the
buffer.
If this isn't made obvious by the the previous answers:
:bd will close the current buffer. If you don't want to grab the buffer list.
Check your buffer id using
:buffers
you will see list of buffers there like
1 a.php
2 b.php
3 c.php
if you want to remove b.php from buffer
:2bw
if you want to remove/close all from buffers
:1,3bw
Rather than browse the ouput of the :ls command and delete (unload, wipe..) a buffer by specifying its number, I find that using file names is often more effective.
For instance, after I opened a couple of .txt file to refresh my memories of some fine point.. copy and paste a few lines of text to use as a template of sorts.. etc. I would type the following:
:bd txt <Tab>
Note that the matching string does not have to be at the start of the file name.
The above displays the list of file names that match 'txt' at the bottom of the screen and keeps the :bd command I initially typed untouched, ready to be completed.
Here's an example:
doc1.txt doc2.txt
:bd txt
I could backspace over the 'txt' bit and type in the file name I wish to delete, but where this becomes really convenient is that I don't have to: if I hit the Tab key a second time, Vim automatically completes my command with the first match:
:bd doc1.txt
If I want to get rid of this particular buffer I just need to hit Enter.
And if the buffer I want to delete happens to be the second (third.. etc.) match, I only need to keep hitting the Tab key to make my :bd command cycle through the list of matches.
Naturally, this method can also be used to switch to a given buffer via such commands as :b.. :sb.. etc.
This approach is particularly useful when the 'hidden' Vim option is set, because the buffer list can quickly become quite large, covering several screens, and making it difficult to spot the particular buffer I am looking for.
To make the most of this feature, it's probably best to read the following Vim help file and tweak the behavior of Tab command-line completion accordingly so that it best suits your workflow:
:help wildmode
The behavior I described above results from the following setting, which I chose for consistency's sake in order to emulate bash completion:
:set wildmode=list:longest,full
As opposed to using buffer numbers, the merit of this approach is that I usually remember at least part of a given file name letting me target the buffer directly rather than having to first look up its number via the :ls command.
Use:
:ls - to list buffers
:bd#n - to close buffer where #n is the buffer number (use ls to get it)
Examples:
to delete buffer 2:
:bd2
You can map next and previous to function keys too, making cycling through buffers a breeze
map <F2> :bprevious<CR>
map <F3> :bnext<CR>
from my vimrc
Close buffer without closing the window
If you want to close a buffer without destroying your window layout (current layout based on splits), you can use a Plugin like bbye. Based on this, you can just use
:Bdelete (instead of :bdelete)
:Bwipeout (instead of :bwipeout)
Or just create a mapping in your .vimrc for easier access like
:nnoremap <Leader>q :Bdelete<CR>
Advantage over vim's :bdelete and :bwipeout
From the plugin's documentation:
Close and remove the buffer.
Show another file in that window.
Show an empty file if you've got no other files open.
Do not leave useless [no file] buffers if you decide to edit another file in that window.
Work even if a file's open in multiple windows.
Work a-okay with various buffer explorers and tabbars.
:bdelete vs :bwipeout
From the plugin's documentation:
Vim has two commands for closing a buffer: :bdelete and :bwipeout. The former removes the file from the buffer list, clears its options, variables and mappings. However, it remains in the jumplist, so Ctrl-o takes you back and reopens the file. If that's not what you want, use :bwipeout or Bbye's equivalent :Bwipeout where you would've used :bdelete.
How about
vim -O a a
That way you can edit a single file on your left and navigate the whole dir on your right...
Just a thought, not the solution...
[EDIT: this was a stupid suggestion from a time I did not know Vim well enough. Please don't use tabs instead of buffers; tabs are Vim's "window layouts"]
Maybe switch to using tabs?
vim -p a/*.php opens the same files in tabs
gt and gT switch tabs back and forth
:q closes only the current tab
:qa closes everything and exits
:tabo closes everything but the current tab
Those using a buffer or tree navigation plugin, like Buffergator or NERDTree, will need to toggle these splits before destroying the current buffer - else you'll send your splits into wonkyville
I use:
"" Buffer Navigation
" Toggle left sidebar: NERDTree and BufferGator
fu! UiToggle()
let b = bufnr("%")
execute "NERDTreeToggle | BuffergatorToggle"
execute ( bufwinnr(b) . "wincmd w" )
execute ":set number!"
endf
map <silent> <Leader>w <esc>:call UiToggle()<cr>
Where "NERDTreeToggle" in that list is the same as typing :NERDTreeToggle. You can modify this function to integrate with your own configuration.