• Stars
    star
    378
  • Rank 109,890 (Top 3 %)
  • Language
    Emacs Lisp
  • License
    GNU General Publi...
  • Created over 4 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A butler for your buffers. Group buffers into workspaces with programmable rules, and easily switch to and manipulate them.

Bufler.el

Bufler is like a butler for your buffers, presenting them to you in an organized way based on your instructions. The instructions are written as grouping rules in a simple language, allowing you to customize the way buffers are grouped. The default rules are designed to be generally useful, so you don’t have to write your own.

It also provides a workspace mode which allows frames to focus on buffers in certain groups. Since the groups are created automatically, the workspaces are created dynamically, rather than requiring you to put buffers in workspaces manually.

Screenshots

This screenshot shows bufler-list in the top window, and bufler-switch-buffer reading a buffer with completion in the bottom window. Note how the same, recursively grouped buffers are shown in both ways.

images/default-theme.png

This screenshot compares Bufler and Ibuffer showing the same buffers with the default settings. Note how Bufler provides collapsible sections to group and hide uninteresting buffers. It also allows commands to be applied to selected sections: for example, pressing k in this Bufler list would kill the buffers in the groups compilation-mode and completion-list-mode (and, of course, since it calls kill-buffer, any unsaved, file-backed buffers would ask to be saved first).

images/vs-ibuffer-doom-one.png

This screenshot shows Bufler Tabs Mode, which works with the new tab-bar-mode and tab-line-mode from Emacs 27. The tab-bar selects the workspace, and the tab-line selects a buffer in the current workspace.

images/workspace-tabs-mode-spacemacs-dark.png

Contents

Installation

If you’ve installed from MELPA, you’re done!

Quelpa

If you prefer, you may install with quelpa-use-package, like this:

(use-package bufler
  :quelpa (bufler :fetcher github :repo "alphapapa/bufler.el"
                  :files (:defaults (:exclude "helm-bufler.el"))))

To install the additional helm-bufler package, use:

(use-package helm-bufler
  :quelpa (helm-bufler :fetcher github :repo "alphapapa/bufler.el"
                       :files ("helm-bufler.el")))

Usage

Bufler provides four primary, user-facing features. They complement each other, but each one may be used independently.

  1. The command bufler shows a list of buffers grouped according to the defined grouping rules. It allows manipulation of buffers and groups of buffers.
  2. The command bufler-switch-buffer prompts for a buffer with completion and switches to the selected one. Buffers are presented by their “path” in the groups.
  3. The global minor mode bufler-mode allows each frame to have a “workspace,” which is a buffer group selected by the user. When the mode is active, the command bufler-switch-buffer presents only buffers from the current workspace (unless called with a prefix, in which case it shows all buffers), and the current workspace is displayed in the mode line and the frame’s title. Buffers can also be manually assigned to named workspaces.
  4. The global minor mode bufler-tabs-mode uses the new Emacs 27 tab-bar and tab-line features to display workspaces and buffers. The tab-bar shows top-level workspaces (and whatever the selected one is, even if not top-level), and the tab-line shows buffers from the current workspace.

Workflow

A workflow using Bufler could be something like this:

  1. Start Emacs.
  2. Activate bufler-mode.
  3. Open some buffers, find some files, etc.
  4. When you need to switch buffers, use M-x bufler-switch-buffer. The buffers are presented by group with their “outline paths,” which makes it easier to find the buffer you’re looking for, since they’re organized by project, directory, mode, etc.
  5. If you want to focus on a certain group’s buffers: a. Use C-u C-u M-x bufler-switch-buffer RET and select a buffer; or b. Use M-x bufler-workspace-frame-set RET and select a workspace; or c. Use M-x bufler RET and press f to focus the current frame on a workspace, or F to open a new frame focused on a workspace.
  6. The next time you call bufler-switch-buffer in that frame, it will only offer buffers from that frame’s buffer group, making it easier to find buffers related to the current project. (Of course, existing commands like switch-to-buffer are not affected; Bufler doesn’t interfere with other modes or commands.)
  7. When you need to switch to a buffer in a different group without changing the frame’s workspace, use C-u M-x bufler-switch-buffer to select from all buffers in all groups.
  8. When you need to kill or save a bunch of buffers at once, use bufler-list, put the cursor on a group you want to kill or save, and press k or s. If you want to see which buffers have unsaved (indicated with *) or uncommitted (indicated with edited) changes, you can browse through the list of buffers (enable bufler-vc-state to show VC state for each buffer; this is disabled by default because getting up-to-date information on a buffer’s VC state can be slow).

