about summary refs log tree commit diff stats
path: root/lisp/acdw-reading.el
blob: ff4f0c29b9cd33d124feac9fac0f2e1da1f6d298 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
;;; acdw-reading.el --- minor mode for reading -*- lexical-binding: t -*-

;; Copyright 2021 Case Duckworth <(rot13-string "npqj@npqj.arg")>
;; This file is NOT part of GNU Emacs.

;;; License:

;; Everyone is permitted to do whatever with this software, without
;; limitation.  This software comes without any warranty whatsoever,
;; but with two pieces of advice:
;; - Don't hurt yourself.
;; - Make good choices.

;;; Commentary:

;; here is my attempt at a reading mode.

;;; Code:

;;; Customizations

(defgroup reading nil
  "Group for Reading mode customizations."
  :prefix "reading-"
  :group 'convenience)                  ; i need to figure this out

(defcustom reading-vars '((indicate-empty-lines . nil)
                          (indicate-buffer-boundaries . nil))
  "Alist of variables to set in function `reading-mode'.
The car of each cell is the variable name, and the cdr is the
value to set it to."
  :type '(alist :key-type variable
                :value-type sexp))

(defcustom reading-modes '((display-fill-column-indicator-mode . -1)
                           (blink-cursor-mode . -1))
  "Alist of modes to set in function `reading-mode'.
The car of each cell is the function name, and the cdr is the
value to call it with."
  :type '(alist :key-type function
                :value-type sexp))

;;; Internal

(defvar reading--remembered-template "reading--remembered-%s-value"
  "The template passed to `format' for remembered modes and variables.")

(defun reading--remember (things func)
  "Apply FUNC to THINGS, remembering their previous value for later."
  (declare (indent 1))
  (unless (listp things)
    (setq things (list things)))
  (dolist (thing things)
    (set (make-local-variable
          (intern (format reading--remembered-template thing)))
         (and (boundp thing)
              (symbol-value thing)))
    (funcall func thing)))

(defun reading--recall (things func)
  "Recall previously remembered THINGS by applying FUNC to them.
FUNC should be a function with the signature (THING REMEMBERED-SETTING)."
  (declare (indent 1))
  (unless (listp things)
    (setq things (list things)))
  (dolist (thing things)
    (with-demoted-errors "reading--recall: %S"
      (let ((value (symbol-value
                    (intern
                     (format reading--remembered-template thing)))))
        (funcall func thing value)))))

;;; Mode

;;;###autoload
(define-minor-mode reading-mode
  "A mode for reading."
  :init-value nil
  :lighter " Read"
  :keymap (make-sparse-keymap)
  (if reading-mode
      ;; turn on
      (progn
        (reading--remember (mapcar #'car reading-vars)
          (lambda (var)
            (set (make-local-variable var)
                 (cdr (assoc var reading-vars)))))
        (reading--remember (mapcar #'car reading-modes)
          (lambda (mode)
            (funcall mode (cdr (assoc mode reading-modes))))))
    ;; turn off
    (reading--recall (mapcar #'car reading-vars)
      (lambda (var orig-val)
        (set (make-local-variable var) orig-val)))
    (reading--recall (mapcar #'car reading-modes)
      (lambda (mode orig-setting)
        (funcall mode (if orig-setting +1 -1))))))

(provide 'acdw-reading)
;;; acdw-reading.el ends here