-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathecho-bar.el
More file actions
139 lines (120 loc) · 5.01 KB
/
echo-bar.el
File metadata and controls
139 lines (120 loc) · 5.01 KB
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
;;; echo-bar.el --- Performant echo-area status display -*- lexical-binding: t -*-
;; Author: Anton Chen <mail@antonchen.ca>
;; Version: 0.1.0
;; Package-Requires: ((emacs "29.1"))
;; Keywords: frames, convenience
;; URL: https://github.com/chenanton/echo-bar
;; SPDX-License-Identifier: GPL-3.0-or-later
;; Copyright (C) 2026 Anton Chen
;;; Commentary:
;;
;; Display status information in the echo area instead of a modeline.
;; Saves one line of screen real estate.
;;
;; Key design: event-driven updates with coalescing, not timer-based polling.
;; Segments declare what triggers them (hooks, advice, timers). When a
;; trigger fires, the segment is marked dirty and a single coalesced
;; update is scheduled via `run-at-time 0 nil'. Only dirty segments
;; recompute. Overlays are written only when the display string changes.
;;
;; Usage:
;; (require 'echo-bar)
;; (setq echo-bar-layout
;; '(:center ("buffer-position" "buffer-name" "major-mode")
;; :right ("battery" "time" "project" "vcs")))
;; (echo-bar-mode 1)
;;; Code:
(require 'echo-bar-faces)
(require 'echo-bar-segments)
(require 'echo-bar-render)
(require 'echo-bar-engine)
;; ──────────────────────────────────────────────────────────────────
;;; Customization
;; ──────────────────────────────────────────────────────────────────
(defgroup echo-bar nil
"Echo-area status display."
:group 'frames
:prefix "echo-bar-")
(defcustom echo-bar-layout
'(:right ("buffer-name" "buffer-position" "major-mode" "vcs"
"project" "battery" "time"))
"Plist mapping positions to segment name lists.
Supported keys: :left, :center, :right. Segments not listed in
any group are not displayed.
Example layouts:
\\=':center + :right -- center group centered, right group right-aligned
\\=':left + :right -- left flush-left, right right-aligned
\\=':right only -- everything right-aligned (simplest)"
:type '(plist :key-type symbol :value-type (repeat string))
:group 'echo-bar)
(defcustom echo-bar-separator " "
"String used to separate segments within a group."
:type 'string
:group 'echo-bar)
(defcustom echo-bar-left-padding 0
"Characters of padding between the left edge and the first segment."
:type 'integer
:group 'echo-bar)
(defcustom echo-bar-right-padding 1
"Characters of padding between the right group and the right edge."
:type 'integer
:group 'echo-bar)
(defcustom echo-bar-center-right-gap 4
"Minimum character gap between center and right groups.
When they would overlap, the center group is pushed left."
:type 'integer
:group 'echo-bar)
(defcustom echo-bar-time-format "%a %b %-e %-I:%M %p"
"Format string for the time segment.
Passed to `format-time-string'. The default produces output like
\"Wed Mar 5 8:48 PM\"."
:type 'string
:group 'echo-bar)
(defcustom echo-bar-idle-fallback-interval 2.0
"Seconds of idle time before a full refresh (safety net).
Set to nil to disable."
:type '(choice number (const nil))
:group 'echo-bar)
(defcustom echo-bar-message-max-width 30
"Maximum character width for messages in the echo area.
Messages longer than this are truncated with an ellipsis before
being centered in the minibuffer."
:type 'integer
:group 'echo-bar)
;; ──────────────────────────────────────────────────────────────────
;;; Mode definition
;; ──────────────────────────────────────────────────────────────────
(defvar echo-bar--saved-mode-line-format nil
"Saved `mode-line-format' to restore when disabling.")
;;;###autoload
(define-minor-mode echo-bar-mode
"Display status information in the echo area instead of the mode line."
:global t
:group 'echo-bar
(if echo-bar-mode
(progn
;; Save and hide mode line
(setq echo-bar--saved-mode-line-format
(default-value 'mode-line-format))
(setq-default mode-line-format nil)
(dolist (buf (buffer-list))
(with-current-buffer buf
(setq mode-line-format nil)))
;; Setup
(echo-bar--setup-overlays)
(echo-bar--register-all-hooks)
;; Initial full render
(echo-bar--mark-all-dirty)
(echo-bar--do-update))
;; Teardown
(echo-bar--remove-all-hooks)
(echo-bar--remove-overlays)
(setq echo-bar--update-pending nil
echo-bar--last-display nil)
;; Restore mode line
(setq-default mode-line-format echo-bar--saved-mode-line-format)
(dolist (buf (buffer-list))
(with-current-buffer buf
(setq mode-line-format echo-bar--saved-mode-line-format)))))
(provide 'echo-bar)
;;; echo-bar.el ends here