summaryrefslogtreecommitdiffhomepage
path: root/sys/jao-minibuffer.el
blob: 7104544ae2fb0ef3d481efc90816b3e17eafe012 (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
101
102
103
104
;;; jao-minibuffer.el --- using the minibuffer to report status  -*- lexical-binding: t; -*-

;; Copyright (C) 2020  jao

;; Author: jao <mail@jao.io>
;; Keywords: extensions

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <https://www.gnu.org/licenses/>.

;;; Commentary:

;; Simple asynchronous display of information in the minibuffer.

;;; Code:

(defvar jao-minibuffer-info ())
(defvar jao-minibuffer-notification nil)
(defvar jao-minibuffer-align-right-p t)
(defvar jao-minibuffer-right-margin (if window-system 0 1))
(defvar jao-minibuffer-maximized-frames-p t)
(defvar jao-minibuffer-notification-timeout 5)

(defconst jao-minibuffer--name " *Minibuf-0*")

(defun jao-minibuffer--trim (s w)
  (if (<= (length s) w)
      (format (format "%%%ds" w) s)
    (substring s 0 w)))

(defun jao-minibuffer--current ()
  (with-current-buffer jao-minibuffer--name
    (buffer-substring (point-min) (point-max))))

(defun jao-minibuffer--aligned (&optional w currentp)
  (let* ((msg (if currentp
                  (jao-minibuffer--current)
                (format-mode-line (or jao-minibuffer-notification
                                      jao-minibuffer-info))))
         (msg (propertize (string-trim msg) :minibuffer-message t)))
    (when (not (string-empty-p msg))
      (if jao-minibuffer-align-right-p
          (let* ((mw (if jao-minibuffer-maximized-frames-p
                         (frame-width)
                       (window-width (minibuffer-window))))
                 (w (mod (or w (length (current-message))) mw))
                 (w (- mw w jao-minibuffer-right-margin)))
            (if (> w 0) (jao-minibuffer--trim msg w) ""))
        (concat " · " msg)))))

(defun jao-minibuffer--set-message (msg)
  (let ((msg (string-trim (replace-regexp-in-string "\n" " " msg))))
    (concat msg (jao-minibuffer--aligned (length msg) t))))

;;;###autoload
(defun jao-minibuffer-refresh ()
  (interactive "")
  (with-current-buffer jao-minibuffer--name
    (erase-buffer)
    (insert (or (jao-minibuffer--aligned) ""))))

;;;###autoload
(defun jao-minibuffer-add-variable (variable-name &optional append)
  (add-to-list 'jao-minibuffer-info `(:eval ,variable-name) append))

(defvar jao-minibuffer--notification-timer nil)

(defun jao-minibuffer--start-notification-timer (timeout)
  (interactive)
  (when jao-minibuffer--notification-timer
    (cancel-timer jao-minibuffer--notification-timer))
  (setq jao-minibuffer--notification-timer
        (run-with-idle-timer (or timeout jao-minibuffer-notification-timeout)
                             nil
                             'jao-minibuffer-pop-notification)))

;;;###autoload
(defun jao-minibuffer-push-notification (msg &optional timeout)
  (setq jao-minibuffer-notification msg)
  (jao-minibuffer--start-notification-timer timeout)
  (jao-minibuffer-refresh))

;;;###autoload
(defun jao-minibuffer-pop-notification ()
  (interactive)
  (setq jao-minibuffer-notification nil)
  (jao-minibuffer-refresh))

(setq set-message-function #'jao-minibuffer--set-message)
(setq clear-message-function #'jao-minibuffer-refresh)
(setq resize-mini-windows nil)

(provide 'jao-minibuffer)
;;; jao-minibuffer.el ends here