How to open vim buffer next to current buffer rather than at the end [duplicate] - vim

This question already has answers here:
How to change order for :bnext and :bprevious in vim?
(2 answers)
Closed 8 years ago.
I don't use tabs in in vim, I just use buffers and buffer switching, but I have a real pickle. I can't figure out how to open a new buffer next to this one, so that when I switch buffers I don't have to switch all the way to the end. Many times I'm opening files for reference.
Let's say I have five buffers open
[0][1][2][3][4]
And I'm working on the second
[0][1][2][3][4]
I'd like to open a new buffer here:
[0][1][new buffer][2][3][4]
Rather than here:
[0][1][2][3][4][new buffer]
Make sense?

If you want to control the ordering and insertion of buffers, you have to use the argument list instead. The buffer numbers increase steadily and are fixed; there's no way to shuffle them around.
So, use :argedit to open another file; it will be placed just after the current entry. You can control the positioning via the optional [count]. As a bonus, the :next / :n command is one character shorter than :bnext / :bn.

Related

Emacs question: display regexp search matches on scroll bar?

Emacs question: Is there a way to display marks on the scrollbar where search matches are to be found in the buffer? Like hitting crtl-f in the new chrome? Best would be if multiple different searches could be displayed in different colours and different vertical bars?
I don't know how to display the matches on the scrollbar (I doubt it can be done in emacs-lisp).
But, as an alternative, you could use M-x occur RET <regexp> RET.
Emacs will open a buffer named *occur* containing the lines of the original buffer which match the regexp. Each line is preceded by its number in the original buffer and the strings which match the given regexp are highlighted. As emacs documentation says:
That buffer can serve as a menu for finding any of the matches
for REGEXP in the current buffer.
If you click or press RET on one of these lines, emacs will move the point to one of the items in the corresponding line in the original buffer.
You may then rename the buffer before calling again occur, in order to keep the two occur buffers active.
(and if you are smart enough, you may consider writing a function to mix the contents of the different occur buffers...)

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.

How do I execute command similar to gg=G in Vim without going to the top of the file? [duplicate]

This question already has answers here:
Indenting entire file in Vim without leaving current cursor location
(5 answers)
Closed 8 years ago.
How can I reformat the whole buffer in Vim, the same way as I am doing using gg=G keys, without going the the top (which is caused by the gg)?
You can mark the current position with m<letter> command and then go back with `<letter>.
mzgg=G`z
The referenced duplicate uses more effective variant of this approach using the fact that double backtick goes to the last cursor position so you don't actually need to mark the current position:
gg=G``
Or you can install a plugin for text object of entire buffer (e.g. https://github.com/kana/vim-textobj-entire) and then do
=ae
(or equivalent with another plugin).

How to get list of files which are currently being diffed in vim

I am writing a vim plugin in which i need to determine all those files which are currently being diffed. That is the ones for which diff is set. I have been going through the manual but could not find much.
Is it possible to do this.
This question is actually related to question how-to-detect-the-position-of-window-in-vim.
In that question i was trying to get the position of window, so as to detect which one of the diffs is the right one and which is left one. The solution i got was to use winnr()
That solution can work only if there are only 2 windows(the ones being diffed). I want to make it generic so that even if multiple windows are open in vim, i can determine which one is on left and which one is right.
This is what i was thinking to solve the problem
Get a list of all listed buffers
For each of this buffers determine if diff is 1 for that
If diff is 1 use bufwinnr() to gets it window number.
From the window numbers determine which one is left and which one is right. left one will have smaller window number
And then determine if current buffer(in which alt-left`alt-right` is pressed) is left or right using winnr of current buffer.
Now the pieces that are missing are 1 and 2. For 1 ls can be used but i need to parse its output. Is there a straightfwd way to get list of all listed buffers. And then is there a way to check if for that buffer diff is 1 or not.
Any suggestions for a simpler solution are also appreciated.
Cycle through all possible buffer numbers from 0 to bufnr('$') and check, whether this buffer exists using bufexists(nr).
Save current buffer number using let curbuf=bufnr('%').
For each existing buffer do execute "buffer ".bufnumber and check &diff variable. Remember two numbers, but do not check bufwinnr().
Do execute "buffer ".curbuf.
Finally call bufwinnr(nr) for two numbers found in step 3.
UPD: another solution
let g:wlist={"0": [], "1":[]}
windo call add(g:wlist[&diff], bufnr('%'))
let g:diffbuffers=g:wlist.1
" here you have list of buffers with &diff option set in g:diffbuffers

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