;; Initialization of my Emacs sessions, part two  │ -*- lexical-binding: t; no-byte-compile: t; -*-
;;
;; This file is loaded by part one of the initialization, q.v. at `http://reluk.ca/.config/emacs/init.el`.
;;
;; PUBLIC at `http://reluk.ca/.config/emacs/` because public files refer to it there, including:
;; http://reluk.ca/project/Breccia/Emacs/brec-mode.el
;; http://reluk.ca/project/Java/Emacs/jmt-mode.el
;; http://reluk.ca/project/wayic/Waybrec/Emacs/waybrec-mode.el


(eval-when-compile (require 'cl-lib)); For macro `cl-assert`.



(defun init/part-two ()
  "Finish the initialization."

  ;; Package management [https://www.gnu.org/software/emacs/manual/html_node/emacs/Packages.html]
  ;; ──────────────────
  (require 'package); If only for sake of `package-generate-autoloads` in `~/.config/emacs/init.el`.
  (defvar package-archives); [FV]
  (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
    ;;; https://melpa.org/
    ;;; https://github.com/melpa/melpa
    ;;; https://github.com/melpa/melpa/blob/master/CONTRIBUTING.org
  ;;(package-initialize); Early that I might override packages’ initial settings
  ;;  ;;; with my own in the code below, rather than have mine overridden by theirs.
  ;;;;; But it delays start up — disabled pending need.

  ;; installing a package
  ;; ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
  ;;   • Run command `list-packages`.
  ;;   • Click on a package name.
  ;;   • Press `install`.
  ;;
  ;; upgrading packages
  ;; ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
  ;;   • Run command `list-packages`.
  ;;   • Type `/u` to show only upgradeable packages.
  ;;   • Type `U` to mark the new versions for installation (I), and the old for deletion (U).
  ;;     Alternatively use `i` and `d` to mark each manually.
  ;;   • Type `x` to execute all marks.
  ;;
  ;; uninstalling packages
  ;; ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
  ;;   • Run command `list-packages`.
  ;;   • Type `/s` to filter by status, for which give `installed`.
  ;;   • Type `d` to mark a package for deletion.
  ;;   • Type `x` to execute all marks.
  ;;   • Run command `package-autoremove`, as prompted.
  ;;
  ;; Custom variable `package-selected-packages` may still list the uninstalled packages.  Not sure why.
  ;; The last time this occured (2023-2), I cleared the list using command `customize-variable`.

  ;; ─────
  (init/general)
  (when (string= window-system "x")
    (init/x)
    (init/fonts)) ; Under X alone, else “error: Fontset `fontset-standard' does not exist”.
  (init/keys)
  (init/modes))



;; ══════════════════════════════════════════════════════════════════════════════════════════════════════
;;  D e c l a r a t i o n s   i n   l e x i c o g r a p h i c   o r d e r
;; ══════════════════════════════════════════════════════════════════════════════════════════════════════


(defconst init/autoload_docstring "[Description not available until function definition is loaded.]" "\
A placeholder description for ‘autoload’ functions.")
  ;;; After the pattern of the placeholder Emacs itself generates for the `arglist`.



(defun init/breccia-automatically (); Mimicing what a package-manager installation would do.
  (load "brec-mode-autoloads" nil t); Q.v. at `http://reluk.ca/sys/computer/workstation/etc/emacs/`.
  (init/breccia))


(defun init/breccia-manually (); As instructed at `http://reluk.ca/project/Breccia/Emacs/brec-mode.el`.
  (autoload 'brec-mode "brec-mode" nil t)
  (set 'auto-mode-alist (cons (cons "\\.brec\\'" 'brec-mode) auto-mode-alist))
  (register-definition-prefixes "brec-mode" '("brec-"))
  (init/breccia))


(defun init/breccia ()
  "Configure Brec Mode and other Breccian particulars."
  (add-hook
   'brec-mode-hook
   (lambda ()
 ;;; (init/set-for-buffer 'line-spacing 2)

     ;; Key bindings for convenience
     ;; ────────────
     (let ((m (make-sparse-keymap))); In order to customize them for the present buffer (below),
         ;;; make the key bindings of `isearch-mode-map` effectively buffer-local:
       (set-keymap-parent m isearch-mode-map)
       (setq-local isearch-mode-map m))

     (local-set-key [f11] [insert ?\\ insert left down]); To overwrite a comment-block delimiter ‘\’,
       ;;; then move point directly beneath it.  (was `toggle-frame-fullscreen`)
     (local-set-key
      [?\C-c ?`]; To wrap a template pattern-matcher around the region if present, else around point.
      (lambda ()
        (interactive)
        (if (use-region-p)
            (let ((start (region-beginning)))
              (goto-char (region-end))
              (insert "$`i")
              (goto-char start)
              (insert "`^^"))
          (insert "`^^${same}$`i")
          (backward-char 10))))
     (local-set-key [?\C-c ?b] (lambda () (interactive)
                                 (init/delimit-by-chars brec-math-block-delimiter-char)))
     (local-set-key [?\C-c ?i] (lambda () (interactive)
                                 (init/delimit-by-chars brec-math-inline-delimiter-char)))
     (let ((sm isearch-mode-map))
       (local-set-key [?\M-m ?b] (lambda () (interactive) (insert-char brec-math-block-delimiter-char)))
       (define-key sm [?\M-m ?b]
                   (lambda () (interactive)
                     (isearch-yank-string (char-to-string brec-math-block-delimiter-char))))
       (local-set-key [?\M-m ?i] (lambda () (interactive) (insert-char brec-math-inline-delimiter-char)))
       (define-key sm [?\M-m ?i]
                   (lambda () (interactive)
                     (isearch-yank-string (char-to-string brec-math-inline-delimiter-char)))))))

  ;; Math Preview integration
  ;; ────────────────────────
  (add-hook
   'brec-original-math-functions
   (lambda (beg -end -exp-beg -exp-end)
     (save-excursion
       (goto-char beg)
       (math-preview-at-point)))))



(defun init/buffer-names-sorted (&optional to-include-specials)
  "Give a list of buffer names in lexicographic order.
Exclude buffers with names starting or ending ‘*’ if TO-INCLUDE-SPECIALS is nil."
  (let (names)
    (dolist (buffer (buffer-list))
      (let ((name (buffer-name buffer)))
        (unless (and (not to-include-specials) (or (string-prefix-p "*" name) (string-suffix-p "*" name)))
          (setq names (cons name names)))))
    (sort names 'init/string-lessp-i)))



(defun init/conf-mode ()
  "Configure `conf-mode`."
  (defvar conf-mode-map); [FV]
  (add-hook
   'conf-mode-hook
   (lambda ()

     ;; Defeat of unwanted key bindings that would override my `init/keys`
     ;; ───────────────────────────────
     ;; TODO more reliably: https://emacs.stackexchange.com/questions/352/how-to-override-major-mode-bindings
     (local-set-key [?\C-c ?8] #'init/delimit-asterisk-quotes)
     (local-set-key [?\C-c ?\"] #'init/delimit-double-quotes)
     (local-set-key [?\C-c ?'] #'init/delimit-single-quotes))))



(defun init/cperl-mode_hook (); Underived major mode, *-mode-map are defined only in here.
  (defvar cperl-mode-map); [FV]
  (define-key cperl-mode-map [?\C-c ?p] #'init/pl-println)
  (define-key cperl-mode-map [f11] #'init/pl-comment-down)

  ;; Undo stuff in `cperl-mode.el`.
  (define-key cperl-mode-map [?{] #'self-insert-command); Was `cperl-electric-lbrace`.
  (define-key cperl-mode-map [?}] #'self-insert-command); Was `cperl-electric-brace`.
  (define-key cperl-mode-map [tab] #'tab-to-tab-stop)
    ;;; Was `cperl-indent-command`, which still is bound to `C-i`.

  (font-lock-add-keywords nil
   '(
     ;; Subdue punctuation
     ("[,;:]" . font-lock-comment-face)
     ("['\"]" 0 font-lock-comment-face t)
  ;;;("[{}$@%*]" . 'init/subdued)
  ;;;;;; But $@ (and presumeably %*) somehow defeat fontification of variable names
     ("[{}]" . 'init/subdued)))

  (setq indent-line-function #'init/indent-relative-plain))



(defun init/css-mode ()
  "Configure CSS mode."
  (defvar css-fontify-colors); [FV]
  (defvar css-mode-map)
  (add-hook
   'css-mode-hook
   (lambda ()
      (let ((m css-mode-map))
        (define-key m [tab] #'tab-to-tab-stop))
          ;;; Was `indent-for-tab-command`, which still is bound to `C-i`.
      (setq
       indent-line-function #'init/indent-relative-plain
       css-fontify-colors nil); Fontification of colour literals.
      (font-lock-add-keywords nil
       '(
         ;; Defeat of unwanted facing
         ;; ─────────────────────────
         ("^\\([[:alpha:]_*.[].*?\\)\\(?:/\\*.*\\)?$"; Buggy, inconsistent selector facing.
          ;;   ────────S─────────        ───C──
          ;; S  selector commencing with character [:alpha:]_  OR  *  OR  .  OR  [
          ;; C  trailing comment
          1 'default t)
       ; ("color: *\\(hsla?(.*)\\)" 1 'default t); Colour literal
       ;;; It seems undefeatable.  https://emacs.stackexchange.com/questions/46629

         ;; Namespace prefix
         ;; ────────────────
         ("\\(\\*\\|[[:alpha:]_][[:alnum:]_]*\\)?\\(|\\)[[:alpha:]_*]" (1 'init/subdued t t)
          (2 font-lock-comment-face t))

         ;; Punctuation
         ;; ───────────
         ("[;:]" . font-lock-comment-face)
         ("['\"]" 0 font-lock-comment-face t)
         ("[{},]" . 'init/subdued)))))
  (autoload 'css-mode "css-mode" init/autoload_docstring t))



(defun init/delimit-asterisk-quotes ()
  ;; FIX so callers instead use `init/delimit-by-chars`, or the like.
  (interactive)
  (if (use-region-p)
      (let* ((start (region-beginning))
             (length (- (region-end) start)))
        (goto-char start)
        (insert-char ?*)
        (forward-char length)
        (insert-char ?*))
    (insert "**")
    (backward-char)))



(defun init/delimit-by-chars (c)
  "Delimit using character C the present region if any, otherwise point."
  (if (use-region-p)
      (let* ((start (region-beginning))
             (length (- (region-end) start)))
        (goto-char start)
        (insert-char c)
        (forward-char length)
        (insert-char c))
    (insert c c)
    (backward-char)))



(defun init/delimit-double-quotes ()
  ;; FIX so callers instead use `init/delimit-by-chars`, or the like.
  (interactive)
  (if (use-region-p)
      (let* ((start (region-beginning))
             (length (- (region-end) start)))
        (goto-char start)
        (insert-char ?\“)
        (forward-char length)
        (insert-char ?\”))
    (insert "“”")
    (backward-char)))



(defun init/delimit-sgml-tag ()
  (interactive)
  (set-mark (point))
  (left-word)
  (kill-region (point) (mark))
  (insert-char ?<)
  (yank)
  (insert-char ?>))



(fset 'init/delimit-sgml-tag-end "</\C-v>\C-r<\C-m")



(defun init/delimit-single-quotes ()
  ;; FIX so callers instead use `init/delimit-by-chars`, or the like.
  (interactive)
  (if (use-region-p)
      (let* ((start (region-beginning))
             (length (- (region-end) start)))
        (goto-char start)
        (insert-char ?\‘)
        (forward-char length)
        (insert-char ?\’))
    (insert "‘’")
    (backward-char)))



(defun init/do-nothing () nil)



(defun init/ebuild-mode ()
  "Define a major mode for Gentoo ebuilds."
  (define-derived-mode ebuild-mode shell-script-mode
    "ebuild" "Gentoo `ebuild` files."
    ;; Per `http://www.gentoo.org/doc/en/gentoo-howto.xml`:
    (setq indent-tabs-mode 1))
  (add-to-list 'auto-mode-alist '("[^/]\\.ebuild$" . ebuild-mode))
  (add-to-list 'auto-mode-alist '("^/home/mike/project/.+/ebuild$" . ebuild-mode))
  (add-to-list 'auto-mode-alist '("[^/]\\.eclass$" . ebuild-mode)))



(defun init/emacs-lisp-mode ()
  "Configure Emacs Lisp mode."
  (add-hook
   'emacs-lisp-mode-hook
   (lambda ()
     (local-set-key [f11] [insert ?\; ?\; ?\; insert left left left down])
       ;;; To overwrite a ‘;;;’, then move point directly beneath it.  (was `toggle-frame-fullscreen`)
     (local-set-key [?\C-c ?p]; Insert ‘(message " ——— =%S" ); TEST’, and move point before the ‘=’.
                    [?\( ?m ?e ?s ?s ?a ?g ?e ?  ?\" ?  ?— ?— ?— ?  ?= ?% ?S ?\" ?  ?\) ?\;
                         ?  ?T ?E ?S ?T left left left left left left left left left left left left]))))



(defun init/fonts (); To control fallback font substitution.
  ;; Modified from `https://emacs.stackexchange.com/a/5714/21090`.
  ;; See also `~/_/zz.brec` § Fonts.
  (let ((font-sets '("fontset-default"
                     "fontset-standard"
                     "fontset-startup"))
        ;; Re Misc Fixed, see `~/_/zz.brec` § Fonts § Misc Fixed,
        ;; also `https://www.cl.cam.ac.uk/~mgk25/ucs-fonts.html`.
    ;;; (my-font    "-Misc-Fixed-*-R-Normal--13-120-75-75-C-70-ISO10646-1"))
    ;;;;;; It insists on the wider 8×13 font for bold, rather than the bold variant of these fonts.
    ;;;;;; Appending the bold variant to each fontset does not help:
    ;;;;;; `(set-fontset-font font-set '(#x000000 . #x3FFFFF) my-font-bold nil 'append)`.
    ;;; (my-font "Fairfax SM-14"))
    ;;; (my-font "Fairfax SM HD-16"))
        (my-font "-Misc-Fixed-*-R-Normal--13-120-75-75-C-80-ISO10646-1"))
        ;;; Changing the font?  Sync ↔ `~/.Xresources`, and there read further instructions.
        ;;; Spec`Emacs.font` in `~/.Xresources` must specify the same font.
        ;;; else duplicate windows (`make-frame` via `C-x 5 2`) use the wrong font.
    (mapcar
     (lambda (font-set)
       (set-fontset-font font-set (cons 0 (max-char)) my-font)

       ;; for all characters without font specification
       ;; in another words it is a setting for lack of fallback font
       ;; if e.g. ℕ called DOUBLE-STRUCK CAPITAL N is not covered by our font
       ;; it will be displayed as placeholder-box,
       ;; because fallback for our font is now... our font :)
   ;;; (set-fontset-font font-set nil my-font))
         ;;; Yet it works reliably only for the originally launched window.  Buffer views in duplicate
         ;;; windows opened `make-frame` (`C-x 5 2`) revert to the original fallback behaviour
         ;;; for some Misc-Fixed characters such as miniscule subscript `ₜ`,
         ;;; though not for others such as extended IPA `ɠ`.
   ;;; (set-fontset-font font-set nil "Fairfax SM HD"))
   ;;;;;;; But Emacs uses too small a size in this case.  The following looks better:
       (set-fontset-font font-set nil "Fairfax SM HD-12"))
         ;;; Here I fallback to Fairfax HD instead, which is my font for Breccian Web images.
         ;;; This way I get both the beauty of Misc Fixed, and the wider coverage of Fairfax HD.
         ;;; Moreover I learn directly whether a typed character will go unrendered in Web images.
         ;;;     And this (unlike the alternative above) appears to work reliably in all windows,
         ;;; both original and duplicates.
     font-sets)))



(defun init/general ()
  "General initialization."
  (delete-selection-mode t)
  (menu-bar-mode 0); Early, else the menu bar briefly flashes on screen.
  (show-paren-mode); Indicate opposing brackets.  To move between the two, use C-M-left and right.
   ;;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Matching.html
  (setq
   auto-save-default nil
   column-number-mode t
;;;column-number-indicator-zero-based nil
;;;;;; Then Breccian perfect indentation would appear at stops 5, 9 and so forth, which is misleading.
;;;font-lock-maximum-decoration 2; TEST
;;;font-lock-maximum-decoration '((java-deprecated-mode . 1)(t . t))
;;;font-lock-maximum-decoration '((jmt-mode . nil)(t . t))
     ;;; css : It fontifies property names as keywords, making the text unreadable.
     ;;;       Unfortunately setting a minimal decoration has no effect.
     ;;; java-deprecated : Minimal, as per `/usr/local/share/emacs/site-lisp/java-deprecated-mode.el`.
     ;;; default (t) : Maximal (t).  Without this, Emacs Lisp mode (at least) fails to fontify
     ;;;               its regular expressions.
;;;custom-unlispify-remove-prefixes t; TEST
   frame-title-format (format "%%b     %%f")
   inhibit-startup-message t
   isearch-lax-whitespace nil
   kill-whole-line t
   make-backup-files nil
   query-replace-highlight t
   read-quoted-char-radix 16
   search-highlight t
;;;track-eol t
;;;;;; Too surprising when I do not want it.
;;;vc-cvs-stay-local nil
;;;;;; But now disabling CVS along with all other version control modes:
   vc-handled-backends nil
     ;;; Disable all version control modes.  The Git one is forcing Emacs to visit symlink
     ;;; targets ("Followed link to") instead of source.
   visual-line-fringe-indicators t); For `visual-line-mode`.
  (setq-default
;;;case-fold-search nil; Making searches case sensitive.
   fill-column 105; (default 70)
   indent-tabs-mode nil
   major-mode #'text-mode; By default, as opposed to `fundamental`.
   recenter-positions '(top middle bottom); As opposed to `middle top bottom`.
   scroll-conservatively 1; With 101, query lines for `query-replace` end up at screen bottom.
     ;;; I would add `scroll-margin 3`, but then `recenter-top-bottom` no longer positions at top.
     ;;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Auto-Scrolling.html
   show-trailing-whitespace t
   tab-width 4
   truncate-lines t)
;;;(put 'narrow-to-region 'disabled nil); Enables the command `narrow-to-region`.
;;;;;; Emacs probably put it here; I cannot remember ever having a use for it, neat as it is.
  (setq require-final-newline t); (setq-default require-final-newline t)
    ;;; But don't know how to mask it or unset it locally in major modes where it is unwanted.
    ;;; So instead I could explicitly set it (locally).  Cf. `mode-require-final-newline`.

  ;; Bell
  ;; ────
;;;(setq bell-volume 0); Enforce silence
;;;;;; Does not work, but this does:
  (setq ring-bell-function #'init/do-nothing)

  ;; Buffer initializations according to source file
  ;; ───────────────────────────────────────────────
  (add-hook
   'find-file-hook
   (lambda ()
      (let ((bfn (file-truename buffer-file-name)))
        ;; Rather than simply using `buffer-file-truename`, which abbreviates e.g. "/home/mike" to "~"

          ;; built files
          ;; ┈┈┈┈┈┈┈┈┈┈┈
          (when (eq (string-match "/home/mike/var/deploy/" bfn) 0)
            (message-box "Warning: this might be a built file."); In case I edit the wrong copy.
            (auto-revert-mode 1))

          ;; source repositories
          ;; ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
      ;;; (when (eq (string-match; GWT
      ;;;            "/home/mike/code/gwt/limb/[^/]+/repo/" bfn) 0)
      ;;;   (message "Set fill column for GWT source code.")
      ;;;   (setq fill-column 80)
      ;;;   )
          (when (eq
                 (string-match; SMBProvider Android app.
                  "/home/mike/code/smbprovider/repo/[^/]*/" bfn)
                 0)
            (message "Set tabbing for SMBProvider source code.")
            (setq indent-tabs-mode 1))
      ;;; (when (eq
      ;;;        (string-match; Textbook Valet..
      ;;;         "/home/mike/client/valet/code/limb/[^/]+/repo/" bfn)
      ;;;        0)
      ;;;   (message "Defeat require-final-newline for Textbook Valet source code.")
      ;;;   (setq require-final-newline nil))

      ;;; ;; remote files served across an SSH file system
      ;;; ;; ┈┈┈┈┈┈┈┈┈┈┈┈
      ;;; (when (eq (string-match "/home/mike/code/uhm/mnt/" bfn) 0)
      ;;;   (message "Enabling auto-revert-mode for this remote file.")
      ;;;   (auto-revert-mode 1)); To avoid spurious editing guards: "file changed on disk".

          ;; current projects
          ;; ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
          ;; For sake of properly ordering their files (by title) on opening them together,
          ;; e.g. by way of `~/sys/bin/lay-editable-tools`.
          (when (eq (string-match "/home/mike/code/100-0/repo/poll/\\([0-9a-zA-Z]+\\)/" bfn) 0)
            (rename-buffer (concat (match-string-no-properties 1 bfn) "/…") t))
          (when (eq
                 (string-match
                  "/home/mike/project/proto-waycast/\\(?:README\\|_/[a-z_]+\\.task$\\)" bfn)
                 0)
            (rename-buffer (concat "proto-waycast (" (file-name-nondirectory bfn) ")") t))
          (when (eq
                 (string-match
                  "/home/mike/work/_/proto-wayic/\\(?:README\\|_/manual\\.task$\\)" bfn)
                    ;;; Omitting any `wayic.task`, which would rename the buffer 'proto-wayic wayic'.
                 0)
            (rename-buffer (concat "proto-wayic (" (file-name-nondirectory bfn) ")") t))
          (when (eq
                 (string-match
                  "/home/mike/work/_/proto-wayic/\\([a-z][a-z_]*\\)/\\(?:_/\\)?\\(?:README\\|[a-z_]+\\.task$\\)"
                  ;;                               └──────────────┘
                  ;;                                 project name
                  bfn)
                 0)
            (rename-buffer
             (concat "proto-wayic." (match-string-no-properties 1 bfn) " ("  (file-name-nondirectory bfn) ")") t))
          (when (eq
                 (string-match
                  "/home/mike/work/\\([A-Za-z].*?\\)/\\(?:README\\.[^/]+\\|[^/]*\\.\\(?:brec\\|task\\)\\)\\'"
                  ;;                 └─────────────┘
                  ;;                   project name
                  bfn)
                 0)
            (rename-buffer
             (concat (match-string-no-properties 1 bfn) " (" (file-name-nondirectory bfn) ")") t)))))

  ;; Customizer, `customize` that is.  Apparently the package manager depends on it.
  ;; ──────────
  (setq custom-file "/home/mike/.config/emacs/customizer-store.el")
  (load custom-file nil t)

  ;; Line spacing
  ;; ────────────
;;;(setq-default line-spacing 1)
;;;;;; Done rather in `~/.Xresources`; but it remains to stop the resulting mystery echo:
   (add-hook 'minibuffer-setup-hook (lambda () (init/set-for-buffer 'line-spacing 0)))
    ;;; Stopping the ‘[Saved text until: …]’ that attends any use of `kill-ring-save` in the echo area,
    ;;; whenever a positive `line-spacing` is in effect.  https://emacs.stackexchange.com/q/71797/21090

  ;; Tabbing and indentation
  ;; ───────────────────────
  (setq tab-stop-list '(4 8 12 16 20 24 28 32 36 40 44 48 52 56 60))
  (electric-indent-mode -1)); A minor mode enabled in 24.4.  It messes up `return` key binding.

  ;; Yank
  ;; ────
;;; (setq yank-handled-properties (assq-delete-all 'face yank-handled-properties))
;;; (setq yank-handled-properties (assq-delete-all 'font-lock-face yank-handled-properties))
;;; (add-to-list 'yank-excluded-properties 'face)
;;; (add-to-list 'yank-excluded-properties 'font-lock-face)
;;;;;; Still I see misfaced text after yanking, at least in Java buffers.
;;; (setq yank-handled-properties (cons (cons 'face 'yank-handle-font-lock-face-property) yank-handled-properties))
;;;;;; Nor does that help.



(fset 'init/html-a-href
      [?\C-w ?< ?a ?  ?h ?r ?e ?f ?= ?' ?' ?> ?\C-v ?< ?/ ?a ?> ?\C-r ?< ?a
             right right right right right right right right right])



(defun init/html-mode ()
  "Configure HTML mode."
  (add-to-list 'auto-mode-alist '("\\.html\\'" . html-mode)); As opposed to `mhtml-mode`, e.g. `XHTML+`.
  (add-to-list 'auto-mode-alist '("[^/]\\.xht$" . html-mode))
  (add-to-list 'auto-mode-alist '("^/home/mike/work/_/proto-wayic/\\(?:.+/\\)?[^./]+$" . html-mode))
    ;;; Wayic files named without an extension are HTML term files.
  (add-hook
   'html-mode-hook
   (lambda ()
     (local-set-key [?\C-c ?, ?a ?h] #'init/html-a-href))))



(defun init/indent-relative-plain () (indent-relative t))



(defun init/Java-automatically (); Mimicing what a package-manager installation would do.
  (load "jmt-mode-autoloads" nil t); Q.v. at `http://reluk.ca/sys/computer/workstation/etc/emacs/`.
  (init/Java))


(defun init/Java-manually (); As instructed at `http://reluk.ca/project/Java/Emacs/jmt-mode.el`.
  (autoload 'jmt-mode "jmt-mode" nil t)
  (set 'auto-mode-alist (cons (cons "\\.java\\'" 'jmt-mode) auto-mode-alist))
  (set 'interpreter-mode-alist; For Java source-launch files encoded with a shebang. [SLS]
       (cons (cons "\\(?:--split-string=\\|-S\\)?java" 'jmt-mode)
             interpreter-mode-alist))
  (register-definition-prefixes "jmt-mode" '("jmt-"))
  (init/Java))


(defun init/Java ()
  "Configure JMT Mode and other Java particulars."
  (add-hook
   'jmt-mode-hook
   (lambda ()

     ;; Key bindings
     ;; ────────────
     (local-set-key [f11] #'init/Java-comment-down); A keyboard macro; was `toggle-frame-fullscreen`.
     (local-set-key [tab] #'tab-to-tab-stop); Was `c-indent-line-or-region`.
     (local-set-key [?\M-\;] #'init/Javadoc-open-comment); A keyboard macro; was `comment-dwim`.
       ;;; https://www.gnu.org/software/emacs/manual/html_node/ccmode/Comment-Commands.html
     (local-set-key [?\C-c ?, ?a ?h] #'init/html-a-href)
     (local-set-key [?\C-c ?, ?l] #'init/Javadoc-linkplain)
     (local-set-key [?\C-c ?p] #'init/Java-println)
     (local-set-key [?\C-\M-,] #'init/delimit-sgml-tag); To `<` unshifted, that is; a keyboard macro.
     (local-set-key [?\C-\M-.] #'init/delimit-sgml-tag-end); One for its opposite, too.

     ;; Unwanted features of the underlying Java Mode
     ;; ─────────────────
     ;; ‘By default… electric mode and syntactic-indentation mode are enabled’
     ;; and (in support of the former) abbrev mode is ‘turned on by default’.
     ;; https://www.gnu.org/software/emacs/manual/html_node/ccmode/Minor-Modes.html
     ;; https://www.gnu.org/software/emacs/manual/html_node/ccmode/Electric-Keys.html
     (init/set-for-buffer 'abbrev-mode nil)
 ;;; (init/set-for-buffer 'c-electric-flag nil)
 ;;;;;; already disabled through my setting (elsewhere) of `electric-indent-mode`
     (init/set-for-buffer 'c-syntactic-indentation nil)))

  ;; Further fontification
  ;; ─────────────────────
  (font-lock-add-keywords
   #'jmt-mode
   (list
    (cons; Subdue any `assert` statements.
     (let (match-beg match-end)
       (lambda (limit)
         (setq match-beg (point)); Presumptively.
         (catch 'to-reface
           (while (< match-beg limit)
             (setq match-end (next-single-property-change match-beg 'face (current-buffer) limit))
             (when (and (eq 'jmt-principal-keyword (get-text-property match-beg 'face))
                        (string= "assert" (buffer-substring-no-properties match-beg match-end)))
               (goto-char match-end)
               (when (search-forward ";" (min (line-end-position) limit) t)
                   ;;; May rarely match a ‘;’ in a string or comment [BUG].  Repair by extending
                   ;;; the search in a `while` loop till face property `jmt-separator` is found.
                 (setq match-end (point))
                 (set-match-data (list match-beg match-end (current-buffer)))
                 (throw 'to-reface t)))
             (setq match-beg match-end))
           nil)))
     '(0 'init/subdued t)))
   t)); To append.



;; A keyboard macro that overwrites a ‘//’, then moves point directly beneath it.
(fset 'init/Java-comment-down [insert ?/ ?/ insert left left down])



(defun init/Java-common-mode (mode-map)
  "Initialization common to Java and JavaScript modes."
  (define-key mode-map [?\C-c ?* ?l] #'init/Javadoc-linkplain)
  (define-key mode-map [?\C-c ?* ?*] #'init/Javadoc-open-comment); A keyboard macro; was `comment-dwim`.
  (define-key mode-map [?\C-c ?/] [?/ ?* ?* ?/ left left])
  (define-key mode-map [f11] #'init/Java-comment-down); A keyboard macro; was `toggle-frame-fullscreen`.
  (define-key mode-map [tab] #'tab-to-tab-stop)
    ;;; Was `indent-for-tab-command`, which still is bound to `C-i`.
  (setq indent-line-function #'init/indent-relative-plain))



(defun init/java-deprecated-mode ()
  "Configure `java-deprecated-mode`."
  (defvar java-deprecated-mode-map); [FV]
  (add-hook
   'java-deprecated-mode-hook
   (lambda ()
     (let ((m java-deprecated-mode-map))
       (define-key m [?\C-c ?p] #'init/Java-println)

       ;; Undo troublesome key assignments in cc-mode.el
   ;;; (define-key m "#" #'self-insert-command)
   ;;; (define-key m "{" #'self-insert-command)
   ;;; (define-key m "}" #'self-insert-command)
   ;;; (define-key m "/" #'self-insert-command)
   ;;; (define-key m "*" #'self-insert-command)
   ;;; (define-key m ";" #'self-insert-command)
   ;;; (define-key m "," #'self-insert-command)
   ;;; (define-key m ":" #'self-insert-command); Otherwise inserts a space.
   ;;; (define-key m "(" #'self-insert-command)
   ;;; (define-key m ")" #'self-insert-command)

   ;;; (init/sgml-common-mode m))
       (init/Java-common-mode m))

     (setq abbrev-mode nil)))
       ;;; Otherwise enabled for some reason.  Not wanted.  Also I want to avoid an
       ;;; infinite loop that I once saw involving `c-electric-continued-statement`,
       ;;; which occurred after typing "else" and other words in the abbreviation table.
  (autoload 'java-deprecated-mode "java-deprecated-mode"
    init/autoload_docstring t); ↑ Q.v. at `http://reluk.ca/sys/computer/workstation/etc/emacs/`.
  (setq auto-mode-alist (cons (cons "\\.java\\'" 'java-deprecated-mode) auto-mode-alist)))



;; A keyboard macro that inserts an `@linkplain` Javadoc tag.  Uses the selected text as the tag body.
;; Saves it to the kill ring, forms the tag around it and places point in readiness to enter (or yank)
;; the tag reference.
(fset 'init/Javadoc-linkplain
  [?\C-w ?{ ?@ ?l ?i ?n ?k ?p ?l ?a ?i ?n ?  ?\C-v ?} ?\C-r ?{ ?@ ?l ?i ?n ?k C-right ? ?#])



;; A keyboard macro that inserts an empty API description before the present line,
;; and places point in readiness to enter its text.
(fset 'init/Javadoc-open-comment [kp-prior ?/ ?* ?* return ?  ?  ?* ?/ up ?  ?. left])



;; A keyboard macro that inserts “System.err.println( \" ——— =\" + )” and moves point before the ‘=’.
(fset 'init/Java-println
  [?S ?y ?s ?t ?e ?m ?. ?e ?r ?r ?. ?p ?r ?i ?n ?t ?l ?n
      ?\( ?  ?\" ?  ?— ?— ?— ?  ?= ?\" ?  ?+ ?  ?  ?\) ?\; ?  ?/ ?/ ?  ?T ?E ?S ?T
      left left left left left left left left left left left left left left left left])



(defun init/js-deprecated-mode ()
  "Configure `js-deprecated-mode`."
  (defvar js-deprecated-mode-map); [FV]
  (add-hook
   'js-deprecated-mode-hook
   (lambda ()
     (let ((m js-deprecated-mode-map))
   ;;; (define-key m [?\C-c ?p] [ ?j ?a ?v ?a ?. ?l ?a ?n ?g ?. ?S ?y ?s ?t ?e ?m ?. ?e ?r ?r ?. ?p ?r ?i ?n ?t ?l ?n ?\( ?  ?' ?  ?— ?— ?— ?  ?= ?' ?  ?+ ?  ?  ?\) ?\; ?  ?/ ?/ ?  ?T ?E ?S ?T left left left left left left left left left left left left left left left left])
   ;;;;;; I guess I need this form when running under a JDK (e.g. as Nashorn).
   ;;;;;; I can sometimes distinguish that using `interpreter-mode-alist` (as below).
   ;;;;;; But this works only for a shebanged executable (headed by the likes of `#!/opt/jdk/bin/jjs`),
   ;;;;;; not for any library it loads, or any script executed by other means.  So just:
       (define-key m [?\C-c ?p] [ ?c ?o ?n ?s ?o ?l ?e ?. ?l ?o ?g ?\( ?  ?' ?  ?— ?— ?— ?  ?= ?'
             ?  ?+ ?  ?  ?\) ?\; ?  ?/ ?/ ?  ?T ?E ?S ?T
             left left left left left left left left left left left left left left left left])
       (init/Java-common-mode m))))
  (autoload 'js-deprecated-mode "js-deprecated-mode"
    init/autoload_docstring t); ↑ Q.v. at `http://reluk.ca/sys/computer/workstation/etc/emacs/`.
  (set 'auto-mode-alist (cons (cons "\\.fab\\'"        'js-deprecated-mode) auto-mode-alist))
  (set 'auto-mode-alist (cons (cons "\\.js\\'"         'js-deprecated-mode) auto-mode-alist))
  (set 'auto-mode-alist (cons (cons "\\.jsm\\'"        'js-deprecated-mode) auto-mode-alist))
    ;;; Waymaker file-associated build scripts (.fab), JavaScript (.js)
    ;;; and Votorola JavaScript modules (.jsm).

  (set 'interpreter-mode-alist (cons (cons "jjs"        'js-deprecated-mode) interpreter-mode-alist))
  (set 'interpreter-mode-alist (cons (cons "jrunscript" 'js-deprecated-mode) interpreter-mode-alist)))
    ;;; JDK Nashorn JavaScript executable (jjs) and JDK JavaScript executable (jrunscript).



(defun init/keys ()
  "Initialize key bindings."

  ;; ═════════════
  ;; Single-stroke
  ;; ═════════════

  (global-unset-key [f10]); Was `tmm-menubar`.
  (global-unset-key [menu]); Was `execute-extended-command`.

  (global-set-key [?\r] #'newline-and-indent); Was `newline`, q.v. herein.

  (global-set-key [kp-end] #'init/newline-after)
  (global-set-key [kp-home] #'init/newline-before)
  (global-set-key [kp-left] (lambda () (interactive) (indent-rigidly (region-beginning)(region-end) -1)))
  (global-set-key [kp-next] #'init/open-line-after)
  (global-set-key [kp-prior] #'init/open-line-before)
  (global-set-key [kp-right] (lambda () (interactive) (indent-rigidly (region-beginning)(region-end) 1)))
  (let ((sm isearch-mode-map))

    ;; `C`-qualified by `Ctrl` key
    ;; ─────────────
    (global-set-key    [?\C-'] [?\u0301]); Accute accent ◌́ combining.
    (global-set-key    [?\C-`] [?\u0300]); Grave accent ◌̀ combining.
    (global-unset-key  [?\C-a]); Was `beginning-of-line`, but for that I use `Home`.
  ;;;(global-set-key   [?\C-c] #'copy-region-as-kill-nomark)
  ;;;;;; Bad idea because it is a standard prefix; modes will clobber it.
  ;;;(global-unset-key [?\C-d]); Was `delete-char`, but for that I use `Del`.
  ;;;;;; Causes `Del` to fail; apparently it is remapped to `C-d` at a low level.
    (global-unset-key  [?\C-o])
      ;;; Was `open-line`, but for that I use my `init/open-line-before` and `init/open-line-after`.
    (global-set-key    [?\C-p] #'math-preview-at-point); Was `previous-line`.
    (global-set-key    [?\C-v] #'yank); Was `scroll-up`.
    (define-key sm     [?\C-v] #'isearch-yank-kill); During incremental search, that is.
    (global-unset-key  [?\C-z]); Was `iconify-or-deiconify-frame`.

;;; (global-set-key [C-end] #'end-of-buffer); Was `end-of-buffer-nomark`.
;;; (global-set-key [C-home] #'beginning-of-buffer); Was `beginning-of-buffer-nomark`.
    (global-set-key [C-next] #'init/switch-to-next-buffer)     ; Was bound to `scroll-left`.
    (global-set-key [C-prior] #'init/switch-to-previous-buffer); Was bound to `scroll-right`.

    ;; `C-M`-qualified by `Ctrl-Alt` keys
    ;; ───────────────
    (global-set-key [?\C-\M-'] [?′])
    (define-key sm  [?\C-\M-'] (lambda () (interactive) (isearch-yank-string "′")))
    (global-set-key [?\C-\M-\"] [?″])
    (define-key sm  [?\C-\M-\"] (lambda () (interactive) (isearch-yank-string "″")))

    ;; `M`-qualified by `Alt` key
    ;; ─────────────
    (global-set-key [?\M-\r] #'newline); Cf. `newline-and-indent` herein.

    (global-set-key [?\M- ] [? ]); Was `just-one-space`.
    (define-key sm  [?\M- ] (lambda () (interactive) (isearch-yank-string " ")))
    (global-set-key [?\M-$] [?§]); Was `ispell-word`.
    (define-key sm  [?\M-$] (lambda () (interactive) (isearch-yank-string "§")))
    (global-set-key [?\M-'] [?\’]); Was `abbrev-prefix-mark`.
    (define-key sm  [?\M-'] (lambda () (interactive) (isearch-yank-string "’")))
    (global-set-key [?\M-*] [?•])
    (define-key sm  [?\M-*] (lambda () (interactive) (isearch-yank-string "•")))
    (global-set-key [?\M--] [?—]); Was `negative-argument`.
    (define-key sm  [?\M--] (lambda () (interactive) (isearch-yank-string "—")))
    (global-set-key [?\M-.] [?…]); Was `xref-find-definitions`.
    (define-key sm  [?\M-.] (lambda () (interactive) (isearch-yank-string "…")))
    (global-set-key [?\M-~] [?∼]); Was `not-modified`.
    (define-key sm  [?\M-~] (lambda () (interactive) (isearch-yank-string "∼")))

    (global-set-key [?\M-b] [?∵])
    (define-key sm  [?\M-b] (lambda () (interactive) (isearch-yank-string "∵")))
    (global-set-key [?\M-k] #'init/kill-ring-save-line); A keyboard macro; was `kill-sentence`.
    (global-set-key [?\M-p] [?¶])
    (define-key sm  [?\M-p] (lambda () (interactive) (isearch-yank-string "¶")))
    (global-set-key [?\M-t] [?∴]); Was `transpose-words`.
    (define-key sm  [?\M-t] (lambda () (interactive) (isearch-yank-string "∴")))
    (global-set-key [?\M-v] #'yank-pop); Was `scroll-down`.
    (define-key sm  [?\M-v] #'isearch-yank-pop)

    (global-set-key [M-down]  (lambda () (interactive) (scroll-up-line))); Was `backward-line-nomark`.
    (global-set-key [M-up]    (lambda () (interactive) (scroll-down-line))); Was `forward-line-nomark`.
    (global-set-key [M-left]  (lambda () (interactive) (scroll-right 1))); Was `left-word`.
    (global-set-key [M-right] (lambda () (interactive) (scroll-left 1))); Was `right-word`.

    (global-set-key  [M-kp-left]  #'init/null-command); Was unbound and translating to `M-left`.  [TOP]
    (global-set-key  [M-kp-right] #'init/null-command); Was unbound and translating to `M-right`. [TOP]
    (global-set-key  [M-S-kp-4]   #'init/null-command); Was unbound and translating to `M-4`.     [TOP]
    (global-set-key  [M-S-kp-6]   #'init/null-command); Was unbound and translating to `M-6`.     [TOP]

    ;; `S-C`-qualified by `Shift-Ctrl` keys
    ;; ───────────────
    (global-set-key [S-C-next]  (lambda () (interactive) (init/switch-to-next-buffer t)))
    (global-set-key [S-C-prior] (lambda () (interactive) (init/switch-to-previous-buffer t)))
      ;;; `S-C-next` and `S-C-prior` fail outside of X Windows.  There `C-prior` (`Page Up`)
      ;;; and `C-next` (`Page Down`) are somehow equivalent to unqualified `prior` and `next`.


    ;; ════════════
    ;; Multi-stroke
    ;; ════════════

    ;; `C-c` based
    ;; ───────────
    (global-set-key [?\C-c ?8] #'init/delimit-asterisk-quotes)
    (global-set-key [?\C-c ?'] #'init/delimit-single-quotes)
    (global-set-key [?\C-c ?\"] #'init/delimit-double-quotes)
    (global-set-key [?\C-c ?h] "http://reluk.ca/project/")

    ;; `C-h` based
    ;; ───────────
    (global-set-key [?\C-h ?c] #'describe-char); Was `describe-key-briefly`.

    ;; `C-x` based
    ;; ───────────
    (global-set-key   [?\C-x ?r ?v] #'yank-rectangle)
    (global-unset-key [?\C-x ?r ?y]); Was `yank-rectangle`.
    (global-set-key   [?\C-x ?s] #'init/save-all-buffers)
      ;;; Was `save-some-buffers` which prompts, whereas this one is silent.
    (global-unset-key [?\C-x ?u]); Was `advertised-undo`, but for that I use `S-C--`.
    (global-unset-key [?\C-x ?\C-z]); Was `iconify-or-deiconify-frame`,
      ;;; but I never do that because it makes the window disappear as though it were killed.

    ;; `M-m` based
    ;; ───────────
    (define-prefix-command 'prefix-map-M-m)
    (global-set-key [?\M-m] #'prefix-map-M-m); Was `back-to-indentation`.
    (global-set-key [?\M-m ?m] [?×])
    (define-key sm  [?\M-m ?m] (lambda () (interactive) (isearch-yank-string "×")))))



(fset 'init/kill-ring-save-line "\C-k\C-_")



(defun init/markdown (); http://jblevins.org/projects/markdown-mode/
  "Configure Markdown particulars."
  (defvar markdown-command); [FV]
  (setq markdown-command "markdown2")
    ;;; The default is `markdown`, but it seems a Gentoo package has installed `markdown2` instead.
  (autoload 'markdown-mode "markdown-mode" init/autoload_docstring t)
  (autoload 'gfm-mode "markdown-mode" init/autoload_docstring t); GitHub Flavoured Markdown (GFM).
    ;;; Likely it cannot do previews without additional work.  See ‘GFM’ in the manual.
  (add-to-list 'auto-mode-alist '("\\.markdown\\'" . markdown-mode))
  (add-to-list 'auto-mode-alist '("\\.md\\'"       . markdown-mode))
  (add-to-list 'auto-mode-alist '("README\\.md\\'" . gfm-mode))
  (add-hook
   'markdown-mode-hook
   (lambda (); Overriding the present mode’s override of my `init/keys`:

     ;; Defeat of unwanted key bindings that would override my `init/keys`
     ;; ───────────────────────────────
     ;; TODO more reliably: https://emacs.stackexchange.com/questions/352/how-to-override-major-mode-bindings
     (local-set-key [?\C-c ?8] #'init/delimit-asterisk-quotes)
     (local-set-key [?\C-c ?\"] #'init/delimit-double-quotes)
     (local-set-key [?\C-c ?'] #'init/delimit-single-quotes))))



(defun init/math-preview ()
  "Initialize `math-preview`."
  ;; https://gitlab.com/matsievskiysv/math-preview
  ;; https://gitlab.com/matsievskiysv/math-preview/-/issues
  ;;
  ;; Requires compiling Emacs with the `svg` use flag, else it fails silently.
  ;;
  ;; To upgrade this package’s Node.js module:
  ;;
  ;;    root > npm --global list
  ;;  # root > npm --global update math-preview|git+https://gitlab.com/matsievskiysv/math-preview
  ;;  ### fails with either form of argument, issuing an error message, so instead reinstall:
  ;;    root > npm --global uninstall math-preview
  ;;    root > npm --global install git+https://gitlab.com/matsievskiysv/math-preview
  ;;      # if ‘npm error File exists: /usr/bin/math-preview’, then `rm /usr/bin/math-preview` and retry
  ;;
  ;; Configure it using Customize (`M-x RET customize-group RET math-preview`) as per instructions at
  ;; the URL above.  For the present Customize configuration, see `~/.config/emacs/customizer-store.el`.
  ;; Alternatively, set the custom variables directly herein.
  ;;
  ;; Note that custom variables `math-preview-mathjax-em`, `-mathjax-ex` and `-mathjax-svg-ex-factor`
  ;; have no effect on the resulting images, nor apparently anything else.
  ;;
  ;; To query an image’s properties, open it separately (under Image Mode).  To query its size,
  ;; evaluate `(image-size (image-get-display-property) :pixels)`.  (So I learned the following.)

  (setq math-preview-margin 0); Default `(5 . 5)`.
  (setq math-preview-mathml-marks-inline (list (list "<math display='inline'" "</math>" 0 nil nil)))

  ;;(setq math-preview--debug-json t); TEST
  ;;(setq math-preview-raise-enable t); Default nil.  TEST
  ;;(setq math-preview-raise 0); Default 0.4 if `math-preview-raise-enable`, else effectively 0.  TEST
  ;;(setq math-preview-relief -5); Default 0.  TEST
  ;;(setq math-preview-scale 1.1); Default 0.  TEST

  ;; Colour the math images, each to match the face colour of its LaTeX/TeX source
  ;; ──────────────────────
  (let (beg; The position of the start delimiter of each mathematic expression being imaged.
        s; Source text of the math to be previewed.
        c; Its face colour.
        end)
    (advice-add; Ensure `beg` is set for each expression being imaged, then nilled afterward.
     #'math-preview--submit-region :around
     (lambda (f-name &rest args)
       (setq beg (car (car args)))
       (prog1 (apply f-name args)
         (setq beg nil)))
     '((name . "init/advice/math-preview--submit-region")))
    (require 'color)
    (add-hook; Colour each image as Math Preview generates it.
     'math-preview-tex-preprocess-functions
     (lambda (preview)
       (when (and beg (string= "tex" (gethash 'type preview))); LaTeX/TeX only, not MathML or AsciiMath.
         (catch 'abort
           (setq s (gethash 'string preview)
                 c (save-excursion; Its face colour.
                     (setq beg (+ beg (length (gethash 'prefix preview))); Start of source text.
                           end (+ beg (length s))); End of source text.
                     (goto-char beg)
                 ;;; (skip-syntax-forward "(" end); Through any characters of opening-parenthesis syntax.
                 ;;;   ;;; This is a workaround to avoid highlighting applied by `show-paren-mode`.
                 ;;; (when (= end (point)); Then somehow all characters have that syntax.
                 ;;;   (throw 'abort nil)); Let the default colour apply.
                 ;;; (foreground-color-at-point))
                 ;;;;;; Yet search highlighting too is a problem.  Therefore exclude such highlighting
                 ;;;;;; by looking (in effect) at the text that lies beneath all overlays.
                     (init/text-foreground-color-at-point)); Excludes overlay facing.
                 c (color-name-to-rgb c); From whatever form `c` is in, to floating RGB,
                 c (color-rgb-to-hex (pop c) (pop c) (pop c) 2); thence to hex `#rrggbb`.
                 s (concat "\\color{" c "} " s)); Prepending a colour directive to match the source.
           (puthash 'string s preview))))))

  ;; Key bindings for convenience
  ;; ────────────
  (global-set-key [?\M-m ?c] #'math-preview-clear-all)
  (global-set-key [?\M-m ?p] #'math-preview-all))



(defun init/modes ()
  "Define and/or customize the various major and minor modes."
  (init/breccia-automatically)
;;;(init/breccia-manually); TEST
  (init/conf-mode)
  (init/css-mode)
  (init/ebuild-mode)
  (init/emacs-lisp-mode)
  (init/html-mode)
  (init/Java-automatically)
;;;(init/Java-manually); TEST
;;;(init/java-deprecated-mode); TEST
  (init/js-deprecated-mode)
  (init/mutt-mode)
  (init/perl-mode)
  (init/sh-mode)
  (init/sgml-mode)
  (init/task-sheet-mode)
;;;(init/test-mode); TEST
;;;(init/test2-mode); TEST
  (init/text-mode)
  (init/waybrec)
  (init/wayscript-mode)
  (when (string= (system-name) "primeval"); Which alone has the necessary packages installed,
    (when (string=(user-login-name) "mike" ); and only for user `mike`, to run the following.
      (init/math-preview)
  ;;; (init/prettify-math); Uncommenting this for TEST purposes?  Then consider commenting out initial
        ;;; calls (elsewhere) to the image-generation functions of alternative package `math-preview`.
      (init/markdown))))



(defun init/mutt-mode ()
  "Define Mutt-Mail mode."
  (define-derived-mode mutt-mail-mode text-mode
    "Mutt-Mail" "For composing mail in a buffer invoked by Mutt."
    (setq show-trailing-whitespace nil
 ;;; indent-line-function #'indent-relative)
     fill-column 70); Though usually you must set this in a mode hook.
    (defvar mutt-mail-font-lock-keywords
      (list
       '("^\\(?:From: \\|Cc: \\|Bcc: \\|Message-ID: \\|Reply-To: \\|In-Reply-To: \\).*$"
         . font-lock-comment-face)
       '("^\\(?:To: \\).*$"
         . font-lock-string-face)
       '("^\\(?:Subject: \\).*$"
         . font-lock-type-face)
       '("^\\(?: *> *>\\)+ *\\(?:[^ >\xA].*\\)?$"; Quote me (even).
         . font-lock-comment-face)
       '("^ *>.*$"                               ; Quote other (odd).
         . font-lock-string-face)
       '("^-- $"                                 ; Signature delimiter.
         . font-lock-comment-face)
       '("^\\(?:Mike\\|Michael Allan\\)$"        ; Signature.
         . font-lock-comment-face))
       "For mutt-mail-mode.")
;;; (make-local-variable 'font-lock-defaults)
;;; (setq font-lock-defaults '(mutt-mail-font-lock-keywords t))
    (init/set-for-buffer 'font-lock-defaults '(mutt-mail-font-lock-keywords t)))
  (add-to-list 'auto-mode-alist '("[mM]utt\\(?:-.*\\)?-[0-9]+-[0-9]+\\'" . mutt-mail-mode))
  (add-hook 'mutt-mail-mode-hook
   (lambda ()
;;; (make-local-variable 'require-final-newline)
;;; (setq require-final-newline nil)
;;;;;; No effect; rather than unsetting it like this, explicitly, I would have to set it explicitly
;;;;;; everywhere else [just don't like how Mutt's viewer shows the final newline] but it's not worth
;;;;;; it [and mail handlers append newlines etc. anyway, it seems]
    (re-search-forward "^$"); Move down to 1st blank line, past the headers.
    (forward-line)))); And one more, to beginning of message body.



(fset 'init/newline-after [end M-return])



(fset 'init/newline-before [home M-return up])



(defun init/null-command (); Does nothing.
  (interactive))



(fset 'init/open-line-after [end return])



(fset 'init/open-line-before [end return ?\C-x ?\C-t up up end])



(defun init/perl-mode ()
  "Configure Perl mode."
  (add-hook 'perl-mode-hook #'init/perl-mode_hook)
  (add-hook 'cperl-mode-hook #'init/cperl-mode_hook))

  ;; Add the following if you want `cperl-mode` instead of `perl-mode`.
  ;;     Note that opening an editor window via `lay-editable-tools` (which includes Perl buffers),
  ;; then switching back and forth among the buffers (Ctrl Page Up, Ctrl Page Down) results (2023-2)
  ;; in copies of the following in the message buffer.
  ;;
  ;;     Error during redisplay: (jit-lock-function 1) signaled (error "No match 4 in highlight (4 font-lock-variable-name-face)")
  ;;     Error during redisplay: (jit-lock-function 2) signaled (error "No match 4 in highlight (4 font-lock-variable-name-face)")
  ;;
  ;; Meanwhile it turns out (2023-2) the JIT Lock debugger is now useless:
  ;; enabling `jit-lock-debug-mode` causes all modes to fail silently.
  ;; [Use instead `(setq font-lock-support-mode nil)`, it works (2024-6).]
  ;;
  ;; However, `cperl-mode.el` has but one line that contains `4 font-lock-variable-name-face`.
;;;(add-to-list 'auto-mode-alist '("\\.\\([pP][Llm]\\|al\\)\\'" . cperl-mode))
;;;(add-to-list 'interpreter-mode-alist '("perl" . cperl-mode))
;;;(add-to-list 'interpreter-mode-alist '("perl5" . cperl-mode))
;;;(add-to-list 'interpreter-mode-alist '("miniperl" . cperl-mode)))



(defun init/perl-mode_hook (); Underived major mode, *-mode-map are defined only in here.
  (defvar perl-mode-map); [FV]
   (define-key perl-mode-map [?\C-c ?p] #'init/pl-println)
   (define-key perl-mode-map [f11] #'init/pl-comment-down)

   ;; Undo stuff in perl-mode.el
   (define-key perl-mode-map [?{] #'self-insert-command); Auto-indent too often wrong.
   (define-key perl-mode-map [?}] #'self-insert-command)
   (define-key perl-mode-map [?\;] #'self-insert-command)
   (define-key perl-mode-map [?:] #'self-insert-command)
   (define-key perl-mode-map [tab] #'tab-to-tab-stop); Can still use C-i for indent.
   (font-lock-add-keywords nil
    '(
      ;; Subdue punctuation
      ("[,;:]" . font-lock-comment-face)
      ("['\"]" 0 font-lock-comment-face t); t override existing fontification.
      ("[{}$@%*]" . 'init/subdued))); Unless already fontified.

   (setq indent-line-function #'init/indent-relative-plain))



(fset 'init/pl-comment-down [insert ?# insert left down])



(fset 'init/pl-println
      [?p ?r ?i ?n ?t ?\( ?  ?\" ?  ?— ?— ?— ?  ?\\ ?= ?\"
          ?  ?. ?  ?  ?. ?  ?\" ?\\ ?n ?\" ?  ?\) ?\;
          left left left left left left left left left left left left left left left])



(defun init/prettify-math (); https://github.com/shaqtsui/prettify-math
  "Initialize `prettify-math`."
  ;; Requires compiling Emacs with the `svg` use flag, else it issues a warning.
  ;; On first running, it prompts to install MathJAX, then stores it
  ;; at `/home/mike/.config/emacs/elpa/prettify-math-VERSION/node_modules\`.
  ;;
  ;; The colour of its images does not match the surrounding text.  The in-line images align with
  ;; each other at their bottoms, not their text baselines, making them inconsistent both mutually
  ;; and with the surrounding text.  Nor does it recognize in-line math that breaks across lines.
  (require 'brec-mode)
  (setq prettify-math-default-scale 1)
  (setq prettify-math-delimiters-alist; This cannot be made buffer-local.  It seems `prettify-math`
          ;;; reads it once only on loading.  I guess that’s why the maintainer warns to set it
          ;;; ‘before this module loaded’.  `https://github.com/shaqtsui/prettify-math`
        (list (list (char-to-string brec-math-inline-delimiter-char) 'tex)
              (list (char-to-string brec-math-block-delimiter-char) 'tex 'block)))
  (require 'prettify-math)); Last, to be affected by the settings above.



(defun init/save-all-buffers ()
  (interactive)
  (save-some-buffers t))



(defun init/sgml-common-mode (mode-map)
  "SGML related init, common to various modes."
   ;;; [unsure if this is still true:]
   ;;; Many keys cannot be bound here, because bindings are clobbered in sgml-mode.el.
   ;;; Test first with describe-key-briefly.
   ;;;
   ;;; Changing? Change also in zz-swatch.txt.

   (define-key mode-map [?/] #'self-insert-command)
     ;;; Was `sgml-slash`, which blocks overwriting of the present selection when I type ‘/’.
   (define-key mode-map [?\C-\M-,] #'init/delimit-sgml-tag); To `<` unshifted, that is; a keyboard macro.
   (define-key mode-map [?\C-\M-.] #'init/delimit-sgml-tag-end)); One for its opposite, too.



(defun init/sgml-mode ()
  "Configure SGML mode."
  (defvar sgml-mode-map); [FV]
  (add-to-list 'auto-mode-alist '("[^/]\\.xml$" . sgml-mode))
    ;;; Somehow puts the buffer into XML mode specifically, which is derived from SGML mode;
    ;;; this as opposed to the default nXML mode which is *not* so derived.
;;;(add-to-list 'auto-mode-alist '("[./]tld$" . sgml-mode))
;;;(add-to-list 'auto-mode-alist '("[^/]\\.ent$" . sgml-mode))
;;;(add-to-list 'auto-mode-alist '("[^/]\\.mod$" . sgml-mode))
;;;(add-to-list 'auto-mode-alist '("[^/]\\.rdf$" . sgml-mode))
;;;(add-to-list 'auto-mode-alist '("[^/]\\.xsd$" . sgml-mode))
  (add-to-list 'auto-mode-alist '("[^/]\\.xslt$" . sgml-mode))
  (add-hook 'sgml-mode-hook
   (lambda ()
  ;;; (define-key sgml-mode-map [tab] #'tab-to-tab-stop); Can still use C-i for indent.
  ;;; (define-key sgml-mode-map "/" #'self-insert-command)
  ;;;   ;;; Undo from sgml-mode.el; refuses to obey insert/overwrite mode.

  ;;; (make-local-variable 'require-final-newline)
  ;;; (setq require-final-newline t)
      (setq indent-line-function #'init/indent-relative-plain)

      ;; As this is un-derived major mode, *-mode-map are defined only in here
      (init/sgml-common-mode sgml-mode-map)

      (font-lock-add-keywords nil; 'nil' so it affects derived modes such as HTML, too.
       '(
         ;; See also my modified older version of sgml-mode.el, from which many of these rules
         ;; were originally taken: /usr/local/share/emacs/site-lisp/._

         ;; Attribute assignment
         ;; ────────────────────
         (" \\([_[:alpha:]][-._[:alnum:]]*:\\)?\\([_[:alpha:]][-._[:alnum:]]*\\) *\\(=\\) *\\(['\"]\\)\\(.*?\\)\\(\\4\\)"
          (1 font-lock-comment-face nil t) (2 font-lock-builtin-face) (3 font-lock-comment-face)
          (4 'init/subdued t) (5 font-lock-comment-face t) (6 'init/subdued t))
     ;;; (" id *= *\\(['\"]\\)\\(.+?\\)\\1" 2 font-lock-string-face t); HTML allows any non-empty value
     ;;;;;; Defeated only because my attempt to override it fails in init/wayscript-mode, q.v.
         (" xmlns:\\([_[:alpha:]][-._[:alnum:]]*\\) *= *['\"]" 1 font-lock-type-face t)

         ;; DTD declaration
         ;; ──────────────-
         ("\\(<!\\)\\([_[:alpha:]][-._[:alnum:]]*\\)"
          (1 font-lock-comment-face) (2 font-lock-constant-face))

         ;; Element start
         ;; ────────────-
     ;;; ("\\(<\\(?:[_[:alpha:]][-._[:alnum:]]*:\\)?\\)\\([_[:alpha:]][-._[:alnum:]]*\\)"
     ;;;  (1 font-lock-comment-face)(2 font-lock-function-name-face))
     ;;;;; But the element name is already faced correctly:
         ("\\(<\\(?:[_[:alpha:]][-._[:alnum:]]*:\\)?\\)[_[:alpha:]]" 1 font-lock-comment-face)

         ;; Element start or end  (trailing delimiter of its start or end tag)
         ;; ────────────────────
         ("/?>" . font-lock-comment-face); In lieu of a multiline pattern.

         ;; Element end
         ;; ──────────-
         ("\\(</.*?\\)>"  1 font-lock-comment-face)

         ;; Processing instruction
         ;; ──────────────────────
         ("\\(<\\?\\(?:[_[:alpha:]][-._[:alnum:]]*:\\)?\\)\\([_[:alpha:]][-._[:alnum:]]*\\)"
          (1 font-lock-comment-face) (2 font-lock-constant-face))
         ("\\(\\?\\)>" 1 font-lock-comment-face)))))); In lieu of a multiline pattern




(defun init/sh-mode ()
  "Configure the shell-script mode, `sh-mode`."
  (defvar sh-mode-map); [FV]
  (add-hook
   'sh-mode-hook
   (lambda (); Underived major mode, *-mode-map are defined only in here.
     (define-key sh-mode-map [tab] #'tab-to-tab-stop)))); Can still use C-i for indent.



(defun init/string-lessp-i (string1 string2)
  "Like ‘string-lessp’ but ignores case."
  (setq string1(downcase string1))
  (setq string2(downcase string2))
  (string-lessp string1 string2))



(defface init/subdued
  `((t . (:inherit shadow))) "\
A face for noisy symbolic clutter that needs subduing."
  :group 'faces)



(defun init/switch-to-next-buffer (&optional to-include-specials)
  "Page to the next buffer in lexicographic order.
Exclude buffers with names starting or ending ‘*’ if TO-INCLUDE-SPECIALS is nil."
  (interactive)
  (delete-other-windows); In case visiting multiple initial files, when Emacs shows a split frame
    ;;; with a buffer list in the second window: this deletes that second window.  Not sure how else to
    ;;; do this, or where better to place this call — both `after-init-hook` and `-funcall` operate too
    ;;; early, prior to load.  Besides, it is not bad to see the buffer list as long as it goes away
    ;;; without effort, and this does the trick.
  (let ((bb (init/buffer-names-sorted to-include-specials))
        (name (buffer-name)))
    (while bb
      (if (equal name (car bb))
          (progn
            ;; Switch to next list entry, or first if current is last.
            (switch-to-buffer
             (or (car(cdr bb))
                 (car(init/buffer-names-sorted to-include-specials))))
            (setq bb nil))
        (setq bb (cdr bb))))))



(defun init/switch-to-previous-buffer (&optional to-include-specials)
  "Page to the previous buffer in lexicographic order.
Exclude buffers with names starting or ending ‘*’ if TO-INCLUDE-SPECIALS is nil."
  (interactive)
  (delete-other-windows); Concordant with init/switch-to-next-buffer.
  (let ((bb (reverse (init/buffer-names-sorted to-include-specials)))
        (name (buffer-name)))
    (while bb
      (if (equal name (car bb))
          (progn
            ;; Switch to previous list entry, or last if current is first.
            (switch-to-buffer
             (or (cadr bb)
                 (car (last (init/buffer-names-sorted to-include-specials)))))
            (setq bb nil)))
      (setq bb (cdr bb)))))



(defun init/task-sheet-mode ()
  "Configure Task Sheet mode."
  (defvar task-sheet-mode-map); [FV]
  (add-hook
   'task-sheet-mode-hook
   (lambda ()
     (let ((m task-sheet-mode-map))
   ;;; (init/sgml-common-mode m))
       (define-key m [f11] [insert ?/ insert left down])
         ;;; To overwrite a ‘/’, then move point directly beneath it.  (was `toggle-frame-fullscreen`)
       (define-key m [?\t] #'tab-to-tab-stop))
 ;;; (make-local-variable 'require-final-newline)
 ;;; (setq require-final-newline t)
     (setq indent-line-function #'init/indent-relative-plain)))
  (autoload 'task-sheet-mode "task-sheet-mode"
    init/autoload_docstring t); ↑ Q.v. at `http://reluk.ca/sys/computer/workstation/etc/emacs/`.
  (add-to-list 'auto-mode-alist '("[./]task$" . task-sheet-mode)))



(defun init/set-for-buffer (variable value)
  "Set buffer-local VARIABLE (a symbol) to VALUE.
Signal an error if the binding is not actually buffer-local.
This might happen, for example, if an externally defined VARIABLE
that was documented as being buffer-local no longer is."
  (set variable value)
  (cl-assert (local-variable-p variable)))



(defvar init/task-sheet-toggle-mode-was); Used by `task-sheet-toggle-mode`, q.v. further below.
(fset 'init/task-sheet-toggle-mode-was 'text-mode)


;;;(fset 'init/test "\223[^[:ascii:]]")
;;;(fset 'init/test [?\S-\C-\M-s ?\\ ?. ?h ?t ?m ?l ?\[ ?^ ?\" ?# ?< ?\]])



(defun init/test-mode ()
  "Configure Test mode."
  (define-derived-mode test-mode text-mode
    "Test" "A major mode for testing purposes."
    (init/set-for-buffer 'truncate-lines t)
    (defconst test-line-spacing-original 4); Assumed for test purposes.
    (init/set-for-buffer 'line-spacing 0); One can selectively enlarge the spacing only, not zero it.
      ;;; Therefore zero it generally, then restore the original spacing on all but starred lines.
    (setq-local font-lock-extra-managed-props '(line-spacing))
    (init/set-for-buffer 'font-lock-defaults '(test-fontifiers))
    (defconst test-fontifiers
      (list
       (cons; A fontifier to restore the original, non-zero line spacing on all but starred `*` lines.
        (lambda (limit)
          (let ((p (point)) c found starred)
            (while (and (not found) (< p limit))
              (setq c (char-after p))
              (cond
               ((= c ?*)
                (setq starred t))
               ((= c ?\n); A terminal newline.
                (if starred; Then keep going, seeking one that is unstarred.
                    (setq starred nil)
                  (setq found t)))); Else (being unstarred) restore the original line spacing.
              (setq p (1+ p)))
            (when found; The newline to propertize is just before `p`.
              (set-match-data (list (1- p) (goto-char p) (current-buffer)))
              t))); Returning t to Font Lock if `found`, else nil.
        '(0 (list  'face nil  'line-spacing test-line-spacing-original)))))); [NF]
  (set 'auto-mode-alist (cons (cons "\\.test\\'" 'test-mode) auto-mode-alist)))



(defun init/test2-mode ()
  "Configure Test2 mode."
  (define-derived-mode test2-mode text-mode
    "Test2" "Another major mode for testing purposes."
    (init/set-for-buffer 'truncate-lines t)
;;; (init/set-for-buffer 'line-spacing 4)
    (setq-local font-lock-extra-managed-props '(line-height))
    (init/set-for-buffer 'font-lock-defaults '(test2-fontifiers))
    (defconst test2-fontifiers
      (list
       (cons
        (lambda (limit)
          (let ((p (point)) c found starred)
            (while (and (not found) (< p limit))
              (setq c (char-after p))
              (cond
               ((= c ?*)
                (setq starred t))
               ((= c ?\n)
                (when starred
                    (setq found t))))
              (setq p (1+ p)))
            (when found
              (set-match-data (list (1- p) (goto-char p) (current-buffer)))
              t)))
        '(0 (list  'face nil  'line-height 0)))))); [NF]
  (set 'auto-mode-alist (cons (cons "\\.test2\\'" 'test2-mode) auto-mode-alist)))



(defun init/text-face-attribute-at-point (attribute &optional attribute-unnamed); Excludes overlay faces.
    ;;; Modified from `faces--attribute-at-point` of Emacs `faces.el` in order to exclude overlay faces
    ;;; by replacing all `get-char-property` with `get-text-property`.  Licence GPL.
  (let ((faces (or (get-text-property (point) 'read-face-name)
                   (and font-lock-mode
                        (get-text-property (point) 'font-lock-face))
                   (get-text-property (point) 'face)))
        (found nil))
    (dolist (face (if (face-list-p faces)
                      faces
                    (list faces)))
      (cond (found)
            ((and face (symbolp face))
             (let ((value (face-attribute-specified-or
                           (face-attribute face attribute nil t)
                           nil)))
               (unless (member value '(nil "unspecified-fg" "unspecified-bg"))
                 (setq found value))))
            ((consp face)
             (setq found (cond ((and attribute-unnamed
                                     (memq attribute-unnamed face))
                                (cdr (memq attribute-unnamed face)))
                               ((memq attribute face) (cadr (memq attribute face))))))))
    (or found
        (face-attribute 'default attribute))))



(defun init/text-foreground-color-at-point (); Excludes overlay facing.  Modified from `foreground-
    ;;; -color-at-point` of Emacs `faces.el` in order to exclude overlay faces.  Licence GPL.
  (init/text-face-attribute-at-point :foreground 'foreground-color))



(defun init/text-mode ()
  "Configure text mode."
  (let ((m text-mode-map))
    (define-key m [?\t] #'tab-to-tab-stop))
  (add-to-list 'auto-mode-alist '("/ChangeLog$" . text-mode))); Was Change Log, which is not Gentoo format.



(defun init/waybrec ()
  "Configure Waybrec Mode and other Waybreccian particulars."
  (load "waybrec-mode-autoloads" nil t); Q.v. at `http://reluk.ca/sys/computer/workstation/etc/emacs/`.
  (set 'auto-mode-alist (cons (cons "/way/.*\\.brec\\'" 'waybrec-mode) auto-mode-alist)))



(defun init/wayscript-mode ()
  "Configure `Wayscript mode`."
;;;(add-hook 'wayscript-mode-hook
;;; (lambda ()
;;;    (font-lock-add-keywords nil; 'nil' so it affects any derived modes, too.
;;;     ;; ID assignment
;;;     ;; ────────────-
;;;     '((" id *= *\\(['\"]\\)\\(.+?\\)\\1" 2 font-lock-warning-face t)))))
;;;       ;;; Override `init/sgml-mode`, toning down the colour soup.
;;;;;; Fails.  (Is it how I defined Wayscript Mode?  Or fontified it?).
;;;;;; Instead defeating in `init/sgml-mode`.
  (autoload 'wayscript-mode "wayscript-mode"
    init/autoload_docstring t); ↑ Q.v. at `http://reluk.ca/sys/computer/workstation/etc/emacs/`.
  (add-to-list 'auto-mode-alist '("^/home/mike/project/proto-waycast/.+\\.xht$" . wayscript-mode)))



(defun init/x ()
  "Configure Emacs for the X Window System."

    (global-set-key [S-down-mouse-1] #'mouse-save-then-kill); Was `mouse-set-font`.
    (global-set-key [mouse-3] #'mouse-set-font); The popup button, was mouse-save-then-kill.
      ;;; What was the purpose of this button swap?  What button is `S-down-mouse-1`?

;;; (global-set-key [C-mouse-4] #'init/switch-to-previous-buffer)
;;; (global-set-key [C-mouse-5] #'init/switch-to-next-buffer)
;;; (global-unset-key [S-mouse-4]); Was `mwheel-scroll`, but (below) I bind that to `M-mouse-4`.
;;; (global-unset-key [S-mouse-5])
;;;;;; I no longer have side buttons.
    (global-unset-key (kbd "<M-down-mouse-1>")); Was `mouse-drag-secondary`.
      ; https://www.reddit.com/r/emacs/comments/3c61zl/abolish_the_secondary_selection_quick_and_easy/csszyto
    (global-unset-key (kbd "<M-drag-mouse-1>")); Was `mouse-set-secondary`.
      ; https://www.reddit.com/r/emacs/comments/3c61zl/abolish_the_secondary_selection_quick_and_easy/csszyto
    (global-unset-key (kbd "<M-mouse-1>")); Was `mouse-start-secondary`.
    (global-unset-key (kbd "<M-mouse-2>")); Was `mouse-yank-secondary`.
    (global-unset-key (kbd "<M-mouse-3>")); Was `mouse-secondary-save-then-kill`.
;;; (global-set-key [M-mouse-4] #'mwheel-scroll)
;;; (global-set-key [M-mouse-5] #'mwheel-scroll)
;;;;;; I no longer have side buttons.
    (setq mouse-wheel-scroll-amount '(5 ((meta) . 1) )); 5 lines normally, but 1 when M modified.

    (setq select-enable-clipboard t); So the latest kill-ring entry is visible to other programs.
    (add-to-list 'default-frame-alist '(unsplittable . t))

    ;; Cursor
    ;; ──────
    (blink-cursor-mode 0)
;;; (mouse-avoidance-mode 'cat-and-mouse)
;;;;;; But raises window whenever it scurries
    (defun adjust-cursor-type (&optional frame)
      "Set cursor style according to overwrite mode."
      (modify-frame-parameters
       (or frame (selected-frame))
       (list
        (cons 'cursor-type
              (if overwrite-mode 'box 'bar)))))
;;; (defadvice overwrite-mode (after adjusted-cursor activate) (adjust-cursor-type))
;;; (defadvice binary-overwrite-mode (after adjusted-cursor activate) (adjust-cursor-type))
;;; (add-hook 'after-make-frame-functions #'adjust-cursor-type)
;;; (defadvice other-window (after adjusted-cursor activate) (adjust-cursor-type))
;;; (defadvice switch-to-buffer (after adjusted-cursor activate) (adjust-cursor-type))
;;;;;; Incomplete.  Overwrite mode is per buffer, but cursor type is per frame.
;;;;;; Need more hooks to tie them together.  Easier to use brute force:
    (add-hook 'post-command-hook #'adjust-cursor-type); OPT, it slows all commands.
;;;;;; But Emacs Lisp manual says the "buffer-local variable cursor-type overrides
;;;;;; the value of the cursor-type frame parameter", so maybe try that?

    (setq-default cursor-in-non-selected-windows 'hollow))
       ;;; Else bar becomes (hardly distinguishable) thin bar.



(defun task-sheet-toggle-mode ()
  "Toggles between major modes ‘task-sheet-mode’ and the current mode."
  (interactive)
  (cond
   ((string= major-mode "task-sheet-mode")
    (init/task-sheet-toggle-mode-was))
   (t
    (fset 'init/task-sheet-toggle-mode-was major-mode)
    (task-sheet-mode))))



(provide 'user-initialization)



;; NOTES
;; ─────
;;   BUG  This code is incorrect.
;;
;;   FV · Suppressing sporadic compiler warnings ‘reference to free variable’
;;        or ‘assignment to free variable’.
;;
;;   NF · In a search-based fontifier, a nil value for the `face` property of a list-form *facespec*
;;        has the (undocumented) effect of leaving the face property untouched at its present value.
;;        https://www.gnu.org/software/emacs/manual/html_node/elisp/Search_002dbased-Fontification.html
;;
;;   SLS  Q.v. at `http://reluk.ca/project/Java/Emacs/jmt-mode.el`.
;;
;;   TOP  Too often pressed accidently.



                                                ;;; Licence GPL — q.v. above for source acknowledgements.