Compare commits

..

51 Commits
2.3.0 ... main

Author SHA1 Message Date
a15d166249 Test new mood-line-segment-vc--rev behavior 2023-12-10 08:25:27 -05:00
7084fafaa4 Fix comment header 2023-12-10 08:25:20 -05:00
d1c024fdf9 Adjust mood-line-frame-status-client face 2023-12-10 08:09:54 -05:00
e0f6ba27a8 Add project segment 2023-12-10 08:08:46 -05:00
fdaeb1fddb Tweak header comments 2023-12-10 08:08:09 -05:00
d5b6b5b355 Fix typo 2023-12-10 07:57:02 -05:00
4ecd41b934 Improve icon contrast (again) 2023-12-09 06:29:07 -05:00
c0331b4879 Improve icon contrast 2023-12-09 06:28:04 -05:00
2a595780b3 Update repo icon 2023-12-09 06:25:44 -05:00
10b5195f1b Merge branch 'master' 2023-12-09 06:10:01 -05:00
99083c7c3a Bump minor version number 2023-12-09 05:52:27 -05:00
9b004b3d94 Tidy docs 2023-12-09 05:51:54 -05:00
020cbc918f Update preview image 2023-12-09 05:19:42 -05:00
a0c84a3c1e Remove obselete face alias definition
3.0.0 broke compatibility with just about everything that may have hooked into
the package, so it should be appropriate to shed this bit of cruft.
2023-12-09 05:13:28 -05:00
a9b55d8308 Refactor client segment
The client status indicator will be propertized with its own face.

The buffer status indicator and default mood-line-format configurations have
also been adjusted to make room for the new client status indicator.
2023-12-09 05:11:04 -05:00
eb3993601d Merge branch 'client-indicator' 2023-12-09 03:51:06 -05:00
5dfc7572dd Merge: handle vc-display-status being nil 2023-12-09 03:13:27 -05:00
731c786af4 Clarify benchmark results 2023-12-06 20:15:14 -05:00
8a580f30bb Remove unnecessary section header 2023-12-06 20:15:07 -05:00
1c22801c96 Add repository icon 2023-12-04 19:48:45 -05:00
fa79a8c302 Move preview.png from LFS 2023-12-04 19:18:29 -05:00
cc7b931a0b Disable LFS 2023-12-04 19:18:04 -05:00
ff0a35672e Remove fboundp check from mood-line--deflazy
Users are reporting errors caused by deflazy'd functions having void function
definitions. fboundp check may be causing this, and may be unnecessary anyhow.
2023-12-04 18:57:08 -05:00
a19fecd385 Bump patch version number 2023-12-04 18:42:20 -05:00
2050f81860 Fix compatibility with Emacs 27
inhibit-buffer-hooks parameter for get-buffer-create was introduced in Emacs 28.
2023-12-04 18:40:10 -05:00
b568f0faa9 Merge branch 'fix-readme' into 'master'
Fix use-package example in README

See merge request jessieh/mood-line!14
2023-11-28 15:27:29 +00:00
abaa476416 Point README at new issue tracker 2023-11-27 21:53:49 -05:00
19dc4775e5 Update Commentary section to reflect README 2023-11-24 19:23:55 -05:00
d8561e8446 Fix typo in README.md 2023-11-24 19:23:55 -05:00
51318ef090 Properly encapsulate byte-compiler declarations 2023-11-24 19:23:55 -05:00
b2172c52c8 Fix tests for revised mood-line-defformat macro 2023-11-24 19:23:52 -05:00
b7bc361b93 Fix typo in benchmark.md 2023-11-21 16:54:50 -05:00
e66e181ac2 Update .gitattributes 2023-11-21 16:54:43 -05:00
6e0af4bd7e Free benchmark.md from LFS 2023-11-21 16:51:09 -05:00
7ef73ff4e3 Fix typo in README.md 2023-11-21 16:48:59 -05:00
c3ff35a807 Bump major version number
Big changes!
2023-11-21 16:46:57 -05:00
84a172a0ea Add basic benchmark results to back up claims 2023-11-21 16:46:14 -05:00
b5551105d4 Rework mood-line-defformat macro to use plist 2023-11-21 16:45:34 -05:00
78925bdb72 Add processing step to escape mode line constructs 2023-11-20 17:40:40 -05:00
8414402234 Add defformat macro 2023-11-20 17:40:27 -05:00
1f0bf3377e Add tests 2023-11-18 20:29:21 -05:00
b41f6ba1dd Restructure project
mood-line has been restructured to improve modularity and configurability
with careful attention paid to performance and overall project complexity.
2023-11-18 20:20:29 -05:00
d948ba7a94 Move preview screenshot to LFS 2023-11-18 20:19:33 -05:00
110ac6dfc4 Add .gitattributes 2023-11-18 20:19:13 -05:00
ce70dc61ab Update README for impending 3.0.0 changes 2023-11-18 16:40:32 -05:00
kngwyu
89d088c5ec Fix use-package example in README 2023-09-23 18:17:26 +09:00
Seth Ladygo
b1028ce61a Handle vc-display-status being nil. 2023-04-28 15:31:08 -07:00
Gregg Sangster
8331e01908 Add xah-fly-keys to modal segment 2023-03-16 15:54:27 -04:00
Trevor Richards
6e3f62f57c
Moved the emacsclient segment to before anzu 2022-12-31 16:19:32 -08:00
Trevor Richards
21e4addc9b
Added emacsclient indicator
Closes feature request from #25
2022-12-31 16:11:30 -08:00
Trevor Richards
25c7846b8f
Align mode-line-evil-state-alist 2022-12-30 21:03:29 -08:00
13 changed files with 1110 additions and 577 deletions

