diff options
Diffstat (limited to 'lib/eos/jao-minibuffer.el')
-rw-r--r-- | lib/eos/jao-minibuffer.el | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/lib/eos/jao-minibuffer.el b/lib/eos/jao-minibuffer.el new file mode 100644 index 0000000..91662bf --- /dev/null +++ b/lib/eos/jao-minibuffer.el @@ -0,0 +1,138 @@ +;;; jao-minibuffer.el --- using the minibuffer to report status -*- lexical-binding: t; -*- + +;; Copyright (C) 2020, 2021 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 nil) +(defvar jao-minibuffer-frame-width nil) +(defvar jao-minibuffer-notification-timeout 5) +(defvar jao-minibuffer-enabled-p t) + +(defconst jao-minibuffer--name " *Minibuf-0*") + +(defun jao-minibuffer--trim (s w) + (if (<= (string-width (or s "")) w) + (format (format "%%%ds" (if jao-minibuffer-align-right-p w (- 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--width () + (cond ((numberp jao-minibuffer-frame-width) jao-minibuffer-frame-width) + (jao-minibuffer-maximized-frames-p (frame-width)) + (t (min (frame-width) (window-width (minibuffer-window)))))) + +(defun jao-minibuffer--format-info () + (mapconcat 'string-trim + (seq-filter (lambda (s) (not (string-blank-p s))) + (mapcar 'format-mode-line + (if jao-minibuffer-align-right-p + jao-minibuffer-info + (reverse jao-minibuffer-info)))) + " ")) + +(defun jao-minibuffer--aligned (&optional w currentp) + (let* ((msg (cond (currentp (jao-minibuffer--current)) + (jao-minibuffer-notification + (format-mode-line jao-minibuffer-notification)) + (t (jao-minibuffer--format-info)))) + (msg (if jao-minibuffer-align-right-p + (string-trim msg) + (string-trim-left msg))) + (msg (propertize msg :minibuffer-message t))) + (when (not (string-empty-p msg)) + (let* ((mw (jao-minibuffer--width)) + (w (mod (or w (string-width (or (current-message) ""))) mw)) + (w (- mw w jao-minibuffer-right-margin))) + (if (> w 0) (jao-minibuffer--trim msg w) ""))))) + +(defun jao-minibuffer--set-message (msg) + (if current-minibuffer-command + msg + (let* ((msg (string-trim (replace-regexp-in-string "\n" " " msg))) + (msg (if (string-blank-p msg) msg (concat msg " ")))) + (if jao-minibuffer-align-right-p + (concat msg (jao-minibuffer--aligned (string-width (or msg "")) t)) + (concat (jao-minibuffer--aligned (+ 3 (string-width (or msg ""))) t) + " " msg))))) + +(defun jao-minibuffer--insert (msg) + (with-current-buffer jao-minibuffer--name + (erase-buffer) + (insert msg))) + +;;;###autoload +(defun jao-minibuffer-refresh () + (interactive) + (when jao-minibuffer-enabled-p + (jao-minibuffer--insert (or (jao-minibuffer--aligned) "")))) + +;;;###autoload +(defun jao-minibuffer-add-variable (variable-name &optional order) + (add-to-ordered-list 'jao-minibuffer-info `(:eval ,variable-name) order)) + +(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)) + +;;;###autoload +(defun jao-minibuffer-toggle () + (interactive) + (setq jao-minibuffer-enabled-p (not jao-minibuffer-enabled-p)) + (if jao-minibuffer-enabled-p + (jao-minibuffer-refresh) + (jao-minibuffer--insert ""))) + +(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 |