Skip to content

Instantly share code, notes, and snippets.

@rougier
Created August 11, 2020 10:58
Show Gist options
  • Save rougier/096323d35ae3af5c8d0740dbb297f3e5 to your computer and use it in GitHub Desktop.
Save rougier/096323d35ae3af5c8d0740dbb297f3e5 to your computer and use it in GitHub Desktop.
An extension of the echo area to display static messages (emacs)
;; -------------------------------------------------------------------
;; An extension of the echo area to display static messages
;; Copyright 2020 Nicolas P. Rougier
;; -------------------------------------------------------------------
;; This file is not part of GNU Emacs.
;;
;; 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 <http://www.gnu.org/licenses/>
;; -------------------------------------------------------------------
(provide 'echo-line)
(require 'subr-x)
(defun echo-line-format ()
"String to be appended at right of echo area."
(propertize (format-mode-line "%l:%c") 'face 'face-faded))
(defun echo-line-message (orig-fun &rest args)
"This enhanced message displays a regular message in the echo area
and adds a specific text on the right part of the echo area. This
is to be used as an advice."
(let* ((right
(concat
;; ! First space is a thin space, not a regular space
;; ! Last space needed to have truncated line
" " (echo-line-format) " "
))
(width (- (frame-width) (length right) 0))
(msg (if (car args) (apply 'format-message args) ""))
;; Hack: The space for the split is a thin space, not a regular space
;; This way, we get rid of the added part if present (unless an actual
;; message uses a thin space.
(msg (car (split-string msg " ")))
(msg (string-trim msg))
(left (truncate-string-to-width msg width nil nil "…"))
(full (format (format "%%-%ds %%s" width) left right))
)
(if (active-minibuffer-window)
;; Regular log and display when minibuffer is active
(apply orig-fun args)
;; Enhanced display
(progn
;; Log actual message without echo
(if message-log-max
(let ((inhibit-message t)) (apply orig-fun (list msg))))
;; Display enhanced message without log
(let ((message-truncate-lines t) (message-log-max nil))
;; (apply orig-fun (list full))
(apply orig-fun (list (substring full 0 -1)))
(set-display-table-slot
(window-display-table (minibuffer-window))
'truncation (make-glyph-code (string-to-char (substring full -2))
'face-faded))
)
;; Set current message explicitely
(setq current-message msg)))))
;; Install advice
(advice-add 'message :around #'echo-line-message)
;; Instal post-command hook
(add-hook 'post-command-hook
(lambda () (let ((message-log-max nil))
(message (current-message)))))
;; Install a display table in minibuffer window
(set-window-display-table (minibuffer-window) (make-display-table))
@schellj
Copy link

schellj commented Aug 18, 2020

The first backtrace happened when using dabbrev-expand and the second happened when using flyspell-buffer. Each command outputs a message that ends in %. I had run the code in the gist (without issue) before running those commands and running into the above errors.

@rougier
Copy link
Author

rougier commented Aug 18, 2020

Ok, thanks, I will try to debug it. In the menatime, you might be interested in mini-modeline

@schellj
Copy link

schellj commented Aug 18, 2020

Thanks and thanks for the suggestion. I tried out mini-modeline, but decided not to use it because, as far as I could tell, it results in using minibuffer instead of the modeline, which isn't what I wanted; I wanted to use both the modeline and the minibuffer to display different information. I've found that I can do that with minibuffer-line, though.

@haji-ali
Copy link

I modified the code slightly to handle these (and other) issues. See here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment