[Top][All Lists]

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

more lexical/dynamic trouble

From: Emanuel Berg
Subject: more lexical/dynamic trouble
Date: Sun, 17 Oct 2021 13:58:38 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux)

With lexical binding, and a closure, I was able to remove two
defvars, i.e. global variables (so they were special/dynamic as

But for some reason first it wouldn't work ... then I saw the
file in the `buffer-menu' /d in red! So the whole file was
actually under dynamic binding despite the use of

-*- lexical-binding: t

in the first line!

Reason, I had put it LAST, not first! Look below how it
should look!

Also: see the use of `declare-function' to shut up the

Also: beware that `checkdoc-current-buffer' reports

  The first line should be of the form: ";;; package --- Summary"

which is incorrect if you'd like `lexical-binding' and the
reason I put it at the back of that line initially (which
doesn't work).

OK, should check out my other packs and see if they are
special/dynamic as well, and if there are `defvar' to prune
there as well ...

;;; -*- lexical-binding: t -*- buc.el --- move between buffers based on category
;;; Author: Emanuel Berg (incal) <>
;;; Created: 2021-05-23
;;; Keywords: docs, files
;;; License: GPL3+
;;; Package-Requires: ((cl-lib "1.0"))
;;; URL:
;;; Version: 1.0.4
;;; 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)) )

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

(declare-function get-ps                   load-file-name)
(declare-function navigate-buffer-category load-file-name)

(let*((nav-keys    '(?\r ?\s ?\t ?\d ?\C-j ?\C-k ?\C-l ?\C-u ?\C-o ?\C-p))
      (nav-keys-str (split-string (key-description nav-keys))) )
  (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, 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 (and key (char-to-string key))))) )

(defun man-buc ()
  "Show man pages.
If you start typing, you get the common prompt."
  (navigate-buffer-category "*Man " #'switch-to-type "[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]