bufler syntax for a browser subgroup
Table of Contents
Edits
- correction: “Buffler” is actually “Bufler”
- added updated groups section, and linked to my Firefox usage post. Added comments sections.
Discussion
Discussion can be had on this post at
- Reddit: https://www.reddit.com/r/emacs/comments/18omuu7/using_bufler_and_exwm_to_group_my_browser_windows/?utm_source=share&utm_medium=web2x&context=3
- Mastodon: https://qoto.org/@worldsendless/111625703559060442
Github issue text
This is associated with a Github issue.1
Note that this is with exwm, so Firefox buffers are first-class buffer citizens2. I used to have a single Firefox tab which contained my various social tabs with their particular settings. I decided that, in order to live a more tab-free lifestyle and maximize the benefits of exwm, I would pull those out. Ideally I could off-load that collection to Bufler to handle. But, though my catch-all Firefox setup in bufler has worked for ages, my desire to seperate a collection of Firefox tabs into their own subgroup is failing. So, two questions: Is such subgrouping possible? And, if so, what syntax do I need?
Here is my failing try:
(group
(name-match "*Firefox*" (rx bos "F:")) ;; this part has worked for a long time
(group-and "Mastodon" ;; is something wrong with my syntax?
(name-match (rx "Mastodon\|mstdn\|qoto"))))
Answer
Bufler author Alphapapa pointed out the simple syntax error with my use of rx, which I hadn’t realized is intended to convert sexp into regexp.
Well, you’re using
rx
, but you’ve got\|
in the string, which defeats the purpose of usingrx
(and it will escape those metacharacters). The point of using rx is being able to write the regexp as a sexp, like(rx (or "Mastodon" "mstdn" ...))
.
I didn’t realize that was the roll of rx and changed accordingly. With a little face change3 to make things a little more visible, here is my working code:
(setf bufler-groups
(bufler-defgroups
;;; other groups...
(group
(name-match "*Firefox*" (rx bos "F:"))
(group-and "Mastodon"
(name-match "Mastodon" (rx (or "Mastodon" "mstdn" "qoto"))))
)
;;; more other
)
Update: Fleshed-out Bufler Firefox groups
group
instead of group-and
or group-or
it gave me the grouping I wanted, particularly putting a catch-all group that would have all the Firefox buffers that didn’t fit one of the other categories.
(setf bufler-groups
(bufler-defgroups
(group
;; Subgroup collecting all named workspaces.
(auto-workspace))
(group
(mode-match "*w3m*" (rx "w3m")))
(group
(name-match "*Nightly Private Browsing" (rx "Private Browsing" eos)))
(group
(name-match "*Firefox*" (rx bos "F:"))
(group
(name-match "Federated" (rx
(or "Mastodon"
"mstdn"
"qoto"
"bookwyrm"
"discord"))))
(group
(name-match "Media" (rx
(or "spotify.com"
"piped"
"youtube.com"
"twitch"))))
(group
(name-match "Comms" (rx
(or "teams.microsoft"
"discord.com"
"zulipchat.com"))))
(group
(name-match "Web" ".*"))
)
(group (mode-match "*EXWM*" (rx bos "EXWM")))
(group
(group-or "Chat"
(mode-match "Telega" (rx bos "telega-"))))
(group
;; Subgroup collecting all `help-mode' and `info-mode' buffers.
(group-or "*Help/Info*"
(mode-match "*Help*" (rx bos "help-"))
(mode-match "*Info*" (rx bos "info-"))))
(group
;; Subgroup collecting all special buffers (i.e. ones that are not
;; file-backed), except `magit-status-mode' buffers (which are allowed to fall
;; through to other groups, so they end up grouped with their project buffers).
(group-and "*Special*"
(lambda (buffer)
(unless (or (funcall (mode-match "Magit" (rx bos "magit-status"))
buffer)
(funcall (mode-match "Dired" (rx bos "dired"))
buffer)
(funcall (auto-file) buffer))
"*Special*")))
(group
;; Subgroup collecting these "special special" buffers
;; separately for convenience.
(name-match "**Special**"
(rx bos "*" (or "Messages" "Warnings" "scratch" "Backtrace") "*")))
(group
;; Subgroup collecting all other Magit buffers, grouped by directory.
(mode-match "*Magit* (non-status)" (rx bos (or "magit" "forge") "-"))
(auto-directory))
;; Remaining special buffers are grouped automatically by mode.
(auto-mode))
;; All buffers under "~/.emacs.d" (or wherever it is).
(dir user-emacs-directory)
(group
;; Subgroup collecting buffers in `org-directory' (or "~/org" if
;; `org-directory' is not yet defined).
(dir (if (bound-and-true-p org-directory)
org-directory
"~/org"))
(group
;; Subgroup collecting indirect Org buffers, grouping them by file.
;; This is very useful when used with `org-tree-to-indirect-buffer'.
(auto-indirect)
(auto-file))
;; Group remaining buffers by whether they're file backed, then by mode.
(group-not "*special*" (auto-file))
(auto-mode))
(group
;; Subgroup collecting buffers in a projectile project.
(auto-projectile))
(group
;; Subgroup collecting buffers in a version-control project,
;; grouping them by directory.
(auto-project))
;; Group remaining buffers by directory, then major mode.
(auto-directory)
(auto-mode)))
Editing my Bufler setup for rapid feedback
As per the image above, it is easy and pleasant to update my bufler setup. I use a literate setup, so I manage my init file via orgmode. Then I have all my bufler settings in a single block, and I can just use C-c '
(org-edit-special)
and get a dedicated buffer of that code snippet, in the editing mode of that language (such as lisp). Once in that dedicated buffer, I make any changes and run M-x eval-buffer
and then switch to by open bufler listing, press g
to refresh, and my updated grouping is available.
Footnotes
1 I have been enjoying AlphaPapa’s Bufler for buffer management for a while https://github.com/alphapapa/bufler.el/issues/93 . Although I use it very plainly, it has excellent support for perspectives, tab bar, etc.
2 You can checkout how I made my firefox mostly tabless, for heightened emacsing: https://tech.toryanderson.com/2021/04/06/firefox-address-in-titles-for-exwm/
3 The face to change was found by running helpful-at-point and seeing that it was git-section-face
and then customizing until I found an acceptable color (saving in customizer would immediately update my bufler window, which was open at the same time), ending up with the following customization line (which, thanks to the customizer, I didn’t write; I just picked the color): (magit-section-highlight ((t (:extend t :background "dark blue"))))