From 134409aa670be39e676f093f5aa5b5b941126375 Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Thu, 12 May 2022 22:37:16 -0500 Subject: Modeline stuff! --- lisp/+modeline.el | 124 +++++++++++++++++++++++++++--------------------------- 1 file changed, 63 insertions(+), 61 deletions(-) (limited to 'lisp/+modeline.el') diff --git a/lisp/+modeline.el b/lisp/+modeline.el index f408757..86dbad4 100644 --- a/lisp/+modeline.el +++ b/lisp/+modeline.el @@ -25,35 +25,27 @@ will default to this string.") ;;; Combinators (defun +modeline-concat (segments &optional separator) - "Concatenate multiple `simple-modeline'-style SEGMENTS. -SEGMENTS is a list of either modeline segment-functions (see -`simple-modeline' functions for an example of types of -functions), though it can also contain cons cells of the -form (SEGMENT . PREDICATE). - -Segments are separated from each other using SEPARATOR, which -defaults to a \" \". Only segments that evaluate to a -non-trivial string (that is, a string not equal to \"\") will be -separated, for a cleaner look. - -This function makes a lambda, so you can throw it straight into -`simple-modeline-segments'." - (setq separator (or separator +modeline-default-spacer)) - (lambda () - (apply #'concat - (let (this-sep result-list) - (dolist (segment segments) - (push (funcall (or (car-safe segment) segment) - this-sep) - result-list) - (if (or (cdr-safe segment) - (and (car result-list) - (not (equal (car result-list) "")))) - (setq this-sep separator) - (setq this-sep nil))) - ;; (unless (seq-some #'null result-list) - ;; (push +modeline-default-spacer result-list)) - (nreverse result-list))))) + "Concatenate multiple functional modeline SEGMENTS. +Each segment in SEGMENTS is a function returning a mode-line +construct. + +Segments are separated using SEPARATOR, which defaults to +`+modeline-default-spacer'. Only segments that evaluate to a +non-zero-length string will be separated, for a cleaner look. + +This function returns a lambda that should be `:eval'd or +`funcall'd in a mode-line context." + (let ((separator (or separator +modeline-default-spacer))) + (lambda () + (let (this-sep result) + (dolist (segment segments) + (let ((segstr (funcall segment this-sep))) + (when (and segstr + (not (equal segstr ""))) + (push segstr result) + (setq this-sep separator)))) + (apply #'concat + (nreverse result)))))) (defun +modeline-spacer (&optional n spacer &rest strings) "Make an N-length SPACER, or prepend SPACER to STRINGS. @@ -152,7 +144,7 @@ in the cdr will be applied to the major-mode in the mode line." "(" (propertize ;; (+string-truncate (format-mode-line mode-name) 16) (format-mode-line mode-name) - 'face (if (actually-selected-window-p) + 'face (when (actually-selected-window-p) ;; XXX: This is probably really inefficient. I need to ;; simply detect which mode it's in when I change major ;; modes (`change-major-mode-hook') and change the face @@ -160,8 +152,7 @@ in the cdr will be applied to the major-mode in the mode line." (catch :done (dolist (cel +modeline-major-mode-faces) (when (derived-mode-p (car cel)) (throw :done (cdr cel)))) - (alist-get t +modeline-major-mode-faces)) - 'unspecified) + (alist-get t +modeline-major-mode-faces))) 'keymap (let ((map (make-sparse-keymap))) (bindings--define-key map [mode-line down-mouse-1] `(menu-item "Menu Bar" ignore @@ -293,13 +284,26 @@ The order of elements matters: whichever one matches first is applied." ;; (t (format "%d%%%%%%%%%%" perc)))) ;; ;; TODO: add scroll-up and scroll-down bindings. ;; )) - (let ((perc (format-mode-line '(-3 "%p")))) + (let ((perc (format-mode-line '(-2 "%p")))) (+modeline-spacer nil spacer + "/" (pcase perc - ("Top" ".^^") - ("Bot" ".__") - ("All" ".::") - (_ (format ".%02d" (string-to-number (substring perc 0 2))))))))) + ("To" "Top") + ("Bo" "Bot") + ("Al" "All") + (_ (format ".%02d" (string-to-number perc)))))))) + +(defun +modeline-file-percentage-ascii-icon (&optional spacer) + (when file-percentage-mode + (+modeline-spacer nil spacer + (let ((perc (format-mode-line '(-2 "%p")))) + (pcase perc + ("To" "/\\") + ("Bo" "\\/") + ("Al" "[]") + (_ (let ((vec (vector "/|" "//" "||" "\\\\" "\\|" "\\|")) + (perc (string-to-number perc))) + (aref vec (floor (/ perc 17)))))))))) (defun +modeline-file-percentage-icon (&optional spacer) "Display the position in the current file as an icon." @@ -307,14 +311,14 @@ The order of elements matters: whichever one matches first is applied." (let ((perc (+modeline--percentage))) (propertize (+modeline-spacer nil spacer (cond - ((+modeline--buffer-contained-in-window-p) "⏹") - ((= perc 0) "▇") - ((< perc 20) "▆") - ((< perc 40) "▅") - ((< perc 60) "▄") - ((< perc 80) "▃") - ((< perc 100) "▂") - ((>= perc 100) "▁"))) + ((+modeline--buffer-contained-in-window-p) "111") + ((= perc 0) "000") + ((< perc 20) "001") + ((< perc 40) "010") + ((< perc 60) "011") + ((< perc 80) "100") + ((< perc 100) "101") + ((>= perc 100) "110"))) 'help-echo (format "Point is %d%% through the buffer." perc))))) @@ -327,30 +331,25 @@ The order of elements matters: whichever one matches first is applied." (when (and region-indicator-mode (region-active-p)) (+modeline-spacer nil spacer - (propertize (format "%s%d" - (if (and (< (point) (mark))) "-" "+") + (propertize (format "%d%s" (apply '+ (mapcar (lambda (pos) (- (cdr pos) (car pos))) - (region-bounds)))) + (region-bounds))) + (if (and (< (point) (mark))) "-" "+")) 'font-lock-face 'font-lock-variable-name-face)))) (defun +modeline-line (&optional spacer) (when line-number-mode - (+modeline-spacer nil spacer "%2l"))) + (+modeline-spacer nil spacer + "%l"))) (defun +modeline-column (&optional spacer) (when column-number-mode (+modeline-spacer nil spacer + "|" (if column-number-indicator-zero-based "%2c" "%2C")))) -(defun +modeline-line-column (&optional spacer) ; adapted from `simple-modeline' - "Display the current cursor line and column depending on modes." - (+modeline-spacer nil spacer - (+modeline-line "") - "|" - (+modeline-column ""))) - (defcustom +modeline-position-function nil "Function to use instead of `+modeline-position' in modeline." :type '(choice (const :tag "Default" nil) @@ -362,11 +361,14 @@ The order of elements matters: whichever one matches first is applied." See `line-number-mode', `column-number-mode', and `file-percentage-mode'. If `+modeline-position-function' is set to a function in the current buffer, call that function instead." - (+modeline-spacer nil spacer - (cond ((functionp +modeline-position-function) - (funcall +modeline-position-function)) - (t (concat (+modeline-region) - (+modeline-line-column)))))) + (cond ((functionp +modeline-position-function) + (+modeline-spacer nil spacer + (funcall +modeline-position-function))) + (t (funcall (+modeline-concat '(+modeline-region + +modeline-line + +modeline-column + +modeline-file-percentage) + ""))))) (defun +modeline-vc (&optional spacer) "Display the version control branch of the current buffer in the modeline." -- cgit 1.4.1-21-gabe81