How to remove buffer from jumplist in vim - 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[!]

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.

Pasting text to a new buffer

I've found questions that are similar, but don't really address what I'm trying to learn. I want to yank or delete text and append it to a new (or existing) buffer without changing buffers. I want to basically redirect the pasted text to its destination at the end of a separate buffer without leaving the original one, similar to what you might do with shell file redirection. I have a hard time believing vim/nvim can't do this, but haven't found an appropriate answer anywhere as of yet.
:'a, 'bw ~/path/to/file.txt
This will copy the text between the two marks 'a and 'b, and write it to a file in the filesystem. This is good, but the file can't be appended to... and it doesn't get opened in a buffer.
There is a :w >> {file} variant that lets you append to a file (:help :write_a).
As #Matt already commented, the usual way would involve switching buffers. Vimscript usage is closely aligned with (mostly Ex-) commands that the user would interactively use. With recent Vim versions, you can alternatively call the low-level appendbufline() function, though. This would bypass any autocmds, buffer setttings, etc. Depending on your use case, this can be desirable or not.
If the target buffer is already visible or can be kept visible as a side effect, temporarily switching to it is easy (mostly involving :sbuffer). My ingo-library plugin has a function ingo#buffer#visible#Execute() that also handles hidden buffers transparently.

Vim: load changes from previous unsaved session

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.

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.

Resetting Buffers in Vim

Is it possible to reset the alternate buffer in a vim session to what it was previously?
By alternate buffer, I mean the one that is referred to by #, i.e. the one that is displayed when you enter cntl-^.
Say I've got two files open main.c and other.c and :ls gives me:
1 %a "main.c" lines 27
2 # "other.c" lines 56
Say I open another file, e.g. refer.c, :ls will now give me:
1 %a "main.c" lines 27
2 "other.c" lines 56
3 # "refer.c" lines 125
If I delete the buffer containing refer.c, :ls now shows:
1 %a "main.c" lines 27
2 "other.c" lines 56
But if I do a cntl-^, refer.c will be displayed again!
Is there some way to get vim to reset the alternate buffer back to what it last was automatically? A "history" of alternate buffers?
Or am I stuck with doing a :2 b to reload other.c into the alternate buffer?
Or maybe there is a good reason for this behaviour?
In this case, "alternate" just means "previous". So, yes, :b2 (or 2 ctrl-6) is probably the easiest way to change which two buffers will be toggled by ctrl-6.
Also, take a look at the :keepalt command.
As you'll come to expect with Vim, there is an excellent reason for this behaviour. :bd (mnemonic for buffer delete) does not delete the buffer, per se, it deletes it from the main buffer list!
If you try :ls! or :buffers! you will see it is is still available but with a u adjacent to it's buffer number, indicating it is now "unlisted" (that is, unlisted unless you list it with an exclamation mark!).
I'm making it sound as horrible as possible, but as with most of Vim it works once you understand it, and the use of exclamation mark / bang to force the command is consistent.
To get rid of the buffer completely you need to wipe it using :bw. When you have done that you will still have the same problem, but this time, attempting to switch to the alternate buffer with CTRL-^ will elicit No alternate file (because this time it really has gone).
To switch to the file you want, yes, use the buffer number: :b2, or whatever the buffer number is of the file you want, and that will establish a new alternate buffer.
I find it's easy to remember buffer numbers or look them up with :buffers or :buffers! really quickly, and of course changing to them is then quick, but of course there's a range of techniques in Vim for changing buffers, especially including marks.
You've also discovered another great Vim feature here, the unlisted buffers. When you're dealing with a few extra files it's sometimes helpful to "delete" them from the :buffers list using :bd, just to get them out of sight, but although hidden they're not unavailable, and you can check which one you want with :buffers! and then :b<num> to pull it up, without having to undelete it or anything.

Resources