nyxt icon indicating copy to clipboard operation
nyxt copied to clipboard

Confusion about buffer ordering | buffer tagging and naming

Open franburstall opened this issue 2 years ago • 28 comments

Describe the bug I am not sure if this is a bug or a feature request or just a rant but I am finding it very difficult to reason about buffer navigation.

We want to efficiently navigate between buffers by keyboard in the absence of visual clues (the long line of tabs we see at the top of chrome or firefox). This means that we (or at least I) need a mental model of buffers and the relations between them. The problem is that nyxt offers TWO models and only one of them is predictable.

Last access model -switch-buffer -switch-buffer-last Anything that uses a buffer-source offers a list of buffers sorted by last-access. This is predictable and often what we want but, by its very nature, it is volatile.

The very wonderful switch-buffer-last hits a good proportion of the use-cases for this model.

Next/previous model -switch-buffer-next -switch-buffer-previous -list-buffers -show-buffers-panel This is non-volatile but utterly unpredictable: it imposes a tree structure on the output of buffer-list which comes from a call to alex:hash-table-values which I guess has no idea about sort order. In particular, newly created buffers get slotted into the ordering at apparently random places. This is the case even when the tree structure is flat, so that is not the issue. Moreover, I know no way to change this ordering (in chrome/firefox, I would use a mouse to place tabs next to each other).

Why I care I would very much like to be able to arrange three buffers in such a way that switch-buffer-next/prev moves between them (think three-way cut/paste tasks: there are times when the admin part of my life is dominated such things, sigh)

Suggestions I guess what I am suggesting is that a rational but user-adjustable ordering underlie the next/previous model. Perhaps start with buffer creation order?

Extra marks for some kind of pinning: mark buffers to be permanently first/second/... in this ordering so that keys like C-1, C-2 could switch to those quickly.

Nyxt version: 2.1.1-413-g69dbf721 Renderer version: GI-GTK Operating system kernel: Linux 4.19.0-17-amd64 Lisp implementation: SBCL 2.1.1 (Dynamic space size: 1073741824) Features: (:SLYNK :WEBKIT2 :WEBKIT2-2.32 :WEBKIT2-PASTE-PLAINTEXT :WEBKIT2-TRACKING :WEBKIT2-MUTE :WEBKIT2-EMOJI :WEBKIT2-MEDIA :WEBKIT2-SANDBOXING :GTK-3-22 :GTK-3-20 :GTK-3-18 :GTK-3-16 :GTK-3-14 :GTK-3-12 :GTK-3-10 :GTK-3-8 :GTK-3-6 :GTK-3-4 :GTK :GDK-3-22 :GDK-3-20 :GDK-3-18 :GDK-3-16 :GDK-3-14 :GDK-3-12 :GDK-3-10 :GDK-3-8 :GDK-3-6 :GDK-3-4 :CAIRO-1-10 :CAIRO-1-12 :GDK-PIXBUF :GLIB-2-30 :GLIB-2-32 :GLIB-2-34 :GLIB-2-36 :GLIB-2-38 :GLIB-2-40 :GLIB-2-42 :GLIB-2-44 :GLIB-2-46 :GLIB-2-48 :GLIB-2-50 :GLIB-2-52 :GLIB-2-54 :GLIB-2-56 :GLIB-2-58 :GLIB :NYXT-2 :FSET-EXT-STRINGS :CUSTOM-HASH-TABLE-NATIVE :SWANK :PLUMP-UTF-32 :GLOBAL-VARS :DECLARE-TYPES :PARENSCRIPT :NAMED-READTABLES :21BIT-CHARS :CHUNGA :FLEXI-STREAMS :CLOSER-MOP :CL-PPCRE-UNICODE :CL-UNICODE :CL-PPCRE :BORDEAUX-THREADS :SPLIT-SEQUENCE CHIPZ-SYSTEM:GRAY-STREAMS :FAST-IO-SV :FAST-IO :SBCL-USES-SB-ROTATE-BYTE :ASDF-SYSTEM-CONNECTIONS :CL-JSON-CLOS :CL-JSON :THREAD-SUPPORT CFFI-FEATURES:FLAT-NAMESPACE CFFI-FEATURES:X86-64 CFFI-FEATURES:UNIX :CFFI CFFI-SYS::FLAT-NAMESPACE ALEXANDRIA::SEQUENCE-EMPTYP :QUICKLISP :ASDF3.3 :ASDF3.2 :ASDF3.1 :ASDF3 :ASDF2 :ASDF :OS-UNIX :NON-BASE-CHARS-EXIST-P :ASDF-UNICODE :X86-64 :GENCGC :64-BIT :ANSI-CL :COMMON-LISP :ELF :IEEE-FLOATING-POINT :LINUX :LITTLE-ENDIAN :PACKAGE-LOCAL-NICKNAMES :SB-LDB :SB-PACKAGE-LOCKS :SB-THREAD :SB-UNICODE :SBCL :UNIX)