Then, you can write your own buffer-grouping rules to make them as simple or as complex as you like. They’re just Lisp functions, so you can do anything with them, but the DSL provided by the macro makes simple ones easy to write.

Commands

bufler
Show the Bufler buffer list.
bufler-mode
Enable the Bufler workspace mode, which allows each frame to have a chosen workspace from Bufler’s groups.
bufler-tabs-mode
Enable the Bufler workspace tabs mode, which uses tab-bar-mode and tab-line-mode from Emacs 27+ to display Bufler workspaces and buffers.
bufler-switch-buffer
Switch to a buffer selected from the frame’s workspace. Without any input, switch to the previous buffer. With prefix, select from all buffers. With two prefixes, also set the frame’s workspace.
bufler-workspace-focus-buffer
Set current frame’s workspace to the current buffer’s workspace.
bufler-workspace-frame-set
Set the frame’s workspace. Setting the workspace may be done automatically by bufler-switch-buffer, but this command may be used to set the workspace to a group containing other groups, after which bufler-switch-buffer will present buffers from the selected group and its subgroups.
bufler-workspace-buffer-set
Set the current buffer’s workspace name. With prefix, unset it. Note that, in order for a buffer to appear in a named workspace, the buffer must be matched by an auto-workspace group before any other group.

Bindings

In the Bufler buffer list, these keys are available (use C-h m to get the most up-to-date listing). They operate on all buffers in the section at point.

  • ? Show key bindings Hydra.
  • 1 – 4 Cycle section levels at point.
  • M-1 – M-4 Cycle top-level sections.
  • RET Switch to buffer.
  • SPC Peek at buffer, keeping focus in buffer list.
  • g Refresh Bufler list (with prefix, force updating buffers’ VC state and grouping).
  • f Set the current frame’s workspace to the group at point (with prefix, unset).
  • F Make a new frame whose workspace is the group at point.
  • N Add buffers to named workspace (with prefix, remove from it).
  • k Kill buffers.
  • s Save buffers.

Tips

  • bufler-switch-buffer works best when completion-styles includes the substring style. It also works well with helm-mode and ivy-mode.
  • Customize settings in the bufler group.

Defining groups

See the =bufler= info page to view this information in Emacs.

The Bufler groups definition is a list stored in variable bufler-groups. Each element of the list is a function which takes a buffer as its only argument and returns a string naming the group the buffer should be in at that level (or nil if the buffer should not be grouped by the function), or a list of such functions; each list may contain more such lists. Each buffer is matched against these functions in-order until the list of functions is exhausted. A list of functions defines a subgroup which short-circuits other groups at the same level, preventing further grouping outside of the subgroup’s functions. Ultimately, it’s functions all the way down.

If this explanation doesn’t seem clear, please see the examples. Once you get the hang of it, it’s powerful and flexible.

For convenience, the macro bufler-defgroups provides a concise vocabulary for defining groups. Note that the macro does not set the variable bufler-groups, it only expands a groups form, so you should use, e.g. (setf bufler-groups (bufler-defgroups ...)) to actually set the groups.

Default groups example

The default groups are defined like this:

(bufler-defgroups
  (group
   ;; Subgroup collecting all named workspaces.
   (auto-workspace))
  (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))
   ;; Subgroup for Helm buffers.
   (mode-match "*Helm*" (rx bos "helm-"))
   ;; 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))

Group types

The following group types are available in bufler-defgroups. Note that each one is expanded into a lambda, so they may also be called by funcall (see example above).

Meta types
These types compose multiple of the other types into a single group.
  • group (TYPE...) Define a subgroup matching given types, which short-circuits other groups at the same level.
  • group-not (NAME TYPE) Groups buffers which do not match the given type.
  • group-and (NAME TYPE...) Groups buffers which match all of the given types.
  • group-or (NAME TYPE...) Groups buffers which match any of the given types.
Auto types
These types automatically create groups for the buffer’s attribute of this type.
  • auto-directory Buffer’s directory.
  • auto-file Buffer’s file name.
  • auto-indirect Whether the buffer is indirect (e.g. a cloned indirect buffer).
  • auto-mode Buffer’s major mode.
  • auto-project Buffer’s version-control project directory according to project.el.
    • auto-parent-project Like auto-project, but if the buffer’s parent directory is in a different project, use that one instead. Useful for git worktrees, where auto-project would show each worktree as a separate project.
  • auto-projectile Buffer’s project as defined in the projectile package (if installed).
  • auto-special Whether the buffer is special (i.e. whether its name starts with *).
  • auto-tramp Whether the buffer is opened via Tramp.
  • auto-workspace The buffer’s named workspace, if any.
