[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: buc.el ready

From: Emanuel Berg
Subject: Re: buc.el ready
Date: Tue, 06 Jul 2021 18:18:28 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

Stefan Monnier via Users list for the GNU Emacs text editor wrote:

>> ;;; buc.el --- move between buffers based on category -*- lexical-binding: t
>> ;;;
>> ;;; Commentary:
>> ;;;
>> ;;; Author: Emanuel Berg (incal) <>
>> ;;; Created: 2021-05-23
>> ;;; Keywords: docs, files
>> ;;; License: GPL3+
>> ;;; Package-Requires: ((cl-lib "1.0"))
>> ;;; URL:
>> ;;; Version: 2.0.0
> Three semi-colons (and more) are used for outline/section
> headers, so it's right for "Commentary:" but not for the
> other lines above, which should only have two semi-colons.

I know/I've seen that but that looks so ugly. But OK...

What do you think of the idea BTW?

;;; buc.el --- move between buffers based on category -*- lexical-binding: t
;; Author: Emanuel Berg (incal) <>
;; Created: 2021-05-23
;; Keywords: docs, files
;; License: GPL3+
;; Package-Requires: ((cl-lib "1.0"))
;; URL:
;; Version: 1.0.3
;;; Commentary:
;; This package enables you to move between similar buffers.
;; So far I have only found one use case for it, namely
;; accessing man pages - try `man-buc' below.
;; The general idea behind the interface is to present
;; alternatives based on your recent answers to the same
;; questions. The alternatives are sorted to present you with
;; the most relevant one first. You pick an alternative by
;; hitting a single key. If your desired choice is not among
;; the alternatives, start typing, that will bypass the
;; interface and the default interface will be used as
;; a fallback. (But technically it is not a fallback, rather
;; the interfaces are cooperating covering different parts of
;; one problem.)
;; Note that If you count the number of keypresses you see
;; the advantage with this package. When the buc interface is
;; used, the count is much lower, since making a choice
;; involves hitting a single key or combination. But even
;; when it is not used, the count still is not higher than
;; what you would use anyway, since the default interface
;; immediately comes to life and utilizes the first keydown
;; as its first input char. Again, try `man-buc' to see how
;; it works first hand.
;; Or take a look at this screenshot:
;; The principle behind the interface is similar to that of
;; a computer hardware memory cache: proximity in space and
;; time, with updates on every single access.
;; The interface is an hybrid between the GUI and CLI style,
;; only the GUI "icons" are here words! Some say icons are
;; more intuitive than words. Well, that is were we agree to
;; disagree - perhaps that holds for infants but not to
;; adults who have spent a HUGE part of their life reading
;; and writing.
;; Because we believe intuition is an acquired skill - just
;; like everything else.
;;; Code:

(require 'cl-lib)

(defun buffer-names ()
  "Get the names of all open buffers, as strings."
  (mapcar #'buffer-name (buffer-list)) )

(defvar nav-keys     nil "The keys used to select buffers.")
(defvar nav-keys-str nil "Descriptions of the buffer-select keys.")

(setq nav-keys     '(?\r ?\s ?\t ?\d ?\C-j ?\C-k ?\C-l ?\C-u ?\C-o ?\C-p))
(setq nav-keys-str  (split-string (key-description nav-keys)))

(defun extract-strings (strings match)
  "From STRINGS, get a list with the parts that MATCH."
  (remove nil
     (lambda (s) (when (string-match match s) (match-string 1 s)))
     strings) ))

(defun get-ps (names)
  "Make the prompt-string, with NAMES."
  (let ((k -1)
        (s " [") )
    (dolist (e names (concat s "] "))
      (setq s (format "%s %s:%s "
                      s (nth (cl-incf k) nav-keys-str) e) ))))

(defun navigate-buffer-category (prefix &optional bad-key &rest args)
  "Display all buffers that start with PREFIX.
If none of the offered buffers are chosen by the user's keystroke,
evaluate (BAD-KEY ARGS)."
  (let ((pages (extract-strings (buffer-names)
                                (format "%s%s" prefix "\\(.*\\)\\*") )))
    (if pages
        (let*((ps         (get-ps pages))
              (key        (read-key ps))
              (page-index (cl-position key nav-keys))
              (page       (when page-index (nth page-index pages))) )
          (if (= key 7)
              (message "quit")
            (if page
                (switch-to-buffer (format "%s%s*" prefix page))
              (when bad-key (apply bad-key `(,@args ,key))) )))
      (if bad-key
          (apply bad-key args)
        (error "Empty category and no fallback function") ))))

(defun switch-to-type (ps fun &optional key)
  "Ask for a string with the prompt-string PS.
Use the string as input to FUN.
If KEY, it'll be the first KEY of the string, auto-inserted."
  (apply fun
         (list (read-string ps
                            (when key
                              (char-to-string key))
                            nil) )))

(defun man-buc ()
  "Show man pages.  If you type, you get the common prompt."
  (navigate-buffer-category "*Man "
                            "[buc] man page: "
                            'man) )

(provide 'buc)
;;; buc.el ends here

underground experts united

reply via email to

[Prev in Thread] Current Thread [Next in Thread]