ASDF version: 3.3.1 Critical dependencies: (/home/fran/common-lisp/nyxt/_build/submodules/cl-cffi-gtk/gtk/cl-cffi-gtk.asd /home/fran/common-lisp/nyxt/_build/quicklisp-client/dists/quicklisp/software/cl-gobject-introspection-20210124-git/cl-gobject-introspection.asd /home/fran/common-lisp/nyxt/_build/submodules/cl-webkit/webkit2/cl-webkit2.asd)

Quicklisp dist version: 2021-06-30 Quicklisp client version: 2020-01-04 Local project directories: (/home/fran/common-lisp/nyxt/_build/submodules/ /home/fran/common-lisp/nyxt/_build/quicklisp-client/local-projects/) Critical dependencies(#<SYSTEM cl-cffi-gtk / cl-cffi-gtk-20201220-git / quicklisp 2021-06-30> #<SYSTEM cl-gobject-introspection / cl-gobject-introspection-20210124-git / quicklisp 2021-06-30> #<SYSTEM cl-webkit2 / cl-webkit-20210630-git / quicklisp 2021-06-30>)

franburstall avatar Jul 30 '21 09:07 franburstall

The tree is ordered by buffer ID, which maps creation order. Does that make more sense?

We should document it more.

What else would you suggest?

About re-ordering, I'm not sure how to do it, but I guess we add a "buffer child position" slot to buffers that the user could modify.

The list-buffers command is also very handy for navigating the tree.

Ambrevar avatar Jul 30 '21 10:07 Ambrevar

The tree is ordered by buffer ID, which maps creation order.

I have just done list-buffers and the buffer ids listed in display order are 11, 9, 5, 4, 3, 2, 6.

franburstall avatar Jul 30 '21 10:07 franburstall

It's a tree, if "6" was a child buffer at some point it's normal that it appears there.

Can you send a precise recipe if you think there is a bug?

Ambrevar avatar Jul 30 '21 11:07 Ambrevar

In the end, I believe switch-buffer-next and switch-buffer-previous are only rarely useful. They are mostly here to allow cycling through all buffers in a reliable order to mimick the equivalent feature of tab-based browsers.

In terms of UX, tabs are poor since they don't scale, so it's only natural that switch-buffer-next doesn't scale either.

The list-buffers or fuzzy-searchable switch-buffer are much better approaches in my opinion.

Ambrevar avatar Jul 30 '21 11:07 Ambrevar

It's a tree, if "6" was a child buffer at some point it's normal that it appears there. Can you send a precise recipe if you think there is a bug.

I am not sure if "6" was ever a child buffer but it is not now (according to list-buffers in tree display). But I am not sure what provokes the parent-child relationship. For example: when I am in a web-buffer and fire a help-buffer---is the help-buffer a child? This is an instance where I see the buffer list not in :id order sometimes. I am afraid that this does not count as "reliable" for me.

If I have the time, I shall see if I can a reproducible recipe...

franburstall avatar Jul 30 '21 11:07 franburstall

In the end, I believe switch-buffer-next and switch-buffer-previous are only rarely useful. They are mostly here to allow cycling through all buffers in a reliable order to mimick the equivalent feature of tab-based browsers.

In terms of UX, tabs are poor since they don't scale, so it's only natural that switch-buffer-next doesn't scale either.

The list-buffers or fuzzy-searchable switch-buffer are much better approaches in my opinion.

I mostly agree, but for work, I frequently need to be able to switch between a small number of buffers with minimum key-strokes and here switch-buffer needs too many key-strokes and list-buffers sends us back to point-and-click.

franburstall avatar Jul 30 '21 11:07 franburstall

A child buffer is one when opened by clicking on a link of a web page to be opened in a new buffer.

follow-hint-new-buffer, C-button1, etc. generate child buffers.

We lack documentation here for sure.

Ambrevar avatar Jul 30 '21 11:07 Ambrevar

What about key-marking buffers?

Press C-shift-1 to mark the current buffer to "1", then at any point you can press C-1 to switch back to this buffer. Same with C-2, etc.

Would that be a good UI?

Another (non mutually exclusive) option would be to create buffer clusters and have switch-buffer-next and switch-buffer-previous stick to this cluster.

A cluster could for instance be a branch of the tree. Or it could be buffers matching some tags. See also

https://github.com/atlas-engineer/nyxt/issues/1654

How do we interactively define a cluster? Could have 2 commands, narrow-buffer-cluster and widen-buffer-cluster to echo Emacs narrowing commands.

Ambrevar avatar Jul 30 '21 11:07 Ambrevar

Sorry, just realized that you wrote the same thing with C-1, I had missed that in the original post! :p

Ambrevar avatar Jul 30 '21 11:07 Ambrevar

What about key-marking buffers? Press C-shift-1 to mark the current buffer to "1", then at any point you can press C-1 to switch back to this buffer. Same with C-2, etc. Would that be a good UI?

That would be a fabulous UI and completely solve my use-case.

Another (non mutually exclusive) option would be to create buffer clusters and have switch-buffer-next and switch-buffer-previous stick to this cluster.

Another good idea.

How do we interactively define a cluster?

That is an action on a buffer-source: just mark the buffers to cluster.

franburstall avatar Jul 30 '21 11:07 franburstall

What about key-marking buffers? Press C-shift-1 to mark the current buffer to "1", then at any point you can press C-1 to switch back to this buffer. Same with C-2, etc. Would that be a good UI?

"1" to "0" could be viewed as tags too, but be assigned to user-defined tagging commands (could be tags "1" to "0" with C-s-1 to C-s-0, but users could prefer categories like "work", "hobby", "reading", "dev", etc., pretty much like workspaces in a tiling WM). This would combine the "quick-tag from keybindings" feature, configurable domain tagging rules, while retaining the ability to set one-time tags on the go from the prompt when in need for a tag that was not predefined in config.

I also like the idea of commands to cycle through buffers within a cluster (or tag). That is what I had in mind with tags when the prompt is open (this allows combining multiple tags and cycling through the filtered matches), but for sure it would be good to also be able to define keys for switching tabs within the current-cluster when the prompt is not visible.

I don't see a trivial way to do assign a single cluster to a combination of tags at once unless there is a clear cluster-buffers command to invoke the prompt, filter buffers (or not) with the text input, and multi-select buffers that should be clustered together. But not sure if this would be necessary.

For single-tag clusters, it would not be necessary since buffers that share the same tag could automatically be clustered together (and buffers with multiple tags would be found in multiple clusters); this way switch-buffer-next-within-cluster and switch-buffer-previous-within-cluster could cycle within the current cluster without first needing to manually set clusters if buffers have been tagged. Or tags could also be mutually exclusive if things need to be kept simple; assigning one tag to an already tagged buffer would overwrite the previous tag, though that's more limiting.

Kabouik avatar Jul 30 '21 12:07 Kabouik

Should we view "0".."9" as tags though? Considering they've got to be unique, and that they may be defined per-window, I'm tempting to think that no, it "marks" should be different from tags.

If we forget about per-window marks for now, then it's doable to implement conflate the idea of marks and tags: when pressing C-1, Nyxt would simply prompt the list of all buffers tagged with "1". If there is just one, switch to it directly.

Thoughts?

Ambrevar avatar Jul 30 '21 13:07 Ambrevar

How would switch-buffer-next-within-cluster work if we allow multiple tags per buffer? Would it AND the tags?

The benefit of tags is that they compose. If we restrict ourselves to a single tag per buffer, then they are not really tags anymore but groups.

Ambrevar avatar Jul 30 '21 13:07 Ambrevar

That is an action on a buffer-source: just mark the buffers to cluster.

And then we could store the clusters in the window, a bit like marks?

Hmm, seems to be overlapping a lot with tags. Maybe clusters are just tags in the end.

Ambrevar avatar Jul 30 '21 13:07 Ambrevar

It would be great to find the most parcimonious system, with as few commands/concepts as possible for as many situations as possible to reduce the overlap.

The way I was seeing it, "0" to "9" are tags and it is up to the user to use them only once (for quick buffer switching with C-0 to C-9) or to group multiple clusters under the same digit, in which case the prompt lists the corresponding switch-buffer-suffix (suffixes being "0" to "9") and wait for user selection within those as you suggested, instead of directly switching. When buffer tiling (= window splitting) is a thing, then all matching buffers could be shown and tiled at once directly, optionally (perhaps with a keybinding variation to trigger tiling instead of showing the matching list in the prompt).

This is pretty much the behaviour of all tiling WMs I have used: you get 10 workspaces, to which you assign windows automatically with WM_CLASS rules or manually with keybindings and window manipulation. Then when you switch among workspaces, if only one window was assigned to the workspace, you see it maximized, else you see all windows therein (which in Nyxt could be both tiling buffers when the feature is implemented, or listing them in the prompt as you said above).

For switch-buffer-next-within-cluster, I am struggling too when thinking whether clusters should be synonyms of tags or would bring something useful if both concepts are orthogonal. If we go with a tag concept only, and set tags this way:

  • Buffer 1 dev perso
  • Buffer 2 dev work
  • Buffer 3 work reading
  • Buffer 4 kittens hobby

Then there is no way to switch-buffer-next-within-cluster among tags that are dev OR work, because switch-buffer-next-within-cluster could only cycle within unique tags. But since buffers can be assigned multiple tags, one could also invoke switch-buffer, input "dev OR work" (in a lispy way) to filter, and assign a new group1 tag to all results:

  • Buffer 1 dev perso group1
  • Buffer 2 dev work group1
  • Buffer 3 work reading group1
  • Buffer 4 kittens hobby

Then, if Nyxt can tell which tag has been used as a filter to switch to a new buffer in the first place (could it?), then the browser could use that initial tag to define the boundaries of switch-buffer-next-within-cluster. I don't know if that is clear, and maybe I didn't think it through.

Kabouik avatar Jul 30 '21 13:07 Kabouik

Thinking a little bit more about it, I doubt anyone would want to go through all those steps to set extra tags like group1 that are actually synonyms to a combination of more restrictive tags like dev and work. Plus when editing tags, group1 would not be tied to the more restrictive tags, so that's even more edits required to keep the thing tidy.

Finding a way to combine those tags without extra steps for switch-buffer-next-within-cluster to extend within dev OR work would be best. But again, if Nyxt can tell which tag(s) have been querried as filter for siwtch-buffer in the first place, then maybe it could just automatically recognize if "dev OR work" was used, or "dev AND work", and set boundaries accordingly for switch-buffer-next-within-cluster ?

Still dependent on using switch-buffer initially though. Jumping into a cluster of tags with a keybinding seems difficult with this.

Kabouik avatar Jul 30 '21 14:07 Kabouik

@Kabouik I like your analysis, I agree with all your points. I'll keep thinking about it and maybe propose an implementation soon, unless someone beats me to it of course :)

Ambrevar avatar Jul 30 '21 15:07 Ambrevar

I just had a look at Firefox' "tab containers". It seems to me that they offer the following features:

  • Contained tabs are visually different (there is a colored outline).
  • There can be only one container per tab.
  • Containers seem to use different local data (cookies, etc.).

And... that's it? Seems to be quite different from what we are trying to achieve here.

For the rest of this discussion, I propose to drop the term "cluster" and use "group" instead, it's more accessible.

So what are the use cases and features we would like from tags / groups?

  • switch-buffer-* should be able to restrict themselves to the designated group.
  • Same for delete-buffer, reload-buffers.
  • And what about search-buffers? jump-to-heading-buffers?

All in all, it seems that all command that leverage list-buffers could be impacted. With that in mind, what about modifying list-buffers so that it returns the list of buffers in the current group, if any, or all buffers otherwise (as before)? Then we are mostly done!

All that's left to do is defining and setting the groups.

  • Groups can be stored in browser (but what about per-window groups?).
  • They can be created with the make-buffer-group command which takes a Lispy tag expression as with the bookmarks in Nyxt 1.5. They are not persisted by default, but we can add a common-settings interface to add them to auto-config.lisp.
  • Tags can be added to buffers with tag-buffer. Tags are persisted and restored when Nyxt restarts.
  • "All known tags" are the collection of those found in all buffers as well as in all groups.
  • The user can set the current group with set-current-group. Then all list-buffers-based commands would restrict themselves to the current group.
  • C-1, C-2, etc. ~~would automatically set the first group in the list, respectively the second one, etc.~~ would set the current group to the group that's just made of tag 1, 2, etc. If the current buffer is not part of the new group, then switch to the most recent buffer of the new group. ~~This means that group ordering matters. Can we graphically set it? Maybe in make-buffer-group?~~ C-shift-1 would toggle the tag 1 of the current buffer. Same for C-shift-2, etc.
  • Last but not least, we would need a status area group indicator.

Thoughts?

EDIT: Clarified what C-1 does with regard to buffer switching.

Ambrevar avatar Jul 31 '21 07:07 Ambrevar

On C-1 etc: I would like these to be global rather than restricted to a group.

Use-case: have C-1 point to my mail buffer and be able to reach it with that single key-stroke wherever I am in nyxt.

This feels orthogonal to the groups idea and perhaps a bit like emacs registers: they should be quick to set and quick to jump to where quick means "very low number of keystrokes".

If one carries on the register analogy, only one buffer could be pointed to by a register at any time and that buffer could be changed at any time by simply overwriting. The whole UI would be C-S-n to set and C-n to jump. Very lightweight.

If you add the possibility to persist the registers then you have a lightweight version of "pinning tabs" from chromium.

franburstall avatar Jul 31 '21 10:07 franburstall

For pinning buffers, see https://github.com/atlas-engineer/nyxt/issues/1608. I don't know if we can conflate tags and pinned buffers. Thoughts?

On C-1 etc: I would like these to be global rather than restricted to a group.

I don't understand what you mean, can you rephrase?

I think my proposal allows you to achieve what you want. C-shift-1 could be bound to "add tag 1 to current buffer, remove tag 1 from any other buffer". Then C-1 would pop up the buffer with tag "1".

Does that make sense?

Ambrevar avatar Jul 31 '21 11:07 Ambrevar

For pinning buffers, see #1608. I don't know if we can conflate tags and pinned buffers. Thoughts?

OK: pinned means different things to different people. I don't mean pinned in the sense of #1608 but pinned as chromium does it: pinned tabs are placed at the head of the buffer-list in fixed order and so the first eight can be jumped to with C-1...C-8.

On C-1 etc: I would like these to be global rather than restricted to a group.

I don't understand what you mean, can you rephrase?

This was a reaction to yr proposal

  • C-1, C-2, etc. would automatically set the first group in the list, respectively the second one, etc. If the current buffer is not part of the new group, then switch to the most recent buffer of the new group. This means that group ordering matters. Can we graphically set it? Maybe in make-buffer-group?

This seems to suggest that C-1 would have a different meaning depending what group, if any, the current buffer is in. But I guess I misunderstood you because:

I think my proposal allows you to achieve what you want. C-shift-1 could be bound to "add tag 1 to current buffer, remove tag 1 from any other buffer". Then C-1 would pop up the buffer with tag "1".

Does that make sense?

This is exactly what I want!

Thank you for taking these concerns seriously!

franburstall avatar Jul 31 '21 13:07 franburstall

I am not familiar with tab containers in Firefox, but another extension that might be worth checking is Tree Style Tabs, which allows arranging tabs as trees (automatically or manually).

So what are the use cases and features we would like from tags / groups?

  1. switch-buffer-* should be able to restrict themselves to the designated group.
  2. Same for delete-buffer, reload-buffers.
  3. And what about search-buffers? jump-to-heading-buffers?

Yes to all, but the beyond-group commands should still be available of course. Maybe there could be a prefix keybinding to restrict all *-buffer commands to the current group?

Same with list-buffers, the per-window (beyond groups) command should take priority in my opinion, but a per-group variant with a prefix would be useful. I'm not a big fan of using a single command that would behave differently depending on whether there are defined groups or not, because I think it's less flexible and could be frustrating in some cases, but maybe I'm just pessimistic.

All that's left to do is defining and setting the groups.

  1. Groups can be stored in browser (but what about per-window groups?).
  2. They can be created with the make-buffer-group command which takes a Lispy tag expression as with the bookmarks in Nyxt 1.5. They are not persisted by default, but we can add a common-settings interface to add them to auto-config.lisp.
  3. Tags can be added to buffers with tag-buffer. Tags are persisted and restored when Nyxt restarts.
  4. "All known tags" are the collection of those found in all buffers as well as in all groups.
  5. The user can set the current group with set-current-group. Then all list-buffers-based commands would restrict themselves to the current group.
  6. C-1, C-2, etc. would set the current group to the group that's just made of tag 1, 2, etc. If the current buffer is not part of the new group, then switch to the most recent buffer of the new group. C-shift-1 would toggle the tag 1 of the current buffer. Same for C-shift-2, etc.
  7. Last but not least, we would need a status area group indicator.

I guess per-window groups wouldn't hurt but that's a comment from someone who doesn't use multiple windows.

If (3) "tags persist and are restored when Nyxt restarts" is confirmed, then maybe a clear-tags (or remove-tag-buffer or whatever) command accepting multiple selections would be useful. Not sure whether it should remove a single tag defined as a suffix to that command, or all tags at once (if no suffix provided maybe?). I imagine some poeple might want to set temporary tags sometimes, like "Urgent" that make no sense if permanent. Perhaps tags could also be combined with auto-mode to decide whether they are saved or not? Not sure, as I haven't fully mastered how auto-mode works yet.

(5) As said above, I would rather imagine a prefix to restrict commands to a group or not, but perhaps the added value wouldn't be worth it.

(6) If no tag 1 is currently set, then C-1 could prompt the user to select multiple buffers to tag (i.e., invoke tag-buffer and automatically use string 1, but wait for the user to select which buffers to tag) instead of just failing quietly to show the non-existent group 1. This is not the same as C-s-1 which would set tag 1 to the current buffer without offering multi selection.

(7) Good idea yup.

C-shift-1 could be bound to "add tag 1 to current buffer, remove tag 1 from any other buffer".

Hum, so C-s-1 would not just toggle tag 1 to the curent buffer, but also make it mutually exclusive with any other buffer? I see why this would be desirable, as it would allow quick-buffer-switching with C-1, but this goes against the idea of tags. Couldn't we just add tags to an unlimited number of buffers without making them mutually exclusive, and let the user decide and take care of whether multiple buffers share the same tag? It would allow the same thing and more without adding manual manipulations. If the users make sure they don't set the same tags more than once each, then C-1 to C-0 will act as quick buffer switching keybindings, and else if multiple buffers share tag 1 to 0, then the binding would show all matching buffers in the prompt. I think this is what I was describing in a previous post when comparing with tiling WMs, but maybe there are drawbacks I didn't see?

In my opinion, C-s-1 should just be a keybinding for tag-buffer followed by string 1 suffix and applied to the current buffer (i.e., without multiselection). Not providing the suffix directly should prompt the user for typing the string (tag) and for selecting which buffers to add it to. This way, it's not an extra command, it's just a shortcut for the 10 digit tags, which can be considered generic enough to be offered as keybindings in vanilla Nyxt. Then tag-buffer should work either with current buffer only if it comes with a tag suffix (1 here) or else invoke a buffer list for multiselection. Likewise, C-1 should be a keybinding for switch-buffer-tag, which should directly switch to the buffer containing the suffix tag filter (1 here, but similar keybindings could be used with the same command and more complex filters like "1" OR "2" or "work" AND "urgent"), or show the prompt with matching buffers if multiple buffers match the fillter.

If I am not wrong, this allows @franburstall to do what he wants as long as he makes sure he doesn't give the same digit tag to several buffers (but if he does, he can easily edit the matching buffers and remove some with C-s-1 on other buffers to toggle 1 off or with the opposite of tag-buffer), while avoiding making different commands for this use case and tagging use cases.

Kabouik avatar Aug 02 '21 12:08 Kabouik

If I am not wrong, this allows @franburstall to do what he wants as long as he makes sure he doesn't give the same digit tag to several buffers (but if he does, he can easily edit the matching buffers and remove some with C-s-1 on other buffers to toggle 1 off or with the opposite of tag-buffer), while avoiding making different commands for this use case and tagging use cases.

Not quite. It makes changing a buffer's numeric tag way more tedious. As I have said before, my use-case is orthogonal to the general story of groups or tags and is more like emacs registers. However, one can superimpose what I want on the tags infrastructure if there would be a remove-tags command that removed a given tag from all buffers. Given that, I could then roll my own.

franburstall avatar Aug 02 '21 16:08 franburstall

True, changing a buffer tag would indeed require an extra step with what I wrote above:

  1. C-s-1: buffer 1
  2. C-s-2: buffer 1 2
  3. C-s-1: buffer 2

Step 3 would not be necessary if C-s-2 removed all pre-existing tags from the current buffer. However, it would allow having several buffers with 2 (or any other tag with the same command structure, even words) and C-2's behaviour (do nothing, switch, show matching buffers in prompt or tiles) could depend on the number of matching buffers (0, 1, or more, respectively).

But I agree that there should be a remove-tag-buffer (remove only tag if suffixed with "tag", remove everything if suffixed with "*"), or an extra clear-tags-buffer to remove everything if this suffix system is not trivial to implement for remove-tag-buffer. From there, it would be straightforward to make a macro on a keybinding that first does remove-tag-buffer "*" on current buffer (or all buffers if configured that way) and then does tag-buffer "1" on current buffer, and this macro could even be provided with vanilla Nyxt, yet made with the same bricks as the tag system.

On 2021-08-02 18:52 Fran Burstall @.***> wrote:

If I am not wrong, this allows @franburstall to do what he wants as long as he makes sure he doesn't give the same digit tag to several buffers (but if he does, he can easily edit the matching buffers and remove some with C-s-1 on other buffers to toggle 1 off or with the opposite of tag-buffer), while avoiding making different commands for this use case and tagging use cases.

Not quite. It makes changing a buffer's numeric tag way more tedious. As I have said before, my use-case is orthogonal to the general story of groups or tags and is more like emacs registers.
However, one can superimpose what I want on the tags infrastructure if there would be a remove-tags command that removed a given tag from all buffers. Given that, I could then roll my own.

--
You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub: https://github.com/atlas-engineer/nyxt/issues/1695#issuecomment-891177 196

Kabouik avatar Aug 02 '21 19:08 Kabouik

@pdelfino @aartaka @jmercouris Any opinion on this? 3.0 could be a good time to re-think our buffer grouping / management!

Ambrevar avatar Jan 19 '22 15:01 Ambrevar

I tend to agree with the WM metaphor of @Kabouik here -- tags that can be freely assigned to any number of buffers, with buffers having 0 to many tags feel usful. If the tag-switching command refers to a tag assigned to only one buffer, then simply switch, otherwise prompt. Tag-removing commands can simply have multi-selection-p to remove several tags.

What I didn't see here is the idea of arbitrary key tags. It'd be nice to have C-x B w (where imaginary C-x B binding is imaginary switch-buffer-by-tag command and w is the tag key) to switch you to the "work" buffer(s). Relatively easy to implement, too. This will obviously strip us off the certainty that numeric tags give, but will give us more tags and non-duplicating keybindings.

switch-buffer-new-within-cluster and group-specific commands I didn't exactly understand, though. I feel like buffer-related commands should be global by default and group-local only if you invoke them in a certain way. Tag-based buffer switching is an exception there -- it should be easily accessible and fast to type.

Restoration of tagged buffers at startup feels similar to pinning. More so: it feels like superset of pinning -- you don't have one pinned group of buffers, you have several of those, restorable at startup! Sounds like an implicit API one can exploit for productivity :D

aartaka avatar Jan 20 '22 10:01 aartaka

I need more time to think about this. I'm not yet certain.

jmercouris avatar Jan 21 '22 04:01 jmercouris

Maybe it's a bit late to get this in 3.0. Unless someone has time to send a PR soon enough of course...

Ambrevar avatar May 30 '22 09:05 Ambrevar

I stumbled upon the River window manager today, which does use a tag system, and I think the way it was implemented could be useful to the discussion here: https://github.com/riverwm/river/wiki/How-tags-work

Kabouik avatar Oct 19 '22 09:10 Kabouik