summaryrefslogtreecommitdiff
path: root/emacs/site-lisp/single-header.el
diff options
context:
space:
mode:
authorTCCQ <thomasmulmer02@gmail.com>2025-06-01 12:18:12 -0700
committerTCCQ <thomasmulmer02@gmail.com>2025-06-01 12:18:12 -0700
commitc4539bad5ce3a39862bddad7583ade0bc967b368 (patch)
tree46c0184dfd0c08d6f99676481b0dc3a2163d246a /emacs/site-lisp/single-header.el
parentb67bc7405e28bfab06f3f1f9e382c7efcbe1524c (diff)
emacs refactor work
Diffstat (limited to 'emacs/site-lisp/single-header.el')
-rwxr-xr-xemacs/site-lisp/single-header.el171
1 files changed, 129 insertions, 42 deletions
diff --git a/emacs/site-lisp/single-header.el b/emacs/site-lisp/single-header.el
index 06faff5..2713c5b 100755
--- a/emacs/site-lisp/single-header.el
+++ b/emacs/site-lisp/single-header.el
@@ -1,40 +1,103 @@
-(provide 'single-header)
+(require 'ednc)
+(require 'battery)
+(require 's)
+(require 'dash)
-(defvar single-header--current-header-buffer nil "Read the name")
+;; not toggled with the mode to prevent user from having to restart
+;; applications producing notifs.
+(when (equal window-system 'x)
+ (ednc-mode 1))
-(defvar single-header-format '(make-header-info-string) "evaluated to fill the header")
+;; testing
+;; (require 'notifications)
+;; (notifications-notify :title "2st test" :body "hello, world" :app-name "EDNC"
+;; :actions '("default" "default"))
+
+(defvar single-header-update-increment 3 "Number of seconds before updating the header again.")
+
+(defvar single-header--current-header-buffer nil "Read the name")
(defface single-header '((default . (:background "#000000" :family "Source Code Pro"))) "Face for top line")
-(require 'battery)
-(defun with-face (str &rest face-plist)
+(setq single-header--active-notifs nil)
+(setq single-header--timer nil
+;; "Timer that triggers updates of the header contents. Use `single-header-update' for forcing updates."
+ )
+
+(defun single-header--with-face (str &rest face-plist)
+ "Convenience wrapper for `add-face-text-property'."
(add-face-text-property 0 (length str) face-plist t str)
str)
-(defun make-header-info-string ()
- "generates the mode line string that contains all the info to the right"
+(defun single-header--register-notif-change (old new)
+ "Function to hook `ednc-notification-presentation-functions'."
+ (when new
+ (push new single-header--active-notifs))
+ (when (and old
+ (member old single-header--active-notifs))
+ (setq single-header--active-notifs
+ (remove old single-header--active-notifs))))
+
+(defun single-header--make-notif-string ()
+ "Produce a string representation of the active notifications."
+ (mapconcat (lambda (e)
+ (format "[%s | %s | %s] "
+ (s-truncate 8 (ednc-notification-app-name e))
+ (s-truncate 8 (ednc-notification-summary e))
+ (s-truncate 20 (ednc-notification-body e)))
+ )
+ (ednc-notifications)))
+
+(defun single-header-dismiss (num)
+ "Dismiss the most recent notification from the header line. With a prefix
+arg, dismiss all the notifications."
+ (interactive "p")
+ (cond ((and (natnump num) (>= num 4))
+ (mapc 'ednc-dismiss-notification (ednc-notifications)))
+ (t
+ (let ((notifs (ednc-notifications)))
+ (when notifs
+ (ednc-dismiss-notification (car notifs))))))
+ (single-header-update))
+
+(defun single-header-format ()
+ "Evaluated in the header buffer when empty to fill the buffer."
+ (let* ((win (get-buffer-window (current-buffer)))
+ (win-width (window-max-chars-per-line win 'single-header))
+ (info (single-header--make-header-info-string))
+ (info-width (string-width info))
+ (notifs (s-truncate (- win-width info-width 2)
+ (single-header--make-notif-string)))
+ (notifs-width (string-width notifs))
+ (filled (min win-width (+ info-width notifs-width)))
+ (padding-width (- win-width filled))
+ (padding (make-string padding-width ? )))
+ (setq notifs (single-header--with-face notifs 'single-header))
+ (setq padding (single-header--with-face padding 'single-header))
+ (setq info (single-header--with-face info 'single-header))
+ (insert notifs padding info)))
+
+
+
+(defun single-header--make-header-info-string ()
+ "Generates the mode line string that contains all the info to the right."
(let ((str (concat
- (with-face (battery-format "[%b%p%%] " (and battery-status-function (funcall battery-status-function)))
+ (single-header--with-face (battery-format "[%b%p%%] " (and battery-status-function (funcall battery-status-function)))
:weight 'bold)
- (with-face (let* ((mi (memory-info))
+ (single-header--with-face (let* ((mi (memory-info))
(tm (float (car mi)))
(fm (float (cadr mi)))
(ts (float (caddr mi)))
(fs (float (cadddr mi))))
(format "{%.2f %.2f} " (- 1 (/ fm tm)) (- 1 (/ fs ts))))
:foreground "#00ced1")
- (with-face (format "<%03.2f> " (car (load-average 1)))
+ (single-header--with-face (format "<%03.2f> " (car (load-average 1)))
:foreground "#da70d6")
(format-time-string "%a, %b %+4Y-%0m-%0d ")
- (with-face (format-time-string "%R")
+ (single-header--with-face (format-time-string "%R")
:weight 'bold)
)))
- (setq str (concat (make-string
- (- (window-max-chars-per-line (minibuffer-window) 'single-header)
- (length str))
- ? )
- str))
- (with-face str 'single-header)))
+ (single-header--with-face str 'single-header)))
(defun single-header-init-buffer (buf)
(with-current-buffer buf
@@ -69,7 +132,7 @@
(window-preserve-size win nil t))))
(defun single-header-show (buf)
- "show / make a header"
+ "Show the header, making it if necessary."
(if (buffer-live-p buf)
(let ((win (display-buffer-in-side-window buf '((side . top)
(slot . -100)))))
@@ -77,43 +140,67 @@
(single-header-make)))
(defun single-header-make ()
- "create the fake header line"
+ "Create the header and show it."
(interactive)
+
+ (let ((registered
+ (or (equal 'single-header--register-notif-change
+ ednc-notification-presentation-functions )
+ (and (listp ednc-notification-presentation-functions)
+ (-contains? ednc-notification-presentation-functions
+ 'single-header--register-notif-change)))))
+ (unless registered
+ (if (listp ednc-notification-presentation-functions)
+ (push 'single-header--register-notif-change ednc-notification-presentation-functions)
+ (list 'single-header--register-notif-change ednc-notification-presentation-functions))))
(unless (buffer-live-p single-header--current-header-buffer)
(let ((buf (generate-new-buffer "*header*")))
(single-header-init-buffer buf)
(setq single-header--current-header-buffer buf)
- (single-header-show buf))))
+ (single-header-show buf)))
+ (unless (timerp single-header--timer)
+ (setq single-header--timer (run-with-timer 0 single-header-update-increment 'single-header-update))))
(defun single-header-delete ()
- "remove an existing header buffer"
+ "Remove an existing header buffer."
(interactive)
+ (let ((reg-list (and (listp ednc-notification-presentation-functions)
+ (-contains? ednc-notification-presentation-functions
+ 'single-header--register-notif-change)))
+ (reg-equal (or (equal 'single-header--register-notif-change
+ ednc-notification-presentation-functions )
+ )))
+ (when reg-list
+ (delete 'single-header--register-notif-change
+ ednc-notification-presentation-functions))
+ (when reg-equal
+ (setq ednc-notification-presentation-functions
+ 'ednc--update-log-buffer)))
+
+ (when (timerp single-header--timer)
+ (cancel-timer single-header--timer)
+ (setq single-header--timer nil))
(when (buffer-live-p single-header--current-header-buffer)
(kill-buffer single-header--current-header-buffer)))
(defun single-header-update ()
- "update the contents of the header line according to `single-header-format'"
+ "Update the contents of the header line by calling `single-header-format'
+with the header buffer current and empty."
(when (buffer-live-p single-header--current-header-buffer)
(with-current-buffer single-header--current-header-buffer
(erase-buffer)
- (insert (eval single-header-format)))
-
- ;; (when exwm-state
- ;; (exwm-input--set-active-window
- ;; (or (frame-parameter exwm-workspace--current 'exwm-outer-id)
- ;; xcb:Window:None)))
- ))
-
-(add-hook 'after-make-frame-functions (lambda (frame)
- (with-selected-frame frame
- (single-header-show single-header--current-header-buffer))))
-
-;; (use-package lv
- ;; :custom ((lv-use-separator . nil)))
-
-;; do init frame seperately
-(single-header-show single-header--current-header-buffer)
-(setq single-header--timer nil)
-(unless single-header--timer
- (setq single-header--timer (run-with-timer 0 3 'single-header-update)))
+ (single-header-format))))
+
+(define-minor-mode single-header-mode
+ "Global minor mode to enable a single info line at the top of each frame."
+ :global t
+ :init-value nil
+ ;; :keymap '(("s-l d" . 'single-header-dismiss)
+ ;; ("s-l t" . 'single-header-mode))
+ :interactive t
+ (if (not single-header-mode)
+ (single-header-delete)
+ (single-header-make)))
+
+(provide 'single-header)