Code Monkey home page Code Monkey logo

bufler.el's Introduction

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.
  • 14 Cycle section levels at point.
  • M-1M-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.4-pre

This release includes additional support for Emacs’s tab-bar-mode. Basically, commands and features that formerly acted on the current frame now act on the current tab when tab-bar-mode is active, otherwise on the current frame.

Notably, these changes are also designed to facilitate integration with Burly’s burly-tabs-mode (e.g. when a Burly bookmark is opened in a tab-bar tab, the tab’s Bufler workspace can be set to the workspace containing the buffer, so that bufler-switch-buffer automatically offers buffers relevant to the tab).

Note as well that the existing bufler-workspace-workspaces-as-tabs-mode overrides some aspects of Emacs’s tab-bar-mode and tab-line-mode; this functionality is still somewhat experimental and may not suit every user’s taste. But while that mode may remain disabled, Bufler’s other features are still useful with standard tab-bar-mode. (Yes, all these names and modes and features do get confusing. The term “workspaces” is vague, encompassing a variety of ideas envisioned by a range of users. Bufler’s implementation is just one iteration of the concept.)

Additions

  • Command bufler-workspace-set sets the workspace of the current tab-bar tab or frame.
  • Option bufler-workspace-switch-buffer-and-tab (enabled by default) automatically switches to a buffer’s workspace’s tab, if it has one, when using bufler-switch-buffer. (This tries to solve the age-old problem of buffers not “staying in their workspace.”)
  • Commands bufler-workspace-open and bufler-workspace-save. These open and save workspaces using Burly as a backend (which is now a dependency). (This is basically like calling burly-open-bookmark and burly-bookmark-windows, but integrating some bufler-workspace features automatically.)
  • Option bufler-workspace-prefix-abbreviation, which abbreviates workspace names in tab/frame names.
  • Option bufler-switch-buffer-include-recent-buffers includes recently shown buffers in the bufler-switch-buffer command’s list of buffers.

Changes

  • Command bufler-workspace-focus-buffer sets the workspace of the current tab-bar tab or frame to the current buffer’s workspace.
  • Command bufler-workspace-switch-buffer offers buffers from the workspace of the current tab-bar tab or frame.
  • Mode bufler-workspace-mode’s mode-line lighter shows the path of the current tab-bar tab or frame.

Fixes

  • The dir buffer group uses the base buffer’s directory for indirect buffers.
  • When testing whether two directories are related, both the paths as-given and the canonicalized paths are compared (so that if a subdirectory is a symlink to a directory outside the parent directory, it will still be considered related).