Regexp types
These types match a value against a buffer’s attribute and group buffers which match.
  • filename-match (NAME REGEXP) Match a regular expression against the buffer’s filename, if it has one.
  • name-match (NAME REGEXP) Match a regular expression against the buffer’s name.
  • mode-match (NAME REGEXP) Match a regular expression against the buffer’s major-mode.
Other types
  • dir (DIRS DEPTH) Groups buffers which match one of the given DIRS. DIRS may be one or a list of directory paths. DEPTH may be nil or a depth above which to produce subdirectory groups (a feature probably broken at the moment). See example above.
  • hidden Groups buffers which are hidden (i.e. whose names start with a space and do not visit a file).

Helm support

Bufler does not require nor depend on Helm, but because it uses completing-read, it requires no special configuration to work with helm-mode for selecting buffers.

To show Bufler’s grouped buffers in a Helm-specific command, a separate helm-bufler package is available, which includes helm-bufler-source, a Helm source that shows buffers in the current workspace (or when the Helm command is called with C-u, all buffers). It looks like this when showing all buffers:

images/helm-bufler.png

After installing the package (see installation instructions above), use it like this:

(helm :sources '(helm-bufler-source))

Ivy support

Bufler does not require nor depend on Ivy, but because it uses completing-read, Bufler requires no special configuration to work with ivy-mode for selecting buffers. For example, this shows bufler-switch-buffer with ivy-mode activated (in the spacemacs-dark theme):

images/ivy-mode-spacemacs-dark-theme.png

Prism support

Bufler does not require nor depend on Prism, but you can use Prism’s level faces with Bufler by using M-x customize-option RET bufler-face-prefix RET and choosing the Prism faces option. For example (showing an earlier version of the package, when it was called Sbuffer):

images/prism.png

Compared to Ibuffer

Bufler is primarily about grouping buffers automatically and dynamically, using smart, customizeable rules. While Ibuffer provides some powerful grouping features, they are restricted to single-level grouping, and they require extensive, manual configuration. Bufler offers recursive, multi-level grouping, and a set of default groups is provided which are designed to be generally useful. Bufler presents groups in bufler-list using the magit-section library, which allows groups and buffers to be toggled, marked, and operated on with commands.

Ibuffer groups must be manually and individually specified. So, for example, to group project A’s buffers into one group, and project B’s into another, Ibuffer requires the user to make a group for each project. Bufler provides a set of automatic grouping rules that create groups automatically. For example, with the rule (auto-project), Bufler would create one group for project A’s buffers and another for project B’s. When those projects’ buffers are closed, the groups are automatically removed.

Bufler also provides optional workspace features in the form of bufler-mode, which helps focus a frame on a group of buffers. When it’s active, the command bufler-switch-buffer presents buffers from that frame’s selected workspace; when called with a prefix argument, it presents all buffers, and then switches the frame’s workspace to the selected buffer’s group.

Of course, Ibuffer is a mature tool with many features, so Bufler doesn’t replace it completely. Bufler is a very young project.

Changelog

0.3-pre

Added

  • Group type auto-parent-project.
  • Option bufler-vc-remote, which controls the displaying of the version control state of remote files (default: off). (Fixes #41. Thanks to Tory S. Anderson for reporting.)
  • Option bufler-workspace-format-path-fn, which formats group paths for display in mode lines and frame titles (e.g. it may be customized to show just the last element).
  • Show an asterisk next to buffers with unsaved changes. (Thanks to Tatu Lahtela.)
  • Name and path columns optionally limit width to that defined in their customization options. (Thanks to Tory S. Anderson.)
  • Column Mode shows buffer’s major mode, sans -mode suffix.
  • More filtering options: bufler-filter-buffer-fns, bufler-workspace-switch-buffer-filter-fns, bufler-filter-buffer-modes, and bufler-filter-buffer-name-regexps. By default, more buffers will be hidden in bufler-list and bufler-switch-buffer, and filters may be disabled by calling those commands with universal prefix arguments.
  • Option bufler-list-display-buffer-action, which controls how the bufler-list buffer is displayed.
  • Option bufler-list-switch-buffer-action, which controls how buffers are displayed when switched to from the buffer list. (Fixes #76. Thanks to Julian M. Burgos, Tory S. Anderson, and jcalve for reporting.)
  • Option bufler-indent-per-level, which sets the indentation applied per level of depth.
  • Command bufler-sidebar displays the Bufler list in a side window.

Fixed

  • Option bufler-filter-buffer-modes had the wrong customization type.
  • Depend on at least version 2.1 of the map package (required for pcase macro expansion).

Changed

  • Don’t show *xref* buffers by default.
  • Command bufler-switch-buffer allows entering a non-existent buffer name to create a buffer and switch to it (like switch-to-buffer).

0.2

Project expanded and renamed from Sbuffer to Bufler.

0.1

First tagged release.

Credits

Development

Bufler bufler bufler bufler bufler bufler bufler bufler.

License

GPLv3

More Repositories

1

org-super-agenda

Supercharge your Org daily/weekly agenda by grouping items
Emacs Lisp
1,182
star
2

org-ql

An Org-mode query language, including search commands and saved views
Emacs Lisp
1,159
star
3

emacs-package-dev-handbook

An Emacs package development handbook. Built with Emacs, by Emacs package developers, for Emacs package developers.
JavaScript
987
star
4

magit-todos

Show source files' TODOs (and FIXMEs, etc) in Magit status buffer
Emacs Lisp
601
star
5

org-web-tools

View, capture, and archive Web pages in Org-mode
Emacs Lisp
519
star
6

org-sidebar

A helpful sidebar for Org mode
Shell
492
star
7

org-rifle

Rifle through your Org-mode buffers and acquire your target
Emacs Lisp
488
star
8

org-protocol-capture-html

Capture HTML from the browser selection into Emacs as org-mode content
Emacs Lisp
442
star
9

ement.el

Matrix client for Emacs
Emacs Lisp
354
star
10

unpackaged.el

A collection of useful Emacs Lisp code that isn't substantial enough to be packaged
Emacs Lisp
345
star
11

solarized-everything-css

A collection of Solarized user-stylesheets for...everything?
CSS
277
star
12

burly.el

Save and restore frames and windows with their buffers in Emacs
Emacs Lisp
252
star
13

matrix-client.el

A Matrix client for Emacs! (deprecated in favor of Ement.el)
Emacs Lisp
241
star
14

prism.el

Disperse Lisp forms (and other languages) into a spectrum of colors by depth
Emacs Lisp
228
star
15

org-graph-view

View Org buffers as a clickable, graphical mind-map
Emacs Lisp
190
star
16

pocket-reader.el

Emacs client for Pocket reading list (getpocket.com)
Emacs Lisp
188
star
17

yequake

Drop-down Emacs frames, like Yakuake
Emacs Lisp
175
star
18

ts.el

Emacs timestamp and date-time library
Emacs Lisp
159
star
19

dogears.el

Never lose your place in Emacs again
Emacs Lisp
154
star
20

with-emacs.sh

Script to easily run Emacs with specified configurations
Shell
142
star
21

makem.sh

Makefile-like script for building and testing Emacs Lisp packages
Shell
128
star
22

plz.el

An HTTP library for Emacs
Emacs Lisp
126
star
23

bucket

A bucket for your shell (like a set of registers, or a clipboard manager)
Shell
118
star
24

restic-runner

Configure and run Restic more easily
Shell
108
star
25

hammy.el

Programmable, interactive interval timers (e.g. for working/resting)
Emacs Lisp
103
star
26

org-sticky-header

Show off-screen Org heading at top of window
Emacs Lisp
103
star
27

alpha-org

A powerful Org configuration
Emacs Lisp
100
star
28

org-make-toc

Automatic tables of contents for Org files
Shell
83
star
29

taxy.el

Programmable taxonomical hierarchies for arbitrary objects
Emacs Lisp
82
star
30

transclusion-in-emacs

Resources about implementing transclusion in Emacs
79
star
31

topsy.el

Simple sticky header showing definition beyond top of window
Emacs Lisp
77
star
32

org-bookmark-heading

Emacs bookmark support for Org-mode
Emacs Lisp
75
star
33

snow.el

Let it snow in Emacs!
Emacs Lisp
72
star
34

org-now

Conveniently show current Org tasks in a sidebar window
Emacs Lisp
50
star
35

bashcaster

An actually simple screen recorder for Linux
Shell
48
star
36

org-recent-headings

Go to recently used Org headings
Shell
47
star
37

obvious.el

Who needs comments when the code is so obvious
Emacs Lisp
46
star
38

frame-purpose.el

Purpose-specific frames for Emacs
Emacs Lisp
46
star
39

org-almanac

Almanac for Org mode
43
star
40

mosey.el

Mosey around inside your Emacs buffer
Emacs Lisp
37
star
41

org-html-theme-darksun

A Solarized Dark version of the Bigblow Org HTML export theme
JavaScript
36
star
42

salv.el

Local minor mode to save a buffer when Emacs is idle
Emacs Lisp
33
star
43

sword-to-org

Convert Sword modules to Org-mode outlines
Emacs Lisp
33
star
44

org-auto-expand

Automatically expand certain Org headings
Shell
28
star
45

mangle

Mangle man pages to show just the parts you need (suitable for aliasing to "man")
Shell
26
star
46

magit.sh

Run Magit in a separate Emacs instance
Shell
26
star
47

org-notely

Pop to new Org headings for quick notetaking
Shell
26
star
48

scrollkeeper.el

Configurable scrolling commands with visual guidelines, for Emacs
Emacs Lisp
22
star
49

ap.el

A simple, Emacs Lisp-focused Emacs config
Emacs Lisp
21
star
50

highlight-function-calls

Highlight function/macro calls in Emacs
Emacs Lisp
21
star
51

org-quick-peek

Quick inline peeks at agenda items and linked nodes in Org-mode
Emacs Lisp
21
star
52

defrepeater.el

Easily define repeatable Emacs commands
Emacs Lisp
20
star
53

pocket-lib.el

Emacs library for the getpocket.com API
Emacs Lisp
19
star
54

org-pocket

Tools to use Pocket with Org-mode
Emacs Lisp
16
star
55

elexandria

Alexandria-like library for Emacs Lisp
Emacs Lisp
13
star
56

sword-converter

Convert SWORD modules to JSON and SQLite and search the converted files
Emacs Lisp
13
star
57

frecency.el

Library to sort items by "frecency" in Emacs
Emacs Lisp
11
star
58

chromatext.el

Apply color gradients to lines of text in Emacs (possibly increasing legibility)
Emacs Lisp
9
star
59

plamix

Mix together M3U playlists, optionally with a desired duration, outputting either a list of files to STDOUT, or writing an M3U playlist to a file
Python
9
star
60

pyza

A command-line/terminal/console Songza player, using VLC or MPD to play audio
Python
8
star
61

melpa-stats

Stats tools for MELPA
Emacs Lisp
6
star
62

org-books

Tools for books in Org-mode
Emacs Lisp
5
star
63

rubbish.py

WIP: A CLI to the XDG trash bin in Python
Python
5
star
64

tp.el

Emacs text-property convenience library
Emacs Lisp
5
star
65

org-search-goto

org-search-goto
Emacs Lisp
5
star
66

buffer-groups.el

A lightweight, automatic grouping rule-based buffer grouper and switcher
Emacs Lisp
5
star
67

ibuffer-auto-groups

Automatically make groups for ibuffer
Emacs Lisp
5
star
68

ampd-tools

A small collection of MPD-related tools
Python
4
star
69

reddit-emacs-css

CSS for /r/emacs
CSS
4
star
70

ox-elisp

Export Org buffers to Emacs Lisp comments
Emacs Lisp
3
star
71

dbg.el

Simple debugging macros
Emacs Lisp
3
star
72

tabtint

Firefox extension which tints Firefox tabs to match color of web page
JavaScript
3
star
73

ya-solarized.el

Yet Another Solarized theme for Emacs
Emacs Lisp
2
star
74

overwatch-formula76

A racing custom game type for Overwatch
C
2
star
75

overwatch-custom-games

A collection of custom games for Overwatch
Emacs Lisp
2
star
76

listen.el

Audio/music player for Emacs
Emacs Lisp
2
star
77

unsplash.hy

Hy
1
star
78

helm-swish

Like helm-swoop, but a little bit faster
Emacs Lisp
1
star
79

greek-hebrew-emacs

How to set up Emacs to easily type Greek and Hebrew
1
star
80

source-status-linker

Turns output of Source engine's status command into links to Steam user profiles
Python
1
star
81

github-solarized

A Solarized user stylesheet for GitHub made with Stylus
CSS
1
star
82

pentadactyl-tabmattach

JavaScript
1
star