[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/nano-modeline 21263a0b3d 01/26: Complete rewrite
From: |
ELPA Syncer |
Subject: |
[elpa] externals/nano-modeline 21263a0b3d 01/26: Complete rewrite |
Date: |
Fri, 2 Jun 2023 03:59:06 -0400 (EDT) |
branch: externals/nano-modeline
commit 21263a0b3d2701262e22565f4ddc1924d985113e
Author: Nicolas P. Rougier <Nicolas.Rougier@inria.fr>
Commit: Nicolas P. Rougier <Nicolas.Rougier@inria.fr>
Complete rewrite
---
nano-modeline.el | 1553 ++++++++++++++++--------------------------------------
1 file changed, 440 insertions(+), 1113 deletions(-)
diff --git a/nano-modeline.el b/nano-modeline.el
index bc8127977e..0f2b7d5f6b 100644
--- a/nano-modeline.el
+++ b/nano-modeline.el
@@ -1,6 +1,6 @@
;;; nano-modeline.el --- N Λ N O modeline -*- lexical-binding: t -*-
-;; Copyright (C) 2021, 2022 Free Software Foundation, Inc.
+;; Copyright (C) 2021-2023 Free Software Foundation, Inc.
;; Maintainer: Nicolas P. Rougier <Nicolas.Rougier@inria.fr>
;; URL: https://github.com/rougier/nano-modeline
@@ -25,29 +25,15 @@
;;; Commentary:
;;
-;; Nano modeline is a minor mode that modify the modeline as:
-;; [ name (primary) secondary ]
-;;
-;; It can be displayed at the bottom (mode-line) or at the top (header-line)
-;; depending on nano-modeline-position custom setting.
-;;
-;; There are two sets of faces (for active and inactive modelines) that
-;; can be customized (M-x: customize-group + nano-modeline)
-;;
-;; - nano-modeline-active / nano-modeline-inactive
-;; - nano-modeline-active-name / nano-modeline-inactive-name
-;; - nano-modeline-active-primary / nano-modeline-inactive-primary
-;; - nano-modeline-active-secondary / nano-modeline-inactive-secondary
-;; - nano-modeline-active-status-RO / nano-modeline-inactive-status-RO
-;; - nano-modeline-active-status-RW / nano-modeline-inactive-status-RW
-;; - nano-modeline-active-status-** / nano-modeline-inactive-status-**
;;
;; Usage example:
;;
-;; M-x: nano-modeline-mode
;;
;;; NEWS:
;;
+;; Version 1.0.0
+;; - Complete rewrite to make it simpler & faster
+;;
;; Version 0.7.2
;; - Fix a bug in info mode (breadcrumbs)
;; - Fix mu header mode for version 1.8
@@ -96,8 +82,6 @@
;;
;;; Code:
-(eval-when-compile
- (require 'term))
(defgroup nano nil
"N Λ N O"
@@ -107,1128 +91,471 @@
"N Λ N O Modeline"
:group 'nano)
-(defgroup nano-modeline-active nil
- "Active modeline faces.
-
-
-Modeline is composed as:
-[ status | name (primary) secondary ]"
- :group 'nano-modeline)
-
-(defgroup nano-modeline-inactive nil
- "Inactive modeline faces
-
-Modeline is composed as:
-[ status | name (primary) secondary ]"
- :group 'nano-modeline)
-
-(defcustom nano-modeline-position 'top
- "Default position (top or bottom)"
- :type '(choice (const :tag "Top" top)
- (const :tag "Bottom" bottom))
- :group 'nano-modeline)
-
-(defcustom nano-modeline-space-top +0.20
- "Space adjustment for top of modeline
-Possitive is upwards"
- :type 'float
- :group 'nano-modeline)
-
-(defcustom nano-modeline-space-bottom -0.25
- "Space adjustment for bottom of modeline
-Negative is downwards."
- :type 'float
+(defcustom nano-modeline-padding '(0.20 . 0.25)
+ "Default vertical space adjustment"
+ :type '(cons (float :tag "Top spacing")
+ (float :tag "Bottom spacing"))
:group 'nano-modeline)
-(defcustom nano-modeline-prefix 'default
- "Type of prefix on the left"
- :type '(choice (const :tag "None" none)
- (const :tag "Status (RO/RW/**)" status)
- (const :tag "Icon" icon))
+(defcustom nano-modeline-position #'nano-modeline-header
+ "Default position for the nano modeline"
+
+ :type '(choice (const :tag "Top" nano-modeline-header)
+ (const :tag "Bottom" nano-modeline-footer))
:group 'nano-modeline)
-(defcustom nano-modeline-prefix-padding t
- "Wheter to add a space after prefix part.
-This is useful (aesthetically) if the face of prefix uses a different
background color than the rest of the modeline."
- :type 'boolean
- :group 'nano-modeline)
+;; Nano line faces
+(defcustom nano-modeline-faces
+ '((header-active . (nano-subtle :box (:line-width 1 :color "white")))
+ (header-inactive . (nano-subtle nano-faded :box (:line-width 1 :color
"white")))
+ (footer-active . (nano-default :overline t))
+ (footer-inactive . (nano-faded :overline t))
+ (bold-active . (bold))
+ (status-**-active . (bold nano-popout-i))
+ (status-**-inactive . (nano-faded))
+ (status-RW-active . (bold nano-faded-i))
+ (status-RO-active . (bold nano-default-i)))
+ "Nano line faces"
+ :type '(alist :key-type symbol :value-type sexp))
-(defcustom nano-modeline-display-tab-number nil
- "Whether to display the tab-number in the mode-line.
-Then number is provided by `nano-modeline-tab-number'."
- :type 'boolean
- :group 'nano-modeline)
+(defface nano-modeline--empty-face
+ `((t (:foreground ,(face-foreground 'default))))
+ "Empty face for resetting mode-line / header-line.")
-(defface nano-modeline-active
- '((t (:inherit mode-line)))
- "Modeline face for active modeline"
- :group 'nano-modeline-active)
-
-(defface nano-modeline-active-name
- '((t (:inherit (nano-modeline-active bold))))
- "Modeline face for active name element (default)"
- :group 'nano-modeline-active)
-
-(defface nano-modeline-active-primary
- '((t (:inherit nano-modeline-active)))
- "Modeline face for active primary element (default)"
- :group 'nano-modeline-active)
-
-(defface nano-modeline-active-secondary
- '((t (:inherit (nano-modeline-active font-lock-comment-face))))
- "Modeline face for active secondary element"
- :group 'nano-modeline-active)
-
-(defface nano-modeline-active-status-RO
- '((t (:inherit nano-modelinea-active)))
- "Modeline face for active READ-ONLY element"
- :group 'nano-modeline-active)
-
-(defface nano-modeline-active-status-RW
- '((t (:inherit nano-modeline-active)))
- "Modeline face for active READ-WRITE element"
- :group 'nano-modeline-active)
-
-(defface nano-modeline-active-status-**
- '((t (:inherit nano-modeline-active)))
- "Modeline face for active MODIFIED element"
- :group 'nano-modeline-active)
-
-(defface nano-modeline-inactive
- '((t (:inherit (mode-line-inactive font-lock-comment-face))))
- "Modeline face for inactive window"
- :group 'nano-modeline-inactive)
-
-(defface nano-modeline-inactive-name
- '((t (:inherit (nano-modeline-inactive))))
- "Modeline face for inactive name element"
- :group 'nano-modeline-inactive)
-
-(defface nano-modeline-inactive-primary
- '((t (:inherit nano-modeline-inactive)))
- "Modeline face for inactive primary element"
- :group 'nano-modeline-inactive)
-
-(defface nano-modeline-inactive-secondary
- '((t (:inherit nano-modeline-inactive)))
- "Modeline face for inactive primary element"
- :group 'nano-modeline-inactive)
-
-(defface nano-modeline-inactive-status-RO
- '((t (:inherit nano-modeline-inactive)))
- "Modeline face for inactive READ-ONLY element"
- :group 'nano-modeline-inactive)
-
-(defface nano-modeline-inactive-status-RW
- '((t (:inherit nano-modeline-inactive)))
- "Modeline face for inactive READ-WRITE element"
- :group 'nano-modeline-inactive)
-
-(defface nano-modeline-inactive-status-**
- '((t (:inherit nano-modeline-inactive)))
- "Modeline face for inactive MODIFIED element"
- :group 'nano-modeline-inactive)
-
-(defcustom nano-modeline-mode-formats
- '(;; with :mode-p first
-
- (imenu-list-mode :mode-p nano-modeline-imenu-list-mode-p
- :format nano-modeline-imenu-list-mode
- :icon "") ;; nerd-font / oct-three-bars
- (org-capture-mode :mode-p nano-modeline-org-capture-mode-p
- :format nano-modeline-org-capture-mode
- :on-activate nano-modeline-org-capture-activate
- :on-inactivate nano-modeline-org-capture-inactivate
- :icon "") ;; nerd-font / oct-calendar
-
- (prog-mode :mode-p nano-modeline-prog-mode-p
- :format nano-modeline-prog-mode
- :icon "") ;; nerd-font / oct-file-code
- (mu4e-compose-mode :mode-p nano-modeline-mu4e-compose-mode-p
- :format nano-modeline-mu4e-compose-mode
- :icon "") ;; nerd-font / oct-pencil
- (mu4e-headers-mode :mode-p nano-modeline-mu4e-headers-mode-p
- :format nano-modeline-mu4e-headers-mode
- :icon "") ;; nerd-font / oct-search
- (mu4e-loading-mode :mode-p nano-modeline-mu4e-loading-mode-p
- :format nano-modeline-mu4e-loading-mode
- :icon "") ;; nerd-font / oct-gears
- (mu4e-main-mode :mode-p nano-modeline-mu4e-main-mode-p
- :format nano-modeline-mu4e-main-mode
- :icon "") ;; nerd-font / oct-inbox
- (mu4e-view-mode :mode-p nano-modeline-mu4e-view-mode-p
- :format nano-modeline-mu4e-view-mode
- :icon "") ;; nerd-font / oct-comment
- (mu4e-dashboard-mode :mode-p nano-modeline-mu4e-dashboard-mode-p
- :format nano-modeline-mu4e-dashboard-mode
- :icon "") ;; nerd-font / oct-inbox
- (messages-mode :mode-p nano-modeline-messages-mode-p
- :format nano-modeline-messages-mode
- :icon "") ;; nerd-font / oct-comment
- (text-mode :mode-p nano-modeline-text-mode-p
- :format nano-modeline-text-mode
- :icon "") ;; nerd-font / oct-file-text
- (term-mode :mode-p nano-modeline-term-mode-p
- :format nano-modeline-term-mode
- :icon "") ;; nerd-font / oct-term
- (vterm-mode :mode-p nano-modeline-vterm-mode-p
- :format nano-modeline-term-mode
- :icon "") ;; nerd-font / oct-term
- (buffer-menu-mode :mode-p nano-modeline-buffer-menu-mode-p
- :format nano-modeline-buffer-menu-mode
- :on-activate nano-modeline-buffer-menu-activate
- :on-inactivate nano-modeline-buffer-menu-inactivate
- :icon "") ;; nerd-font / oct-three-bars
-
- (calendar-mode :mode-p nano-modeline-calendar-mode-p
- :format nano-modeline-calendar-mode
- :on-activate nano-modeline-calendar-activate
- :on-inactivate nano-modeline-calendar-inactivate
- :icon "") ;; nerd-font / oct-calendar
- (completion-list-mode :mode-p nano-modeline-completion-list-mode-p
- :format nano-modeline-completion-list-mode
- :icon "") ;; nerd-font / oct-list-unordered
- (deft-mode :mode-p nano-modeline-deft-mode-p
- :format nano-modeline-deft-mode
- :icon "") ;; nerd-font / oct-search
- (doc-view-mode :mode-p nano-modeline-doc-view-mode-p
- :format nano-modeline-doc-view-mode
- :icon "") ;; nerd-font / oct-
- (elfeed-search-mode :mode-p nano-modeline-elfeed-search-mode-p
- :format nano-modeline-elfeed-search-mode
- :on-activate nano-modeline-elfeed-search-activate
- :on-inactivate
nano-modeline-elfeed-search-inactivate
- :icon "") ;; nerd-font / oct-search
- (elfeed-show-mode :mode-p nano-modeline-elfeed-show-mode-p
- :format nano-modeline-elfeed-show-mode
- :icon "") ;; nerd-font / oct-comment
- (elpher-mode :mode-p nano-modeline-elpher-mode-p
- :format nano-modeline-elpher-mode
- :on-activate nano-modeline-elpher-activate
- :icon "") ;; nerd-font / oct-browser
- (info-mode :mode-p nano-modeline-info-mode-p
- :format nano-modeline-info-mode
- :on-activate nano-modeline-info-activate
- :on-inactivate nano-modeline-info-inactivate
- :icon "") ;; nerd-font / oct-info
- (nano-help-mode :mode-p nano-modeline-nano-help-mode-p
- :format nano-modeline-nano-help-mode
- :icon "") ;; nerd-font / oct-info
- (org-agenda-mode :mode-p nano-modeline-org-agenda-mode-p
- :format nano-modeline-org-agenda-mode
- :icon "") ;; nerd-font / oct-calendar
- (org-clock-mode :mode-p nano-modeline-org-clock-mode-p
- :format nano-modeline-org-clock-mode
- :on-activate nano-modeline-org-clock-activate
- :on-inactivate nano-modeline-org-clock-inactivate
- :icon "") ;; nerd-font / oct-clock
- (pdf-view-mode :mode-p nano-modeline-pdf-view-mode-p
- :format nano-modeline-pdf-view-mode
- :icon "") ;; nerd-font/ oct-file-pdf
-
- ;; hooks only last
- (ein-notebook-mode :on-activate nano-modeline-ein-notebook-activate
- :on-inactivate
nano-modeline-ein-notebook-inactivate)
- (esh-mode :on-activate nano-modeline-esh-activate
- :on-inactivate nano-modeline-esh-inactivate)
- (ispell-mode :on-activate nano-modeline-ispell-activate
- :on-inactivate nano-modeline-ispell-inactivate)
- (mu4e-mode :on-activate nano-modeline-mu4e-activate
- :on-inactivate nano-modeline-mu4e-inactivate))
- "Modes to be evalued for modeline.
-KEY mode name, for reference only. Easier to do lookups and/or replacements.
-:MODE-P the function to check if :FORMAT needs to be used, first one wins.
-:ON-ACTIVATE and :ON-INACTIVATE do hook magic on enabling/disabling the mode.
-"
- :type '(alist :key-type symbol
- :value-type (plist :key-type (choice (const :mode-p)
- (const :format)
- (const :icon)
- (const :on-activate)
- (const :on-inactivate))))
- :group 'nano-modeline)
-
-(defcustom nano-modeline-mode-format-activate-hook nil
- "Add hooks on activation of the mode, for those modes that do their own
mode-line magic"
- :type 'hook
- :options '(turn-on-auto-fill flyspell-mode)
- :group 'nano-modeline)
+(defvar nano-modeline--selected-window nil
+ "Selected window before mode-line was activated.")
-(defcustom nano-modeline-mode-format-inactivate-hook nil
- "Remove hooks on de-activation of the mode, for those modes that do their
own mode-line magic"
- :type 'hook
- :options '(turn-on-auto-fill flyspell-mode)
- :group 'nano-modeline)
-
-(defcustom nano-modeline-default-mode-format 'nano-modeline-default-mode
- "Default mode to evaluate if no match could be found in
`nano-modeline-mode-formats'"
- :type 'function
- :group 'nano-modeline)
-
-(defcustom nano-modeline-user-mode nil
- "User supplied mode to be evaluated for modeline."
- :type '(choice (const nil) function)
- :group 'nano-modeline)
-(make-obsolete-variable nano-modeline-user-mode
- "Add to `nano-modeline-mode-formats' instead" "0.5")
+(defun nano-modeline--update-selected-window ()
+ "Update selected window (before mode-line is active)"
+ (setq nano-modeline--selected-window (selected-window)))
-(defcustom nano-modeline-user-mode-p nil
- "Function to indicate whether the user supplied mode should be used instead
f the default one. This function will be dynamically called and can return t or
nil depending on some user conditions. If the provied function always return t,
this fully overrides the nano-modeline."
- :type '(choice (const nil) function)
- :group 'nano-modeline)
-(make-obsolete-variable nano-modeline-user-mode-p
- "Add to `nano-modeline-mode-formats' instead" "0.5")
+(defun nano-modeline--base-face (face-prefix)
+ "Return the face for FACE-PREFIX according to current active state."
-(defun nano-modeline-truncate (str size &optional ellipsis)
- "If STR is longer than SIZE, truncate it and add ELLIPSIS."
+ (let* ((window (get-buffer-window (current-buffer)))
+ (active (eq window nano-modeline--selected-window))
+ (state (intern (concat (symbol-name face-prefix)
+ (if active "-active" "-inactive"))))
+ (face (cdr (assoc state nano-modeline-faces))))
+ face))
- (let ((ellipsis (or ellipsis "…")))
- (if (> (length str) size)
- (format "%s%s" (substring str 0 (- size (length ellipsis))) ellipsis)
- str)))
+(defun nano-modeline--face (&optional face-prefix)
+ "Return the face for FACE-PREFIX according to current active state and
+make it inherit the base face."
-(defun nano-modeline-vc-branch ()
- "Return current VC branch if any."
+ (let* ((window (get-buffer-window (current-buffer)))
+ (active (eq window nano-modeline--selected-window))
+ (state (intern (concat (symbol-name face-prefix)
+ (if active "-active" "-inactive"))))
+ (face (cdr (assoc state nano-modeline-faces)))
+ (face (if (boundp 'nano-modeline-base-face)
+ (push nano-modeline-base-face face)
+ face))
+ (face (reverse face)))
+ `(:inherit ,face)))
+
+(defun nano-modeline--make (left right face-prefix)
+ "Build a dynamic mode/header line made of LEFT and RIGHT part,
+using the given FACE-PREFIX as the default."
+
+ `(:eval
+ (let* ((nano-modeline-base-face (nano-modeline--base-face ',face-prefix))
+ (left (mapconcat
+ (lambda (element)
+ (if (stringp element)
+ (propertize element 'face nano-modeline-base-face)
+ (apply (car element) (cdr element))))
+ ',left))
+ (right (mapconcat
+ (lambda (element)
+ (if (stringp element)
+ (propertize element 'face nano-modeline-base-face)
+ (apply (car element) (cdr element))))
+ ',right))
+ (width (window-width))
+ (left-max-size (- width (length right) 2))
+ (left (if (> (length left) left-max-size)
+ (concat (truncate-string-to-width left left-max-size)
+ (propertize "…" 'face `(:inherit
,nano-modeline-base-face)))
+ left)))
+ (concat left
+ (propertize " "
+ 'face `(:inherit ,nano-modeline-base-face)
+ 'display `(space :align-to (- right ,(length right))))
+ right))))
+
+(defun nano-modeline-header (left &optional right)
+ "Install a header line made of LEFT and RIGHT parts."
+
+ (set-face-attribute 'mode-line nil :height 0.1 :box nil)
+ (set-face-attribute 'mode-line-inactive nil :height 0.1 :box nil)
+ (setq-default mode-line-format "")
+ (setq-local header-line-format (nano-modeline--make left right 'header))
+ (face-remap-set-base 'header-line 'nano-modeline--empty-face)
+ (add-hook 'post-command-hook #'nano-modeline--update-selected-window))
+
+(defun nano-modeline-footer (left &optional right)
+ "Install a footer line made of LEFT and RIGHT parts."
+
+ (setq-local mode-line-format (nano-modeline--make left right 'header))
+ (setq-default header-line-format nil)
+ (face-remap-set-base 'mode-line 'nano-modeline--empty-face)
+ (face-remap-set-base 'mode-line-inactive 'nano-modeline-empty-face)
+ (add-hook 'post-command-hook #'nano-modeline--update-selected-window))
+
+(defun nano-modeline-buffer-name (&optional name)
+ "Buffer name"
+
+ (propertize
+ (cond (name name)
+ ((buffer-narrowed-p) (format"%s [narrow]" (buffer-name)))
+ (t (buffer-name)))
+ 'face (nano-modeline--face 'bold)))
+
+(defun nano-modeline-buffer-status (&optional status padding)
+ "Generic prefix to indicate buffer STATUS with vertical PADDING (top .
bottom)"
+
+ (let* ((padding (or padding nano-modeline-padding))
+ (top (propertize " " 'display `(raise ,(car padding))))
+ (bot (propertize " " 'display `(raise ,(- (cdr padding))))))
+ (cond (buffer-read-only
+ (propertize (concat top (or status "RO") bot)
+ 'face (nano-modeline--face 'status-RO)))
+ ((buffer-modified-p)
+ (propertize (concat top (or status "**") bot)
+ 'face (nano-modeline--face 'status-**)))
+ (t
+ (propertize (concat top (or status "RW") bot)
+ 'face (nano-modeline--face 'status-RW))))))
+
+(defun nano-modeline-file-size ()
+ "File size in human readable format"
+
+ (if-let* ((file-name (buffer-file-name))
+ (file-attributes (file-attributes file-name))
+ (file-size (file-attribute-size file-attributes))
+ (file-size (file-size-human-readable file-size)))
+ (propertize (format "(%s)" file-size)
+ 'face (nano-modeline--face))
+ ""))
+
+(defun nano-modeline-cursor-position (&optional format)
+ "Cursor position using given FORMAT."
+
+ (let ((format (or format "%l:%c ")))
+ (propertize (format-mode-line format)
+ 'face (nano-modeline--face))))
+
+(defun nano-modeline-buffer-line-count ()
+ "Buffer total number of lines"
+
+ (save-excursion
+ (goto-char (point-max))
+ (propertize
+ (format-mode-line "(%l lines)")
+ 'face (nano-modeline--face))))
+
+(defun nano-modeline-window-dedicated ()
+ "Pin symbol when window is dedicated"
+
+ (propertize (if (window-dedicated-p) " " "")
+ 'face (nano-modeline--face)))
+
+(defun nano-modeline-git-info ()
+ "Git information as (branch, file status)"
+
(if vc-mode
- (let ((backend (vc-backend buffer-file-name)))
- (concat "#" (substring-no-properties vc-mode
- (+ (if (eq backend 'Hg) 2 3) 2)))) nil))
-
-(defun nano-modeline-mode-name ()
- "Return current major mode name"
- (format-mode-line mode-name))
-
-;; From https://amitp.blogspot.com/2011/08/emacs-custom-mode-line.html
-(defun nano-modeline-shorten-directory (dir max-length)
- "Show up to `max-length' characters of a directory name `dir'."
- (let ((path (reverse (split-string (abbreviate-file-name dir) "/")))
- (output ""))
+ (when-let* ((file (buffer-file-name))
+ (branch (substring-no-properties vc-mode 5))
+ (state (vc-state file)))
+ (propertize (format "(%s, %s)" branch state)
+ 'face (nano-modeline--face)))
+ (propertize "" 'face (nano-modeline--face))))
+
+(defun nano-modeline-mu4e-search-filter ()
+ "Mu4e current search"
+
+ (propertize (mu4e-last-query) 'face (nano-modeline--face 'bold)))
+
+(defun nano-modeline-mu4e-context ()
+ "Mu4e current context"
+
+ (let* ((context (mu4e-context-current))
+ (name (if context (mu4e-context-name context) "none")))
+ (propertize (format "[%s] " name)
+ 'face (nano-modeline--face))))
+
+(defun nano-modeline-mu4e-message-subject ()
+ "Mu4e message subject"
+
+ (let* ((msg (mu4e-message-at-point))
+ (subject (mu4e-message-field msg :subject)))
+ (propertize (format "%s" subject) 'face (nano-modeline--face 'bold))))
+
+(defun nano-modeline-mu4e-message-date ()
+ "Mu4e message date"
+
+ (let* ((msg (mu4e-message-at-point))
+ (date (mu4e-message-field msg :date)))
+ (propertize (format-time-string " %d/%m " date) 'face
(nano-modeline--face))))
+
+(defun nano-modeline-pdf-page ()
+ "PDF view mode page number / page total"
+
+ (let ((page-current (image-mode-window-get 'page))
+ (page-total (pdf-cache-number-of-pages)))
+ (propertize (format "%d/%d " page-current page-total)
+ 'face (nano-modeline--face))))
+
+(defun nano-modeline-elfeed-entry-status ()
+ "Elfeed entry status"
+
+ (let* ((feed (elfeed-entry-feed elfeed-show-entry))
+ (feed-title (plist-get (elfeed-feed-meta feed) :title)))
+ (nano-modeline-buffer-status feed-title)))
+
+(defun nano-modeline-elfeed-entry-title ()
+ "Elfeed entry title"
+
+ (let* ((title (elfeed-entry-title elfeed-show-entry)))
+ (propertize title 'face (nano-modeline--face 'bold))))
+
+(defun nano-modeline-elfeed-search-filter ()
+ "Elfeed search filter"
+
+ (propertize
+ (if (and (not (zerop (elfeed-db-last-update)))
+ (> (elfeed-queue-count-total) 0))
+ (let ((total (elfeed-queue-count-total))
+ (in-process (elfeed-queue-count-active)))
+ (format "%d jobs pending, %d active" (- total in-process)
in-process))
+ (cond (elfeed-search-filter-active "")
+ ((string-match-p "[^ ]" elfeed-search-filter) elfeed-search-filter)
+ (t "")))
+ 'face (nano-modeline--face 'bold)))
+
+(defun nano-modeline-elfeed-search-count ()
+ "Elfeed search statistics"
+
+ (propertize (cond ((zerop (elfeed-db-last-update)) "")
+ ((> (elfeed-queue-count-total) 0) "")
+ (t (concat (elfeed-search--count-unread) " ")))
+ 'face (nano-modeline--face)))
+
+(defun nano-modeline-date (&optional date format)
+ "Date using given FORMAT and DATE"
+
+ (propertize (format-time-string (or format "%A %-e %B %Y") date)
+ 'face (nano-modeline--face)))
+
+(defun nano-modeline-org-agenda-date (&optional format)
+ "Date at point in org agenda using given FORMAT"
+
+ (when-let* ((day (or (org-get-at-bol 'day)
+ (org-get-at-bol 'ts-date)))
+ (date (calendar-gregorian-from-absolute day))
+ (day (nth 1 date))
+ (month (nth 0 date))
+ (year (nth 2 date))
+ (date (encode-time 0 0 0 day month year)))
+ (propertize (format-time-string (or format "%A %-e %B %Y") date)
+ 'face (nano-modeline--face))))
+
+(defun nano-modeline-term-shell-name ()
+ "Term shell name"
+
+ (propertize shell-file-name
+ 'face (nano-modeline--face 'bold)))
+
+(defun nano-modeline-term-shell-mode ()
+ "Term shell mode"
+
+ (propertize (if (term-in-char-mode)
+ "(char mode)"
+ "(line mode)")
+ 'face (nano-modeline--face)))
+
+(defun nano-modeline-term-directory (&optional max-length)
+ "Term current directory"
+
+ (let* ((max-length (or max-length 32))
+ (dir default-directory)
+ (path (reverse (split-string (abbreviate-file-name dir) "/")))
+ (output ""))
(when (and path (equal "" (car path)))
(setq path (cdr path)))
- (while (and path (< (length output) (- max-length 4)))
+ (while (and path (< (length output) (- max-length 0)))
(setq output (concat (car path) "/" output))
(setq path (cdr path)))
(when path
(setq output (concat "…/" output)))
- output))
-
-
-(defun nano-modeline-status ()
- "Return buffer status, one of 'read-only, 'modified or 'read-write."
-
- (with-current-buffer (or (buffer-base-buffer) (current-buffer))
- (let ((read-only buffer-read-only)
- (modified (and buffer-file-name (buffer-modified-p))))
- (cond (modified 'modified)
- (read-only 'read-only)
- (t 'read-write)))))
-
-(defun nano-modeline-tab-number ()
- "Return the number of the current tab as a string if there are more than 1
tab open.
-Return \"0\" if there is only on tab open.
-When return value is \"0\", then the section is hidden"
- (number-to-string
- (if (length> (frame-parameter nil 'tabs) 1)
- (let* ((current-tab (tab-bar--current-tab))
- (tab-index (tab-bar--current-tab-index))
- (explicit-name (alist-get 'explicit-name current-tab))
- (tab-name (alist-get 'name current-tab)))
- (if explicit-name tab-name (+ 1 tab-index)))
- (string-to-number "0"))))
-
-(defun nano-modeline-render (icon name primary secondary &optional status)
- "Compose a string with provided information"
-
- (let* ((window (get-buffer-window (current-buffer)))
- (name-max-width (- (window-body-width) 1
- (length primary) 5
- (length secondary) 1))
- (name (if (and (stringp name) (> (length name) name-max-width))
- (format "%s…" (substring name 0 (- name-max-width 1)))
- name))
- (status (or status (nano-modeline-status)))
- (active (eq window nano-modeline--selected-window))
-
- (prefix (cond ((eq nano-modeline-prefix 'none) nil)
- ((eq nano-modeline-prefix 'icon) icon)
- (t (cond ((eq status 'read-only) "RO")
- ((eq status 'read-write) "RW")
- ((eq status 'modified) "**")
- (t "--")))))
-
- (face-modeline (if active
- 'nano-modeline-active
- 'nano-modeline-inactive))
- (face-prefix (if (not prefix) face-modeline
- (if active
- (cond ((eq status 'read-only)
'nano-modeline-active-status-RO)
- ((eq status 'read-write)
'nano-modeline-active-status-RW)
- ((eq status 'modified)
'nano-modeline-active-status-**)
- (t
'nano-modeline-active))
- (cond ((eq status 'read-only)
'nano-modeline-inactive-status-RO)
- ((eq status 'read-write)
'nano-modeline-inactive-status-RW)
- ((eq status 'modified)
'nano-modeline-inactive-status-**)
- (t
'nano-modeline-inactive)))))
- (face-name (if active
- 'nano-modeline-active-name
- 'nano-modeline-inactive-name))
- (face-primary (if active
- 'nano-modeline-active-primary
- 'nano-modeline-inactive-primary))
- (face-secondary (if active
- 'nano-modeline-active-secondary
- 'nano-modeline-inactive-secondary))
-
- (left (concat
- (propertize " " 'face `(:inherit ,face-prefix)
- 'display `(raise ,nano-modeline-space-top))
- (if prefix
- (concat
- (propertize prefix 'face face-prefix)
- (propertize " " 'face face-prefix)
- ;; When do we add space on the left?
- (if nano-modeline-prefix-padding
- (propertize " " 'face face-modeline))))
- (propertize name 'face face-name)
- (if (length name)
- (propertize " " 'face face-modeline))
- (propertize primary 'face face-primary)))
- (right (concat
- (propertize secondary 'face face-secondary)
- (if (and (not (eq nano-modeline-prefix 'status))
- (eq status 'modified))
- (propertize " [M]" 'face face-name)
- (if (window-dedicated-p)
- (propertize " •" 'face face-secondary)))
- (propertize " " 'face `(:inherit ,face-modeline)
- 'display `(raise
,nano-modeline-space-bottom))
- (if nano-modeline-display-tab-number
- (if (not (equal "0" (nano-modeline-tab-number)))
- (propertize (format " -%s- "
(nano-modeline-tab-number)) 'face face-secondary)))))
- (right-len (length (format-mode-line right))))
- (concat
- left
- (propertize " " 'face face-secondary
- 'display `(space :align-to (- right
- (-1 . right-margin)
- ,(- right-len 0))))
- right)))
-
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-ein-notebook-mode ()
- (let ((buffer-name (format-mode-line "%b")))
- (nano-modeline-render nil
- buffer-name
- ""
- (ein:header-line)
- (if (ein:notebook-modified-p)
- 'modified
- 'read-write))))
-
-;; since the EIN library itself is constantly re-rendering the notebook, and
thus
-;; re-setting the header-line-format, we cannot use the nano-modeline function
to set
-;; the header format in a notebook buffer. Fortunately, EIN exposes the
-;; ein:header-line-format variable for just this purpose.
-
-(defun nano-modeline-ein-notebook-activate ()
- (with-eval-after-load 'ein
- (if (eq nano-modeline-position 'top)
- (setq ein:header-line-format '((:eval
(nano-modeline-ein-notebook-mode)))))))
-
-(defun nano-modeline-ein-notebook-inactivate ()
- (if (boundp 'ein:header-line-format)
- (setq ein:header-line-format '(:eval (ein:header-line)))))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-elfeed-search-mode-p ()
- (derived-mode-p 'elfeed-search-mode))
-
-(defun nano-modeline-elfeed-search-mode ()
- (let* ((icon (plist-get (cdr (assoc 'elfeed-search-mode
nano-modeline-mode-formats)) :icon))
- (no-database (zerop (elfeed-db-last-update)))
- (update (> (elfeed-queue-count-total) 0))
- (name (cond (no-database "No database")
- (update "Update:")
- (t "Search:")))
- (primary (cond (no-database "")
- (update
- (let ((total (elfeed-queue-count-total))
- (in-process (elfeed-queue-count-active)))
- (format "%d jobs pending, %d active"
- (- total in-process) in-process)))
- (t (let* ((db-time (seconds-to-time
(elfeed-db-last-update)))
- (unread ))
- (cond (elfeed-search-filter-active "")
- ((string-match-p "[^ ]"
elfeed-search-filter)
- elfeed-search-filter)
- (""))))))
- (secondary (cond
- ((zerop (elfeed-db-last-update)) "")
- ((> (elfeed-queue-count-total) 0) "")
- (t (elfeed-search--count-unread)))))
- (nano-modeline-render icon name primary secondary)))
-
-;; Elfeed uses header-line, we need to tell it to use our own format
-(defun nano-modeline-elfeed-setup-header ()
- (setq header-line-format (default-value 'header-line-format)))
-
-(defun nano-modeline-elfeed-search-activate ()
- (with-eval-after-load 'elfeed
- (if (eq nano-modeline-position 'top)
- (setq elfeed-search-header-function
#'nano-modeline-elfeed-setup-header))))
-
-(defun nano-modeline-elfeed-search-inactivate ()
- (if (boundp 'elfeed-search-header-function)
- (setq elfeed-search-header-function #'elfeed-search--header)))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-elfeed-show-mode-p ()
- (derived-mode-p 'elfeed-show-mode))
-
-(defun nano-modeline-elfeed-show-mode ()
- (let* ((icon (plist-get (cdr (assoc 'elfeed-show-mode
nano-modeline-mode-formats)) :icon))
- (title (elfeed-entry-title elfeed-show-entry))
- (tags (elfeed-entry-tags elfeed-show-entry))
- (tags-str (mapconcat #'symbol-name tags ", "))
- (date (seconds-to-time (elfeed-entry-date elfeed-show-entry)))
- (feed (elfeed-entry-feed elfeed-show-entry))
- (feed-title (plist-get (elfeed-feed-meta feed) :title))
- (entry-author (elfeed-meta elfeed-show-entry :author)))
- (nano-modeline-render icon
- title
- ;;(nano-modeline-truncate title 40)
- (concat "(" tags-str ") ")
- feed-title)))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-calendar-mode-p ()
- (derived-mode-p 'calendar-mode))
-
-(defun nano-modeline-calendar-mode () "")
-
-;; Calendar (no header, only overline)
-(defun nano-modeline-calendar-setup-header ()
- (setq header-line-format "")
- (face-remap-add-relative
- 'header-line `(:overline ,(face-foreground 'default)
- :height 0.5
- :background ,(face-background 'default))))
-
-;; From https://emacs.stackexchange.com/questions/45650
-;; (add-to-list 'display-buffer-alist
-;; `(,(rx string-start "*Calendar*" string-end)
-;; (display-buffer-below-selected)))
-
-(defun nano-modeline-calendar-activate ()
- (with-eval-after-load 'calendar
- (add-hook 'calendar-initial-window-hook
- #'nano-modeline-calendar-setup-header)))
-
-(defun nano-modeline-calendar-inactivate ()
- (remove-hook 'calendar-initial-window-hook
- #'nano-modeline-calendar-setup-header))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-org-capture-mode-p ()
- (bound-and-true-p org-capture-mode))
-
-(defun nano-modeline-org-capture-mode ()
- (nano-modeline-render (plist-get (cdr (assoc 'org-capture-mode
nano-modeline-mode-formats)) :icon)
- "Capture"
- (concat "(" (org-capture-get :description) ")")
- "Finish: C-c C-c, refile: C-c C-w, cancel: C-c C-k "))
-
-(defun nano-modeline-org-capture-turn-off-header-line ()
- (setq-local header-line-format (default-value 'header-line-format))
- (message nil))
-
-(defun nano-modeline-org-capture-activate ()
- (with-eval-after-load 'org-capture
- (add-hook 'org-capture-mode-hook
- #'nano-modeline-org-capture-turn-off-header-line)))
-
-(defun nano-modeline-org-capture-inactivate ()
- (remove-hook 'org-capture-mode-hook
- #'nano-modeline-org-capture-turn-off-header-line))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-info-breadcrumbs ()
- (let ((nodes (Info-toc-nodes Info-current-file))
- (cnode Info-current-node)
- (node Info-current-node)
- (crumbs ())
- (depth Info-breadcrumbs-depth)
- line)
- (save-excursion
- (while (> depth 0)
- (setq node (nth 1 (assoc node nodes)))
- (if node (push node crumbs))
- (setq depth (1- depth)))
- (setq crumbs (cons "Top" (if (member (pop crumbs) '(nil "Top"))
- crumbs (cons nil crumbs))))
- (forward-line 1)
- (dolist (node crumbs)
- (let ((text
- (if (not (equal node "Top")) node
- (format "%s"
- (if (stringp Info-current-file)
- (file-name-sans-extension
- (file-name-nondirectory Info-current-file))
- Info-current-file)))))
- (setq line (concat line (if (null line) "" " > ")
- (if (null node) "..." text)))))
- (if (and cnode (not (equal cnode "Top")))
- (setq line (concat line (if (null line) "" " > ") cnode)))
- line)))
-
-(defun nano-modeline-info-mode-p ()
- (derived-mode-p 'Info-mode))
-
-(defun nano-modeline-info-mode ()
- (nano-modeline-render (plist-get (cdr (assoc 'info-mode
nano-modeline-mode-formats)) :icon)
- (nano-modeline-info-breadcrumbs)
- ""
- ""))
-
-(defun nano-modeline-info-activate ()
- (if (eq nano-modeline-position 'top)
- (setq Info-use-header-line nil)))
-
-(defun nano-modeline-info-inactivate ()
- (custom-reevaluate-setting 'Info-use-header-line))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-enlarge-ispell-choices-buffer (buffer)
- (when (string= (buffer-name buffer) "*Choices*")
- (with-current-buffer buffer
- ;; (enlarge-window +2)
- (setq-local header-line-format nil)
- (setq-local mode-line-format nil))))
-
-(defun nano-modeline-ispell-activate ()
- (with-eval-after-load 'ispell
- (advice-add #'ispell-display-buffer :after
- #'nano-modeline-enlarge-ispell-choices-buffer)))
-
-(defun nano-modeline-ispell-inactivate ()
- (advice-remove #'ispell-display-buffer
- #'nano-modeline-enlarge-ispell-choices-buffer))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-org-agenda-mode-p ()
- (derived-mode-p 'org-agenda-mode))
-
-(defun nano-modeline-org-agenda-mode ()
- (nano-modeline-render (plist-get (cdr (assoc 'org-agenda-mode
nano-modeline-mode-formats)) :icon)
- "Agenda"
- ""
-;; (format "%s" org-agenda-span-name)
- (format-time-string "%A %-e %B %Y")))
-
-;; ---------------------------------------------------------------------
-
-(defun nano-modeline-term-mode-p ()
- (derived-mode-p 'term-mode))
-
-(defun nano-modeline-vterm-mode-p ()
- (derived-mode-p 'vterm-mode))
-
-(defun nano-modeline-term-mode ()
- (nano-modeline-render (plist-get (cdr (assoc 'term-mode
nano-modeline-mode-formats)) :icon)
- shell-file-name
- (if (term-in-char-mode)
- "(char mode)"
- "(line mode)")
- (nano-modeline-shorten-directory default-directory
32)))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-mu4e-last-query ()
- "Get the most recent mu4e query or nil if there is none."
- (if (fboundp 'mu4e-last-query)
- (mu4e-last-query)
- mu4e~headers-last-query))
-
-(defun nano-modeline-mu4e-context ()
- "Return the current mu4e context as a non propertized string."
-
- (if (> (length (mu4e-context-label)) 0)
- (concat "(" (substring-no-properties (mu4e-context-label) 1 -1) ")")
- "(none)"))
-
-(defun nano-modeline-mu4e-server-props ()
- "Encapsulates the call to the variable mu4e-/~server-props
-depending on the version of mu4e."
- (if (version< mu4e-mu-version "1.6.0")
- mu4e~server-props
- mu4e--server-props))
-
-(defun nano-modeline-mu4e-activate ()
- (with-eval-after-load 'mu4e
- (advice-add 'mu4e~header-line-format :override #'nano-modeline)))
-
-(defun nano-modeline-mu4e-inactivate ()
- (advice-remove #'mu4e~header-line-format #'nano-modeline))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-mu4e-dashboard-mode-p ()
- (bound-and-true-p mu4e-dashboard-mode))
-
-(defun nano-modeline-mu4e-dashboard-mode ()
- (nano-modeline-render (plist-get (cdr (assoc 'mu4e-dashboard-mode
nano-modeline-mode-formats)) :icon)
- (format "%d messages"
- (plist-get (nano-modeline-mu4e-server-props)
:doccount))
- ""
- ""))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-mu4e-loading-mode-p ()
- (derived-mode-p 'mu4e-loading-mode))
-
-(defun nano-modeline-mu4e-loading-mode ()
- (nano-modeline-render (plist-get (cdr (assoc 'mu4e-loading-mode
nano-modeline-mode-formats)) :icon)
- "Loading…"
- (nano-modeline-mu4e-context)
- (format-time-string "%A %d %B %Y, %H:%M")))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-mu4e-main-mode-p ()
- (derived-mode-p 'mu4e-main-mode))
-
-(defun nano-modeline-mu4e-main-mode ()
- (nano-modeline-render (plist-get (cdr (assoc 'mu4e-main-mode
nano-modeline-mode-formats)) :icon)
- (nano-modeline-mu4e-context)
- ""
- (format-time-string "%A %d %B %Y, %H:%M")))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-mu4e-compose-mode-p ()
- (derived-mode-p 'mu4e-compose-mode))
-
-(defun nano-modeline-mu4e-compose-mode ()
- (nano-modeline-render (plist-get (cdr (assoc 'mu4e-compose-mode
nano-modeline-mode-formats)) :icon)
- (format-mode-line "%b")
- ""
- (format "[%s]"
- (nano-modeline-mu4e-quote
- (mu4e-context-name (mu4e-context-current))))))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-mu4e-quote (str)
- (if (version< mu4e-mu-version "1.8.0")
- (mu4e~quote-for-modeline str)
- (mu4e-quote-for-modeline str)))
-
-(defun nano-modeline-mu4e-headers-mode-p ()
- (derived-mode-p 'mu4e-headers-mode))
-
-(defun nano-modeline-mu4e-headers-mode ()
- (let ((mu4e-modeline-max-width 120))
- (nano-modeline-render (plist-get (cdr (assoc 'mu4e-headers-mode
nano-modeline-mode-formats)) :icon)
- "Search:"
- (or (nano-modeline-mu4e-quote
- (nano-modeline-mu4e-last-query)) "")
- (format "[%s]"
- (nano-modeline-mu4e-quote
- (mu4e-context-name
(mu4e-context-current)))))))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-mu4e-view-mode-p ()
- (derived-mode-p 'mu4e-view-mode))
-
-(defun nano-modeline-mu4e-view-mode ()
- (let* ((msg (mu4e-message-at-point))
- (subject (mu4e-message-field msg :subject))
- (from (mu4e~headers-contact-str (mu4e-message-field msg :from)))
- (date (mu4e-message-field msg :date)))
- (nano-modeline-render (plist-get (cdr (assoc 'mu4e-view-mode
nano-modeline-mode-formats)) :icon)
- (or subject "")
- ""
- (or from "")
- 'read-only)))
-
-(defun nano-modeline-mu4e-view-hook ()
- (setq header-line-format "%-")
- (face-remap-add-relative 'header-line
- '(:background "#ffffff"
- :underline nil
- :box nil
- :height 1.0)))
-;; (add-hook 'mu4e-view-mode-hook #'nano-modeline-mu4e-view-hook)
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-nano-help-mode-p ()
- (derived-mode-p 'nano-help-mode))
-
-(defun nano-modeline-nano-help-mode ()
- (nano-modeline-render (plist-get (cdr (assoc 'nano-help-mode
nano-modeline-mode-formats)) :icon)
- "Emacs / N Λ N O"
- "(help)"
- ""))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-messages-mode-p ()
- (derived-mode-p 'messages-buffer-mode))
-
-(defun nano-modeline-messages-mode ()
- (nano-modeline-render (plist-get (cdr (assoc 'messages-mode
nano-modeline-mode-formats)) :icon)
- "Messages" "" ""))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-org-clock-mode-p ()
- (and (boundp 'org-mode-line-string)
- (stringp org-mode-line-string)
- (> (length org-mode-line-string) 0)))
-
-(defun nano-modeline-org-clock-mode ()
- (let ((buffer-name (format-mode-line "%b"))
- (mode-name (nano-modeline-mode-name))
- (branch (nano-modeline-vc-branch))
- (position (format-mode-line "%l:%c")))
- (nano-modeline-render (plist-get (cdr (assoc 'org-clock-mode
nano-modeline-mode-formats)) :icon)
- buffer-name
- (concat "(" mode-name
- (if branch (concat ", " branch))
- ")" )
- org-mode-line-string)))
-
-(defun nano-modeline-org-clock-out ()
- (setq org-mode-line-string nil)
- (force-mode-line-update))
-
-(defun nano-modeline-org-clock-activate ()
- (with-eval-after-load 'org-clock
- (add-hook 'org-clock-out-hook #'nano-modeline-org-clock-out)))
-
-(defun nano-modeline-org-clock-inactivate ()
- (remove-hook 'org-clock-out-hook
- #'nano-modeline-org-clock-out))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-esh-activate ()
- (with-eval-after-load 'esh-mode
- (setq eshell-status-in-mode-line nil)))
-
-(defun nano-modeline-esh-inactivate ()
- (custom-reevaluate-setting 'eshell-status-in-mode-line))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-doc-view-mode-p ()
- (derived-mode-p 'doc-view-mode))
-
-(defun nano-modeline-doc-view-mode ()
- (let ((buffer-name (format-mode-line "%b"))
- (mode-name (nano-modeline-mode-name))
- (branch (nano-modeline-vc-branch))
- (page-number (concat
- (number-to-string (image-mode-window-get 'page)) "/"
- (or (ignore-errors
- (number-to-string (doc-view-last-page-number)))
- "???"))))
- (nano-modeline-render (plist-get (cdr (assoc 'doc-view-mode
nano-modeline-mode-formats)) :icon)
- buffer-name
- (if branch (concat "(" branch ")") "")
- page-number)))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-pdf-view-mode-p ()
- (derived-mode-p 'pdf-view-mode))
-
-(defun nano-modeline-pdf-view-mode ()
- (let ((buffer-name (format-mode-line "%b"))
- (mode-name (nano-modeline-mode-name))
- (branch (nano-modeline-vc-branch))
- (page-number (concat
- (number-to-string (image-mode-window-get 'page)) "/"
- (or (ignore-errors
- (number-to-string (pdf-cache-number-of-pages)))
- "???"))))
- (nano-modeline-render (plist-get (cdr (assoc 'pdf-view-mode
nano-modeline-mode-formats)) :icon)
- buffer-name
- (if branch (concat "(" branch ")") "")
- page-number)))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-buffer-menu-mode-p ()
- (derived-mode-p 'buffer-menu-mode))
-
-(defun nano-modeline-buffer-menu-mode ()
- (let ((buffer-name "Buffer list")
- (mode-name (nano-modeline-mode-name))
- (position (format-mode-line "%l:%c")))
-
- (nano-modeline-render (plist-get (cdr (assoc 'buffer-menu-mode
nano-modeline-mode-formats)) :icon)
- buffer-name "" position)))
-;;(defun buffer-menu-mode-header-line ()
-;; (face-remap-add-relative
-;; 'header-line `(:background ,(face-background 'nano-subtle))))
-;;(add-hook 'Buffer-menu-mode-hook
-;; #'buffer-menu-mode-header-line)
-
-(defun nano-modeline-buffer-menu-activate ()
- (if (eq nano-modeline-position 'top)
- (setq Buffer-menu-use-header-line nil)))
-
-(defun nano-modeline-buffer-menu-inactivate ()
- (custom-reevaluate-setting 'Buffer-menu-use-header-line))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-elpher-mode-p ()
- (derived-mode-p 'elpher-mode))
-
-(defun nano-modeline-elpher-mode ()
- (let* ((display-string (elpher-page-display-string elpher-current-page))
- (sanitized-display-string (replace-regexp-in-string "%" "%%"
display-string))
- (address (elpher-page-address elpher-current-page))
- (tls-string (if (and (not (elpher-address-about-p address))
- (member (elpher-address-protocol address)
- '("gophers" "gemini")))
- "(TLS encryption)"
- "")))
- (nano-modeline-render (plist-get (cdr (assoc 'elpher-mode
nano-modeline-mode-formats)) :icon)
- sanitized-display-string
- tls-string
- "")))
-
-(defun nano-modeline-elpher-activate ()
- (with-eval-after-load 'elpher
- (setq elpher-use-header nil)))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-completion-list-mode-p ()
- (derived-mode-p 'completion-list-mode))
-
-(defun nano-modeline-completion-list-mode ()
- (let ((buffer-name (format-mode-line "%b"))
- (mode-name (nano-modeline-mode-name))
- (position (format-mode-line "%l:%c")))
-
- (nano-modeline-render (plist-get (cdr (assoc 'completion-list-mode
nano-modeline-mode-formats)) :icon)
- buffer-name
- ""
- position)))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-imenu-list-mode-p ()
- (derived-mode-p 'imenu-list-major-mode))
-
-(defun nano-modeline-imenu-list-mode (&optional icon)
- (let ((icon (or icon
- (plist-get (cdr (assoc 'imenu-list-mode
nano-modeline-mode-formats)) :icon)))
- ;; We take into account the case of narrowed buffers
- (buffer-name (buffer-name imenu-list--displayed-buffer))
- (branch (nano-modeline-vc-branch))
- (position (format-mode-line "%l:%c")))
- (nano-modeline-render icon
- buffer-name
- "(imenu list)"
- "")))
-
-;; ---------------------------------------------------------------------
-(with-eval-after-load 'deft
- (defun nano-modeline-deft-print-header ()
- (force-mode-line-update)
- (widget-insert "\n")))
-
-(defun nano-modeline-deft-mode-p ()
- (derived-mode-p 'deft-mode))
-
-(defun nano-modeline-deft-mode ()
- (let ((icon (plist-get (cdr (assoc 'deft-mode nano-modeline-mode-formats))
:icon))
- (primary "Notes")
- (filter (concat (if deft-filter-regexp
- (deft-whole-filter-regexp)) "_"))
- (matches (if deft-filter-regexp
- (format "%d matches" (length deft-current-files))
- (format "%d notes" (length deft-all-files)))))
- (nano-modeline-render icon "Search:" filter matches 'read-only)))
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-prog-mode-p ()
- (derived-mode-p 'prog-mode))
+ (propertize output 'face (nano-modeline--face))))
+
+(defun nano-modeline-xwidget-uri ()
+ "xwidget URI"
+
+ (propertize (xwidget-webkit-uri (xwidget-at (point-min)))
+ 'face (nano-modeline--face 'bold)))
+
+(defun nano-modeline-org-buffer-name (&optional name)
+ "Org buffer name"
+
+ (propertize
+ (cond (name
+ name)
+ ((buffer-narrowed-p)
+ (format"%s [%s]" (or (buffer-base-buffer) (buffer-name))
+ (org-link-display-format
+ (substring-no-properties
+ (or (org-get-heading 'no-tags) "-")))))
+ (t
+ (buffer-name)))
+ 'face (nano-modeline--face 'bold)))
+
+(defun nano-modeline-org-capture-description ()
+ "Org capture descrioption"
+
+ (propertize (format "(%s)"
+ (substring-no-properties (org-capture-get :description)))
+ 'face (nano-modeline--face)))
(defun nano-modeline-prog-mode ()
- (nano-modeline-default-mode
- (plist-get (cdr (assoc 'prog-mode nano-modeline-mode-formats)) :icon)))
-
-(defun nano-modeline-text-mode-p ()
- (derived-mode-p 'text-mode))
+ "Nano line for prog mode"
+
+ (funcall nano-modeline-position
+ '((nano-modeline-buffer-status) " "
+ (nano-modeline-buffer-name) " "
+ (nano-modeline-git-info))
+ '((nano-modeline-cursor-position)
+ (nano-modeline-window-dedicated))))
(defun nano-modeline-text-mode ()
- (nano-modeline-default-mode
- (plist-get (cdr (assoc 'text-mode nano-modeline-mode-formats)) :icon)))
-
-(defun nano-modeline-default-mode (&optional icon)
- (let ((icon (or icon
- (plist-get (cdr (assoc 'text-mode
nano-modeline-mode-formats)) :icon)))
- ;; We take into account the case of narrowed buffers
- (buffer-name (cond
- ((and (derived-mode-p 'org-mode)
- (buffer-narrowed-p)
- (buffer-base-buffer))
- (format"%s [%s]" (buffer-base-buffer)
- (org-link-display-format
- (substring-no-properties (or (org-get-heading
'no-tags)
- "-")))))
- ((and (buffer-narrowed-p)
- (buffer-base-buffer))
- (format"%s [narrow]" (buffer-base-buffer)))
- (t
- (format-mode-line "%b"))))
-
- (mode-name (nano-modeline-mode-name))
- (branch (nano-modeline-vc-branch))
- (position (format-mode-line
- (cond ((and (bound-and-true-p column-number-mode)
- (bound-and-true-p line-number-mode)) "%l:%c")
- ((bound-and-true-p column-number-mode) "%c")
- ((bound-and-true-p line-number-mode) "%l")
- (t "")))))
-
- (nano-modeline-render icon
- buffer-name
- (if branch (concat "(" branch ")") "")
- position)))
-
-
-;; ---------------------------------------------------------------------
-(defun nano-modeline-face-clear (face)
- "Clear FACE"
- (set-face-attribute face nil
- :foreground 'unspecified :background 'unspecified
- :family 'unspecified :slant 'unspecified
- :weight 'unspecified :height 'unspecified
- :underline 'unspecified :overline 'unspecified
- :box 'unspecified :inherit 'unspecified))
-
-;; ---------------------------------------------------------------------
-(defvar nano-modeline--saved-mode-line-format nil)
-(defvar nano-modeline--saved-header-line-format nil)
-(defvar nano-modeline--selected-window nil)
-
-(defun nano-modeline--update-selected-window ()
- "Update selected window (before mode-line is active)"
- (setq nano-modeline--selected-window (selected-window)))
-
-(defun nano-modeline ()
- "Build and set the modeline."
- (let* ((format
- '((:eval
- (funcall
- (or (catch 'found
- (dolist (elt nano-modeline-mode-formats)
- (let* ((config (cdr elt))
- (mode-p (plist-get config :mode-p))
- (format (plist-get config :format)))
- (when mode-p
- (when (funcall mode-p)
- (throw 'found format))))))
- nano-modeline-default-mode-format))))))
- (if (eq nano-modeline-position 'top)
- (progn
- (setq header-line-format format)
- (setq-default header-line-format format))
- (progn
- (setq mode-line-format format)
- (setq-default mode-line-format format)))))
-
-
-(defun nano-modeline-update-windows ()
- "Hide the mode line depending on the presence of a window
-below or a buffer local variable 'no-mode-line'."
- (dolist (window (window-list))
- (with-selected-window window
- (with-current-buffer (window-buffer window)
- (if (or (not (boundp 'no-mode-line)) (not no-mode-line))
- (setq mode-line-format
- (cond ((one-window-p t) (list ""))
- ((eq (window-in-direction 'below) (minibuffer-window))
(list ""))
- ((not (window-in-direction 'below)) (list ""))
- (t nil))))))))
-
-(defun nano-modeline-mode--activate ()
- "Activate nano modeline"
-
- ;; Save current mode-line and header-line
- (unless nano-modeline--saved-mode-line-format
- (setq nano-modeline--saved-mode-line-format mode-line-format)
- (setq nano-modeline--saved-header-line-format header-line-format))
-
- (dolist (elt nano-modeline-mode-formats)
- (let* ((config (cdr elt))
- (fn (plist-get config :on-activate)))
- (when fn (funcall fn))))
-
- (run-hooks 'nano-modeline-mode-format-activate-hook)
-
- ;; Should we do this only when modeline is at top ?
- (define-key mode-line-major-mode-keymap [header-line]
- (lookup-key mode-line-major-mode-keymap [mode-line]))
-
- ;; Update selected window
- (nano-modeline--update-selected-window)
- ;; (setq nano-modeline--selected-window (selected-window))
-
- (setq mode-line-format nil)
- (setq-default mode-line-format nil)
- (setq header-line-format nil)
- (setq-default header-line-format nil)
-
- (nano-modeline)
-
- ;; This hooks is necessary to register selected window because when
- ;; a modeline is evaluated, the corresponding window is always selected.
- (add-hook 'post-command-hook #'nano-modeline--update-selected-window)
-
- ;; This hooks hide the modeline for windows having a window below them
- ;; Disabled for the time being,
- ;; -> see https://github.com/rougier/nano-modeline/issues/24
- ;; (add-hook 'window-configuration-change-hook
#'nano-modeline-update-windows)
-
- (force-mode-line-update t)
-
- ;; `eldoc-minibuffer-message' changes `mode-line-format' but
- ;; nano-modeline when `nano-modeline-position' is `top' only displays
- ;; the header-line.
- ;; -> see https://github.com/rougier/nano-modeline/issues/36
- (when (eq nano-modeline-position 'top)
- (setq eldoc-message-function #'message)))
-
-(defun nano-modeline-mode--inactivate ()
- "Inactivate nano mode line and restored default mode-line"
+ "Nano line for text mode"
+
+ (funcall nano-modeline-position
+ '((nano-modeline-buffer-status) " "
+ (nano-modeline-buffer-name) " "
+ (nano-modeline-git-info))
+ '((nano-modeline-cursor-position)
+ (nano-modeline-window-dedicated))))
+
+(defun nano-modeline-org-mode ()
+ "Nano line for org mode"
+
+ (funcall nano-modeline-position
+ '((nano-modeline-buffer-status) " "
+ (nano-modeline-buffer-name) " "
+ (nano-modeline-git-info))
+ '((nano-modeline-cursor-position)
+ (nano-modeline-window-dedicated))))
+
+(defun nano-modeline-pdf-mode ()
+ "Nano line for text mode"
+
+ (funcall nano-modeline-position
+ '((nano-modeline-buffer-status "PDF") " "
+ (nano-modeline-buffer-name) " "
+ (nano-modeline-file-size))
+ '((nano-modeline-pdf-page)
+ (nano-modeline-window-dedicated))))
- (dolist (elt nano-modeline-mode-formats)
- (let* ((config (cdr elt))
- (fn (plist-get config :on-inactivate)))
- (when fn (funcall fn))))
-
- (run-hooks 'nano-modeline-mode-format-inactivate-hook)
-
- (remove-hook 'post-command-hook
- #'nano-modeline--update-selected-window)
- (remove-hook 'window-configuration-change-hook
- #'nano-modeline-update-windows)
+(defun nano-modeline-mu4e-headers-mode ()
+ "Nano line for mu4e headers mode"
+
+ (funcall nano-modeline-position
+ '((nano-modeline-buffer-status "MAIL") " "
+ (nano-modeline-mu4e-search-filter))
+ '((nano-modeline-mu4e-context)
+ (nano-modeline-window-dedicated))))
+
+(defun nano-modeline-mu4e-message-mode ()
+ "Nano line for mu4e message mode"
+
+ (funcall nano-modeline-position
+ '((nano-modeline-buffer-status "MAIL") " "
+ (nano-modeline-mu4e-message-subject))
+ '((nano-modeline-mu4e-message-date)
+ (nano-modeline-window-dedicated))))
+
+(defun nano-modeline-elfeed-entry-mode ()
+ "Nano line for elfeed entry mode"
+
+ (funcall nano-modeline-position
+ '((nano-modeline-elfeed-entry-status) " "
+ (nano-modeline-elfeed-entry-title))))
- (setq mode-line-format nano-modeline--saved-mode-line-format)
- (setq-default mode-line-format nano-modeline--saved-mode-line-format)
- (setq header-line-format nano-modeline--saved-header-line-format)
- (setq-default header-line-format nano-modeline--saved-header-line-format))
+(defun nano-modeline-elfeed-search-mode ()
+ "Nano line for elfeed search mode"
+
+ (add-hook 'elfeed-search-update-hook #'force-mode-line-update)
+ (funcall nano-modeline-position
+ '((nano-modeline-buffer-status "NEWS") " "
+ (nano-modeline-elfeed-search-filter))
+ '((nano-modeline-elfeed-search-count)
+ (nano-modeline-window-dedicated))))
-;;;###autoload
-(define-minor-mode nano-modeline-mode
- "Toggle nano-modeline minor mode"
- :group 'nano-modeline
- :global t
- :init-value nil
+(defun nano-modeline-term-mode ()
+ "Nano line for term mode"
+
+ (funcall nano-modeline-position
+ '((nano-modeline-buffer-status ">_") " "
+ (nano-modeline-term-shell-name) " "
+ (nano-modeline-term-shell-mode))
+ '((nano-modeline-term-directory) " "
+ (nano-modeline-window-dedicated))))
+
+(defun nano-modeline-xwidget-mode ()
+ "Nano line for xwidget mode"
+
+ (funcall nano-modeline-position
+ '((nano-modeline-buffer-status "URL") " "
+ (nano-modeline-xwidget-uri))
+ '((nano-modeline-window-dedicated))))
+
+(defun nano-modeline-message-mode ()
+ "Nano line for messages mode"
+
+ (funcall nano-modeline-position
+ '((nano-modeline-buffer-status "LOG") " "
+ (nano-modeline-buffer-name) " "
+ (nano-modeline-buffer-line-count))
+ '((nano-modeline-window-dedicated))))
- (if nano-modeline-mode
- (nano-modeline-mode--activate)
- (nano-modeline-mode--inactivate))
+(defun nano-modeline-org-capture-mode ()
+ "Nano line for org capture mode"
+
+ (funcall nano-modeline-position
+ '((nano-modeline-buffer-status "ORG") " "
+ (nano-modeline-buffer-name "Capture") " "
+ (nano-modeline-org-capture-description))
+ '("Finish: C-c C-c, refile: C-c C-w, cancel: C-c C-k "
+ (nano-modeline-window-dedicated))))
- ;; Run any registered hooks
- (run-hooks 'nano-modeline-mode-hook))
+(defun nano-modeline-org-agenda-mode ()
+ "Nano line for org capture mode"
+ (add-hook 'post-command-hook #'force-mode-line-update)
+ (funcall nano-modeline-position
+ '((nano-modeline-buffer-status "ORG") " "
+ (nano-modeline-buffer-name "Agenda"))
+ '((nano-modeline-org-agenda-date) " "
+ (nano-modeline-window-dedicated))))
(provide 'nano-modeline)
;;; nano-modeline.el ends here
+
+
+;; (add-hook 'prog-mode-hook #'nano-modeline-prog-mode)
+;; (add-hook 'text-mode-hook #'nano-modeline-text-mode)
+;; (add-hook 'org-mode-hook #'nano-modeline-org-mode)
+;; (add-hook 'pdf-view-mode-hook #'nano-modeline-pdf-mode)
+;; (add-hook 'mu4e-headers-mode-hook #'nano-modeline-mu4e-headers-mode)
+;; (add-hook 'mu4e-view-mode-hook #'nano-modeline-mu4e-message-mode)
+;; (add-hook 'elfeed-show-mode-hook #'nano-modeline-elfeed-entry-mode)
+;; (add-hook 'elfeed-search-mode-hook #'nano-modeline-elfeed-search-mode)
+;; (add-hook 'term-mode-hook #'nano-modeline-term-mode)
+;; (add-hook 'xwidget-webkit-mode-hook #'nano-modeline-xwidget-mode)
+;; (add-hook 'messages-buffer-mode-hook #'nano-modeline-message-mode)
+;; (add-hook 'org-capture-mode-hook #'nano-modeline-org-capture-mode)
+;; (add-hook 'org-agenda-mode-hook #'nano-modeline-org-agenda-mode)
- [elpa] externals/nano-modeline updated (b8795c14ad -> bead6850a1), ELPA Syncer, 2023/06/02
- [elpa] externals/nano-modeline 21263a0b3d 01/26: Complete rewrite,
ELPA Syncer <=
- [elpa] externals/nano-modeline 7f8c45c5fb 02/26: Some modelines can be made default (text or prog), ELPA Syncer, 2023/06/02
- [elpa] externals/nano-modeline d18fa48999 08/26: Update documentation, ELPA Syncer, 2023/06/02
- [elpa] externals/nano-modeline 3e29afaea2 09/26: Better alignment with fringes and margins, ELPA Syncer, 2023/06/02
- [elpa] externals/nano-modeline 7663311747 04/26: Bugfix with deadline date, ELPA Syncer, 2023/06/02
- [elpa] externals/nano-modeline 26470be833 07/26: Nil face is ok, ELPA Syncer, 2023/06/02
- [elpa] externals/nano-modeline 7503853c0b 13/26: Added clickalt text/svg buttons, ELPA Syncer, 2023/06/02
- [elpa] externals/nano-modeline 961065fe66 16/26: Added possibility to have icon in buttons, ELPA Syncer, 2023/06/02
- [elpa] externals/nano-modeline a2bf4fd073 22/26: Several group of butons are now possible, ELPA Syncer, 2023/06/02
- [elpa] externals/nano-modeline bead6850a1 26/26: Add usage example to documentation, ELPA Syncer, 2023/06/02
- [elpa] externals/nano-modeline 0b47e73d04 18/26: Added possibility for dynamic buttons, ELPA Syncer, 2023/06/02