0.3

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.
  • Project metadata cache (because the project-current function can be slow when called for many paths in rapid succession, as when many buffers are open).

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).
  • Columns’ max-width options. (Fixes #79. Thanks to Tory S. Anderson for reporting.)

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

bufler.el's People

Contributors

alphapapa avatar basil-conto avatar daviwil avatar gonewest818 avatar lerouxrgd avatar seblemaguer avatar worldsendless avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

bufler.el's Issues

Consider option to not refresh VC state of remote buffers

I'm enjoying buffler very much; thanks!

Tramp is a core part of my day-to-day work, including tramp login a sudo. However, while doing that, I find that pressing C-x b (bufler-switch-buffer) apparently re-logs into or renews my buffers every time so I have lengthy pauses while it does:

Tramp: Found remote shell prompt on ‘yvbeta’ Tramp: Opening connection for root@yvbeta using sudo…done

every single time. Is there anything I can do about this so I can keep using buffler while in my remote Tramp workflows without this lag?

Emacs turns unresponsive with a long delay when killing buffer with a large number of buffers open

When I kill a buffer with *bufler* in any section and when a large number of buffers are open; more than 700 in the present case; there's a long delay and emacs turns unresponsive. A quick profiler report suggests that bufler-group-tree is consuming a lot of CPU. I'm hypothesizing that it's just updating the entire *bufler* buffer which seems overkill for each kill operation especially if it's a single file. Perhaps some caching and update of only the corresponding section can be done?

helm-bufler: "--debug-init" causes "void-function helm-make-source" backtrace

With helm-bufler package installed, I get the below error early on in initialization.

  • Error is when package system is getting set up; it is earlier than the `use-package' calls for helm, helm sub-packages, bufler, helm-bufler, etc.
  • Error happens even when I comment out the `use-package' block for helm-bufler. Only goes away when I delete the helm-bufler package from my melpa package folder.

The error only happens with '--debug-init'. If I call runemacs.exe without that flag, it starts fine.

Platform: Windows 7 and Windows 10
Version: GNU Emacs 26.3 (build 1, x86_64-w64-mingw32) of 2019-08-29
Helm: 20200506.729
Bufler: 20200409.1253
Helm-Bufler: 20200409.1253

Issue appeared when helm-bufler was split off from bufler - I did not have a problem with helm-bufler when it was part of the bufler package. Circa this commit's date: cole-brown/.emacs.d@51cf9dd

Debugger entered--Lisp error: (void-function helm-make-source)
  (helm-make-source "Bufler's workspace buffers" (quote helm-source-sync) :header-name (function (lambda (_name) (concat "Bufler" (if current-prefix-arg nil (concat ": " (bufler-format-path (frame-parameter nil ...))))))) :candidates (function (lambda nil (let* ((bufler-vc-state nil) (group-path (if current-prefix-arg nil (if ... ... ...)))) (bufler-buffer-alist-at group-path)))) :action (cons (cons "Switch to buffer with Bufler" (quote helm-bufler-switch-buffer)) helm-type-buffer-actions))
  (defvar helm-bufler-source (helm-make-source "Bufler's workspace buffers" (quote helm-source-sync) :header-name (function (lambda (_name) (concat "Bufler" (if current-prefix-arg nil (concat ": " (bufler-format-path ...)))))) :candidates (function (lambda nil (let* ((bufler-vc-state nil) (group-path (if current-prefix-arg nil ...))) (bufler-buffer-alist-at group-path)))) :action (cons (cons "Switch to buffer with Bufler" (quote helm-bufler-switch-buffer)) helm-type-buffer-actions)) "Helm source for `bufler'.")
  eval-buffer(#<buffer  *load*-623938> nil "c:/home/cole/.emacs.d/packages/elpa/helm-bufler-20200409.1253/helm-bufler-autoloads.el" nil t)  ; Reading at buffer position 981
  load-with-code-conversion("c:/home/cole/.emacs.d/packages/elpa/helm-bufler-20200409.1253/helm-bufler-autoloads.el" "c:/home/cole/.emacs.d/packages/elpa/helm-bufler-20200409.1253/helm-bufler-autoloads.el" nil t)
  load("c:/home/cole/.emacs.d/packages/elpa/helm-bufler-20200409.1253/helm-bufler-autoloads" nil t)
  package--activate-autoloads-and-load-path(#s(package-desc :name helm-bufler :version (20200409 1253) :summary "Helm source for Bufler" :reqs ((emacs (26 3)) (bufler (0 2 -1)) (helm (1 9 4))) :kind nil :archive nil :dir "c:/home/cole/.emacs.d/packages/elpa/helm-bufler-20200409.1253" :extras ((:url . "https://github.com/alphapapa/bufler.el") (:maintainer "Adam Porter" . "[email protected]") (:authors ("Adam Porter" . "[email protected]")) (:keywords "convenience") (:commit . "b2b260e4f9e8ba76bb8b4d71344c7b75e05ac44f")) :signed nil))
  package--load-files-for-activation(#s(package-desc :name helm-bufler :version (20200409 1253) :summary "Helm source for Bufler" :reqs ((emacs (26 3)) (bufler (0 2 -1)) (helm (1 9 4))) :kind nil :archive nil :dir "c:/home/cole/.emacs.d/packages/elpa/helm-bufler-20200409.1253" :extras ((:url . "https://github.com/alphapapa/bufler.el") (:maintainer "Adam Porter" . "[email protected]") (:authors ("Adam Porter" . "[email protected]")) (:keywords "convenience") (:commit . "b2b260e4f9e8ba76bb8b4d71344c7b75e05ac44f")) :signed nil) nil)
  package-activate-1(#s(package-desc :name helm-bufler :version (20200409 1253) :summary "Helm source for Bufler" :reqs ((emacs (26 3)) (bufler (0 2 -1)) (helm (1 9 4))) :kind nil :archive nil :dir "c:/home/cole/.emacs.d/packages/elpa/helm-bufler-20200409.1253" :extras ((:url . "https://github.com/alphapapa/bufler.el") (:maintainer "Adam Porter" . "[email protected]") (:authors ("Adam Porter" . "[email protected]")) (:keywords "convenience") (:commit . "b2b260e4f9e8ba76bb8b4d71344c7b75e05ac44f")) :signed nil) nil deps)
  package-activate(helm-bufler)
  package-initialize()
  eval-buffer(#<buffer  *load*-808373> nil "c:/home/cole/.emacs.d/personal/init/boot/bootstrap-package.el" nil t)  ; Reading at buffer position 4011
  load-with-code-conversion("c:/home/cole/.emacs.d/personal/init/boot/bootstrap-package.el" "c:/home/cole/.emacs.d/personal/init/boot/bootstrap-package.el" nil t)
  require(bootstrap-package nil nil)
  (prog1 (require symbol filename noerror) (if (null filename) (progn (let* ((require-name (symbol-name symbol)) (secret-name (format spydez/require/piggyback-format require-name)) (secret-symbol (intern secret-name)) (time-start-secret (current-time))) (if (locate-library secret-name) (progn (mis/init/sequence (mis/init/get-indent ... spydez/require/recursion-level) nil "(require '%s)" secret-symbol) (require secret-symbol nil (quote noerror)) (mis/init/sequence (mis/init/get-indent ... spydez/require/recursion-level) (quote left) "(require '%s)...done (%s)" secret-symbol (format "%.3f seconds" ...))))))) (mis/init/sequence (mis/init/get-indent (quote require) (1- spydez/require/recursion-level)) (quote left) "(require '%s)...done (%s)" symbol (format "%.3f seconds" (float-time (time-subtract (current-time) time-start)))))
  (let ((spydez/require/recursion-level (1+ spydez/require/recursion-level))) (prog1 (require symbol filename noerror) (if (null filename) (progn (let* ((require-name (symbol-name symbol)) (secret-name (format spydez/require/piggyback-format require-name)) (secret-symbol (intern secret-name)) (time-start-secret (current-time))) (if (locate-library secret-name) (progn (mis/init/sequence ... nil "(require '%s)" secret-symbol) (require secret-symbol nil ...) (mis/init/sequence ... ... "(require '%s)...done (%s)" secret-symbol ...)))))) (mis/init/sequence (mis/init/get-indent (quote require) (1- spydez/require/recursion-level)) (quote left) "(require '%s)...done (%s)" symbol (format "%.3f seconds" (float-time (time-subtract (current-time) time-start))))))
  (let ((time-start (current-time))) (mis/init/sequence (mis/init/get-indent (quote require) spydez/require/recursion-level) nil "(require '%s)" symbol) (let ((spydez/require/recursion-level (1+ spydez/require/recursion-level))) (prog1 (require symbol filename noerror) (if (null filename) (progn (let* ((require-name ...) (secret-name ...) (secret-symbol ...) (time-start-secret ...)) (if (locate-library secret-name) (progn ... ... ...))))) (mis/init/sequence (mis/init/get-indent (quote require) (1- spydez/require/recursion-level)) (quote left) "(require '%s)...done (%s)" symbol (format "%.3f seconds" (float-time (time-subtract (current-time) time-start)))))))
  spydez/require(bootstrap-package)
  eval-buffer(#<buffer  *load*> nil "c:/home/cole/.emacs.d/init.el" nil t)  ; Reading at buffer position 23097
  load-with-code-conversion("c:/home/cole/.emacs.d/init.el" "c:/home/cole/.emacs.d/init.el" t t)
  load("c:/home/cole/.emacs.d/init" t t)
  #f(compiled-function () #<bytecode 0x1000baab9>)()
  command-line()
  normal-top-level()

Programmatically switch frame's workspace

I just tried bufler, and it seems extremely like what I want: A way to change/restrict "what I'm working on" based on projects I'm in. I set it up to automatically group by project.el projects via auto-project, and I have a shortcut that opens a magit repository; now I would like to set the frame's workspace to the project-inferred one whenever I use that shortcut.

Unfortunately, I could not find a way to do it - the docs for bufler-workspace-frame-set mention a "path", but passing in the project entry from bufler-buffers doesn't seem to do it, and neither does just passing the workspace name "Project: /Users/asf/Hacks/kleinhirn" - that creates an empty workspace with no buffers in it. So, my questions are:

  • What shape should the path argument have?
  • How can I construct one from the current buffer (which already is in the right workspace, afaict)?

Thanks in advance!

defvar: Symbol’s value as variable is void: magit-section-mode-map

I get this error on M-x bufler:

defvar: Symbol’s value as variable is void: magit-section-mode-map

I get the same error with all M-x bufler* commands. buffer and buffer run fine. Magit also runs fine.

I see that magit-section version 2.90.1 was installed as a dependency in the folder elpa/magit-section-2.90.1/magit-section.

Magit also has the same map file installed under elpa/magit-2.90.1/magit-section.

My config is a one-liner:

(use-package 'bafler :ensure t)

I'm running compiled Emacs from the latest master trunk.

===============================================
Addendum: Just ran toggle on error and trapped this error:

Debugger entered--Lisp error: (void-variable magit-section-mode-map)
  byte-code("\301 \302\1\10\"\210\303\1\304\305#\210\303\1\306\307#\210\303\1\310\311#\210\303\1\312\313#\210\303\1\314\315#\210\303\1\316\317#\210\303\1\320\321#\210\303..." [magit-section-mode-map make-sparse-keymap set-keymap-parent define-key "?" hydra:bufler/body "g" bufler "f" bufler-list-group-frame "F" bufler-list-group-make-frame "N" bufler-list-buffer-name-workspace "k" bufler-list-buffer-kill "s" bufler-list-buffer-save "\15" bufler-list-buffer-switch " " bufler-list-buffer-peek] 5)
  (defvar bufler-list-mode-map (byte-code "\301 \302\1\10\"\210\303\1\304\305#\210\303\1\306\307#\210\303\1\310\311#\210\303\1\312\313#\210\303\1\314\315#\210\303\1\316\317#\210\303\1\320\321#\210\303..." [magit-section-mode-map make-sparse-keymap set-keymap-parent define-key "?" hydra:bufler/body "g" bufler "f" bufler-list-group-frame "F" bufler-list-group-make-frame "N" bufler-list-buffer-name-workspace "k" bufler-list-buffer-kill "s" bufler-list-buffer-save "\15" bufler-list-buffer-switch " " bufler-list-buffer-peek] 5))
  autoload-do-load((autoload "bufler" "Show Bufler's list.\nWith prefix argument FORCE-REF..." t nil) bufler)
  command-execute(bufler record)
  execute-extended-command(nil "bufler" #("buf\ntoggle-debug-on-error\nbufler\nibuffer-list-buff..." 3 4 (read-only t) 4 13 (read-only t face selectrum-current-candidate) 13 15 (read-only t face (selectrum-primary-highlight selectrum-current-candidate)) 15 25 (read-only t face selectrum-current-candidate) 25 26 (read-only t) 26 28 (read-only t face selectrum-primary-highlight) 28 34 (read-only t) 34 36 (read-only t face selectrum-primary-highlight) 36 54 (read-only t) 54 56 (read-only t face selectrum-primary-highlight) 56 75 (read-only t) 75 77 (read-only t face selectrum-primary-highlight) 77 93 (read-only t) 93 95 (read-only t face selectrum-primary-highlight) 95 106 (read-only t) 106 108 (read-only t face selectrum-primary-highlight) ...))
  funcall-interactively(execute-extended-command nil "bufler" #("buf\ntoggle-debug-on-error\nbufler\nibuffer-list-buff..." 3 4 (read-only t) 4 13 (read-only t face selectrum-current-candidate) 13 15 (read-only t face (selectrum-primary-highlight selectrum-current-candidate)) 15 25 (read-only t face selectrum-current-candidate) 25 26 (read-only t) 26 28 (read-only t face selectrum-primary-highlight) 28 34 (read-only t) 34 36 (read-only t face selectrum-primary-highlight) 36 54 (read-only t) 54 56 (read-only t face selectrum-primary-highlight) 56 75 (read-only t) 75 77 (read-only t face selectrum-primary-highlight) 77 93 (read-only t) 93 95 (read-only t face selectrum-primary-highlight) 95 106 (read-only t) 106 108 (read-only t face selectrum-primary-highlight) ...))
  #<subr call-interactively>(execute-extended-command nil nil)
  apply(#<subr call-interactively> execute-extended-command (nil nil))
  (let ((ido-cr+-current-command command)) (apply orig-fun command args))
  call-interactively@ido-cr+-record-current-command(#<subr call-interactively> execute-extended-command nil nil)
  apply(call-interactively@ido-cr+-record-current-command #<subr call-interactively> (execute-extended-command nil nil))
  call-interactively(execute-extended-command nil nil)
  command-execute(execute-extended-command)

"Function provided is already compiled [3 times]"

I don't think this is affecting the behavior of anything, just a message I get on start-up when loading bufler from my init.el. This happens without any customiztion of bufler as well.
Here's a backtrace:

  message("Function %s is already compiled" "provided")
  #f(compiled-function (form) #<bytecode -0x11a371bd1ff14045>)(#f(compiled-function (x) #<bytecode 0x86bd1c1a92be51e>))
  byte-compile(#f(compiled-function (x) #<bytecode 0x86bd1c1a92be51e>))
  bufler-or("*Help/Info*" #f(compiled-function (&rest args2) #<bytecode 0x13d4cecbe5232542>) #f(compiled-function (&rest args2) #<bytecode 0x13d491cabfe9f542>))
  #f(compiled-function () #<bytecode 0x1e067a0e48bc8306>)()
  funcall(#f(compiled-function () #<bytecode 0x1e067a0e48bc8306>))
  eval((funcall #'#f(compiled-function () #<bytecode 0x1e067a0e48bc8306>)))
  custom-initialize-reset(bufler-groups (funcall #'#f(compiled-function () #<bytecode 0x1e067a0e48bc8306>)))
  custom-declare-variable(bufler-groups (funcall #'#f(compiled-function () #<bytecode 0x1e067a0e48bc8306>)) "List of grouping functions recursively applied to ..." :type (repeat (or function list)))
  byte-code("\300\301\302\303#\304\305\306\307\310DD\311\312\313%\210\314\315!\207" [function-put bufler-defgroups lisp-indent-function defun custom-declare-variable bufler-groups funcall function #f(compiled-function () #<bytecode 0x1e067a0e48bc8306>) "List of grouping functions recursively applied to ..." :type (repeat (or function list)) provide bufler] 7)
  require(bufler nil nil)

Is this intended or is there a way to silence it on my end?

Newer version of map library is required for pcase expansion

I installed bufler and I saw the given message out of the box when I run M-x bufler. What am I doing wrong?

(Edit: the message - no longer in the subject - was "Symbol's value as variable is void: max-width")

I use straight and use-package. The bufler config is just

(use-package bufler
  :bind (("C-x C-b" . bufler)))

I see the same behavior when starting in a clean emacs:

  • $ emacs -Q
  • M-x load-file RET ~/.emacs.d/straight/repos/straight.el/bootstrap.el RET
  • M-x straight-use-package RET bufler RET
  • M-x bufler

I appear to have the latest version (from the repo that straight downloads):

17:21:54 $ git describe
0.2-50-g3017104

Here is the backtrace that I see:

Debugger entered--Lisp error: (void-variable max-width)
  (cons max-width (cons max-width-docstring '(:type '(choice (integer :tag "Maximum width") (const :tag "Unlimited width" nil)))))
  (cons max-width-variable (cons max-width (cons max-width-docstring '(:type '(choice (integer :tag "Maximum width") (const :tag "Unlimited width" nil))))))
  (cons 'defcustom (cons max-width-variable (cons max-width (cons max-width-docstring '(:type '(choice ... ...))))))
  (progn (cons 'defcustom (cons max-width-variable (cons max-width (cons max-width-docstring '(:type '...))))))
  (if (plist-member plist :max-width) (progn (cons 'defcustom (cons max-width-variable (cons max-width (cons max-width-docstring '(:type ...)))))))
  (list 'progn (if (plist-member plist :max-width) (progn (cons 'defcustom (cons max-width-variable (cons max-width (cons max-width-docstring '...)))))) (list 'defun fn-name '(buffer depth) (cons 'if-let (cons (list (list 'string (cons 'progn body))) (cons (cons 'progn (cons (if max-width ...) (cons ... ...))) '(""))))) (list 'setf (list 'map-elt 'bufler-column-format-fns name) (list 'function fn-name)))
  (let* ((max-width-variable (intern (concat "bufler-column-" name "-max-width"))) (max-width-docstring (format "Maximum width of the %s column." name))) (list 'progn (if (plist-member plist :max-width) (progn (cons 'defcustom (cons max-width-variable (cons max-width (cons max-width-docstring ...)))))) (list 'defun fn-name '(buffer depth) (cons 'if-let (cons (list (list 'string (cons ... body))) (cons (cons 'progn (cons ... ...)) '(""))))) (list 'setf (list 'map-elt 'bufler-column-format-fns name) (list 'function fn-name))))
  (progn (let* ((max-width-variable (intern (concat "bufler-column-" name "-max-width"))) (max-width-docstring (format "Maximum width of the %s column." name))) (list 'progn (if (plist-member plist :max-width) (progn (cons 'defcustom (cons max-width-variable (cons max-width ...))))) (list 'defun fn-name '(buffer depth) (cons 'if-let (cons (list (list ... ...)) (cons (cons ... ...) '...)))) (list 'setf (list 'map-elt 'bufler-column-format-fns name) (list 'function fn-name)))))
  (let* ((fn-name (intern (concat "bufler-column-format-" (downcase name)))) (x26 (map-elt plist ':face)) (x27 (map-elt plist ':max-width))) (progn (let* ((max-width-variable (intern (concat "bufler-column-" name "-max-width"))) (max-width-docstring (format "Maximum width of the %s column." name))) (list 'progn (if (plist-member plist :max-width) (progn (cons 'defcustom (cons max-width-variable ...)))) (list 'defun fn-name '(buffer depth) (cons 'if-let (cons (list ...) (cons ... ...)))) (list 'setf (list 'map-elt 'bufler-column-format-fns name) (list 'function fn-name))))))
  (closure (cl-struct-bufler-group-tags bufler-groups t) (name plist &rest body) "Define a column formatting function with NAME.\nNAM..." (progn (or (stringp name) (signal 'wrong-type-argument (list 'string name 'name))) nil) (let* ((fn-name (intern (concat "bufler-column-format-" (downcase name)))) (x26 (map-elt plist ':face)) (x27 (map-elt plist ':max-width))) (progn (let* ((max-width-variable (intern ...)) (max-width-docstring (format "Maximum width of the %s column." name))) (list 'progn (if (plist-member plist :max-width) (progn ...)) (list 'defun fn-name '... (cons ... ...)) (list 'setf (list ... ... name) (list ... fn-name)))))))("Name" (:max-width nil) (let ((indentation (make-string (* 2 depth) 32)) (mode-annotation (when (cl-loop for fn in bufler-buffer-mode-annotate-preds thereis (funcall fn buffer)) (propertize (concat (replace-regexp-in-string ... "" ... t t) " ") 'face 'bufler-mode))) (buffer-name (buffer-name buffer)) (modified (when (and (buffer-file-name buffer) (buffer-modified-p buffer)) (propertize bufler-column-name-modified-buffer-sigil 'face 'font-lock-warning-face)))) (concat indentation mode-annotation buffer-name modified)))
  (bufler-define-column "Name" (:max-width nil) (let ((indentation (make-string (* 2 depth) 32)) (mode-annotation (when (cl-loop for fn in bufler-buffer-mode-annotate-preds thereis (funcall fn buffer)) (propertize (concat (replace-regexp-in-string ... "" ... t t) " ") 'face 'bufler-mode))) (buffer-name (buffer-name buffer)) (modified (when (and (buffer-file-name buffer) (buffer-modified-p buffer)) (propertize bufler-column-name-modified-buffer-sigil 'face 'font-lock-warning-face)))) (concat indentation mode-annotation buffer-name modified)))
  eval-buffer(#<buffer  *load*> nil "/Users/rory/.emacs.d/straight/build/bufler/bufler...." nil t)  ; Reading at buffer position 35354
  load-with-code-conversion("/Users/rory/.emacs.d/straight/build/bufler/bufler...." "/Users/rory/.emacs.d/straight/build/bufler/bufler...." nil t)
  autoload-do-load((autoload "bufler" "Show Bufler's list.\nWith prefix argument ARG, forc..." t nil) bufler)
  command-execute(bufler record)
  execute-extended-command(nil "bufler" "bufler")
  funcall-interactively(execute-extended-command nil "bufler" "bufler")
  call-interactively(execute-extended-command nil nil)
  command-execute(execute-extended-command)

Improve window management for bufler-list

I normally run a full-screen Emacs with a vertical split (C-x 3). When I start M-x bufler in this environment, it reuses one of the existing windows (this may be due to customization, but I don't think so; it looks like bufler uses pop-to-buffer, which uses display-buffer, which is customizable but doesn't seem to be customized in my installation). When I select a buffer with bufler-list-buffer-switch, bufler calls delete-window on this window, which is not what I want.

I think that delete window should either be optional (e.g., (defcustom bufler-delete-window-on-switch) or (and I think this is more likely, but also probably more controversial) the switch command should simply be redefined as something like:

(bufler-define-buffer-command switch "Switch to buffer."
  (lambda (buffer)
    (pop-to-buffer-same-window buffer)
  :refresh-p nil)

I note that there is even a comment in the switch command noting that it's difficult to "get it right" under the current regime. For me, that's probably an indication that the default behavior is doing too much, and it should either be replaced by a user-defined callback or something that simply uses the built-in Emacs window management along with the user's configured preferences.

There may even be an argument that pop-to-buffer is the right function, but I don't think so; I think the user would expect *Bufler* to be replaced with the selected buffer.

This is a low priority report for me; I have defined a bufler command show which is exactly the above, and the problem is "fixed" from my perspective. I am reporting it only because it was a surprising behavior to me, and I thought you may wish to know about it. (Both buffer-list and ibuffer behave as expected in this fashion, although bufler is clearly better in other ways!)

[suggestion] pop up buffer and focus on it

When I use the shortcut "RET" on a buffer, it opens it in another window but the focus is staying on the bufler buffer (that is fun to write :D).

I would suggest having 2 shortcuts:

  • RET = open and change the focus to the new window
  • C-RET= open the buffer but keep the focus into bufler

bufler-filter-buffer-modes has wrong customization type

@@ -165,7 +165,7 @@ must be called to get up-to-date results."
                      magit-diff-mode magit-process-mode magit-revision-mode magit-section-mode
                      special-mode timer-list-mode)
   "List of major modes whose buffers are not shown by default."
-  :type '(repeat string))
+  :type '(repeat symbol))
 
 (defcustom bufler-filter-buffer-name-regexps
   (list (rx "*Compile-Log*") (rx "*Disabled Command*")

native-comp problems with bufler tab-bar functionality

i can't quite get the tab-bar functions to work. i use doom emacs and i've removed as many references to its own +workspaces concept as i can, but i still can't quite get bufler to work. here's the stack track i get when running (tab-bar-new-tab) or (bufler-workspace-tabs-mode). attempting to toggle the frame's tab bar doesn't work with either (toggle-frame-tab-bar) or by running (bufler-workspace-mode) twice.

Debugger entered--Lisp error: (invalid-function ((&plist :name :path) workspace))
  ((&plist :name :path) workspace)()
  #f(compiled-function (workspace &optional type) #<bytecode -0x3c3eaae35942352>)((:name ("*Special*") :path ("*Special*")))
  mapcar(#f(compiled-function (workspace &optional type) #<bytecode -0x3c3eaae35942352>) ((:name ("*Special*") :path ("*Special*"))))
  bufler-workspace-tabs()
  tab-bar-format-tabs()
  #f(compiled-function (format) #<bytecode -0x16947f291f641f48>)(tab-bar-format-tabs)
  tab-bar-format-list((tab-bar-format-history tab-bar-format-tabs tab-bar-separator tab-bar-format-add-tab))
  tab-bar-make-keymap-1()
  tab-bar-make-keymap(ignore)
  redisplay_internal\ \(C\ function\)()

various arbirtary stack traces appear for me when using Bufler's tab-bar functionality (which i think will be what emacs users turn to from centaur-tabs), however, they all seem to crash in fns.c in the Emacs C source directory. I've got the native-comp debugging configured with my emacs C-source path. Somewhat confusingly, these bugs proceed differently depending on whether i've run (+doom/reload-autoloads) to regenerate the ~/.emacs.d/.local/autoloads.28.0.50.el file. The first Emacs session (or two?) that i run after regenerating this file seem to be much smoother, with bufler's tab-bar functionality quickly becoming unusable. the stack traces I before the autoloads.*.el file is corrupted seem to be different.

bufler-list seems to group stuff correctly. here's what i'm seeing there.

emacs-bufler-screenshot

I do plan on changing the default groupings once i get everything working. this package Bufler along with Burly seem to be very useful and handle window/frame management almost as ideally as i'd like. (and i've examined like a dozen different packages/methods for doing so). You have some fantastic packages. I may have some mild "CVI-like" dyslexia, so Prism helps me a lot in processing groups of lisp expressions.

tab-line as an alternative to tab-bar for macOS?

I'm on a mac, and the graphical version of emacs has no visible tab-bar implemented yet, so none of the convenient workspace-switching tools work for me /-:

Would it be possible to disable the tab-bar and only use tab-line (which is working & lists all the buffers, something I don't really need) to list the available workspaces? I've tried a few things, but the most success I had with something like this:

(defun asf-bufler-global-tab-line-mode-activate ()
  (setf tab-line-tabs-function #'bufler-workspace-tabs)
  (tab-bar-mode 0)
  (global-tab-line-mode 1))

(defun asf--switch-to-tab-n (n)
  `(lambda ()
     (interactive)
     (bufler-workspace-tabs--tab-bar-select-tab ,n)))

(bind-key "s-1" (asf--switch-to-tab-n 1))
(bind-key "s-2" (asf--switch-to-tab-n 2))
(bind-key "s-3" (asf--switch-to-tab-n 3))
(bind-key "s-4" (asf--switch-to-tab-n 4))
(bind-key "s-5" (asf--switch-to-tab-n 5))
(bind-key "s-6" (asf--switch-to-tab-n 6))
(bind-key "s-7" (asf--switch-to-tab-n 7))
(bind-key "s-8" (asf--switch-to-tab-n 8))
(bind-key "s-9" (asf--switch-to-tab-n 9))
(bind-key "s-0" (asf--switch-to-tab-n 10))

So far, this kiiiinda gets the workspaces listed on the tab-line, but clicking them doesn't work, and there is no feedback on which tab is the "selected" workspace. That's not great, so I figured I'd open an issue here so we can discuss.

I guess one alternative for macOS users would be to implement a reduced-feature-set version that displays the tabs in the minibuffer/echo area (a la mini-mode-line)...

projectile integration

How would you envision projectile to be integrated:

  • implement auto-projectile as its own grouping mechanism?
  • on switching buffers set the workspace to the projectile project (if projectile detects one) and then let workspace grouping take care of the rest?
  • or, some other mechanism?

How to create nested groups in buffler?

I use exwm and have the following two groups, one for all exwm buffers and one for just the Firefox ones, which are the majority of exwm buffers for me (note that I rename my exwm buffers to be the first initial of the program name and colon, as "F :" below).

(group
 (group-and "*Firefox*"
	    (mode-match "*EXWM*" (rx bos "EXWM"))
	    (name-match "*Firefox*" (rx bos "F :"))))
(group
 (mode-match "*EXWM*" (rx bos "EXWM")))

These work as expected, and is an ibuffer-like way of doing it. But to utilize buffler, this really ought to be exwm a a parent of firefox. I don't see in the readme, How do I create this nested structure?

Feedback

Hi,
I just spend 15min trying to find out the email address of @alphapapa and failed. ;-)

Here are my thoughts. Feel free to close this and drop me an email. My email address should be quite easy to find.

bufler.el is an interesting solution to provide task-based structure to buffers. I do thing that I get that.

However, my personal tasks seldom consists more of two buffers. I handle this via eyebrowse and at the moment, I think that this is handled OKish for my situation. If a task has two Org buffers, a dired buffer and a source code buffer, I tend to have two buffers side by side and use C-x b RET on both. This way, I handle up to four buffers for a task.

One of the most precious tools for me is your org-tree-to-indirect-buffer. (btw, I found a small drawback: it's not possible to org-tree-to-indirect-buffer within an indirect buffer.)

The lack of necessity to organize task-based buffers is also expressed by the fact that I do not even use projectile or a similar package.

Readme workflow assumes `set-workspace-p`

Hi!

After reading the Workflow section in the Readme, I expected bufler-switch-buffer to only offer me buffers in the group on subsequent calls, as described in step 4 & 5.
It seems it will only work as described when either bufler-workspace-switch-buffer-sets-workspace or SET-WORKSPACE-P is true.

I think defaulting bufler-workspace-switch-buffer-sets-workspace to t might be sensible, since the user expects the described workflow without any configuration. What do you think?

On a related note, I also expected selecting a buffer via bufler-list to automatically set the workspace.

Awesome package, keep up the good work!

Emacs requirement version 26.3

Hi,

Emacs in Debian Stable is 26.1, but Bufler requires 26.3. Is there any way to relax that dependency so that Debian Stable installs can get bufler installed? Melpa says its incompatible, because of this.

Thanks!

Long titles push columns out of view-port

When, somewhere in my list of buffers, something has an exceptionally long title, it pushes the entire column -- and all the remaining columns -- out of view, rendering buffler-list almost not useful. I don't see a customization option for this; is there a solution to limit columns to some width?

bufler hydra remains open

To reproduce:

  • Run bufler
  • Press ? to open hydra help
  • Press ? again, the bufler buffer gets killed and the hydra help remains

Error on killing buffer

Hello,

I faced this error today when I killed a dired buffer:

bufler-special-buffer-p: Wrong type argument: stringp, nil
Error in post-command-hook (magit-section-update-highlight): (wrong-type-argument number-or-marker-p nil)

here is the stacktrace

  string-match("\\`\\(?:[[:blank:]]+\\)?\\*" nil nil)
  bufler-special-buffer-p(#<killed buffer>)
  bufler-format-buffer(#<killed buffer> 2)
  #f(compiled-function (buffer level) #<bytecode 0x276ae9d>)(#<killed buffer> 2)
  #f(compiled-function (arg1 arg2 &rest rest) #<bytecode 0x4a71969>)(#<killed buffer> ("*Special*" nil nil nil nil nil nil #("dired-mode" 0 10 (face magit-head))) 2)
part containing personal info!
  bufler-list()
  bufler-list-buffer-kill()
  funcall-interactively(bufler-list-buffer-kill)
  call-interactively(bufler-list-buffer-kill nil nil)
  command-execute(bufler-list-buffer-kill)

Symbol’s function definition is void: map-put!

I'm getting this error when I install bufler with use-package in Emacs 27, then quit, and then launch Emacs 26.3.

Error (use-package): bufler/:init: Symbol’s function definition is void: map-put!
Error (use-package): bufler/:catch: Symbol’s function definition is void: map-put!

But not the other way around, i.e. if I install bufler in an Emacs 26 session then I can run either Emacs 26 or Emacs 27.

tab-line group sorting

By default tab-line sorts tabs according to buffer-list order, which I prefer, but when activating bufler-tabs-mode tabs are sorted alphabetically, setting tab-line-tabs-buffer-group-sort-function doesn't have any effect. There is a configuration for the sort function?

Thanks in advance.

Couldn't select default buffer in `bufler-workspace-switch-buffer`

The feature done in #23 is not working for me. When I open bufler-workspace-switch-buffer it shows the other-buffer at the top. The name of the buffer is correct, but the path is missing.
But I couldn't switch to that buffer as I get eq: Wrong type argument: stringp, nil. I think it happens because you get selected-buffer with (alist-get ... #'string=) and it produces nil.

Here is what I see:

24   Buffer:   
bufler.el
X11 » WWW » [github.com] New Issue · alphapapa/bufler.el
Projectile: bufler.el » bufler-workspace.el
Dir: /home/sarg/ » *scratch*

The first line should be Projectile: bufler.el » bufler.el instead.

`bufler-switch-buffer` with just buffer name

Is it possible to display only buffer name without its "outline path" using bufler-switch-buffer?

This would be useful when a workspace is active - I don't really care much about the whole path.

Make tab-bar-switch-to-tab work

Thanks again for the fix from yesterday. Works like a charm.

I had some time to play around with bufler some more and thought I'd document how bufler-workspace-tabs-mode interacts with tab-bar-mode.
Some of these may be non-issues depending on your vision for the mode:

Command Epxected Observed Error
tab-bar-switch-to-tab completion prompt to switch No prompt (wrong-type-argument number-or-marker-p nil)
tab-bar-close-tab tab to be removed from tab bar Tab perisists (wrong-type-argument number-or-marker-p nil)
tab-bar-close-other-tabs other tab to be removed from tab bar Tabs perisist  
tab-bar-undo-close-tab last closed to be undone Since tabs are not removed, last "deleted" just gets focus until exhausting tab-bar-mode's undo stack  
tab-bar-move-tab-right current tab to be moved right tab is not moved  
tab-bar-move-tab-left current tab to be moved left tab is not moved  
tab-bar-rename-tab tab to be renamed to input tab is not renamed  
tab-bar-move-tab-to-frame current tab to be moved to new frame tab is not moved  
tab-bar-close-tab tab to be removed from tab bar Tab perisists (wrong-type-argument number-or-marker-p nil)

For my personal use-case, I'd like definitely like to be able use the following while bufler-workspace-tabs-mode is enabled:
`tab-bar-switch-to-tab`, `tab-bar-move-tab-right`, `tab-bar-move-tab-left`.

I'm not sure if that complicates the design of things too much, but just my two cents.

Some of the other commands I don't use as much, but it'd be great if they worked similar to how they work without bufler-workspace-tabs-mode enabled.

Faces don't show until magit is loaded

You're using some faces from magit.el but don't take care to load that file, resulting in some fairly bland buffer lists until it is loaded by some other action.

Ivy's beautification does not survive blufer

hi!

I'm using [ivy-rich](https://github.com/Yevgnen/ivy-rich) and [all-the-icons-ivy-rich](https://github.com/seagle0128/all-the-icons-ivy-rich) to beautify the candidates, this is what counsel-switch-buffer displays:

image of counsel-switch-buffer

Compared to blufer-switch-buffer:

image

is there anything I can do to workaround this "beautification problem"? Any chance for bufler to play nice with these decorations?

buffler path can get too long, needs abbrev or trunc

Previously issue #50 noted the filename getting out of hand. Likewise can the file path get out of hand -- especially when using eww (and the path is the entire web address), or when working in deeply nested dirs or on long paths on remote servers (Tramp). Some kind of truncation would be good here, probably like Doom or others do for the filename that appears in the mode-line.

bufler-filepath

make better integration with helm-mini

Hello. I would like to add some groups from helm-bufler-source to helm-mini-default-sources. For example I would like to have a group with projectile's buffers in helm-mini. With helm-bufler-source there are many duplicate buffers. I still don't know the best way to do this, maybe it would be nice to have their own source for each group. There are many sources here in helm-mini, such as helm-source-recentf helm-source-bookmarks helm-source-locate. So I would like to stay with that, but use bufler as additional sources. Thank you!

Missing buffer in bufler (fundamental-mode?)

I'm still trying to make sense of bufler-groups, so this might be a bit confused, but I notice that one specific kind of buffer is completely missing from my Bufler, even using the default bufler-groups.

The missing buffers are ipynb notebook buffers from ein: they have names like #<buffer *ein: http://127.0.0.1:8888/scratch.ipynb*> (output of (current-buffer)). I checked that they aren't file backed ((bufler-group-auto-file (current-buffer)) is nil).

I tried introducing a (group (name-match "*Ein*" (rx bos "*ein"))) into the Special subgroup, but it doesn't capture them.

Other ein buffers, for example #<buffer *ein:notebooklist http://127.0.0.1:8888*> do get shown and organized correctly.

Ibuffer does show these buffers.

Any ideas?

Edit: it actually seems like all fundamental-mode buffers are missing. I can't seem to capture them using a mode-match either..

bufler list unusable after killing something: (wrong-type-argument stringp nil)

The problem is, I show bufler-list and kill a buffer (often an exwm one). After this, I can't take any actions in buffler as it gives me the following error. Funny thing is, very often this is fixed by my executing C-x b (switch-to-buffer), which seems to jog buffler back into a working place again. I see from this lengthy error stack that it seems to have something to do with my buffer names.

Debugger entered–Lisp error: (wrong-type-argument stringp nil) string-width(nil) truncate-string-to-width(nil 30) (if bufler-column-name-max-length (truncate-string-to-width (buffer-name buffer) bufler-column-name-max-length) (buffer-name buffer)) (let ((indentation (make-string (* 2 depth) 32)) (mode-annotation (if (let* ((–cl-var– bufler-buffer-mode-annotate-preds) (fn nil) (–cl-flag– t) –cl-var–) (while (and (consp –cl-var–) (progn … …)) (setq –cl-var– (cdr –cl-var–))) –cl-var–) (progn (propertize (concat (replace-regexp-in-string "-mode\\'" "" … t t) " ") 'face 'bufler-mode)))) (constrained-buffer-name (if bufler-column-name-max-length (truncate-string-to-width (buffer-name buffer) bufler-column-name-max-length) (buffer-name buffer))) (modified (if (and (buffer-file-name buffer) (buffer-modified-p buffer)) (progn (propertize bufler-column-name-modified-buffer-sigil 'face 'font-lock-warning-face))))) (concat indentation mode-annotation constrained-buffer-name modified)) (progn (let ((indentation (make-string (* 2 depth) 32)) (mode-annotation (if (let* ((–cl-var– bufler-buffer-mode-annotate-preds) (fn nil) (–cl-flag– t) –cl-var–) (while (and … …) (setq –cl-var– …)) –cl-var–) (progn (propertize (concat … " ") 'face 'bufler-mode)))) (constrained-buffer-name (if bufler-column-name-max-length (truncate-string-to-width (buffer-name buffer) bufler-column-name-max-length) (buffer-name buffer))) (modified (if (and (buffer-file-name buffer) (buffer-modified-p buffer)) (progn (propertize bufler-column-name-modified-buffer-sigil 'face 'font-lock-warning-face))))) (concat indentation mode-annotation constrained-buffer-name modified))) (and t (progn (let ((indentation (make-string (* 2 depth) 32)) (mode-annotation (if (let* (… … … –cl-var–) (while … …) –cl-var–) (progn (propertize … … …)))) (constrained-buffer-name (if bufler-column-name-max-length (truncate-string-to-width (buffer-name buffer) bufler-column-name-max-length) (buffer-name buffer))) (modified (if (and (buffer-file-name buffer) (buffer-modified-p buffer)) (progn (propertize bufler-column-name-modified-buffer-sigil … …))))) (concat indentation mode-annotation constrained-buffer-name modified)))) (let* ((string (and t (progn (let ((indentation …) (mode-annotation …) (constrained-buffer-name …) (modified …)) (concat indentation mode-annotation constrained-buffer-name modified)))))) (if string (if nil (propertize string 'face nil) string) "")) bufler-column-format-name(# 2) funcall(bufler-column-format-name # 2) (let* ((fn (alist-get column-name bufler-column-format-fns nil nil #'string=)) (value (funcall fn buffer depth)) (current-column-size (or (map-elt column-sizes column-name) 0))) (let* ((key column-name)) (condition-case nil (with-no-warnings (map-put! column-sizes key (max current-column-size (1+ (length …))) nil)) (map-not-inplace (setq column-sizes (map-insert column-sizes key (max current-column-size (1+ …))))))) value) (closure ((–cl-each-buffer– closure #2 (fn groups depth) (let (… …) (while list … … …))) (–cl-format-buffer– closure #2 (buffer depth) (puthash buffer (mapcar … columns) table)) (–cl-format-column– . #0) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil … … … … … … … … … …)) ("Dir: ~/emacs/.emacs.d/" (… … …)) (nil (… …) (… …) (… …) (… … …) (… … …) (… … …))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (buffer depth column-name) (let ((fn (alist-get column-name bufler-column-format-fns nil nil …)) (value (funcall fn buffer depth)) (current-column-size (or … 0))) (let* ((key column-name)) (condition-case nil (with-no-warnings …) (map-not-inplace …))) value))(# 2 "Name") funcall((closure ((–cl-each-buffer– closure #3 (fn groups depth) (let ((list groups) (it-index 0)) (while list (let (…) (cond … …)) (setq it-index (1+ it-index)) (setq list (cdr list))))) (–cl-format-buffer– closure #3 (buffer depth) (puthash buffer (mapcar #'(lambda … …) columns) table)) (–cl-format-column– . #1) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil ("bufler-list-mode" #<buffer *Bufler*>) ("org-agenda-mode" #<buffer *Org Agenda(a)*>) ("gnus-group-mode" #<buffer *Group*>) ("comint-mode" #<buffer *compilation*>) ("special-mode" #<buffer *elfeed-log*>) ("bbdb-mode" #<buffer *BBDB*>) ("fundamental-mode" #<buffer *trace of SMTP session to gateway.byu.edu*> #<buffer *trace of SMTP session to smtp.gmail.com*>) ("eww-mode" #<buffer *eww*>) ("calendar-mode" #<buffer *Calendar*>) ("shell-mode" #<buffer *shell*> #<buffer *Async Shell Command*> # #<buffer *Async Shell Command*<5>> #<buffer *Async Shell Command*<6>>))) ("Dir: ~/emacs/.emacs.d/" (#("Dir: home/torysa/emacs.emacs.d/straight/build/pd…" 0 71 (face magit-section-heading)) ("message-mode" #<buffer *sent mail to John Cheng*> #<buffer *sent reply to Clemens Radermacher*> #<buffer *sent reply to Brad Woodward*> #<buffer *sent reply to Shannon Resare*>) ("fundamental-mode" #<buffer .newsrc-dribble>))) (nil (#("Dir: home/torysa/Documents/Diary" 0 34 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/Documents/Priesthood" 0 39 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/Language/Natural" 0 35 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/emacs" 0 24 (face magit-section-heading)) ("org-mode" #) ("emacs-lisp-mode" #)) (#("Dir: home/torysa/emacs/org" 0 28 (face magit-section-heading)) ("org-mode" #<buffer odhmeetings.org> # #<buffer odhagenda.org> # # # # # # # # #) ("message-mode" #<buffer *sent mail to Bonnie Bingham*>)) (#("Dir: home/torysa/Language/Formal" 0 34 (face magit-section-heading)) ("org-mode" # #) ("message-mode" #<buffer *sent mail to John Cheng*<2>>)))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (buffer depth column-name) (let ((fn (alist-get column-name bufler-column-format-fns nil nil #'string=)) (value (funcall fn buffer depth)) (current-column-size (or (map-elt column-sizes column-name) 0))) (let* ((key column-name)) (condition-case nil (with-no-warnings (map-put! column-sizes key (max current-column-size …) nil)) (map-not-inplace (setq column-sizes (map-insert column-sizes key …))))) value)) # 2 "Name") (closure ((depth . 2) (buffer . #) (–cl-each-buffer– closure #4 (fn groups depth) (let (… …) (while list … … …))) (–cl-format-buffer– closure #4 (buffer depth) (puthash buffer (mapcar … columns) table)) (–cl-format-column– closure #4 (buffer depth column-name) (let* (… … …) (let* … …) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil … … … … … … … … … …)) ("Dir: ~/emacs/.emacs.d/" (… … …)) (nil (… …) (… …) (… …) (… … …) (… … …) (… … …))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (it) (funcall –cl-format-column– buffer depth it))("Name") mapcar((closure ((depth . 2) (buffer . #) (–cl-each-buffer– closure #5 (fn groups depth) (let ((list groups) (it-index 0)) (while list (let (…) (cond … …)) (setq it-index (1+ it-index)) (setq list (cdr list))))) (–cl-format-buffer– closure #5 (buffer depth) (puthash buffer (mapcar #'(lambda … …) columns) table)) (–cl-format-column– closure #5 (buffer depth column-name) (let ((fn (alist-get column-name bufler-column-format-fns nil nil …)) (value (funcall fn buffer depth)) (current-column-size (or … 0))) (let* ((key column-name)) (condition-case nil (with-no-warnings …) (map-not-inplace …))) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer *scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil ("bufler-list-mode" #<buffer *Bufler*>) ("org-agenda-mode" #<buffer *Org Agenda(a)*>) ("gnus-group-mode" #<buffer *Group*>) ("comint-mode" #<buffer *compilation*>) ("special-mode" #<buffer *elfeed-log*>) ("bbdb-mode" #<buffer *BBDB*>) ("fundamental-mode" #<buffer *trace of SMTP session to gateway.byu.edu*> #<buffer *trace of SMTP session to smtp.gmail.com*>) ("eww-mode" #<buffer *eww*>) ("calendar-mode" #<buffer *Calendar*>) ("shell-mode" #<buffer *shell*> #<buffer *Async Shell Command*> # #<buffer *Async Shell Command*<5>> #<buffer *Async Shell Command*<6>>))) ("Dir: ~/emacs/.emacs.d/" (#("Dir: home/torysa/emacs.emacs.d/straight/build/pd…" 0 71 (face magit-section-heading)) ("message-mode" #<buffer *sent mail to John Cheng*> #<buffer *sent reply to Clemens Radermacher*> #<buffer *sent reply to Brad Woodward*> #<buffer *sent reply to Shannon Resare*>) ("fundamental-mode" #<buffer .newsrc-dribble>))) (nil (#("Dir: home/torysa/Documents/Diary" 0 34 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/Documents/Priesthood" 0 39 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/Language/Natural" 0 35 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/emacs" 0 24 (face magit-section-heading)) ("org-mode" #) ("emacs-lisp-mode" #)) (#("Dir: home/torysa/emacs/org" 0 28 (face magit-section-heading)) ("org-mode" #<buffer odhmeetings.org> # #<buffer odhagenda.org> # # # # # # # # #) ("message-mode" #<buffer *sent mail to Bonnie Bingham*>)) (#("Dir: home/torysa/Language/Formal" 0 34 (face magit-section-heading)) ("org-mode" # #) ("message-mode" #<buffer *sent mail to John Cheng*<2>>)))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (it) (funcall –cl-format-column– buffer depth it)) ("Name" "Size" "Path")) (puthash buffer (mapcar #'(lambda (it) (funcall –cl-format-column– buffer depth it)) columns) table) (closure ((–cl-each-buffer– closure #2 (fn groups depth) (let (… …) (while list … … …))) (–cl-format-buffer– . #0) (–cl-format-column– closure #2 (buffer depth column-name) (let* (… … …) (let* … …) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil … … … … … … … … … …)) ("Dir: ~/emacs/.emacs.d/" (… … …)) (nil (… …) (… …) (… …) (… … …) (… … …) (… … …))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (buffer depth) (puthash buffer (mapcar #'(lambda … …) columns) table))(# 2) funcall((closure ((–cl-each-buffer– closure #3 (fn groups depth) (let ((list groups) (it-index 0)) (while list (let (…) (cond … …)) (setq it-index (1+ it-index)) (setq list (cdr list))))) (–cl-format-buffer– . #1) (–cl-format-column– closure #3 (buffer depth column-name) (let ((fn (alist-get column-name bufler-column-format-fns nil nil …)) (value (funcall fn buffer depth)) (current-column-size (or … 0))) (let* ((key column-name)) (condition-case nil (with-no-warnings …) (map-not-inplace …))) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer *scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil ("bufler-list-mode" #<buffer *Bufler*>) ("org-agenda-mode" #<buffer *Org Agenda(a)*>) ("gnus-group-mode" #<buffer *Group*>) ("comint-mode" #<buffer *compilation*>) ("special-mode" #<buffer *elfeed-log*>) ("bbdb-mode" #<buffer *BBDB*>) ("fundamental-mode" #<buffer *trace of SMTP session to gateway.byu.edu*> #<buffer *trace of SMTP session to smtp.gmail.com*>) ("eww-mode" #<buffer *eww*>) ("calendar-mode" #<buffer *Calendar*>) ("shell-mode" #<buffer *shell*> #<buffer *Async Shell Command*> # #<buffer *Async Shell Command*<5>> #<buffer *Async Shell Command*<6>>))) ("Dir: ~/emacs/.emacs.d/" (#("Dir: home/torysa/emacs.emacs.d/straight/build/pd…" 0 71 (face magit-section-heading)) ("message-mode" #<buffer *sent mail to John Cheng*> #<buffer *sent reply to Clemens Radermacher*> #<buffer *sent reply to Brad Woodward*> #<buffer *sent reply to Shannon Resare*>) ("fundamental-mode" #<buffer .newsrc-dribble>))) (nil (#("Dir: home/torysa/Documents/Diary" 0 34 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/Documents/Priesthood" 0 39 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/Language/Natural" 0 35 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/emacs" 0 24 (face magit-section-heading)) ("org-mode" #) ("emacs-lisp-mode" #)) (#("Dir: home/torysa/emacs/org" 0 28 (face magit-section-heading)) ("org-mode" #<buffer odhmeetings.org> # #<buffer odhagenda.org> # # # # # # # # #) ("message-mode" #<buffer *sent mail to Bonnie Bingham*>)) (#("Dir: home/torysa/Language/Formal" 0 34 (face magit-section-heading)) ("org-mode" # #) ("message-mode" #<buffer *sent mail to John Cheng*<2>>)))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (buffer depth) (puthash buffer (mapcar #'(lambda (it) (funcall –cl-format-column– buffer depth it)) columns) table)) # 2) (cond ((bufferp it) (funcall –cl-format-buffer– it depth)) ((listp it) (funcall –cl-each-buffer– fn it (if (car it) (1+ depth) depth)))) (let ((it (car list))) (cond ((bufferp it) (funcall –cl-format-buffer– it depth)) ((listp it) (funcall –cl-each-buffer– fn it (if (car it) (1+ depth) depth))))) (while list (let ((it (car list))) (cond ((bufferp it) (funcall –cl-format-buffer– it depth)) ((listp it) (funcall –cl-each-buffer– fn it (if (car it) (1+ depth) depth))))) (setq it-index (1+ it-index)) (setq list (cdr list))) (let ((list groups) (it-index 0)) (while list (let ((it (car list))) (cond ((bufferp it) (funcall –cl-format-buffer– it depth)) ((listp it) (funcall –cl-each-buffer– fn it (if (car it) (1+ depth) depth))))) (setq it-index (1+ it-index)) (setq list (cdr list)))) (closure ((–cl-each-buffer– . #0) (–cl-format-buffer– closure #2 (buffer depth) (puthash buffer (mapcar … columns) table)) (–cl-format-column– closure #2 (buffer depth column-name) (let* (… … …) (let* … …) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil … … … … … … … … … …)) ("Dir: ~/emacs/.emacs.d/" (… … …)) (nil (… …) (… …) (… …) (… … …) (… … …) (… … …))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (fn groups depth) (let ((list groups) (it-index 0)) (while list (let (…) (cond … …)) (setq it-index (1+ it-index)) (setq list (cdr list)))))((closure ((–cl-each-buffer– closure #3 (fn groups depth) (let ((list groups) (it-index 0)) (while list (let (…) (cond … …)) (setq it-index (1+ it-index)) (setq list (cdr list))))) (–cl-format-buffer– . #1) (–cl-format-column– closure #3 (buffer depth column-name) (let ((fn (alist-get column-name bufler-column-format-fns nil nil …)) (value (funcall fn buffer depth)) (current-column-size (or … 0))) (let* ((key column-name)) (condition-case nil (with-no-warnings …) (map-not-inplace …))) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil ("bufler-list-mode" #<buffer *Bufler*>) ("org-agenda-mode" #<buffer *Org Agenda(a)*>) ("gnus-group-mode" #<buffer *Group*>) ("comint-mode" #<buffer *compilation*>) ("special-mode" #<buffer *elfeed-log*>) ("bbdb-mode" #<buffer *BBDB*>) ("fundamental-mode" #<buffer *trace of SMTP session to gateway.byu.edu*> #<buffer *trace of SMTP session to smtp.gmail.com*>) ("eww-mode" #<buffer *eww*>) ("calendar-mode" #<buffer *Calendar*>) ("shell-mode" #<buffer *shell*> #<buffer *Async Shell Command*> # #<buffer *Async Shell Command*<5>> #<buffer *Async Shell Command*<6>>))) ("Dir: ~/emacs/.emacs.d/" (#("Dir: home/torysa/emacs.emacs.d/straight/build/pd…" 0 71 (face magit-section-heading)) ("message-mode" #<buffer *sent mail to John Cheng*> #<buffer *sent reply to Clemens Radermacher*> #<buffer *sent reply to Brad Woodward*> #<buffer *sent reply to Shannon Resare*>) ("fundamental-mode" #<buffer .newsrc-dribble>))) (nil (#("Dir: home/torysa/Documents/Diary" 0 34 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/Documents/Priesthood" 0 39 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/Language/Natural" 0 35 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/emacs" 0 24 (face magit-section-heading)) ("org-mode" #) ("emacs-lisp-mode" #)) (#("Dir: home/torysa/emacs/org" 0 28 (face magit-section-heading)) ("org-mode" #<buffer odhmeetings.org> # #<buffer odhagenda.org> # # # # # # # # #) ("message-mode" #<buffer *sent mail to Bonnie Bingham*>)) (#("Dir: home/torysa/Language/Formal" 0 34 (face magit-section-heading)) ("org-mode" # #) ("message-mode" #<buffer *sent mail to John Cheng*<2>>)))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (buffer depth) (puthash buffer (mapcar #'(lambda (it) (funcall –cl-format-column– buffer depth it)) columns) table)) ("shell-mode" #<buffer *shell*> #<buffer *Async Shell Command*> # #<buffer *Async Shell Command*<5>> #<buffer *Async Shell Command*<6>>) 2) funcall((closure ((–cl-each-buffer– . #1) (–cl-format-buffer– closure #3 (buffer depth) (puthash buffer (mapcar … columns) table)) (–cl-format-column– closure #3 (buffer depth column-name) (let (… … …) (let* … …) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil … … … … … … … … … …)) ("Dir: ~/emacs/.emacs.d/" (… … …)) (nil (… …) (… …) (… …) (… … …) (… … …) (… … …))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (fn groups depth) (let ((list groups) (it-index 0)) (while list (let (…) (cond … …)) (setq it-index (1+ it-index)) (setq list (cdr list))))) (closure ((–cl-each-buffer– closure #4 (fn groups depth) (let (… …) (while list … … …))) (–cl-format-buffer– . #2) (–cl-format-column– closure #4 (buffer depth column-name) (let (… … …) (let* … …) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer *scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil … … … … … … … … … …)) ("Dir: ~/emacs/.emacs.d/" (… … …)) (nil (… …) (… …) (… …) (… … …) (… … …) (… … …))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (buffer depth) (puthash buffer (mapcar #'(lambda … …) columns) table)) ("shell-mode" #<buffer *shell*> #<buffer *Async Shell Command*> # #<buffer *Async Shell Command*<5>> #<buffer *Async Shell Command*<6>>) 2) (cond ((bufferp it) (funcall –cl-format-buffer– it depth)) ((listp it) (funcall –cl-each-buffer– fn it (if (car it) (1+ depth) depth)))) (let ((it (car list))) (cond ((bufferp it) (funcall –cl-format-buffer– it depth)) ((listp it) (funcall –cl-each-buffer– fn it (if (car it) (1+ depth) depth))))) (while list (let ((it (car list))) (cond ((bufferp it) (funcall –cl-format-buffer– it depth)) ((listp it) (funcall –cl-each-buffer– fn it (if (car it) (1+ depth) depth))))) (setq it-index (1+ it-index)) (setq list (cdr list))) (let ((list groups) (it-index 0)) (while list (let ((it (car list))) (cond ((bufferp it) (funcall –cl-format-buffer– it depth)) ((listp it) (funcall –cl-each-buffer– fn it (if (car it) (1+ depth) depth))))) (setq it-index (1+ it-index)) (setq list (cdr list)))) (closure ((–cl-each-buffer– . #0) (–cl-format-buffer– closure #2 (buffer depth) (puthash buffer (mapcar … columns) table)) (–cl-format-column– closure #2 (buffer depth column-name) (let* (… … …) (let* … …) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil … … … … … … … … … …)) ("Dir: ~/emacs/.emacs.d/" (… … …)) (nil (… …) (… …) (… …) (… … …) (… … …) (… … …))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (fn groups depth) (let ((list groups) (it-index 0)) (while list (let (…) (cond … …)) (setq it-index (1+ it-index)) (setq list (cdr list)))))((closure ((–cl-each-buffer– closure #3 (fn groups depth) (let ((list groups) (it-index 0)) (while list (let (…) (cond … …)) (setq it-index (1+ it-index)) (setq list (cdr list))))) (–cl-format-buffer– . #1) (–cl-format-column– closure #3 (buffer depth column-name) (let ((fn (alist-get column-name bufler-column-format-fns nil nil …)) (value (funcall fn buffer depth)) (current-column-size (or … 0))) (let* ((key column-name)) (condition-case nil (with-no-warnings …) (map-not-inplace …))) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil ("bufler-list-mode" #<buffer *Bufler*>) ("org-agenda-mode" #<buffer *Org Agenda(a)*>) ("gnus-group-mode" #<buffer *Group*>) ("comint-mode" #<buffer *compilation*>) ("special-mode" #<buffer *elfeed-log*>) ("bbdb-mode" #<buffer *BBDB*>) ("fundamental-mode" #<buffer *trace of SMTP session to gateway.byu.edu*> #<buffer *trace of SMTP session to smtp.gmail.com*>) ("eww-mode" #<buffer *eww*>) ("calendar-mode" #<buffer *Calendar*>) ("shell-mode" #<buffer *shell*> #<buffer *Async Shell Command*> # #<buffer *Async Shell Command*<5>> #<buffer *Async Shell Command*<6>>))) ("Dir: ~/emacs/.emacs.d/" (#("Dir: home/torysa/emacs.emacs.d/straight/build/pd…" 0 71 (face magit-section-heading)) ("message-mode" #<buffer *sent mail to John Cheng*> #<buffer *sent reply to Clemens Radermacher*> #<buffer *sent reply to Brad Woodward*> #<buffer *sent reply to Shannon Resare*>) ("fundamental-mode" #<buffer .newsrc-dribble>))) (nil (#("Dir: home/torysa/Documents/Diary" 0 34 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/Documents/Priesthood" 0 39 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/Language/Natural" 0 35 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/emacs" 0 24 (face magit-section-heading)) ("org-mode" #) ("emacs-lisp-mode" #)) (#("Dir: home/torysa/emacs/org" 0 28 (face magit-section-heading)) ("org-mode" #<buffer odhmeetings.org> # #<buffer odhagenda.org> # # # # # # # # #) ("message-mode" #<buffer *sent mail to Bonnie Bingham*>)) (#("Dir: home/torysa/Language/Formal" 0 34 (face magit-section-heading)) ("org-mode" # #) ("message-mode" #<buffer *sent mail to John Cheng*<2>>)))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (buffer depth) (puthash buffer (mapcar #'(lambda (it) (funcall –cl-format-column– buffer depth it)) columns) table)) (nil ("bufler-list-mode" #<buffer *Bufler*>) ("org-agenda-mode" #<buffer *Org Agenda(a)*>) ("gnus-group-mode" #<buffer *Group*>) ("comint-mode" #<buffer *compilation*>) ("special-mode" #<buffer *elfeed-log*>) ("bbdb-mode" #<buffer *BBDB*>) ("fundamental-mode" #<buffer *trace of SMTP session to gateway.byu.edu*> #<buffer *trace of SMTP session to smtp.gmail.com*>) ("eww-mode" #<buffer *eww*>) ("calendar-mode" #<buffer *Calendar*>) ("shell-mode" #<buffer *shell*> #<buffer *Async Shell Command*> # #<buffer *Async Shell Command*<5>> #<buffer *Async Shell Command*<6>>)) 1) funcall((closure ((–cl-each-buffer– . #1) (–cl-format-buffer– closure #3 (buffer depth) (puthash buffer (mapcar … columns) table)) (–cl-format-column– closure #3 (buffer depth column-name) (let (… … …) (let* … …) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil … … … … … … … … … …)) ("Dir: ~/emacs/.emacs.d/" (… … …)) (nil (… …) (… …) (… …) (… … …) (… … …) (… … …))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (fn groups depth) (let ((list groups) (it-index 0)) (while list (let (…) (cond … …)) (setq it-index (1+ it-index)) (setq list (cdr list))))) (closure ((–cl-each-buffer– closure #4 (fn groups depth) (let (… …) (while list … … …))) (–cl-format-buffer– . #2) (–cl-format-column– closure #4 (buffer depth column-name) (let (… … …) (let* … …) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer *scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil … … … … … … … … … …)) ("Dir: ~/emacs/.emacs.d/" (… … …)) (nil (… …) (… …) (… …) (… … …) (… … …) (… … …))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (buffer depth) (puthash buffer (mapcar #'(lambda … …) columns) table)) (nil ("bufler-list-mode" #<buffer *Bufler*>) ("org-agenda-mode" #<buffer *Org Agenda(a)*>) ("gnus-group-mode" #<buffer *Group*>) ("comint-mode" #<buffer *compilation*>) ("special-mode" #<buffer *elfeed-log*>) ("bbdb-mode" #<buffer *BBDB*>) ("fundamental-mode" #<buffer *trace of SMTP session to gateway.byu.edu*> #<buffer *trace of SMTP session to smtp.gmail.com*>) ("eww-mode" #<buffer *eww*>) ("calendar-mode" #<buffer *Calendar*>) ("shell-mode" #<buffer *shell*> #<buffer *Async Shell Command*> # #<buffer *Async Shell Command*<5>> #<buffer *Async Shell Command*<6>>)) 1) (cond ((bufferp it) (funcall –cl-format-buffer– it depth)) ((listp it) (funcall –cl-each-buffer– fn it (if (car it) (1+ depth) depth)))) (let ((it (car list))) (cond ((bufferp it) (funcall –cl-format-buffer– it depth)) ((listp it) (funcall –cl-each-buffer– fn it (if (car it) (1+ depth) depth))))) (while list (let ((it (car list))) (cond ((bufferp it) (funcall –cl-format-buffer– it depth)) ((listp it) (funcall –cl-each-buffer– fn it (if (car it) (1+ depth) depth))))) (setq it-index (1+ it-index)) (setq list (cdr list))) (let ((list groups) (it-index 0)) (while list (let ((it (car list))) (cond ((bufferp it) (funcall –cl-format-buffer– it depth)) ((listp it) (funcall –cl-each-buffer– fn it (if (car it) (1+ depth) depth))))) (setq it-index (1+ it-index)) (setq list (cdr list)))) (closure ((–cl-each-buffer– . #0) (–cl-format-buffer– closure #2 (buffer depth) (puthash buffer (mapcar … columns) table)) (–cl-format-column– closure #2 (buffer depth column-name) (let* (… … …) (let* … …) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil … … … … … … … … … …)) ("Dir: ~/emacs/.emacs.d/" (… … …)) (nil (… …) (… …) (… …) (… … …) (… … …) (… … …))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (fn groups depth) (let ((list groups) (it-index 0)) (while list (let (…) (cond … …)) (setq it-index (1+ it-index)) (setq list (cdr list)))))((closure ((–cl-each-buffer– closure #3 (fn groups depth) (let ((list groups) (it-index 0)) (while list (let … …) (setq it-index …) (setq list …)))) (–cl-format-buffer– . #1) (–cl-format-column– closure #3 (buffer depth column-name) (let ((fn …) (value …) (current-column-size …)) (let* (…) (condition-case nil … …)) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil ("bufler-list-mode" #<buffer *Bufler*>) ("org-agenda-mode" #<buffer *Org Agenda(a)*>) ("gnus-group-mode" #<buffer *Group*>) ("comint-mode" #<buffer *compilation*>) ("special-mode" #<buffer *elfeed-log*>) ("bbdb-mode" #<buffer *BBDB*>) ("fundamental-mode" #<buffer *trace of SMTP session to gateway.byu.edu*> #<buffer *trace of SMTP session to smtp.gmail.com*>) ("eww-mode" #<buffer *eww*>) ("calendar-mode" #<buffer *Calendar*>) ("shell-mode" #<buffer *shell*> #<buffer *Async Shell Command*> # #<buffer *Async Shell Command*<5>> #<buffer *Async Shell Command*<6>>))) ("Dir: ~/emacs/.emacs.d/" (#("Dir: home/torysa/emacs.emacs.d/straight/bu…" 0 71 …) ("message-mode" #<buffer *sent mail to John Cheng*> #<buffer *sent reply to Clemens Radermacher*> #<buffer *sent reply to Brad Woodward*> #<buffer *sent reply to Shannon Resare*>) ("fundamental-mode" #<buffer .newsrc-dribble>))) (nil (#("Dir: home/torysa/Documents/Diary" 0 34 …) ("org-mode" #)) (#("Dir: home/torysa/Documents/Priesthood" 0 39 …) ("org-mode" #)) (#("Dir: home/torysa/Language/Natural" 0 35 …) ("org-mode" #)) (#("Dir: home/torysa/emacs" 0 24 …) ("org-mode" #) ("emacs-lisp-mode" #)) (#("Dir: home/torysa/emacs/org" 0 28 …) ("org-mode" #<buffer odhmeetings.org> # #<buffer odhagenda.org> # # # # # # # # #) ("message-mode" #<buffer *sent mail to Bonnie Bingham*>)) (#("Dir: home/torysa/Language/Formal" 0 34 …) ("org-mode" # #) ("message-mode" #<buffer *sent mail to John Cheng*<2>>)))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (buffer depth) (puthash buffer (mapcar #'(lambda (it) (funcall –cl-format-column– buffer depth it)) columns) table)) ("*Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil ("bufler-list-mode" #<buffer *Bufler*>) ("org-agenda-mode" #<buffer *Org Agenda(a)*>) ("gnus-group-mode" #<buffer *Group*>) ("comint-mode" #<buffer *compilation*>) ("special-mode" #<buffer *elfeed-log*>) ("bbdb-mode" #<buffer *BBDB*>) ("fundamental-mode" #<buffer *trace of SMTP session to gateway.byu.edu*> #<buffer *trace of SMTP session to smtp.gmail.com*>) ("eww-mode" #<buffer *eww*>) ("calendar-mode" #<buffer *Calendar*>) ("shell-mode" #<buffer *shell*> #<buffer *Async Shell Command*> # #<buffer *Async Shell Command*<5>> #<buffer *Async Shell Command*<6>>))) 1) funcall((closure ((–cl-each-buffer– . #1) (–cl-format-buffer– closure #3 (buffer depth) (puthash buffer (mapcar … columns) table)) (–cl-format-column– closure #3 (buffer depth column-name) (let (… … …) (let* … …) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil … … … … … … … … … …)) ("Dir: ~/emacs/.emacs.d/" (… … …)) (nil (… …) (… …) (… …) (… … …) (… … …) (… … …))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (fn groups depth) (let ((list groups) (it-index 0)) (while list (let (…) (cond … …)) (setq it-index (1+ it-index)) (setq list (cdr list))))) (closure ((–cl-each-buffer– closure #4 (fn groups depth) (let (… …) (while list … … …))) (–cl-format-buffer– . #2) (–cl-format-column– closure #4 (buffer depth column-name) (let (… … …) (let* … …) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil … … … … … … … … … …)) ("Dir: ~/emacs/.emacs.d/" (… … …)) (nil (… …) (… …) (… …) (… … …) (… … …) (… … …))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (buffer depth) (puthash buffer (mapcar #'(lambda … …) columns) table)) ("*Special" ("Special" #<buffer *scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil ("bufler-list-mode" #<buffer *Bufler*>) ("org-agenda-mode" #<buffer *Org Agenda(a)*>) ("gnus-group-mode" #<buffer *Group*>) ("comint-mode" #<buffer *compilation*>) ("special-mode" #<buffer *elfeed-log*>) ("bbdb-mode" #<buffer *BBDB*>) ("fundamental-mode" #<buffer *trace of SMTP session to gateway.byu.edu*> #<buffer *trace of SMTP session to smtp.gmail.com*>) ("eww-mode" #<buffer *eww*>) ("calendar-mode" #<buffer *Calendar*>) ("shell-mode" #<buffer *shell*> #<buffer *Async Shell Command*> # #<buffer *Async Shell Command*<5>> #<buffer *Async Shell Command*<6>>))) 1) (cond ((bufferp it) (funcall –cl-format-buffer– it depth)) ((listp it) (funcall –cl-each-buffer– fn it (if (car it) (1+ depth) depth)))) (let ((it (car list))) (cond ((bufferp it) (funcall –cl-format-buffer– it depth)) ((listp it) (funcall –cl-each-buffer– fn it (if (car it) (1+ depth) depth))))) (while list (let ((it (car list))) (cond ((bufferp it) (funcall –cl-format-buffer– it depth)) ((listp it) (funcall –cl-each-buffer– fn it (if (car it) (1+ depth) depth))))) (setq it-index (1+ it-index)) (setq list (cdr list))) (let ((list groups) (it-index 0)) (while list (let ((it (car list))) (cond ((bufferp it) (funcall –cl-format-buffer– it depth)) ((listp it) (funcall –cl-each-buffer– fn it (if (car it) (1+ depth) depth))))) (setq it-index (1+ it-index)) (setq list (cdr list)))) (closure ((–cl-each-buffer– . #0) (–cl-format-buffer– closure #2 (buffer depth) (puthash buffer (mapcar … columns) table)) (–cl-format-column– closure #2 (buffer depth column-name) (let* (… … …) (let* … …) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil … … … … … … … … … …)) ("Dir: ~/emacs/.emacs.d/" (… … …)) (nil (… …) (… …) (… …) (… … …) (… … …) (… … …))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (fn groups depth) (let ((list groups) (it-index 0)) (while list (let (…) (cond … …)) (setq it-index (1+ it-index)) (setq list (cdr list)))))((closure ((–cl-each-buffer– closure #3 (fn groups depth) (let (… …) (while list … … …))) (–cl-format-buffer– . #1) (–cl-format-column– closure #3 (buffer depth column-name) (let (… … …) (let* … …) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil … … … … … … … … … …)) ("Dir: ~/emacs/.emacs.d/" (… … …)) (nil (… …) (… …) (… …) (… … …) (… … …) (… … …))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (buffer depth) (puthash buffer (mapcar #'(lambda … …) columns) table)) (("*EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil ("bufler-list-mode" #<buffer *Bufler*>) ("org-agenda-mode" #<buffer *Org Agenda(a)*>) ("gnus-group-mode" #<buffer *Group*>) ("comint-mode" #<buffer *compilation*>) ("special-mode" #<buffer *elfeed-log*>) ("bbdb-mode" #<buffer *BBDB*>) ("fundamental-mode" #<buffer *trace of SMTP session to gateway.byu.edu*> #<buffer *trace of SMTP session to smtp.gmail.com*>) ("eww-mode" #<buffer *eww*>) ("calendar-mode" #<buffer *Calendar*>) ("shell-mode" #<buffer *shell*> #<buffer *Async Shell Command*> # #<buffer *Async Shell Command*<5>> #<buffer *Async Shell Command*<6>>))) ("Dir: ~/emacs/.emacs.d/" (#("Dir: home/torysa/emacs.emacs.d/strai…" 0 71 (face magit-section-heading)) ("message-mode" #<buffer *sent mail to John Cheng*> #<buffer *sent reply to Clemens Radermacher*> #<buffer *sent reply to Brad Woodward*> #<buffer *sent reply to Shannon Resare*>) ("fundamental-mode" #<buffer .newsrc-dribble>))) (nil (#("Dir: home/torysa/Documents/Diary" 0 34 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/Documents/Priesthood…" 0 39 (face magit-section-heading)) ("org-mode" #)) (#("Dir: /home/torysa/Language/Natural" 0 35 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/emacs" 0 24 (face magit-section-heading)) ("org-mode" #) ("emacs-lisp-mode" #)) (#("Dir: home/torysa/emacs/org" 0 28 (face magit-section-heading)) ("org-mode" #<buffer odhmeetings.org> # #<buffer odhagenda.org> # # # # # # # # #) ("message-mode" #<buffer *sent mail to Bonnie Bingham*>)) (#("Dir: home/torysa/Language/Formal" 0 34 (face magit-section-heading)) ("org-mode" # #) ("message-mode" #<buffer *sent mail to John Cheng*<2>>)))) 0) funcall((closure ((–cl-each-buffer– . #1) (–cl-format-buffer– closure #3 (buffer depth) (puthash buffer (mapcar … columns) table)) (–cl-format-column– closure #3 (buffer depth column-name) (let (… … …) (let* … …) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil … … … … … … … … … …)) ("Dir: ~/emacs/.emacs.d/" (… … …)) (nil (… …) (… …) (… …) (… … …) (… … …) (… … …))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (fn groups depth) (let ((list groups) (it-index 0)) (while list (let (…) (cond … …)) (setq it-index (1+ it-index)) (setq list (cdr list))))) (closure ((–cl-each-buffer– closure #4 (fn groups depth) (let (… …) (while list … … …))) (–cl-format-buffer– . #2) (–cl-format-column– closure #4 (buffer depth column-name) (let (… … …) (let* … …) value)) (column-sizes ("Path" . 56) ("Size" . 6) ("Name" . 35)) (columns "Name" "Size" "Path") (table . #<hash-table eql 22/65 0x5b6e15>) (groups ("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil … … … … … … … … … …)) ("Dir: ~/emacs/.emacs.d/" (… … …)) (nil (… …) (… …) (… …) (… … …) (… … …) (… … …))) cl-struct-bufler-group-tags bufler-list-mode-abbrev-table bufler-list-mode-syntax-table bufler-groups t) (buffer depth) (puthash buffer (mapcar #'(lambda … …) columns) table)) (("*EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil ("bufler-list-mode" #<buffer *Bufler*>) ("org-agenda-mode" #<buffer *Org Agenda(a)*>) ("gnus-group-mode" #<buffer *Group*>) ("comint-mode" #<buffer *compilation*>) ("special-mode" #<buffer *elfeed-log*>) ("bbdb-mode" #<buffer *BBDB*>) ("fundamental-mode" #<buffer *trace of SMTP session to gateway.byu.edu*> #<buffer *trace of SMTP session to smtp.gmail.com*>) ("eww-mode" #<buffer *eww*>) ("calendar-mode" #<buffer *Calendar*>) ("shell-mode" #<buffer *shell*> #<buffer *Async Shell Command*> # #<buffer *Async Shell Command*<5>> #<buffer *Async Shell Command*<6>>))) ("Dir: ~/emacs/.emacs.d/" (#("Dir: home/torysa/emacs.emacs.d/strai…" 0 71 (face magit-section-heading)) ("message-mode" #<buffer *sent mail to John Cheng*> #<buffer *sent reply to Clemens Radermacher*> #<buffer *sent reply to Brad Woodward*> #<buffer *sent reply to Shannon Resare*>) ("fundamental-mode" #<buffer .newsrc-dribble>))) (nil (#("Dir: home/torysa/Documents/Diary" 0 34 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/Documents/Priesthood…" 0 39 (face magit-section-heading)) ("org-mode" #)) (#("Dir: /home/torysa/Language/Natural" 0 35 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/emacs" 0 24 (face magit-section-heading)) ("org-mode" #) ("emacs-lisp-mode" #)) (#("Dir: home/torysa/emacs/org" 0 28 (face magit-section-heading)) ("org-mode" #<buffer odhmeetings.org> # #<buffer odhagenda.org> # # # # # # # # #) ("message-mode" #<buffer *sent mail to Bonnie Bingham*>)) (#("Dir: home/torysa/Language/Formal" 0 34 (face magit-section-heading)) ("org-mode" # #) ("message-mode" #<buffer *sent mail to John Cheng*<2>>)))) 0) (let (–cl-format-column– –cl-format-buffer– –cl-each-buffer–) (setq –cl-format-column– #'(lambda (buffer depth column-name) (let ((fn (alist-get column-name bufler-column-format-fns nil nil …)) (value (funcall fn buffer depth)) (current-column-size (or … 0))) (let* ((key column-name)) (condition-case nil (with-no-warnings …) (map-not-inplace …))) value))) (setq –cl-format-buffer– #'(lambda (buffer depth) (puthash buffer (mapcar #'(lambda … …) columns) table))) (setq –cl-each-buffer– #'(lambda (fn groups depth) (let ((list groups) (it-index 0)) (while list (let (…) (cond … …)) (setq it-index (1+ it-index)) (setq list (cdr list)))))) (funcall –cl-each-buffer– –cl-format-buffer– groups 0) (let* ((column-sizes (nreverse column-sizes)) (format-string (string-join (let* ((–cl-var– column-sizes) (size nil) (–cl-var–) (–cl-var– nil)) (while (consp –cl-var–) (setq size … –cl-var– …) (setq –cl-var– …) (setq –cl-var– …)) (nreverse –cl-var–)) " "))) (maphash #'(lambda (buffer column-values) (puthash buffer (apply #'format format-string column-values) table)) table) (cons table column-sizes))) (let ((table (make-hash-table)) (columns bufler-columns) column-sizes) (let (–cl-format-column– –cl-format-buffer– –cl-each-buffer–) (setq –cl-format-column– #'(lambda (buffer depth column-name) (let* ((fn …) (value …) (current-column-size …)) (let* (…) (condition-case nil … …)) value))) (setq –cl-format-buffer– #'(lambda (buffer depth) (puthash buffer (mapcar #'… columns) table))) (setq –cl-each-buffer– #'(lambda (fn groups depth) (let ((list groups) (it-index 0)) (while list (let … …) (setq it-index …) (setq list …))))) (funcall –cl-each-buffer– –cl-format-buffer– groups 0) (let* ((column-sizes (nreverse column-sizes)) (format-string (string-join (let* (… … … …) (while … … … …) (nreverse –cl-var–)) " "))) (maphash #'(lambda (buffer column-values) (puthash buffer (apply … format-string column-values) table)) table) (cons table column-sizes)))) bufler-format-buffer-groups((("EXWM" ("Firefox" # #<buffer F : Notifications / Twit> #<buffer F : Slack | Lindsay Chin>) (nil #<buffer G : Thank you - Zoom - G> #<buffer E : emacs@endless-inside> #<buffer T : Telegram (7)> #)) ("Special" ("Special" #<buffer scratch*> #<buffer *Messages*> #<buffer *Warnings*>) (nil ("bufler-list-mode" #<buffer *Bufler*>) ("org-agenda-mode" #<buffer *Org Agenda(a)*>) ("gnus-group-mode" #<buffer *Group*>) ("comint-mode" #<buffer *compilation*>) ("special-mode" #<buffer *elfeed-log*>) ("bbdb-mode" #<buffer *BBDB*>) ("fundamental-mode" #<buffer *trace of SMTP session to gateway.byu.edu*> #<buffer *trace of SMTP session to smtp.gmail.com*>) ("eww-mode" #<buffer *eww*>) ("calendar-mode" #<buffer *Calendar*>) ("shell-mode" #<buffer *shell*> #<buffer *Async Shell Command*> # #<buffer *Async Shell Command*<5>> #<buffer *Async Shell Command*<6>>))) ("Dir: ~/emacs/.emacs.d/" (#("Dir: home/torysa/emacs.emacs.d/straight/build/pd…" 0 71 (face magit-section-heading)) ("message-mode" #<buffer *sent mail to John Cheng*> #<buffer *sent reply to Clemens Radermacher*> #<buffer *sent reply to Brad Woodward*> #<buffer *sent reply to Shannon Resare*>) ("fundamental-mode" #<buffer .newsrc-dribble>))) (nil (#("Dir: home/torysa/Documents/Diary" 0 34 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/Documents/Priesthood" 0 39 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/Language/Natural" 0 35 (face magit-section-heading)) ("org-mode" #)) (#("Dir: home/torysa/emacs" 0 24 (face magit-section-heading)) ("org-mode" #) ("emacs-lisp-mode" #)) (#("Dir: home/torysa/emacs/org" 0 28 (face magit-section-heading)) ("org-mode" #<buffer odhmeetings.org> # #<buffer odhagenda.org> # # # # # # # # #) ("message-mode" #<buffer *sent mail to Bonnie Bingham*>)) (#("Dir: home/torysa/Language/Formal" 0 34 (face magit-section-heading)) ("org-mode" # #) ("message-mode" #<buffer *sent mail to John Cheng*<2>>))))) (let ((inhibit-read-only t) (bufler-vc-refresh force-refresh) (groups (bufler-buffers)) (val (bufler-format-buffer-groups groups)) (x23 (car val)) (x24 (cdr val))) (let ((column-sizes x24) (format-table x23)) (let ((header (concat (format (format " %%-%ss" …) (car …)) (let* (… … … … …) (while … … … … …) –cl-var–))) (pos)) (progn (setq format-table format-table) (if bufler-reverse (progn (setq groups (nreverse …)))) (save-current-buffer (set-buffer (get-buffer-create "*Bufler")) (setq pos (point)) (bufler-list-mode) (erase-buffer) (let* ((type24 …) (section25 …)) (eieio-oset section25 'hidden (let … …)) (let (… … …) (catch … … … … … … …) section25)) (setq header-line-format header) (setq buffer-read-only t) (pop-to-buffer (current-buffer)) (goto-char pos)) (if bufler-cache-related-dirs-timer (progn (cancel-timer bufler-cache-related-dirs-timer))) (setq bufler-cache-related-dirs-timer (run-with-idle-timer bufler-cache-related-dirs-timeout nil #'(lambda nil …))))))) (let (–cl-insert-thing– –cl-insert-buffer– –cl-insert-group– –cl-format-group– –cl-hidden-p– –cl-as-string– –cl-format<– –cl-boring-p–) (setq –cl-insert-thing– #'(lambda (thing path &rest –cl-rest–) "\n\n(fn THING PATH &optional (LEVEL 0))" (let* ((level (if –cl-rest– … 0))) (progn (if –cl-rest– (signal … …)) (if (bufferp thing) (progn …) (funcall –cl-insert-group– thing … level)))))) (setq –cl-insert-buffer– #'(lambda (buffer) (let* ((type20 'bufler-buffer) (section21 (funcall … :type … :value buffer :start … :parent magit-insert-section–parent))) (eieio-oset section21 'hidden (let (…) (if value … …))) (let ((magit-insert-section–current section21) (magit-insert-section–parent section21) (magit-insert-section–oldroot …)) (catch 'cancel-section (insert … "\n") (run-hooks …) (magit-insert-child-count section21) (set-marker-insertion-type … t) (let* … …) (if … … …)) section21)))) (setq –cl-insert-group– #'(lambda (group path level) (let* ((val (car group))) (if (null val) (progn (let* … …)) (let* (… …) (let … …)))))) (setq –cl-format-group– #'(lambda (group level) (let* ((string (cond … …))) (propertize string 'face (list :inherit (list … …)))))) (setq –cl-hidden-p– #'(lambda (buffer) (string-prefix-p " " (buffer-name buffer)))) (setq –cl-as-string– #'(lambda (arg) (cond ((stringp arg) arg) (t (format "%s" arg))))) (setq –cl-format<– #'(lambda (test-dir buffer-dir) (string< (funcall –cl-as-string– test-dir) (funcall –cl-as-string– buffer-dir)))) (setq –cl-boring-p– #'(lambda (buffer) (funcall –cl-hidden-p– buffer))) (if force-refresh (progn (setq bufler-cache nil))) (let* ((inhibit-read-only t) (bufler-vc-refresh force-refresh) (groups (bufler-buffers)) (val (bufler-format-buffer-groups groups)) (x23 (car val)) (x24 (cdr val))) (let ((column-sizes x24) (format-table x23)) (let ((header (concat (format … …) (let* … … –cl-var–))) (pos)) (progn (setq format-table format-table) (if bufler-reverse (progn (setq groups …))) (save-current-buffer (set-buffer (get-buffer-create "*Bufler")) (setq pos (point)) (bufler-list-mode) (erase-buffer) (let* (… …) (eieio-oset section25 … …) (let … … section25)) (setq header-line-format header) (setq buffer-read-only t) (pop-to-buffer (current-buffer)) (goto-char pos)) (if bufler-cache-related-dirs-timer (progn (cancel-timer bufler-cache-related-dirs-timer))) (setq bufler-cache-related-dirs-timer (run-with-idle-timer bufler-cache-related-dirs-timeout nil #'…))))))) (let (format-table) (let (–cl-insert-thing– –cl-insert-buffer– –cl-insert-group– –cl-format-group– –cl-hidden-p– –cl-as-string– –cl-format<– –cl-boring-p–) (setq –cl-insert-thing– #'(lambda (thing path &rest –cl-rest–) "\n\n(fn THING PATH &optional (LEVEL 0))" (let* ((level …)) (progn (if –cl-rest– …) (if … … …))))) (setq –cl-insert-buffer– #'(lambda (buffer) (let* ((type20 …) (section21 …)) (eieio-oset section21 'hidden (let … …)) (let (… … …) (catch … … … … … … …) section21)))) (setq –cl-insert-group– #'(lambda (group path level) (let* ((val …)) (if (null val) (progn …) (let* … …))))) (setq –cl-format-group– #'(lambda (group level) (let* ((string …)) (propertize string 'face (list :inherit …))))) (setq –cl-hidden-p– #'(lambda (buffer) (string-prefix-p " " (buffer-name buffer)))) (setq –cl-as-string– #'(lambda (arg) (cond ((stringp arg) arg) (t (format "%s" arg))))) (setq –cl-format<– #'(lambda (test-dir buffer-dir) (string< (funcall –cl-as-string– test-dir) (funcall –cl-as-string– buffer-dir)))) (setq –cl-boring-p– #'(lambda (buffer) (funcall –cl-hidden-p– buffer))) (if force-refresh (progn (setq bufler-cache nil))) (let* ((inhibit-read-only t) (bufler-vc-refresh force-refresh) (groups (bufler-buffers)) (val (bufler-format-buffer-groups groups)) (x23 (car val)) (x24 (cdr val))) (let ((column-sizes x24) (format-table x23)) (let ((header (concat … …)) (pos)) (progn (setq format-table format-table) (if bufler-reverse (progn …)) (save-current-buffer (set-buffer …) (setq pos …) (bufler-list-mode) (erase-buffer) (let … … …) (setq header-line-format header) (setq buffer-read-only t) (pop-to-buffer …) (goto-char pos)) (if bufler-cache-related-dirs-timer (progn …)) (setq bufler-cache-related-dirs-timer (run-with-idle-timer bufler-cache-related-dirs-timeout nil …)))))))) bufler-list() (let* nil (bufler–map-sections #'kill-buffer sections) (bufler-list)) (if sections (let* nil (bufler–map-sections #'kill-buffer sections) (bufler-list))) (let* ((sections (and t (or (magit-region-sections) (list (magit-current-section)))))) (if sections (let* nil (bufler–map-sections #'kill-buffer sections) (bufler-list)))) bufler-list-buffer-kill() funcall-interactively(bufler-list-buffer-kill) call-interactively(bufler-list-buffer-kill nil nil) command-execute(bufler-list-buffer-kill)

bufler-workspace-tabs-mode breaks tab-bar--current-tab-index

Another great package! bufler-workspace-tabs-mode looks particularly promising.
I've been experimenting with it and ran into a minor issue:
bufler-workspace-tabs seems to break tab-bar--current-tab-index

I haven't had much time to look into the source, but I did note your commentary on bufler-workspace-tabs and the complicated requirements of its implementation.
An ECM:

(bufler-workspace-tabs-mode)
(condition-case err
    (tab-bar--current-tab-index)
  (error err))

returns:

(wrong-type-argument framep nil)

Here's a backtrace:

Debugger entered--Lisp error: (wrong-type-argument framep nil)
select-frame(nil norecord)
(progn (select-frame frame 'norecord) (cl-labels ((tab-type (path) (if (equal path (frame-parameter nil 'bufler-workspace-path)) 'current-tab 'tab)) (path-first (path) (cl-typecase path (string (list path)) (list (if (car path) (list ...) (list ...))))) (workspace-to-tab (workspace &optional type) (-let* (((&plist :name :path) workspace)) (list (or type (tab-type path)) (cons 'name (car name)) (cons 'path path)))) (path-top-level (path) (pcase-exhaustive path (`(... ... \, _rest) (ignore first second) (cl-subseq path 0 2)) (`(... \, _rest) (list first)))) (path-to-workspace (path) (list :name (path-first path) :path path))) (let* ((bufler-vc-refresh nil) (buffer-paths (bufler-group-tree-paths (bufler-buffers))) (group-paths (mapcar #'butlast buffer-paths)) (top-level-paths (mapcar #'path-top-level group-paths)) (top-level-workspaces (mapcar #'path-to-workspace top-level-paths)) (unique-top-level-workspaces (seq-uniq top-level-workspaces #'equal)) (tabs (mapcar #'workspace-to-tab unique-top-level-workspaces))) (unless (cl-loop with current-path = (frame-parameter nil 'bufler-workspace-path) for tab in tabs for tab-path = (alist-get 'path tab) thereis (equal tab-path current-path)) (push (list 'current-tab (cons 'name (bufler-format-path ...)) (cons 'path (frame-parameter nil ...))) tabs)) tabs)))
(unwind-protect (progn (select-frame frame 'norecord) (cl-labels ((tab-type (path) (if (equal path (frame-parameter nil ...)) 'current-tab 'tab)) (path-first (path) (cl-typecase path (string (list path)) (list (if ... ... ...)))) (workspace-to-tab (workspace &optional type) (-let* ((... workspace)) (list (or type ...) (cons ... ...) (cons ... path)))) (path-top-level (path) (pcase-exhaustive path (`... (ignore first second) (cl-subseq path 0 2)) (`... (list first)))) (path-to-workspace (path) (list :name (path-first path) :path path))) (let* ((bufler-vc-refresh nil) (buffer-paths (bufler-group-tree-paths (bufler-buffers))) (group-paths (mapcar #'butlast buffer-paths)) (top-level-paths (mapcar #'path-top-level group-paths)) (top-level-workspaces (mapcar #'path-to-workspace top-level-paths)) (unique-top-level-workspaces (seq-uniq top-level-workspaces #'equal)) (tabs (mapcar #'workspace-to-tab unique-top-level-workspaces))) (unless (cl-loop with current-path = (frame-parameter nil 'bufler-workspace-path) for tab in tabs for tab-path = (alist-get 'path tab) thereis (equal tab-path current-path)) (push (list 'current-tab (cons ... ...) (cons ... ...)) tabs)) tabs))) (when (frame-live-p old-frame) (select-frame old-frame 'norecord)) (when (buffer-live-p old-buffer) (set-buffer old-buffer)))
(let ((old-frame (selected-frame)) (old-buffer (current-buffer))) (unwind-protect (progn (select-frame frame 'norecord) (cl-labels ((tab-type (path) (if (equal path ...) 'current-tab 'tab)) (path-first (path) (cl-typecase path (string ...) (list ...))) (workspace-to-tab (workspace &optional type) (-let* (...) (list ... ... ...))) (path-top-level (path) (pcase-exhaustive path (... ... ...) (... ...))) (path-to-workspace (path) (list :name (path-first path) :path path))) (let* ((bufler-vc-refresh nil) (buffer-paths (bufler-group-tree-paths ...)) (group-paths (mapcar ... buffer-paths)) (top-level-paths (mapcar ... group-paths)) (top-level-workspaces (mapcar ... top-level-paths)) (unique-top-level-workspaces (seq-uniq top-level-workspaces ...)) (tabs (mapcar ... unique-top-level-workspaces))) (unless (cl-loop with current-path = (frame-parameter nil ...) for tab in tabs for tab-path = (alist-get ... tab) thereis (equal tab-path current-path)) (push (list ... ... ...) tabs)) tabs))) (when (frame-live-p old-frame) (select-frame old-frame 'norecord)) (when (buffer-live-p old-buffer) (set-buffer old-buffer))))
(with-selected-frame frame (cl-labels ((tab-type (path) (if (equal path (frame-parameter nil 'bufler-workspace-path)) 'current-tab 'tab)) (path-first (path) (cl-typecase path (string (list path)) (list (if (car path) (list ...) (list ...))))) (workspace-to-tab (workspace &optional type) (-let* (((&plist :name :path) workspace)) (list (or type (tab-type path)) (cons 'name (car name)) (cons 'path path)))) (path-top-level (path) (pcase-exhaustive path (`(... ... \, _rest) (ignore first second) (cl-subseq path 0 2)) (`(... \, _rest) (list first)))) (path-to-workspace (path) (list :name (path-first path) :path path))) (let* ((bufler-vc-refresh nil) (buffer-paths (bufler-group-tree-paths (bufler-buffers))) (group-paths (mapcar #'butlast buffer-paths)) (top-level-paths (mapcar #'path-top-level group-paths)) (top-level-workspaces (mapcar #'path-to-workspace top-level-paths)) (unique-top-level-workspaces (seq-uniq top-level-workspaces #'equal)) (tabs (mapcar #'workspace-to-tab unique-top-level-workspaces))) (unless (cl-loop with current-path = (frame-parameter nil 'bufler-workspace-path) for tab in tabs for tab-path = (alist-get 'path tab) thereis (equal tab-path current-path)) (push (list 'current-tab (cons 'name (bufler-format-path ...)) (cons 'path (frame-parameter nil ...))) tabs)) tabs)))
(catch '--cl-block-bufler-workspace-tabs-- (with-selected-frame frame (cl-labels ((tab-type (path) (if (equal path (frame-parameter nil ...)) 'current-tab 'tab)) (path-first (path) (cl-typecase path (string (list path)) (list (if ... ... ...)))) (workspace-to-tab (workspace &optional type) (-let* ((... workspace)) (list (or type ...) (cons ... ...) (cons ... path)))) (path-top-level (path) (pcase-exhaustive path (`... (ignore first second) (cl-subseq path 0 2)) (`... (list first)))) (path-to-workspace (path) (list :name (path-first path) :path path))) (let* ((bufler-vc-refresh nil) (buffer-paths (bufler-group-tree-paths (bufler-buffers))) (group-paths (mapcar #'butlast buffer-paths)) (top-level-paths (mapcar #'path-top-level group-paths)) (top-level-workspaces (mapcar #'path-to-workspace top-level-paths)) (unique-top-level-workspaces (seq-uniq top-level-workspaces #'equal)) (tabs (mapcar #'workspace-to-tab unique-top-level-workspaces))) (unless (cl-loop with current-path = (frame-parameter nil 'bufler-workspace-path) for tab in tabs for tab-path = (alist-get 'path tab) thereis (equal tab-path current-path)) (push (list 'current-tab (cons ... ...) (cons ... ...)) tabs)) tabs))))
(cl--block-wrapper (catch '--cl-block-bufler-workspace-tabs-- (with-selected-frame frame (cl-labels ((tab-type (path) (if (equal path ...) 'current-tab 'tab)) (path-first (path) (cl-typecase path (string ...) (list ...))) (workspace-to-tab (workspace &optional type) (-let* (...) (list ... ... ...))) (path-top-level (path) (pcase-exhaustive path (... ... ...) (... ...))) (path-to-workspace (path) (list :name (path-first path) :path path))) (let* ((bufler-vc-refresh nil) (buffer-paths (bufler-group-tree-paths ...)) (group-paths (mapcar ... buffer-paths)) (top-level-paths (mapcar ... group-paths)) (top-level-workspaces (mapcar ... top-level-paths)) (unique-top-level-workspaces (seq-uniq top-level-workspaces ...)) (tabs (mapcar ... unique-top-level-workspaces))) (unless (cl-loop with current-path = (frame-parameter nil ...) for tab in tabs for tab-path = (alist-get ... tab) thereis (equal tab-path current-path)) (push (list ... ... ...) tabs)) tabs)))))
(cl-block bufler-workspace-tabs (with-selected-frame frame (cl-labels ((tab-type (path) (if (equal path (frame-parameter nil ...)) 'current-tab 'tab)) (path-first (path) (cl-typecase path (string (list path)) (list (if ... ... ...)))) (workspace-to-tab (workspace &optional type) (-let* ((... workspace)) (list (or type ...) (cons ... ...) (cons ... path)))) (path-top-level (path) (pcase-exhaustive path (`... (ignore first second) (cl-subseq path 0 2)) (`... (list first)))) (path-to-workspace (path) (list :name (path-first path) :path path))) (let* ((bufler-vc-refresh nil) (buffer-paths (bufler-group-tree-paths (bufler-buffers))) (group-paths (mapcar #'butlast buffer-paths)) (top-level-paths (mapcar #'path-top-level group-paths)) (top-level-workspaces (mapcar #'path-to-workspace top-level-paths)) (unique-top-level-workspaces (seq-uniq top-level-workspaces #'equal)) (tabs (mapcar #'workspace-to-tab unique-top-level-workspaces))) (unless (cl-loop with current-path = (frame-parameter nil 'bufler-workspace-path) for tab in tabs for tab-path = (alist-get 'path tab) thereis (equal tab-path current-path)) (push (list 'current-tab (cons ... ...) (cons ... ...)) tabs)) tabs))))
(progn (if --cl-rest-- (signal 'wrong-number-of-arguments (list 'bufler-workspace-tabs (+ 1 (length --cl-rest--))))) (cl-block bufler-workspace-tabs (with-selected-frame frame (cl-labels ((tab-type (path) (if (equal path ...) 'current-tab 'tab)) (path-first (path) (cl-typecase path (string ...) (list ...))) (workspace-to-tab (workspace &optional type) (-let* (...) (list ... ... ...))) (path-top-level (path) (pcase-exhaustive path (... ... ...) (... ...))) (path-to-workspace (path) (list :name (path-first path) :path path))) (let* ((bufler-vc-refresh nil) (buffer-paths (bufler-group-tree-paths ...)) (group-paths (mapcar ... buffer-paths)) (top-level-paths (mapcar ... group-paths)) (top-level-workspaces (mapcar ... top-level-paths)) (unique-top-level-workspaces (seq-uniq top-level-workspaces ...)) (tabs (mapcar ... unique-top-level-workspaces))) (unless (cl-loop with current-path = (frame-parameter nil ...) for tab in tabs for tab-path = (alist-get ... tab) thereis (equal tab-path current-path)) (push (list ... ... ...) tabs)) tabs)))))
(let* ((frame (if --cl-rest-- (pop --cl-rest--) (selected-frame)))) (progn (if --cl-rest-- (signal 'wrong-number-of-arguments (list 'bufler-workspace-tabs (+ 1 (length --cl-rest--))))) (cl-block bufler-workspace-tabs (with-selected-frame frame (cl-labels ((tab-type (path) (if ... ... ...)) (path-first (path) (cl-typecase path ... ...)) (workspace-to-tab (workspace &optional type) (-let* ... ...)) (path-top-level (path) (pcase-exhaustive path ... ...)) (path-to-workspace (path) (list :name ... :path path))) (let* ((bufler-vc-refresh nil) (buffer-paths ...) (group-paths ...) (top-level-paths ...) (top-level-workspaces ...) (unique-top-level-workspaces ...) (tabs ...)) (unless (cl-loop with current-path = ... for tab in tabs for tab-path = ... thereis ...) (push ... tabs)) tabs))))))
bufler-workspace-tabs(nil)
tab-bar--current-tab-index()
(progn (tab-bar--current-tab-index))
eval((progn (tab-bar--current-tab-index)) t)
elisp--eval-last-sexp(nil)
eval-last-sexp(nil)
funcall-interactively(eval-last-sexp nil)
call-interactively(eval-last-sexp nil nil)
command-execute(eval-last-sexp)

What initially brought this to my attention was doom-modeline.
It has a segment that displays the current tab index in the modeline and it signals (quite a few depending on the situation) errors on redisplay:

Error during redisplay: (eval (doom-modeline-segment--workspace-name)) signaled (wrong-type-argument framep nil) [1038 times]

If there's anything more I can do to help, let me know.

Thanks again for the great package,
Nick Vollmer

bufler-switch-buffer: Default to "other" buffer?

In a workspace, using bufler-switch-buffer, the default (topmost sorted) buffer often is the buffer I'm currently in. You can reproduce the current behavior by setting the frame-workspace in a frame with one buffer, opening a second buffer, and then using M-x bufler-switch-buffer twice in a row: I'd expect the buffer that is not currently active to be selected.

It would be great (since I use that b-s-b on C-x b and finger memory for "let's go back" is so strong), to be able to switch to the other-buffer from the buffer I'm currently in, like switch-buffer does it via the read-buffer-to-switch function:

      (read-buffer prompt (other-buffer (current-buffer))
                   (confirm-nonexistent-file-or-buffer))

Marking and acting on non-adjacent buffers

Hey! Incredible job on this, you're a more tenacious person than I am. I tried to configure ibuffer to do exactly what you've made bufler do and your implementation is so much better. However there's one feature I miss.

Having the marking of buffers and all associated features would be absolutely killer. I often regex mark ibuffers by term mode, and other such things. In particular, the following functions are really useful for managing buffers. The keybindings also match the other killer emacs package, dired:

From ibuffer

‘S’ - Save the marked buffers.
‘A’ - View the marked buffers in the selected frame.
‘H’ - View the marked buffers in another frame.
‘V’ - Revert the marked buffers.
‘T’ - Toggle read-only state of marked buffers.
‘L’ - Toggle lock state of marked buffers.
‘D’ - Kill the marked buffers.
‘M-s a C-s’ - Do incremental search in the marked buffers.
‘M-s a C-M-s’ - Isearch for regexp in the marked buffers.
‘r’ - Replace by regexp in each of the marked
‘Q’ - Query replace in each of the marked buffers.
‘P’ - Print the marked buffers.
‘O’ - List lines in all marked buffers which match
‘X’ - Pipe the contents of the marked
‘N’ - Replace the contents of the marked
‘E’ - Evaluate a form in each of the marked buffers.
‘k’ - Remove the marked lines from the Ibuffer buffer,
‘x’ - Kill all buffers marked for deletion.
‘m’ - Mark the buffer at point.
‘t’ - Unmark all currently marked buffers, and mark all unmarked buffers.
‘* c’ - Change the mark used on marked buffers.
‘u’ - Unmark the buffer at point.
‘DEL’ - Unmark the previous buffer.
‘M -DEL’ - Unmark buffers marked with MARK.
‘U’ - Unmark all marked buffers.
‘* M’ - Mark buffers by major mode.
‘* u’ - Mark all "unsaved" buffers.
‘* m’ - Mark all modified buffers,
‘* s’ - Mark all buffers whose name begins and
‘* e’ - Mark all buffers which have
‘* r’ - Mark all read-only buffers.
‘* /’ - Mark buffers in ‘dired-mode’.
‘* h’ - Mark buffers in ‘help-mode’, ‘apropos-mode’, etc.
‘.’ - Mark buffers older than ‘ibuffer-old-time’.
‘d’ - Mark the buffer at point for deletion.
‘% n’ - Mark buffers by their name, using a regexp.
‘% m’ - Mark buffers by their major mode, using a regexp.
‘% f’ - Mark buffers by their filename, using a regexp.
‘% g’ - Mark buffers by their content, using a regexp.
‘% L’ - Mark all locked buffers.

From dired:

m dired-mark
t dired-toggle-marks
u dired-unmark
DEL dired-unmark-backward
C-t f image-dired-mark-tagged-files
M-{ dired-prev-marked-file
M-} dired-next-marked-file
% g dired-mark-files-containing-regexp
% m dired-mark-files-regexp
* ! dired-unmark-all-marks
* % dired-mark-files-regexp
* * dired-mark-executables
* / dired-mark-directories
* ? dired-unmark-all-files
* @ dired-mark-symlinks
* N dired-number-of-marked-files
* c dired-change-marks
* m dired-mark
* s dired-mark-subdir-files

deeper levels

Hello,

I am sorry in advance as I am pretty sure my question is completely stupid at this stage. Nevertheless, here it is :D.

I try to configure a group with a "deeper level architecture". My plan is to get something like this:

Chatty
   |
   +------------ ERC  <buffers with mode name matching "^erc-.*">
   |              |
   |              +------------ Channels
   |              |               |
   |              |               + <buffers with name matching "^#">  
   |              |
   |              +------------ Server
   |              |               |
   |              |               + <buffers with name matching "^[a-zA-Z0-9.]*:[0-9]\\{4\\}">
   |              |
   |              +------------- Remaining
   |                              |
   |                              + everything which is neither a channel or a server
   |
   ...

I want to keep the name of the section like this as well as I find it clearer. My main problem comes from the main condition (the ERC part) and how to force the creation of the groups Channels, Server and Remaining. Do you have a direction I can start to look at?

Thanks a lot

bufler-list-buffer-kill occasionally leaves an open row

I apologize in advance that I can't make this happen reliably, but it seems bufler-list-buffer-kill sometimes leaves a nearly-empty row in the *Bufler* window.

For instance:
Screen Shot 2020-03-19 at 3 54 39 PM

That blank row was the *Warnings* buffer with size 95, and I just killed it (k). Once I refresh the buffer (g) this row will get be cleaned up. I'll keep watching for ways to repeat this. So far I think it has always been special buffers, not file-backed buffers, but I might be wrong about that.

throws error on buffer list refresh

How to reproduce

  1. M-x bufler-list
  2. Kill any buffer using k

Stacktrace

Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p nil)
  >=(nil 16)
  (if (>= arg 16) nil bufler-filter-buffer-fns)
  (bufler-buffers :filter-fns (if (>= arg 16) nil bufler-filter-buffer-fns))
  (let* ((inhibit-read-only t) (bufler-vc-refresh arg) (groups (bufler-buffers :filter-fns (if (>= arg 16) nil bufler-filter-buffer-fns))) (val (bufler-format-buffer-groups groups)) (x76 (car val)) (x77 (cdr val))) (let ((column-sizes x77) (*format-table x76)) (let* ((header (concat (format (format " %%-%ss" ...) (car ...)) (let* (... ... ... ... ...) (while ... ... ... ... ...) --cl-var--))) (pos)) (progn (setq format-table *format-table) (if bufler-reverse (progn (setq groups (nreverse ...)))) (save-current-buffer (set-buffer (get-buffer-create "*Bufler*")) (setq pos (point)) (bufler-list-mode) (erase-buffer) (let* ((type17 ...) (section18 ...)) (eieio-oset section18 'hidden (let ... ...)) (let (... ... ...) (catch ... ... ... ... ... ... ...) section18)) (setq header-line-format header) (setq buffer-read-only t) (pop-to-buffer (current-buffer)) (goto-char pos)) (if bufler-cache-related-dirs-timer (progn (cancel-timer bufler-cache-related-dirs-timer))) (setq bufler-cache-related-dirs-timer (run-with-idle-timer bufler-cache-related-dirs-timeout nil #'(lambda nil ...)))))))
  (let (--cl-insert-thing-- --cl-insert-buffer-- --cl-insert-group-- --cl-format-group-- --cl-hidden-p-- --cl-as-string-- --cl-format<--) (setq --cl-insert-thing-- #'(lambda (thing path &rest --cl-rest--) "\n\n(fn THING PATH &optional (LEVEL 0))" (let* ((level (if --cl-rest-- ... 0))) (progn (if --cl-rest-- (signal ... ...)) (if (bufferp thing) (progn ...) (funcall --cl-insert-group-- thing ... level)))))) (setq --cl-insert-buffer-- #'(lambda (buffer) (let* ((type13 'bufler-buffer) (section14 (funcall ... :type ... :value buffer :start ... :parent magit-insert-section--parent))) (eieio-oset section14 'hidden (let (...) (if value ... ...))) (let ((magit-insert-section--current section14) (magit-insert-section--parent section14) (magit-insert-section--oldroot ...)) (catch 'cancel-section (insert ... "\n") (run-hooks ...) (magit-insert-child-count section14) (set-marker-insertion-type ... t) (let* ... ...) (if ... ... ...)) section14)))) (setq --cl-insert-group-- #'(lambda (group path level) (let* ((val (car group))) (if (null val) (progn (let* ... ...)) (let* (... ...) (let ... ...)))))) (setq --cl-format-group-- #'(lambda (group level) (let* ((string (cond ... ...))) (propertize string 'face (list :inherit (list ... ...)))))) (setq --cl-hidden-p-- #'(lambda (buffer) (string-prefix-p " " (buffer-name buffer)))) (setq --cl-as-string-- #'(lambda (arg) (cond ((stringp arg) arg) (t (format "%s" arg))))) (setq --cl-format<-- #'(lambda (test-dir buffer-dir) (string< (funcall --cl-as-string-- test-dir) (funcall --cl-as-string-- buffer-dir)))) (if arg (progn (setq bufler-cache nil))) (let* ((inhibit-read-only t) (bufler-vc-refresh arg) (groups (bufler-buffers :filter-fns (if (>= arg 16) nil bufler-filter-buffer-fns))) (val (bufler-format-buffer-groups groups)) (x76 (car val)) (x77 (cdr val))) (let ((column-sizes x77) (*format-table x76)) (let* ((header (concat (format ... ...) (let* ... ... --cl-var--))) (pos)) (progn (setq format-table *format-table) (if bufler-reverse (progn (setq groups ...))) (save-current-buffer (set-buffer (get-buffer-create "*Bufler*")) (setq pos (point)) (bufler-list-mode) (erase-buffer) (let* (... ...) (eieio-oset section18 ... ...) (let ... ... section18)) (setq header-line-format header) (setq buffer-read-only t) (pop-to-buffer (current-buffer)) (goto-char pos)) (if bufler-cache-related-dirs-timer (progn (cancel-timer bufler-cache-related-dirs-timer))) (setq bufler-cache-related-dirs-timer (run-with-idle-timer bufler-cache-related-dirs-timeout nil #'...)))))))
  (let (format-table) (let (--cl-insert-thing-- --cl-insert-buffer-- --cl-insert-group-- --cl-format-group-- --cl-hidden-p-- --cl-as-string-- --cl-format<--) (setq --cl-insert-thing-- #'(lambda (thing path &rest --cl-rest--) "\n\n(fn THING PATH &optional (LEVEL 0))" (let* ((level ...)) (progn (if --cl-rest-- ...) (if ... ... ...))))) (setq --cl-insert-buffer-- #'(lambda (buffer) (let* ((type13 ...) (section14 ...)) (eieio-oset section14 'hidden (let ... ...)) (let (... ... ...) (catch ... ... ... ... ... ... ...) section14)))) (setq --cl-insert-group-- #'(lambda (group path level) (let* ((val ...)) (if (null val) (progn ...) (let* ... ...))))) (setq --cl-format-group-- #'(lambda (group level) (let* ((string ...)) (propertize string 'face (list :inherit ...))))) (setq --cl-hidden-p-- #'(lambda (buffer) (string-prefix-p " " (buffer-name buffer)))) (setq --cl-as-string-- #'(lambda (arg) (cond ((stringp arg) arg) (t (format "%s" arg))))) (setq --cl-format<-- #'(lambda (test-dir buffer-dir) (string< (funcall --cl-as-string-- test-dir) (funcall --cl-as-string-- buffer-dir)))) (if arg (progn (setq bufler-cache nil))) (let* ((inhibit-read-only t) (bufler-vc-refresh arg) (groups (bufler-buffers :filter-fns (if (>= arg 16) nil bufler-filter-buffer-fns))) (val (bufler-format-buffer-groups groups)) (x76 (car val)) (x77 (cdr val))) (let ((column-sizes x77) (*format-table x76)) (let* ((header (concat ... ...)) (pos)) (progn (setq format-table *format-table) (if bufler-reverse (progn ...)) (save-current-buffer (set-buffer ...) (setq pos ...) (bufler-list-mode) (erase-buffer) (let* ... ... ...) (setq header-line-format header) (setq buffer-read-only t) (pop-to-buffer ...) (goto-char pos)) (if bufler-cache-related-dirs-timer (progn ...)) (setq bufler-cache-related-dirs-timer (run-with-idle-timer bufler-cache-related-dirs-timeout nil ...))))))))
  bufler-list()
  bufler-list-buffer-kill()
  funcall-interactively(bufler-list-buffer-kill)
  call-interactively(bufler-list-buffer-kill nil nil)
  command-execute(bufler-list-buffer-kill)

Suspect

looks like the bug was introduced by 62d64c9

bufler-switch-to-buffer: Behavior when no matching buffers

So I've been using bufler-switch-to-buffer quite happily for a few days now, but today was the first time I hit a limitation: I meant to create a new buffer by typing a new name, like *foo*, expecting that it would be created with that name verbatim. However, what bufler did was a bit baffling: It switched to a completely unrelated, existing buffer.

I'm wondering what a good behavior would be, under the circumstances:

  • If no frame workspace is set, I think it's completely reasonable to create (or prompt to create the buffer with the given name).
  • If one is set, that's an open question: The buffer name entered might match an off-workspace buffer (e.g. enter *scratch* in a non-"Special" workspace). I see two options:
    • switch to the matching buffer (maybe even show it on the list of available completions? Does that work?)
    • prompt to create a second one.
    • do nothing? (That's my least favorite)

Does that sound reasonable? If you agree, I can try to cobble something together in a PR (:

https://melpa.org/packages/magit-section-20200123.2235.tar: Not found

Tried installing with:

(use-package sbuffer
  :quelpa (sbuffer :fetcher github :repo "alphapapa/sbuffer.el"))

It fails with the following messages:

Fetcher: github
Source: alphapapa/sbuffer.el

Cloning https://github.com/alphapapa/sbuffer.el.git to /home/mark/.config/emacs/quelpa/build/sbuffer/
Saving file /home/mark/.config/emacs/quelpa/packages/sbuffer-20200219.347.el...
Wrote /home/mark/.config/emacs/quelpa/packages/sbuffer-20200219.347.el
Wrote /home/mark/.config/emacs/quelpa/packages/sbuffer-readme.txt
Contacting host: melpa.org:443
package--with-response-buffer-1: https://melpa.org/packages/magit-section-20200123.2235.tar: Not found

My environment is:

GNU Emacs 28.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.22.30, cairo version 1.15.10) of 2020-01-15
Magit 20200208.551, Git 2.17.1, Emacs 28.0.50, gnu/linux

Using auto-project when vc is disabled

I'm sure this must be possible but I'm not sure how you express it in the group syntax. I want all buffers associated with the same (magit-git-dir) to be grouped together. This is instead of having stuff configured using projectile or project.

Do I need to define another bufler-defauto-group macro?

Auto refresh?

Is there a way to make bufler automatically refresh when buffers change?

Enhancement idea: recent list?

I realize that Bufler is combining ideas of ibuffer and persp/perspective/torus, so I'm not sure this idea completely fits, but it would be nice for my usecase...

I don't care so much about the persp parts of bufler, but I quite like the buffler-switch-buffers list and display; I love the way it automatically places things in categories and groups. What I really miss compared to plain ivy-switch-buffer and helm-switch-buffer, however, is the "recently visited" inclusion so that all my recents are among my choices. I know that bufler is centered on the buffer list, which obviously doesn't include buffers that aren't currently open, but this might be a worthy discussion point. Have you considered any ways of including files from the recent list in the bufler-switch-buffer list?

buffer-tabs-mode doesn't support sym link

My inbox.org is in "~/org" which follows a symlink.

The tab-bar says "~/org". But the tab-line is empty. The xx.org buffer was classified into "Special"
instead.

Buffer list is normal.

My guess is that the tab-line buffer names follows symlink which fails to match the tab-bar name.

I am on win 10 using wsl with emacs v28.0.x

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.