# Brainstorm for a more flexible buffer list

**URL:** <https://discuss.kakoune.com/t/brainstorm-for-a-more-flexible-buffer-list/767>\
**Category:** Complaints & Improvements\
**Tags:** buffer\
**Created:** [October 24, 2019, 1:12pm UTC](https://discuss.kakoune.com/t/brainstorm-for-a-more-flexible-buffer-list/767 "2019-10-24T13:12:16Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Delapouite](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/delapouite/32/10_2.png) [@Delapouite](https://discuss.kakoune.com/u/Delapouite)\
**Post date:** [October 24, 2019, 1:12pm UTC](https://discuss.kakoune.com/t/brainstorm-for-a-more-flexible-buffer-list/767/1 "2019-10-24T13:12:16Z")

</div>

Hello

### Current situation

Kakoune code has a `BufferManager` which is basically a wrapper class around a `Vector` of buffers: [buffer\_manager.hh](https://github.com/mawww/kakoune/blob/master/src/buffer_manager.hh)

To walk through this vector, the editor offers 2 basic commands `buffer-previous` and `buffer-next`. Internally, they both let [cycle\_buffer](https://github.com/mawww/kakoune/blob/master/src/commands.cc#L726) function do the heavy lifting.

There’s also the `ga` command to go back and forth between 2 buffers.

### Problem

The **user has very little control about the order** in which the buffers are stored in this vector. Over the years, a few issues were raised about this topic:

- [Store buffer view history for ga (goto previous buffer)](https://github.com/mawww/kakoune/issues/2559)
- [Keep the entire history of ‘previous buffer’](https://github.com/mawww/kakoune/issues/1993)
- [Counter-intuitive buffers order](https://github.com/mawww/kakoune/issues/2705)

To summarize, the main problem from a user perspective is that it’s often not very intuitive/predictable which buffer will be displayed when `buffer-next` is called.

### Other editors

A lot of graphical editors, display buffers in “tabs” (like “Firefox tabs”). Using the mouse, these tabs can be freely drag’n’drop, to reorder the buffers. As Kakoune is keyboard centric we have to find another paradigm.

### A few ideas

Here are some proposals. They can be complementary or not. Keep in mind that they are just broad ideas, no specific details is set in stone.

1. a new **`sort-buffers`** command. This command can take arguments specifying how to reorder the `buffer_manager` vector. For example:

- `sort-buffers alphabetical` to reorder them by `bufname`.

- `sort-buffers path` to reorder them by filepath.

- `sort-buffers modified` to reorder them by last modification date

- `sort-buffers filetype` to reorder them filetype

- …

1. a new **`move-buffer`** command. Something like `move-buffer qux.txt -1`. Example, it will have an effect like `[foo.txt, bar.txt, qux.txt]` → `[foo.txt, qux.txt, bar.txt]`

2. an interactive `*buffers*` buffer. By using the new **`list buffers`** command, a debug `*buffers`\* is created. It contains the list of current buffers, with names, filetype, dates flags… By editing and then saving this special buffer, the `buffer_manager` vector is adapted accordingly.

### My opinion

I think I prefer option 3 (the interactive `*buffers*`) for several reasons. Firstly, it only introduces 1 new command which is `list <arg>`. This command can be useful for other purposes, for example `list registers` (but that’s another topic entirely).  
Secondly, the user is free to use regular Kakoune commands, `|sort` or whatever tool he knows to deal with this buffer list.

@andreyorst built something quite similar in the `plug.kak` plugin for the `plug-list` command.  
@occivink also built an interactive buffer in the `kakoune-find` plugin.

* * *

What’s your take on this broad inflexible buffer-list subject?

---

<div class="post-metadata">

**Author:** ![eraserhd](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/eraserhd/32/15_2.png) [@eraserhd](https://discuss.kakoune.com/u/eraserhd)\
**Post date:** [October 24, 2019, 1:47pm UTC](https://discuss.kakoune.com/t/brainstorm-for-a-more-flexible-buffer-list/767/2 "2019-10-24T13:47:29Z")

</div>

There’s already a way to list buffers: `%val{buflist}`. `move-buffer` is simple, and sufficient to implement the rest in the Kakoune configuration language.

I’ll admit I can never really predict what is `next` and what is `prevous`, and I almost never get it right. The only piece of this that I use is that I expect `delete-buffer` to return to the previous thing I was editing, and it usually does. I’m not sure where I might use it.

---

<div class="post-metadata">

**Author:** ![andreyorst](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/andreyorst/32/29_2.png) [@andreyorst](https://discuss.kakoune.com/u/andreyorst)\
**Post date:** [October 24, 2019, 1:58pm UTC](https://discuss.kakoune.com/t/brainstorm-for-a-more-flexible-buffer-list/767/3 "2019-10-24T13:58:20Z")

</div>

On topic of `move-buffer` command.

Emacs also features `bury-buffer` to move buffer to the last position in the list, which is quite handy thing.

I also propose `move-buffer` to have fomrat `move-buffer WHERE WHAT` so `WHAT` could be omitted, e.g. `move-buffer last` would move current buffer to the last position, and `move-buffer last foo.txt` would do that for `foo.txt` buffer.

I also thought about creating a buf-list plugin/command that would open interactive split with list of buffers, that will allow opening, closing, saving, updating, and possibly redirecting if `move-buffer` would become a thing. Since Kakoune doesn’t have tabs, like Vim or Emacs, this would be handy.

---

<div class="post-metadata">

**Author:** ![Screwtapello](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/screwtapello/32/12_2.png) [@Screwtapello](https://discuss.kakoune.com/u/Screwtapello)\
**Post date:** [October 24, 2019, 2:54pm UTC](https://discuss.kakoune.com/t/brainstorm-for-a-more-flexible-buffer-list/767/4 "2019-10-24T14:54:35Z")

</div>

How about an `arrange-buffers` command, which takes zero or more buffer names, and re-arranges the buffer list so the given buffer names are the first in the list. For example, if Kakoune’s current buffer list looks like:

- `foo.txt`
- `bar.txt`
- `qux.txt`
- `*debug*`

…and then the user runs:

```
arrange-buffers bar.txt *debug*

```

…then the resulting buffer list would be:

- `bar.txt`
- `*debug*`
- `foo.txt`
- `qux.txt`

…with the named buffers at the beginning in the given order, and all the other buffers afterward in their original order.

Invoking `arrange-buffers` with a name that is _not_ a currently-open buffer would be an error.

With this command, it should be possible to implement all the other commands mentioned so far with some shell-scripting — `sort-buffers`, `move-buffer`, even a magic `*buffers*` scratch buffer.

Of course, if we wanted to be even more minmalist, we could make the list of open buffers an option, so we could set it with the regular `set-option` command rather than a special `arrange-buffers` command. On the other hand, it would be weird to have a `str-list` option that you couldn’t use `set -add` with, or remove things from.

---

<div class="post-metadata">

**Author:** ![robertmeta](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/robertmeta/32/833_2.png) [@robertmeta](https://discuss.kakoune.com/u/robertmeta)\
**Post date:** [October 24, 2019, 4:28pm UTC](https://discuss.kakoune.com/t/brainstorm-for-a-more-flexible-buffer-list/767/5 "2019-10-24T16:28:41Z")

</div>

The idea of magical buffers like #3 both makes me very excited, and horrified, in nearly equal parts.

I sincerely don’t know how I feel. 🙂

---

<div class="post-metadata">

**Author:** ![occivink](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/occivink/32/27_2.png) [@occivink](https://discuss.kakoune.com/u/occivink)\
**Post date:** [October 24, 2019, 6:16pm UTC](https://discuss.kakoune.com/t/brainstorm-for-a-more-flexible-buffer-list/767/6 "2019-10-24T18:16:03Z")

</div>

I like both Delapouite’s suggestion #2 and Screwtape’s suggestion.

I’m also fond of Delapouite’s suggestion #3, but I think this is better left as a userscript. I actually already use a [special buffer](https://github.com/occivink/config/blob/master/.config/kak/kakrc#L372-L398) for switching around between buffers.  
It’s a little crude but it’s my main way of changing the current buffer. I would definitely like to reorder the buffers by moving the lines around (and also deleting them by removing lines, but that’s already possible).

---

<div class="post-metadata">

**Author:** ![Delapouite](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/delapouite/32/10_2.png) [@Delapouite](https://discuss.kakoune.com/u/Delapouite)\
**Post date:** [October 24, 2019, 6:51pm UTC](https://discuss.kakoune.com/t/brainstorm-for-a-more-flexible-buffer-list/767/7 "2019-10-24T18:51:39Z")

</div>

Thanks all for you input!

I think Screwtape you’re definitely on the right track, because as you mention, `arrange-buffers` is the only building block needed to allow scripting the other approaches.

I’ll try to come up with a prototype implementation if my `C++fu` is strong enough.

---

<div class="post-metadata">

**Author:** ![danr](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/danr/32/700_2.png) [@danr](https://discuss.kakoune.com/u/danr)\
**Post date:** [October 25, 2019, 11:24am UTC](https://discuss.kakoune.com/t/brainstorm-for-a-more-flexible-buffer-list/767/8 "2019-10-25T11:24:07Z")

</div>

I would go for Screwtape’s. It’s minimal and expressive in the sense that all the other ideas you had can be implemented on top of it.

---

<div class="post-metadata">

**Author:** ![lisael](https://discuss.kakoune.com/letter_avatar_proxy/v4/letter/l/8c91f0/32.png) [@lisael](https://discuss.kakoune.com/u/lisael)\
**Post date:** [November 26, 2019, 4:08pm UTC](https://discuss.kakoune.com/t/brainstorm-for-a-more-flexible-buffer-list/767/9 "2019-11-26T16:08:10Z")

</div>

I wrote a small script a long ago, that opens a buffer with a buffer list, let me re-order them and when I type :w it maps the ten first buffers on \<a-1…0\>. It keeps track of these ten buffers in an opt so they do appear in the same order in subsequent calls. (I mention this here, because it’s the same philosophy as Screwtape’s solution and is enough for my buffers needs).

I didn’t want to learn about fifo at the time so it’s a quite rough, writting temp files in /tmp…

> <https://gist.github.com/lisael/84a1d7d1c4f1699662fd55225a122637>

---

<div class="post-metadata">

**Author:** ![vbauerster](https://discuss.kakoune.com/letter_avatar_proxy/v4/letter/v/85e7bf/32.png) [@vbauerster](https://discuss.kakoune.com/u/vbauerster)\
**Post date:** [December 5, 2019, 6:19pm UTC](https://discuss.kakoune.com/t/brainstorm-for-a-more-flexible-buffer-list/767/10 "2019-12-05T18:19:43Z")

</div>

I’d like buffers have register concept, so it’s possible to group buffers logically.  
For example move some related buffers to register `a`, then display only those with `:buffer --reg=a`.

---

<div class="post-metadata">

**Author:** ![Delapouite](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/delapouite/32/10_2.png) [@Delapouite](https://discuss.kakoune.com/u/Delapouite)\
**Post date:** [March 15, 2020, 10:46am UTC](https://discuss.kakoune.com/t/brainstorm-for-a-more-flexible-buffer-list/767/11 "2020-03-15T10:46:31Z")

</div>

Merged in [https://github.com/mawww/kakoune/commit/09375edf546dc2845960adb718db28bdcb220df1](https://github.com/mawww/kakoune/commit/09375edf546dc2845960adb718db28bdcb220df1)

Thanks all!

---

<div class="post-metadata">

**Author:** ![occivink](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/occivink/32/27_2.png) [@occivink](https://discuss.kakoune.com/u/occivink)\
**Post date:** [April 22, 2020, 9:41am UTC](https://discuss.kakoune.com/t/brainstorm-for-a-more-flexible-buffer-list/767/12 "2020-04-22T09:41:53Z")

</div>

I ended up publishing my [`buffer-switcher` plugin](https://github.com/occivink/kakoune-buffer-switcher) which makes use of this. As improvements I’m thinking of showing some buffer flags, such as modified/scratch/readonly. Suggestions are welcome too.