20
.repo-assets/benchmark.md Normal file
View File

@ -0,0 +1,20 @@
```lisp
;; Emacs 29 with native compilation, default GC threshold
;; Run in a lisp-interaction-mode buffer with Flymake
(defun time-mode-line (num &optional and-mem)
(let ((gc-cons-threshold (if and-mem gc-cons-threshold most-positive-fixnum))
(start-time (current-time)))
(cl-loop for i to num
do (format-mode-line mode-line-format))
(format-time-string "%s.%3N seconds" (time-since start-time))))
;; Default mode line:
(time-mode-line 10000) ;; "0.440 seconds"
(time-mode-line 10000 :and-mem) ;; "2.402 seconds"
;; mood-line (default settings):
(mood-line-mode t)
(time-mode-line 10000) ;; "0.309 seconds"
(time-mode-line 10000 :and-mem) ;; "1.286 seconds"
```

BIN
.repo-assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
.repo-assets/icon.xcf Normal file

Binary file not shown.

BIN
.repo-assets/preview.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

View File

@ -1,32 +1,25 @@
# mood-line # <img src=".repo-assets/icon.png" width=50> mood-line
A lightweight, drop-in replacement for the default Emacs mode line configuration.
[![MELPA](https://melpa.org/packages/mood-line-badge.svg)](https://melpa.org/#/mood-line) [![MELPA](https://melpa.org/packages/mood-line-badge.svg)](https://melpa.org/#/mood-line)
[![MELPA Stable](https://stable.melpa.org/packages/mood-line-badge.svg)](https://stable.melpa.org/#/mood-line) [![MELPA Stable](https://stable.melpa.org/packages/mood-line-badge.svg)](https://stable.melpa.org/#/mood-line)
## About
mood-line is a minimal mode line configuration that aims to replicate some of the features of the
more advanced [doom-modeline](https://github.com/seagle0128/doom-modeline) package.
## Features ## Features
* Clean, minimal design * Clean, informative design
* Customizable, modular segment format
* Customizable glyph sets * Customizable glyph sets
* Anzu and multiple-cursors counters * Lazy-loaded extensions
* Encoding and EOL style indicator * [Lightweight](.repo-assets/benchmark.md), no dependencies
* Version control status indicator
* Custom Flycheck/Flymake indicator
* Lightweight with no dependencies
## Preview ## Preview
![Preview Image](https://gitlab.com/jessieh/mood-line/raw/assets/mood-line.png "Preview Image") ![Preview Image](.repo-assets/preview.webp "Preview Image")
## Configuration ## Configuration
@ -45,15 +38,49 @@ If you are a user of `use-package`, it is easy to configure mood-line directly i
;; Use pretty Fira Code-compatible glyphs ;; Use pretty Fira Code-compatible glyphs
:custom :custom
(mood-line-glyph-alist . mood-line-glyphs-fira-code)) (mood-line-glyph-alist mood-line-glyphs-fira-code))
``` ```
### Format
mood-line uses a modular segment format, and it is easy to reconfigure:
```elisp
;; Default format:
;; * init.el 4:32 Top ELisp ! Issues: 2
(setq mood-line-format mood-line-format-default)
;; Extended format:
;; * init.el 4:32:52 Top SPCx2 LF UTF-8 ELisp ! Issues: 2
(setq mood-line-format mood-line-format-default-extended)
;; Custom format:
;; * init.el : ELisp Top 4:32 | ! Issues: 2
(setq mood-line-format
(mood-line-defformat
:left
(((mood-line-segment-buffer-status) . " ")
((mood-line-segment-buffer-name) . " : ")
(mood-line-segment-major-mode))
:right
(((mood-line-segment-scroll) . " ")
((mood-line-segment-cursor-position) . " ")
((when (mood-line-segment-checker) "|") . " ")
((mood-line-segment-checker) . " "))))
```
More information on the format specification is available in the documentation:\
`M-x describe-variable mood-line-format`\
`M-x describe-function mood-line-defformat`
### Glyphs
By default, mood-line will use basic ASCII character glyphs to decorate mode line segments. By default, mood-line will use basic ASCII character glyphs to decorate mode line segments.
If you'd like to see prettier Unicode glyphs, you can change the value of `mood-line-glyph-alist`: If you'd like to see prettier Unicode glyphs, you can change the value of `mood-line-glyph-alist`:
```elisp ```elisp
;; The default set of glyphs: ;; The default set of glyphs:
;; * myModifiedFile.js Replace*3 + main Javascript ! Issues: 2 ;; * myModifiedFile.js Replace*3 + main JavaScript ! Issues: 2
(setq mood-line-glyph-alist mood-line-glyphs-ascii) (setq mood-line-glyph-alist mood-line-glyphs-ascii)
;; A set of Fira Code-compatible Unicode glyphs: ;; A set of Fira Code-compatible Unicode glyphs:
@ -72,10 +99,18 @@ If you'd like to supply your own glyphs, you can use the customization interface
You can further tweak the behavior and appearance of mood-line by viewing the customizable variables You can further tweak the behavior and appearance of mood-line by viewing the customizable variables
and faces in the `mood-line` and `mood-line-faces` customization groups. (`M-x customize-group mood-line`) and faces in the `mood-line` and `mood-line-faces` customization groups. (`M-x customize-group mood-line`)
## Testing
To run the included tests:
```bash
./ert-test.sh
```
## Feedback ## Feedback
If you experience any issues with this package, please If you experience any issues with this package, please
[open an issue](https://gitlab.com/jessieh/mood-line/issues/new) [open an issue](https://git.tty.dog/jessieh/mood-line/issues/new)
on the issue tracker. on the issue tracker.
Suggestions for improvements and feature requests are always appreciated, as well! Suggestions for improvements and feature requests are always appreciated, as well!

5
ert-test.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
emacs --quick --batch --load=ert \
--load=test/mood-line-test.el \
--load=test/mood-line-segment-vc-test.el \
--funcall=ert-run-tests-batch-and-exit

View File

@ -0,0 +1,168 @@
;;; mood-line-segment-checker.el --- A checker status segment for mood-line -*- lexical-binding: t; -*-
;;
;; Author: Jessie Hildebrandt <jessieh.net>
;; Homepage: https://gitlab.com/jessieh/mood-line
;;
;; This file is not part of GNU Emacs.
;;; Commentary:
;;
;; This segment displays the current status of any active checker.
;;; License:
;;
;; 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 2, 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; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
;; Floor, Boston, MA 02110-1301, USA.
;;; Code:
;; -------------------------------------------------------------------------- ;;
;;
;; Byte-compiler declarations
;;
;; -------------------------------------------------------------------------- ;;
;; ---------------------------------- ;;
;; Required features
;; ---------------------------------- ;;
(eval-when-compile
(require 'flymake))
;; ---------------------------------- ;;
;; External variable defs
;; ---------------------------------- ;;
(eval-when-compile
(defvar flycheck-current-errors))
;; ---------------------------------- ;;
;; External function decls
;; ---------------------------------- ;;
(eval-when-compile
(declare-function mood-line--get-glyph "mood-line")
(declare-function flycheck-count-errors "flycheck")
(declare-function flymake-running-backends "flymake")
(declare-function flymake-reporting-backends "flymake")
(declare-function flymake--lookup-type-property "flymake"))
;; -------------------------------------------------------------------------- ;;
;;
;; Helper functions
;;
;; -------------------------------------------------------------------------- ;;
(defun mood-line-segment-checker--format-status (status error warning note)
"Format STATUS into a segment string with ERROR, WARNING, and NOTE counts."
(pcase status
('running
(format #("%s Checking"
0 11 (face mood-line-status-neutral))
(mood-line--get-glyph :checker-checking)))
('errored
(format #("%s Error"
0 2 (face mood-line-status-error))
(mood-line--get-glyph :checker-errored)))
('interrupted
(format #("%s Paused"
0 9 (face mood-line-status-neutral))
(mood-line--get-glyph :checker-interrupted)))
('finished
(cond
((> error 0)
(let ((issues (+ error warning)))
(format #("%s %s Issue%s"
0 2 (face mood-line-status-error))
(mood-line--get-glyph :checker-issues)
issues
(if (> issues 1) "s" ""))))
((> warning 0)
(format #("%s %s Issue%s"
0 2 (face mood-line-status-warning))
(mood-line--get-glyph :checker-issues)
warning
(if (> warning 1) "s" "")))
((> note 0)
(format #("%s %s Note%s"
0 2 (face mood-line-status-info))
(mood-line--get-glyph :checker-info)
note
(if (> note 1) "s" "")))
(t
(format #("%s No Issues"
0 12 (face mood-line-status-neutral))
(mood-line--get-glyph :checker-good)))))))
;; -------------------------------------------------------------------------- ;;
;;
;; Flycheck update handler
;;
;; -------------------------------------------------------------------------- ;;
(defvar-local mood-line-segment-checker--flycheck-text nil
"Mode line segment string indicating the current state of `flycheck-mode'.")
(defun mood-line-segment-checker--flycheck-update (&optional status)
"Update `mood-line-segment-checker--flycheck-text' with flycheck's STATUS."
(setq mood-line-segment-checker--flycheck-text
(let-alist (flycheck-count-errors flycheck-current-errors)
(when-let* ((valid-statuses '(finished running errored interrupted))
(status-valid (member status valid-statuses))
(error (or .error 0))
(warning (or .warning 0))
(note (or .info 0)))
(mood-line-segment-checker--format-status
status error warning note)))))
;; -------------------------------------------------------------------------- ;;
;;
;; Flymake update handler
;;
;; -------------------------------------------------------------------------- ;;
(defvar-local mood-line-segment-checker--flymake-text nil
"Mode line segment string indicating the current state of `flymake-mode'.")
(defun mood-line-segment-checker--flymake-count (type)
"Return count of current flymake reports of TYPE."
(cl-loop for diag in (flymake-diagnostics)
as diag-type = (flymake-diagnostic-type diag)
count (eq (flymake--lookup-type-property diag-type 'severity)
(flymake--lookup-type-property type 'severity))))
(defun mood-line-segment-checker--flymake-update (&rest _args)
"Update `mood-line-segment-checker--flymake-state' with flymake's status."
(setq mood-line-segment-checker--flymake-text
(when-let ((flymake-active (and (fboundp 'flymake-is-running)
(flymake-is-running)))
(status (if (seq-difference (flymake-running-backends)
(flymake-reporting-backends))
'running 'finished))
(error (mood-line-segment-checker--flymake-count :error))
(warning (mood-line-segment-checker--flymake-count :warning))
(note (mood-line-segment-checker--flymake-count :note)))
(mood-line-segment-checker--format-status
status error warning note))))
;; -------------------------------------------------------------------------- ;;
;;
;; Provide package
;;
;; -------------------------------------------------------------------------- ;;
(provide 'mood-line-segment-checker)
;;; mood-line-segment-checker.el ends here

View File

@ -3,7 +3,7 @@
;; Author: Alynx Zhou <alynx.zhou@gmail.com> ;; Author: Alynx Zhou <alynx.zhou@gmail.com>
;; Jessie Hildebrandt <jessieh.net> ;; Jessie Hildebrandt <jessieh.net>
;; Homepage: https://gitlab.com/jessieh/mood-line ;; Homepage: https://gitlab.com/jessieh/mood-line
;;
;; This file is not part of GNU Emacs. ;; This file is not part of GNU Emacs.
;;; Commentary: ;;; Commentary:
@ -39,7 +39,8 @@
;; External function decls ;; External function decls
;; ---------------------------------- ;; ;; ---------------------------------- ;;
(declare-function mood-line--get-glyph "mood-line" (glyph)) (eval-when-compile
(declare-function mood-line--get-glyph "mood-line"))
;; -------------------------------------------------------------------------- ;; ;; -------------------------------------------------------------------------- ;;
;; ;;
@ -47,6 +48,14 @@
;; ;;
;; -------------------------------------------------------------------------- ;; ;; -------------------------------------------------------------------------- ;;
;; ---------------------------------- ;;
;; Group definitions
;; ---------------------------------- ;;
(defgroup mood-line-segment-indentation nil
"An indentation info segment for mood-line."
:group 'mood-line)
;; ---------------------------------- ;; ;; ---------------------------------- ;;
;; Variable definitions ;; Variable definitions
;; ---------------------------------- ;; ;; ---------------------------------- ;;
@ -62,7 +71,7 @@ When `mood-line-segment-indentation-always-show-offset' is set to non-nil, the
indentation offset will always be shown alongside `tab-width'. If an offset indentation offset will always be shown alongside `tab-width'. If an offset
value cannot be found for the current mode, a \"?\" character will be displayed value cannot be found for the current mode, a \"?\" character will be displayed
alongside `tab-width'." alongside `tab-width'."
:group 'mood-line :group 'mood-line-segment-indentation
:type 'boolean) :type 'boolean)
;; Assembled from `editorconfig-indentation-alist' and `doom-modeline-indent-alist': ;; Assembled from `editorconfig-indentation-alist' and `doom-modeline-indent-alist':
@ -173,9 +182,9 @@ alongside `tab-width'."
"Alist mapping major mode names to their respective indent offset variables. "Alist mapping major mode names to their respective indent offset variables.
When multiple variables are specified for a given mode, the offset value will When multiple variables are specified for a given mode, the offset value will
be retrieved from the first variable that resolves to a value (evaluated in the be retrieved from the first variable that resolves to a value, evaluated in the
order provided)." order provided."
:group 'mood-line :group 'mood-line-segment-indentation
:type '(alist :key-type symbol :value-type sexp)) :type '(alist :key-type symbol :value-type sexp))
;; -------------------------------------------------------------------------- ;; ;; -------------------------------------------------------------------------- ;;
@ -188,8 +197,8 @@ order provided)."
;; Segment function ;; Segment function
;; ---------------------------------- ;; ;; ---------------------------------- ;;
(defun mood-line-segment-indentation--segment () (defun mood-line-segment-indentation ()
"Display the indentation style of the current buffer." "Return the indentation style of the current buffer."
(let* ((mode-offset (symbol-value (let* ((mode-offset (symbol-value
(seq-some #'identity (seq-some #'identity
(cdr (assoc major-mode (cdr (assoc major-mode
@ -202,8 +211,7 @@ order provided)."
tab-width) tab-width)
(number-to-string (if indent-tabs-mode (number-to-string (if indent-tabs-mode
tab-width tab-width
(or mode-offset tab-width)))) (or mode-offset tab-width)))))
" ")
'face 'mood-line-encoding))) 'face 'mood-line-encoding)))
;; -------------------------------------------------------------------------- ;; ;; -------------------------------------------------------------------------- ;;

View File

@ -1,9 +1,9 @@
;;; mood-line-segment-modal.el --- A modal editing segment for mood-line -*- lexical-binding: t; -*- ;;; mood-line-segment-modal.el --- A modal editing status segment for mood-line -*- lexical-binding: t; -*-
;; ;;
;; Author: trevDev() <trev@trevdev.ca> ;; Author: trevDev() <trev@trevdev.ca>
;; Jessie Hildebrandt <jessieh.net> ;; Jessie Hildebrandt <jessieh.net>
;; Homepage: https://gitlab.com/jessieh/mood-line ;; Homepage: https://gitlab.com/jessieh/mood-line
;;
;; This file is not part of GNU Emacs. ;; This file is not part of GNU Emacs.
;;; Commentary: ;;; Commentary:
@ -35,11 +35,19 @@
;; ;;
;; -------------------------------------------------------------------------- ;; ;; -------------------------------------------------------------------------- ;;
;; ---------------------------------- ;;
;; Group definitions
;; ---------------------------------- ;;
(defgroup mood-line-segment-modal nil
"A modal editing status segment for mood-line."
:group 'mood-line)
;; ---------------------------------- ;; ;; ---------------------------------- ;;
;; Variable definitions ;; Variable definitions
;; ---------------------------------- ;; ;; ---------------------------------- ;;
(defcustom mood-line-evil-state-alist (defcustom mood-line-segment-modal-evil-state-alist
'((normal . ("<N>" . font-lock-variable-name-face)) '((normal . ("<N>" . font-lock-variable-name-face))
(insert . ("<I>" . font-lock-string-face)) (insert . ("<I>" . font-lock-string-face))
(visual . ("<V>" . font-lock-keyword-face)) (visual . ("<V>" . font-lock-keyword-face))
@ -47,71 +55,76 @@
(motion . ("<M>" . font-lock-constant-face)) (motion . ("<M>" . font-lock-constant-face))
(operator . ("<O>" . font-lock-function-name-face)) (operator . ("<O>" . font-lock-function-name-face))
(emacs . ("<E>" . font-lock-builtin-face))) (emacs . ("<E>" . font-lock-builtin-face)))
"Set the string and corresponding face for any `evil-mode' state. "Alist specifying indicators and faces for corresponding `evil-mode' states.
The `Face' may be either a face symbol or a property list of key-value pairs The face may be either a face symbol or a property list of key-value pairs;
e.g. (:foreground \"red\")." e.g., (:foreground \"red\")."
:group 'mood-line :group 'mood-line-segment-modal
:type '(alist :type '(alist :key-type symbol
:key-type symbol :value-type (cons (string :tag "Display text")
:value-type (choice :tag "Face" face plist))))
(cons (string :tag "Display Text") (choice :tag "Face" face plist))))
(defcustom mood-line-meow-state-alist (defcustom mood-line-segment-modal-meow-state-alist
'((normal . ("<N>" . font-lock-variable-name-face)) '((normal . ("<N>" . font-lock-variable-name-face))
(insert . ("<I>" . font-lock-string-face)) (insert . ("<I>" . font-lock-string-face))
(keypad . ("<K>" . font-lock-keyword-face)) (keypad . ("<K>" . font-lock-keyword-face))
(beacon . ("<B>" . font-lock-type-face)) (beacon . ("<B>" . font-lock-type-face))
(motion . ("<M>" . font-lock-constant-face))) (motion . ("<M>" . font-lock-constant-face)))
"Set the string and corresponding face for any `meow-mode' state. "Alist specifying indicators and faces corresponding `meow-mode' states.
The `Face' may be either a face symbol or a property list of key-value pairs The face may be either a face symbol or a property list of key-value pairs;
e.g. (:foreground \"red\")." e.g., (:foreground \"red\")."
:group 'mood-line :group 'mood-line-segment-modal
:type '(alist :type '(alist :key-type symbol
:key-type symbol :value-type (cons (string :tag "Display text")
:value-type (choice :tag "Face" face plist))))
(cons (string :tag "Display Text") (choice :tag "Face" face plist))))
;; -------------------------------------------------------------------------- ;; ;; -------------------------------------------------------------------------- ;;
;; ;;
;; Modal editing segment ;; Modal editing segments
;; ;;
;; -------------------------------------------------------------------------- ;; ;; -------------------------------------------------------------------------- ;;
;; ---------------------------------- ;; ;; ---------------------------------- ;;
;; Evil segment function ;; Evil segment
;; ---------------------------------- ;; ;; ---------------------------------- ;;
(defun mood-line-segment-modal--evil () (defun mood-line-segment-modal--evil-fn ()
"Display the current evil-mode state." "Return the current `evil-mode' state."
(when (boundp 'evil-state) (when (boundp 'evil-state)
(let ((mode-cons (alist-get evil-state mood-line-evil-state-alist))) (let ((mode-cons (alist-get evil-state
mood-line-segment-modal-evil-state-alist)))
(concat (propertize (car mode-cons) (concat (propertize (car mode-cons)
'face (cdr mode-cons)) 'face (cdr mode-cons))))))
" "))))
;; ---------------------------------- ;; ;; ---------------------------------- ;;
;; Meow segment function ;; Meow segment
;; ---------------------------------- ;; ;; ---------------------------------- ;;
(defun mood-line-segment-modal--meow () (defun mood-line-segment-modal--meow-fn ()
"Display the current meow-mode state." "Return the current `meow-mode' state."
(when (boundp 'meow--current-state) (when (boundp 'meow--current-state)
(let ((mode-cons (alist-get (let ((mode-cons (alist-get meow--current-state
meow--current-state mood-line-segment-modal-meow-state-alist)))
mood-line-meow-state-alist)))
(concat (propertize (car mode-cons) (concat (propertize (car mode-cons)
'face (cdr mode-cons)) 'face (cdr mode-cons))))))
" "))))
;; ---------------------------------- ;; ;; ---------------------------------- ;;
;; God segment function ;; Xah segment
;; ---------------------------------- ;; ;; ---------------------------------- ;;
(defun mood-line-segment-modal--god () (defun mood-line-segment-modal--xah-fn ()
"Indicate whether or not god-mode is active." "Display the current xah-fly-keys state."
(if (bound-and-true-p xah-fly-insert-state-p)
"<I>"
"<C>"))
;; ---------------------------------- ;;
;; God segment
;; ---------------------------------- ;;
(defun mood-line-segment-modal--god-fn ()
"Return an indicator of whether or not `god-mode' is active."
(if (bound-and-true-p god-local-mode) (if (bound-and-true-p god-local-mode)
'(:propertize "<G> " (propertize "<G>" 'face 'mood-line-status-warning)
face (:inherit mood-line-status-warning))
"---")) "---"))
;; -------------------------------------------------------------------------- ;; ;; -------------------------------------------------------------------------- ;;

114
mood-line-segment-vc.el Normal file
View File

@ -0,0 +1,114 @@
;;; mood-line-segment-vc.el --- A vc-mode info segment for mood-line -*- lexical-binding: t; -*-
;;
;; Author: Jessie Hildebrandt <jessieh.net>
;; Homepage: https://gitlab.com/jessieh/mood-line
;;
;; This file is not part of GNU Emacs.
;;; Commentary:
;;
;; This segment displays the current status of vc-mode.
;;; License:
;;
;; 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 2, 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; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
;; Floor, Boston, MA 02110-1301, USA.
;;; Code:
;; -------------------------------------------------------------------------- ;;
;;
;; Byte-compiler declarations
;;
;; -------------------------------------------------------------------------- ;;
;; ---------------------------------- ;;
;; External function decls
;; ---------------------------------- ;;
(eval-when-compile
(declare-function mood-line--get-glyph "mood-line"))
;; -------------------------------------------------------------------------- ;;
;;
;; Helper functions
;;
;; -------------------------------------------------------------------------- ;;
(defun mood-line-segment-vc--rev (vc-mode-str backend)
"Return name of current file's revision for BACKEND according to `vc-mode'.
VC-MODE-STR is expected to be the value of `vc-mode' in the current buffer.
If `vc-display-status' is nil, return the name of BACKEND."
(or (unless vc-display-status
(symbol-name backend))
(pcase backend
('Git (substring-no-properties vc-mode-str 5))
('Hg (substring-no-properties vc-mode-str 4)))
(ignore-errors
(substring (vc-working-revision buffer-file-name backend) 0 7))
"???"))
;; -------------------------------------------------------------------------- ;;
;;
;; VC segment
;;
;; -------------------------------------------------------------------------- ;;
(defvar-local mood-line-segment-vc--text nil
"Mode line segment string indicating the current state of `vc-mode'.")
(defun mood-line-segment-vc--update (&rest _args)
"Update `mood-line-segment-vc--text' against the current VCS state."
(setq mood-line-segment-vc--text
(when-let* ((vc-active (and vc-mode buffer-file-name))
(backend (vc-backend buffer-file-name))
(state (vc-state buffer-file-name))
(rev (mood-line-segment-vc--rev vc-mode backend)))
(cond
((memq state '(edited added))
(format #("%s %s"
0 2 (face mood-line-status-info))
(mood-line--get-glyph :vc-added)
rev))
((eq state 'needs-merge)
(format #("%s %s"
0 2 (face mood-line-status-warning))
(mood-line--get-glyph :vc-needs-merge)
rev))
((eq state 'needs-update)
(format #("%s %s"
0 2 (face mood-line-status-warning))
(mood-line--get-glyph :vc-needs-update)
rev))
((memq state '(removed conflict unregistered))
(format #("%s %s"
0 2 (face mood-line-status-error))
(mood-line--get-glyph :vc-conflict)
rev))
(t
(format #("%s %s"
0 5 (face mood-line-status-neutral))
(mood-line--get-glyph :vc-good)
rev))))))
;; -------------------------------------------------------------------------- ;;
;;
;; Provide package
;;
;; -------------------------------------------------------------------------- ;;
(provide 'mood-line-segment-vc)
;;; mood-line-segment-vc.el ends here

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,45 @@
;;; mood-line-segment-vc-test.el --- Test specifications for mood-line-segment-vc.el -*- lexical-binding: t; -*-
(add-to-list 'load-path ".")
(require 'ert)
(require 'mood-line)
(require 'mood-line-segment-vc)
;;; Code:
;; -------------------------------------------------------------------------- ;;
;;
;; Helper functions
;;
;; -------------------------------------------------------------------------- ;;
;; ---------------------------------- ;;
;; mood-line-segment-vc--rev
;; ---------------------------------- ;;
(ert-deftest --rev/git ()
"Current rev should be cleanly extracted from git `vc-mode' status string."
(should (string= (mood-line-segment-vc--rev " Git:main" 'Git)
"main")))
(ert-deftest --rev/hg ()
"Current rev should be cleanly extracted from hg `vc-mode' status string."
(should (string= (mood-line-segment-vc--rev " Hg:main" 'Hg)
"main")))
(ert-deftest --rev/unknown ()
"Current rev should be reported as \"???\" when backend is unsupported."
(let ((buffer-file-name ""))
(should (string= (mood-line-segment-vc--rev "" 'SVN)
"???"))))
(ert-deftest --rev/vc-display-status-nil ()
"Name of the VCS backend should be reported when `vc-display-status' is nil."
(let ((vc-display-status nil))
(should (string= (mood-line-segment-vc--rev " Git:main" 'Git)
"Git"))
(should (string= (mood-line-segment-vc--rev " Hg:main" 'Hg)
"Hg"))))
;;; mood-line-segment-vc-test.el ends here

206
test/mood-line-test.el Normal file
View File

@ -0,0 +1,206 @@
;;; mood-line-test.el --- Test specifications for mood-line.el -*- lexical-binding: t; -*-
(add-to-list 'load-path ".")
(require 'ert)
(require 'mood-line)
;;; Code:
;; -------------------------------------------------------------------------- ;;
;;
;; Macros
;;
;; -------------------------------------------------------------------------- ;;
;; ---------------------------------- ;;
;; mood-line-defformat
;; ---------------------------------- ;;
(ert-deftest -defformat/padding ()
"The expanded sequence should include the provided (or default) padding."
(should (equal (mood-line-defformat)
(list
;; Left
'(" ")
;; Right
'(" "))))
(should (equal (mood-line-defformat
:padding
"---")
(list
;; Left
'("---")
;; Right
'("---")))))
(ert-deftest -defformat/left-right-nil ()
"The format sequence should expand if the left or right segment list is nil."
(should (equal (mood-line-defformat
:left
("XYZ"))
(list
;; Left
'(" " "XYZ")
;; Right
'(" "))))
(should (equal (mood-line-defformat
:right
("XYZ"))
(list
;; Left
'(" ")
;; Right
'("XYZ" " ")))))
(ert-deftest -defformat/left-right ()
"The expanded sequence should include left and right segments lists."
(should (equal (mood-line-defformat
:left
("ABC")
:right
("XYZ"))
(list
;; Left
'(" " "ABC")
;; Right
'("XYZ" " ")))))
(ert-deftest -defformat/cons-cells ()
"Cons cell segments should expand into their `car' and `cdr' values."
(should (equal (mood-line-defformat
:left
("ABC" ("ABC" . "XYZ") "XYZ")
:right
("..." ((some-fn) . " ") "..."))
(list
;; Left
'(" " "ABC" "ABC" "XYZ" "XYZ")
;; Right
'("..." (some-fn) " " "..." " ")))))
(ert-deftest -defformat/exp-separators ()
"Non-string, non-cons expressions should expand followed by a blank string."
(should (equal (mood-line-defformat
:left
("ABC" ("ABC" . "XYZ") some-exp "XYZ" (some-fn))
:right
("..." ((some-fn) . " ") (another-fn) "..."))
(list
;; Left
'(" " "ABC" "ABC" "XYZ" some-exp "" "XYZ" (some-fn) "")
;; Right
'("..." (some-fn) " " (another-fn) "" "..." " ")))))
;; -------------------------------------------------------------------------- ;;
;;
;; Helper functions
;;
;; -------------------------------------------------------------------------- ;;
;; ---------------------------------- ;;
;; mood-line--get-glyph
;; ---------------------------------- ;;
(ert-deftest --get-glyph/unicode ()
"Glyphs should be fethed from `mood-line-glyph-alist'."
(let ((mood-line-glyph-alist '((:checker-info . ?🛈))))
(should (string= (mood-line--get-glyph :checker-info) "🛈"))))
(ert-deftest --get-glyph/fallback-ascii ()
"Glyphs should be fetched from `mood-line-glyphs-ascii' as a fallback."
(let ((mood-line-glyph-alist nil))
(should (string= (mood-line--get-glyph :checker-info) "i"))))
;; ---------------------------------- ;;
;; mood-line--process-segments
;; ---------------------------------- ;;
(ert-deftest --process-segments/default ()
"`mood-line-format-default' should be processed without error."
(let* ((left (car mood-line-format-default))
(right (cadr mood-line-format-default))
(left-str (mood-line--process-segments left))
(right-str (mood-line--process-segments right)))
(should (> (length left-str) 0))
(should (> (length right-str) 0))))
(ert-deftest --process-segments/strings ()
"Literal strings should be concatenated."
(let* ((segments '("ABC" " " "123" " " "XYZ"))
(segments-str (mood-line--process-segments segments)))
(should (string= segments-str "ABC 123 XYZ"))))
(ert-deftest --process-segments/nil-neighbor-exclusion ()
"A nil value should mean skipping evaluation of the following segment."
(let* ((segments '("ABC" nil " " "123" nil " " "XYZ" nil))
(segments-str (mood-line--process-segments segments)))
(should (string= segments-str "ABC123XYZ"))))
(ert-deftest --process-segments/functions ()
"Functions should be evaluated, and their return values concatenated."
(let* ((segments '((string ?A ?B ?C)
(numberp nil) " "
(number-to-string (+ 100 20 3))
(identity nil) " "
(concat "X" "Y" "Z")))
(segments-str (mood-line--process-segments segments)))
(should (string= segments-str "ABC123XYZ"))))
;; ---------------------------------- ;;
;; mood-line--process-format
;; ---------------------------------- ;;
(ert-deftest --process-format/default ()
"`mood-line-format-default' should be processed without error."
(let* ((format-str (mood-line--process-format mood-line-format-default)))
(should (> (length format-str) 0))))
(ert-deftest --process-format/nil-okay ()
"Either segment list should process without error if the other list is nil."
(let* ((format-l-nil '(nil ("ABC" nil " " "123" nil " " "XYZ")))
(format-r-nil '(("ABC" nil " " "123" nil " " "XYZ") nil))
(format-l-nil-str (mood-line--process-format format-l-nil))
(format-r-nil-str (mood-line--process-format format-r-nil)))
(should (string-suffix-p "ABC123XYZ" format-l-nil-str))
(should (string-prefix-p "ABC123XYZ" format-r-nil-str))))
;; -------------------------------------------------------------------------- ;;
;;
;; mood-line-mode
;;
;; -------------------------------------------------------------------------- ;;
;; ---------------------------------- ;;
;; mood-line--activate
;; ---------------------------------- ;;
(ert-deftest --activate/mode-line-format ()
"`mode-line-format' should be set by `mood-line--activate'."
(let* ((setting-val (alist-get 'mode-line-format
mood-line--settings-alist))
(mood-line--settings-alist `((mode-line-format . ,setting-val)))
(mood-line-format mood-line-format-default)
(mode-line-format '("ABC 123 XYZ"))
(format-str (mood-line--process-format mood-line-format)))
(mood-line--activate)
(should (string= (format-mode-line mode-line-format)
(format-mode-line format-str)))))
;; ---------------------------------- ;;
;; mood-line--deactivate
;; ---------------------------------- ;;
(ert-deftest --deactivate/mode-line-format ()
"`mode-line-format' should be restored by `mood-line--deactivate'."
(let* ((setting-val (alist-get 'mode-line-format
mood-line--settings-alist))
(mood-line--settings-alist `((mode-line-format . ,setting-val)))
(mood-line--settings-backup-alist nil)
(mood-line-format mood-line-format-default)
(mode-line-format "ABC 123 XYZ"))
(mood-line--activate)
(mood-line--deactivate)
(should (string= mode-line-format "ABC 123 XYZ"))))
;;; mood-line-test.el ends here