Vim: load changes from previous unsaved session - vim

I have edited file X and closed the file without saving it. Now when I try to open file X vim alerts "No write since last change...".
Is there a way to get those changes back?

Below explanation from :help message
*E37* *E89*
No write since last change (add ! to override)
No write since last change for buffer {N} (add ! to override)
You are trying to |abandon| a file that has changes. Vim protects you from
losing your work. You can either write the changed file with ":w", or, if you
are sure, |abandon| it anyway, and lose all the changes. This can be done by
adding a '!' character just after the command you used. Example: >
:e other_file
changes to: >
:e! other_file
*E162*
No write since last change for buffer "{name}"
This appears when you try to exit Vim while some buffers are changed. You
will either have to write the changed buffer (with |:w|), or use a command to
abandon the buffer forcefully, e.g., with ":qa!". Careful, make sure you
don't throw away changes you really want to keep. You might have forgotten
about a buffer, especially when 'hidden' is set.
[No write since last change]
This appears when executing a shell command while at least one buffer was
changed. To avoid the message reset the 'warn' option.

Related

How to save buffer (preferably if changed) and then close the buffer but not VIM?

So, I just realized I could use marks with capital letters to go to different files. That's great! However, I'm trying to find a way to close the buffer and return to the previous one. Say I go to my header file to change or add the declaration of the function I'm writing, and then I'd like to save the file, but only if there's changes to it, to go back to working on the contents of the function. How can I do this?
There's :x, but it also quits VIM
There's :bd!, but it doesnt save the changes
There's :bw, but that's even worse (unfortunately that's w[ipeout], not w[rite]...)
There's ctrl+O, but it doesnt seem to work when I edit the file (also, it doesnt actually close the buffer)
There's :up followed by :bd, but that's two commands and VIM's about efficiency, so I'd prefer a single command if it exists
There's a few other options and variants, but none that do what I wanted, afaik
It feels like this should be simple enough to do with one command, preferably without macros/plugins/functions/snippets/etc; as close to vanilla as possible. I get the feeling I'm missing something obvious.
You could concatenate commands like so:
:w|bd
I'd like to save the file, but only if there's changes to it
:up[date]
to go back to working on the contents of the function
Press Ctrl^, or enter the command :e[dit] #
I'd prefer a single command if it exists
Set an option :set autowrite and then Vim will save the current buffer on pressing Ctrl^ automatically.

How to remove buffer from jumplist in vim

How could I delete a buffer and remove it from the jumplist? so that the next time I hit <CTRL-o> or <CTRL-i> it doesn't open it again.
To do that you should use one of the built-in commands provided by vim
:bdelete that only closes the buffer and replace it with the one next to it in the jumplist unless there are changed that has not been saved, if you want to delete the buffer and discard the changes :bdelete! is what should be used.
The problem with :bdelete[!] is that only the buffer will be deleted but everything else related to it will stay there like it's position in the jumplit and the marks that registered on it and so on.
So the second command that I find very powerful is :bwipeout[!] which will remove the buffer completely and all the metadata related to it.
With both these commands you can specify counters and ranges, for example:
to delete all buffers use :%bd[elete][!]
to delete all buffers from buffer number 4 to the last one use :4,$bdelete[!] and so on.
the same goes for :bwipeout[!]

How could I judge whether the file has been changed since last saving in vim

I am trying to quantify my vim action by logging timestamp when saving(:w) a file.
Is it possible to know whether the file had really been edited since the last saving?
for example, I saved the file by :w, then, did nothing and just type :w to save it again, is it possible to judge that the file wasn't actually modified?
You can check the value of the 'modified' option:
if &modified
" do something if the buffer is modified
else
" do something else if it is not
endif
Vim displays a '[+]' next to the file name when the file has been modified. However it displays it even if there is no diff between the file on disk and your buffer (for example if you add the letter 'a' then remove it it will consider that the file has been edited).
press :file and if changes have been made [Modified] will be displayed after your file name.
If you have set laststatus to 2 in Vim, it shows you a status line at the bottom of the window which has a [+] indicator next to the filename when the file has been modified since it was last written.
Relevant help pages: laststatus, statusline
Before reading your answer, I thought it was about knowing if the file had been updated from another vim instance / editor before saving it!
If so, vim usally tell me when I want to save it :
WARNING : the file has been updated since vim read it !
Do you want to write it anyway (y/n)?
If it's only about knowing if you change anything since last time, as explained before, Vim display a [+] after your filename.

How to undo up to last write in vim?

Let me pose the question this way. I open a new file in vim, (version 1)
#include<stdio.h>
main()
{
...blah
}
and then use <Esc>:w<Enter> to write the file. Then made changes (version 2)
#include<stdio.h>
main()
{
...blah
... edit1
... edit2 //and large number of changes here and there in code
}
then I save changes using <Esc>:w<Enter>.
Is there a way to undo changes to version 1 directly (Since it was a last save) i.e., without constantly pressing u for undoing
From Vim's help:
:earlier {N}f Go to older text state {N} file writes before.
When changes were made since the last write
":earlier 1f" will revert the text to the state when
it was written. Otherwise it will go to the write
before that.
When at the state of the first file write, or when
the file was not written, ":earlier 1f" will go to
before the first change.
So, if you didn't make changes after the second save, you can do what you want with:
:earlier 1f
On the other hand, if you did unsaved changes after the second save, then:
:earlier 2f
will solve your problem.
See :help :earlier, :help :undolist.
You can get all the way back to when you first opened the file pretty easily. Just type a number before u.
10000u, will undo 10000 times. If that's not enough try 1000000u :)
If you want to undo bit by bit, you can do it in any increment, try 5u.
If you just want to reload the file from disk use :e.
Put this into your .vimrc.
In normal mode shift u will undo till previous save. Pressing again it will undo till the save before that. You can still go back to original point with a lot of <C-R> if you dint made any changes.
nnoremap U :ea 1f<CR>

Undo all changes since opening buffer in vim

How can I undo all changes since opening a buffer? I imagine there may be some form of :earlier that does this.
UPDATE: Many are suggesting solutions for traversing to earlier file writes. This isn't what I asked for. I want to return to the original state the file was in when I originally loaded it into a buffer, no matter how many writes were made since then.
To revert the current buffer to the original state prior to the very
first change recorded in its undo list (see :help undo-tree), one
can use the following two consecutive invocations of the :undo
command:
:u1|u
The first command (:undo 1) reverts to the state of the buffer just
after the very first registered change, while the second command
(:undo) reverts that first change itself.
Starting with version 8.1 (see :helpg Patch 8.0.1441), Vim accepts
the change number 0 as a valid argument to the :undo command,
finally providing a way to refer to the state prior to any registered
changes. This makes it possible to achieve the same effect in
a single-command invocation:
:u0
You can use the
:edit!
command to get into the earliest saved state. See :help edit! for more information.
You can also check something like gundo.vim (can be found here), which displays the whole undo tree graphically, and you can easily jump between points. Then there is the histwin plugin which I did not used yet, but offers similar functionality.
In vim 8.1+ as well as in neovim, you can just use :u0
From the documentation
:u[ndo] {N} Jump to after change number {N}. See |undo-branches|
for the meaning of {N}. {not in Vi}
If you type
:u 1
it appears to go to after the first change; pressing u or typing :u will then go back to the change.
Otherwise, you can use a very large count to :earlier or g-
e.g.
:earlier 100000000 or 100000000g-
If you put this into a mapping/command, it could do any of these without too much trouble.
e.g.
:nnoremap <C-F12> :earlier 100000000<CR>
To access previously saved file status, I think the following work :
:earlier 1f
From the documentation :
:earlier {N}f Go to older text state {N} file writes before.
When changes were made since the last write
":earlier 1f" will revert the text to the state when
it was written. Otherwise it will go to the write
before that.
When at the state of the first file write, or when
the file was not written, ":earlier 1f" will go to
before the first change.
:earlier {N}m Go to older text state about {N} minutes before.
That should help... And even you have {N}h which is about {N} hours before.
A graphic solution:
The Gundo plugin allows visual comparison of changes in the undo history.
Open Gundo's "undo history pane", type G go to the last line, then we can back to the original file.

Resources