emacs-elpa-diffs
[Top][All Lists]
Advanced

[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)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]