diff --git a/code/elpa/doom-modeline-20220412.853/doom-modeline-autoloads.el b/code/elpa/doom-modeline-20220412.853/doom-modeline-autoloads.el
new file mode 100644
index 0000000..481641c
--- /dev/null
+++ b/code/elpa/doom-modeline-20220412.853/doom-modeline-autoloads.el
@@ -0,0 +1,135 @@
+;;; doom-modeline-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "doom-modeline" "doom-modeline.el" (0 0 0 0))
+;;; Generated autoloads from doom-modeline.el
+
+(autoload 'doom-modeline-init "doom-modeline" "\
+Initialize doom mode-line." nil nil)
+
+(autoload 'doom-modeline-set-main-modeline "doom-modeline" "\
+Set main mode-line.
+If DEFAULT is non-nil, set the default mode-line for all buffers.
+
+\(fn &optional DEFAULT)" nil nil)
+
+(autoload 'doom-modeline-set-minimal-modeline "doom-modeline" "\
+Set minimal mode-line." nil nil)
+
+(autoload 'doom-modeline-set-special-modeline "doom-modeline" "\
+Set special mode-line." nil nil)
+
+(autoload 'doom-modeline-set-project-modeline "doom-modeline" "\
+Set project mode-line." nil nil)
+
+(autoload 'doom-modeline-set-dashboard-modeline "doom-modeline" "\
+Set dashboard mode-line." nil nil)
+
+(autoload 'doom-modeline-set-vcs-modeline "doom-modeline" "\
+Set vcs mode-line." nil nil)
+
+(autoload 'doom-modeline-set-info-modeline "doom-modeline" "\
+Set Info mode-line." nil nil)
+
+(autoload 'doom-modeline-set-package-modeline "doom-modeline" "\
+Set package mode-line." nil nil)
+
+(autoload 'doom-modeline-set-media-modeline "doom-modeline" "\
+Set media mode-line." nil nil)
+
+(autoload 'doom-modeline-set-message-modeline "doom-modeline" "\
+Set message mode-line." nil nil)
+
+(autoload 'doom-modeline-set-pdf-modeline "doom-modeline" "\
+Set pdf mode-line." nil nil)
+
+(autoload 'doom-modeline-set-org-src-modeline "doom-modeline" "\
+Set org-src mode-line." nil nil)
+
+(autoload 'doom-modeline-set-helm-modeline "doom-modeline" "\
+Set helm mode-line.
+
+\(fn &rest _)" nil nil)
+
+(autoload 'doom-modeline-set-timemachine-modeline "doom-modeline" "\
+Set timemachine mode-line." nil nil)
+
+(defvar doom-modeline-mode nil "\
+Non-nil if Doom-Modeline mode is enabled.
+See the `doom-modeline-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `doom-modeline-mode'.")
+
+(custom-autoload 'doom-modeline-mode "doom-modeline" nil)
+
+(autoload 'doom-modeline-mode "doom-modeline" "\
+Toggle doom-modeline on or off.
+
+This is a minor mode. If called interactively, toggle the
+`Doom-Modeline mode' mode. If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value \\='doom-modeline-mode)'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+\(fn &optional ARG)" t nil)
+
+(register-definition-prefixes "doom-modeline" '("doom-modeline-mode-map"))
+
+;;;***
+
+;;;### (autoloads nil "doom-modeline-core" "doom-modeline-core.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-modeline-core.el
+
+(register-definition-prefixes "doom-modeline-core" '("doom-modeline"))
+
+;;;***
+
+;;;### (autoloads nil "doom-modeline-env" "doom-modeline-env.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-modeline-env.el
+ (autoload 'doom-modeline-env-setup-python "doom-modeline-env")
+ (autoload 'doom-modeline-env-setup-ruby "doom-modeline-env")
+ (autoload 'doom-modeline-env-setup-perl "doom-modeline-env")
+ (autoload 'doom-modeline-env-setup-go "doom-modeline-env")
+ (autoload 'doom-modeline-env-setup-elixir "doom-modeline-env")
+ (autoload 'doom-modeline-env-setup-rust "doom-modeline-env")
+
+(register-definition-prefixes "doom-modeline-env" '("doom-modeline-"))
+
+;;;***
+
+;;;### (autoloads nil "doom-modeline-segments" "doom-modeline-segments.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-modeline-segments.el
+
+(register-definition-prefixes "doom-modeline-segments" '("doom-modeline-"))
+
+;;;***
+
+;;;### (autoloads nil nil ("doom-modeline-pkg.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; doom-modeline-autoloads.el ends here
diff --git a/code/elpa/doom-modeline-20220412.853/doom-modeline-core.el b/code/elpa/doom-modeline-20220412.853/doom-modeline-core.el
new file mode 100644
index 0000000..86360f1
--- /dev/null
+++ b/code/elpa/doom-modeline-20220412.853/doom-modeline-core.el
@@ -0,0 +1,1394 @@
+;;; doom-modeline-core.el --- The core libraries for doom-modeline -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2020 Vincent Zhang
+
+;; This file is not part of GNU Emacs.
+
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see .
+;;
+
+;;; Commentary:
+;;
+;; The core libraries for doom-modeline.
+;;
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'subr-x)
+(require 'dash)
+(require 'all-the-icons)
+(require 'shrink-path)
+
+
+;;
+;; Compatibility
+;;
+
+(eval-and-compile
+ (when (< emacs-major-version 26)
+ ;; Define `if-let*' and `when-let*' variants for 25 users.
+ (unless (fboundp 'if-let*) (defalias 'if-let* #'if-let))
+ (unless (fboundp 'when-let*) (defalias 'when-let* #'when-let))))
+
+;; Donβt compact font caches during GC.
+(when (eq system-type 'windows-nt)
+ (setq inhibit-compacting-font-caches t))
+
+;;`file-local-name' is introduced in 25.2.2.
+(unless (fboundp 'file-local-name)
+ (defun file-local-name (file)
+ "Return the local name component of FILE.
+It returns a file name which can be used directly as argument of
+`process-file', `start-file-process', or `shell-command'."
+ (or (file-remote-p file 'localname) file)))
+
+;; Set correct font width for `all-the-icons' for appropriate mode-line width.
+;; @see https://emacs.stackexchange.com/questions/14420/how-can-i-fix-incorrect-character-width
+(defun doom-modeline--set-char-widths (alist)
+ "Set correct widths of icons characters in ALIST."
+ (while (char-table-parent char-width-table)
+ (setq char-width-table (char-table-parent char-width-table)))
+ (dolist (pair alist)
+ (let ((width (car pair))
+ (chars (cdr pair))
+ (table (make-char-table nil)))
+ (dolist (char chars)
+ (set-char-table-range table char width))
+ (optimize-char-table table)
+ (set-char-table-parent table char-width-table)
+ (setq char-width-table table))))
+
+(defconst doom-modeline-rhs-icons-alist
+ '((2 . (;; VCS
+ ?\xf0ac ; git-compare
+ ?\xf023 ; git-merge
+ ?\xf03f ; arrow-down
+ ?\xf02d ; alert
+ ?\xf020 ; git-branch
+
+ ;; Checker
+ ?\xe611 ; do_not_disturb_alt
+ ?\xe5ca ; check
+ ?\xe192 ; access_time
+ ?\xe624 ; sim_card_alert
+ ?\xe034 ; pause
+ ?\xe645 ; priority_high
+
+ ;; Minor modes
+ ?\xf02f ; gear
+
+ ;; Persp
+ ?\xe2c7 ; folder
+
+ ;; Preview
+ ?\xe8a0 ; pageview
+
+ ;; REPL
+ ?\xf155 ; dollar-sign
+
+ ;; LSP
+ ?\xf135 ; rocket
+
+ ;; GitHub
+ ?\xf09b ; github
+
+ ;; Debug
+ ?\xf188 ; bug
+
+ ;; Mail
+ ?\xe0be ; email
+
+ ;; IRC
+ ?\xe0c9 ; message
+
+ ;; Battery
+ ?\xe939 ; battery-charging
+ ?\xf244 ; battery-empty
+ ?\xf240 ; battery-full
+ ?\xf242 ; battery-half
+ ?\xf243 ; battery-quarter
+ ?\xf241 ; battery-three-quarters
+ ))))
+
+(defun doom-modeline-set-char-widths (&rest _)
+ "Set char widths for the unicode icons."
+ (doom-modeline--set-char-widths doom-modeline-rhs-icons-alist))
+
+(if (and (daemonp)
+ (not (frame-parameter nil 'client)))
+ (add-hook 'after-make-frame-functions #'doom-modeline-set-char-widths)
+ (and (display-graphic-p) (doom-modeline-set-char-widths)))
+
+
+;;
+;; Customization
+;;
+
+(defgroup doom-modeline nil
+ "A minimal and modern mode-line."
+ :group 'mode-line
+ :link '(url-link :tag "Homepage" "https://github.com/seagle0128/doom-modeline"))
+
+(defcustom doom-modeline-support-imenu nil
+ "If non-nil, cause imenu to see `doom-modeline' declarations.
+This is done by adjusting `lisp-imenu-generic-expression' to
+include support for finding `doom-modeline-def-*' forms.
+
+Must be set before loading doom-modeline."
+ :type 'boolean
+ :set (lambda (_sym val)
+ (if val
+ (add-hook 'emacs-lisp-mode-hook #'doom-modeline-add-imenu)
+ (remove-hook 'emacs-lisp-mode-hook #'doom-modeline-add-imenu)))
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-height 25
+ "How tall the mode-line should be. It's only respected in GUI.
+If the actual char height is larger, it respects the actual char height.
+If `doom-modeline-height' is <= 0 the modeline will have default height."
+ :type 'integer
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-bar-width 4
+ "How wide the mode-line bar should be. It's only respected in GUI."
+ :type 'integer
+ :set (lambda (sym val)
+ (set sym (if (> val 0) val 1)))
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-hud nil
+ "Whether to use hud instead of default bar. It's only respected in GUI."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-hud-min-height 2
+ "Minimum height in pixels of the \"thumb\" of the hud.
+Only respected in GUI."
+ :type 'integer
+ :set (lambda (sym val)
+ (set sym (if (> val 1) val 1)))
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-window-width-limit 0.25
+ "The limit of the window width.
+
+If `window-width' is smaller than the limit, some information won't be
+displayed. It can be an integer or a float number. `nil' means no limit."
+ :type '(choice integer
+ float
+ (const :tag "Disable" nil))
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-project-detection 'auto
+ "How to detect the project root.
+
+nil means to use `default-directory'.
+
+The project management packages have some issues on detecting project root.
+e.g. `projectile' doesn't handle symlink folders well, while `project' is
+unable to handle sub-projects.
+Specify another one if you encounter the issue."
+ :type '(choice (const :tag "Auto-detect" auto)
+ (const :tag "Find File in Project" ffip)
+ (const :tag "Projectile" projectile)
+ (const :tag "Built-in Project" project)
+ (const :tag "Disable" nil))
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-buffer-file-name-style 'auto
+ "Determines the style used by `doom-modeline-buffer-file-name'.
+
+Given ~/Projects/FOSS/emacs/lisp/comint.el
+ auto => emacs/lisp/comint.el (in a project) or comint.el
+ truncate-upto-project => ~/P/F/emacs/lisp/comint.el
+ truncate-from-project => ~/Projects/FOSS/emacs/l/comint.el
+ truncate-with-project => emacs/l/comint.el
+ truncate-except-project => ~/P/F/emacs/l/comint.el
+ truncate-upto-root => ~/P/F/e/lisp/comint.el
+ truncate-all => ~/P/F/e/l/comint.el
+ truncate-nil => ~/Projects/FOSS/emacs/lisp/comint.el
+ relative-from-project => emacs/lisp/comint.el
+ relative-to-project => lisp/comint.el
+ file-name => comint.el
+ buffer-name => comint.el<2> (uniquify buffer name)"
+ :type '(choice (const auto)
+ (const truncate-upto-project)
+ (const truncate-upto-project)
+ (const truncate-from-project)
+ (const truncate-with-project)
+ (const truncate-except-project)
+ (const truncate-upto-root)
+ (const truncate-all)
+ (const truncate-nil)
+ (const relative-from-project)
+ (const relative-to-project)
+ (const file-name)
+ (const buffer-name))
+ :group'doom-modeline)
+
+(defcustom doom-modeline-icon t
+ "Whether display the icons in the mode-line.
+
+While using the server mode in GUI, should set the value explicitly."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-major-mode-icon t
+ "Whether display the icon for `major-mode'.
+
+It respects `doom-modeline-icon'."
+ :type 'boolean
+ :group'doom-modeline)
+
+(defcustom doom-modeline-major-mode-color-icon t
+ "Whether display the colorful icon for `major-mode'.
+
+It respects `all-the-icons-color-icons'."
+ :type 'boolean
+ :group'doom-modeline)
+
+(defcustom doom-modeline-buffer-state-icon t
+ "Whether display the icon for the buffer state.
+
+It respects `doom-modeline-icon'."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-buffer-modification-icon t
+ "Whether display the modification icon for the buffer.
+
+It respects `doom-modeline-icon' and `doom-modeline-buffer-state-icon'."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-unicode-fallback nil
+ "Whether to use unicode as a fallback (instead of ASCII) when not using icons."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-buffer-name t
+ "Whether display the buffer name."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-minor-modes nil
+ "Whether display the minor modes in the mode-line."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-enable-word-count nil
+ "If non-nil, a word count will be added to the selection-info modeline segment."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-continuous-word-count-modes
+ '(markdown-mode gfm-mode org-mode)
+ "Major modes in which to display word count continuously.
+
+It respects `doom-modeline-enable-word-count'."
+ :type '(repeat (symbol :tag "Major-Mode") )
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-buffer-encoding t
+ "Whether display the buffer encoding."
+ :type '(choice (const :tag "Always" t)
+ (const :tag "When non-default" nondefault)
+ (const :tag "Never" nil))
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-default-coding-system 'utf-8
+ "Default coding system for `doom-modeline-buffer-encoding' `nondefault'."
+ :type 'coding-system
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-default-eol-type 0
+ "Default EOL type for `doom-modeline-buffer-encoding' `nondefault'."
+ :type '(choice (const :tag "Unix-style LF" 0)
+ (const :tag "DOS-style CRLF" 1)
+ (const :tag "Mac-style CR" 2))
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-indent-info nil
+ "Whether display the indentation information."
+ :type 'boolean
+ :group 'doom-modeline)
+
+;; It is based upon `editorconfig-indentation-alist' but is used to read indentation levels instead
+;; of setting them. (https://github.com/editorconfig/editorconfig-emacs)
+(defcustom doom-modeline-indent-alist
+ '((apache-mode apache-indent-level)
+ (awk-mode c-basic-offset)
+ (bpftrace-mode c-basic-offset)
+ (c++-mode c-basic-offset)
+ (c-mode c-basic-offset)
+ (cmake-mode cmake-tab-width)
+ (coffee-mode coffee-tab-width)
+ (cperl-mode cperl-indent-level)
+ (crystal-mode crystal-indent-level)
+ (csharp-mode c-basic-offset)
+ (css-mode css-indent-offset)
+ (d-mode c-basic-offset)
+ (emacs-lisp-mode lisp-indent-offset)
+ (enh-ruby-mode enh-ruby-indent-level)
+ (erlang-mode erlang-indent-level)
+ (ess-mode ess-indent-offset)
+ (f90-mode f90-associate-indent
+ f90-continuation-indent
+ f90-critical-indent
+ f90-do-indent
+ f90-if-indent
+ f90-program-indent
+ f90-type-indent)
+ (feature-mode feature-indent-offset
+ feature-indent-level)
+ (fsharp-mode fsharp-continuation-offset
+ fsharp-indent-level
+ fsharp-indent-offset)
+ (groovy-mode groovy-indent-offset)
+ (haskell-mode haskell-indent-spaces
+ haskell-indent-offset
+ haskell-indentation-layout-offset
+ haskell-indentation-left-offset
+ haskell-indentation-starter-offset
+ haskell-indentation-where-post-offset
+ haskell-indentation-where-pre-offset
+ shm-indent-spaces)
+ (haxor-mode haxor-tab-width)
+ (idl-mode c-basic-offset)
+ (jade-mode jade-tab-width)
+ (java-mode c-basic-offset)
+ (js-mode js-indent-level)
+ (js-jsx-mode js-indent-level
+ sgml-basic-offset)
+ (js2-mode js2-basic-offset)
+ (js2-jsx-mode js2-basic-offset
+ sgml-basic-offset)
+ (js3-mode js3-indent-level)
+ (json-mode js-indent-level)
+ (julia-mode julia-indent-offset)
+ (kotlin-mode kotlin-tab-width)
+ (latex-mode tex-indent-basic)
+ (lisp-mode lisp-indent-offset)
+ (livescript-mode livescript-tab-width)
+ (lua-mode lua-indent-level)
+ (matlab-mode matlab-indent-level)
+ (mips-mode mips-tab-width)
+ (mustache-mode mustache-basic-offset)
+ (nasm-mode nasm-basic-offset)
+ (nginx-mode nginx-indent-level)
+ (nxml-mode nxml-child-indent)
+ (objc-mode c-basic-offset)
+ (octave-mode octave-block-offset)
+ (perl-mode perl-indent-level)
+ (php-mode c-basic-offset)
+ (pike-mode c-basic-offset)
+ (ps-mode ps-mode-tab)
+ (pug-mode pug-tab-width)
+ (puppet-mode puppet-indent-level)
+ (python-mode python-indent-offset)
+ (ruby-mode ruby-indent-level)
+ (rust-mode rust-indent-offset)
+ (rustic-mode rustic-indent-offset)
+ (scala-mode scala-indent:step)
+ (scss-mode css-indent-offset)
+ (sgml-mode sgml-basic-offset)
+ (sh-mode sh-basic-offset
+ sh-indentation)
+ (slim-mode slim-indent-offset)
+ (sml-mode sml-indent-level)
+ (tcl-mode tcl-indent-level
+ tcl-continued-indent-level)
+ (terra-mode terra-indent-level)
+ (typescript-mode typescript-indent-level)
+ (verilog-mode verilog-indent-level
+ verilog-indent-level-behavioral
+ verilog-indent-level-declaration
+ verilog-indent-level-module
+ verilog-cexp-indent
+ verilog-case-indent)
+ (web-mode web-mode-attr-indent-offset
+ web-mode-attr-value-indent-offset
+ web-mode-code-indent-offset
+ web-mode-css-indent-offset
+ web-mode-markup-indent-offset
+ web-mode-sql-indent-offset
+ web-mode-block-padding
+ web-mode-script-padding
+ web-mode-style-padding)
+ (yaml-mode yaml-indent-offset))
+ "Indentation retrieving variables matched to major modes used
+ when `doom-modeline-indent-info' is non-nil. When multiple
+ variables are specified for a mode, they will be tried resolved
+ in the given order."
+ :type '(alist :key-type symbol :value-type sexp)
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-checker-simple-format t
+ "If non-nil, only display one number for checker information if applicable."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-number-limit 99
+ "The maximum number displayed for notifications."
+ :type 'integer
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-vcs-max-length 12
+ "The maximum displayed length of the branch name of version control."
+ :type 'integer
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-workspace-name t
+ "Whether display the workspace name.
+
+Non-nil to display in the mode-line."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-persp-name t
+ "Whether display the perspective name.
+
+Non-nil to display in the mode-line."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-display-default-persp-name nil
+ "If non nil the default perspective name is displayed in the mode-line."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-persp-icon t
+ "If non nil the perspective name is displayed alongside a folder icon."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-repl t
+ "Whether display the `repl' state.
+
+Non-nil to display in the mode-line."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-lsp t
+ "Whether display the `lsp' state.
+
+Non-nil to display in the mode-line."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-github nil
+ "Whether display the GitHub notifications.
+
+It requires `ghub' and `async' packages."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-github-interval 1800 ; (* 30 60)
+ "The interval of checking GitHub."
+ :type 'integer
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-env-version t
+ "Whether display the environment version."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-modal-icon t
+ "Whether display the modal state icon.
+
+Including `evil', `overwrite', `god', `ryo' and `xah-fly-keys', etc."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-mu4e nil
+ "Whether display the mu4e notifications.
+
+It requires `mu4e-alert' package."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-gnus nil
+ "Whether to display notifications from gnus.
+
+It requires `gnus' to be setup"
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-gnus-timer 2
+ "The wait time in minutes before gnus fetches mail.
+
+If nil, don't set up a hook."
+ :type 'integer
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-gnus-idle nil
+ "Whether to wait an idle time to scan for news.
+
+When t, sets `doom-modeline-gnus-timer' as an idle timer. If a
+number, Emacs must have been idle this given time, checked after
+reach the defined timer, to fetch news. The time step can be
+configured in `gnus-demon-timestep'."
+ :type '(choice
+ (boolean :tag "Set `doom-modeline-gnus-timer' as an idle timer")
+ (number :tag "Set a custom idle timer"))
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-gnus-excluded-groups nil
+ "A list of groups to be excluded from the unread count.
+Groups' names list in `gnus-newsrc-alist'`"
+ :type '(repeat string)
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-irc t
+ "Whether display the irc notifications.
+
+It requires `circe' or `erc' package."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-irc-buffers nil
+ "Whether display the unread irc buffers."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-irc-stylize 'identity
+ "Function to stylize the irc buffer names."
+ :type 'function
+ :group 'doom-modeline)
+
+
+;;
+;; Faces
+;;
+
+(defgroup doom-modeline-faces nil
+ "The faces of `doom-modeline'."
+ :group 'doom-modeline
+ :group 'faces
+ :link '(url-link :tag "Homepage" "https://github.com/seagle0128/doom-modeline"))
+
+(defface doom-modeline-spc-face
+ '((t (:inherit mode-line)))
+ "Face used for the white space."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-spc-inactive-face
+ '((t (:inherit mode-line-inactive)))
+ "Face used for the inactive white space."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-vspc-face
+ '((t (:inherit variable-pitch)))
+ "Face used for the variable white space."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-vspc-inactive-face
+ '((t (:inherit (mode-line-inactive doom-modeline-vspc-face))))
+ "Face used for the variable white space."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-buffer-path
+ '((t (:inherit (mode-line-emphasis bold))))
+ "Face used for the dirname part of the buffer path."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-buffer-file
+ '((t (:inherit (mode-line-buffer-id bold))))
+ "Face used for the filename part of the mode-line buffer path."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-buffer-modified
+ '((t (:inherit (error bold) :background nil)))
+ "Face used for the 'unsaved' symbol in the mode-line."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-buffer-major-mode
+ '((t (:inherit (mode-line-emphasis bold))))
+ "Face used for the major-mode segment in the mode-line."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-buffer-minor-mode
+ '((t (:inherit font-lock-doc-face :slant normal)))
+ "Face used for the minor-modes segment in the mode-line."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-project-parent-dir
+ '((t (:inherit (font-lock-comment-face bold))))
+ "Face used for the project parent directory of the mode-line buffer path."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-project-dir
+ '((t (:inherit (font-lock-string-face bold))))
+ "Face used for the project directory of the mode-line buffer path."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-project-root-dir
+ '((t (:inherit (mode-line-emphasis bold))))
+ "Face used for the project part of the mode-line buffer path."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-highlight
+ '((t (:inherit mode-line-emphasis)))
+ "Face for bright segments of the mode-line."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-panel
+ '((t (:inherit mode-line-highlight)))
+ "Face for 'X out of Y' segments, such as `anzu', `evil-substitute' and`iedit', etc."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-host
+ '((t (:inherit italic)))
+ "Face for remote hosts in the mode-line."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-input-method
+ '((t (:inherit (mode-line-emphasis bold))))
+ "Face for input method in the mode-line."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-input-method-alt
+ '((t (:inherit (font-lock-doc-face bold) :slant normal)))
+ "Alternative face for input method in the mode-line."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-debug
+ '((t (:inherit (font-lock-doc-face bold) :slant normal)))
+ "Face for debug-level messages in the mode-line. Used by vcs, checker, etc."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-info
+ '((t (:inherit (success bold))))
+ "Face for info-level messages in the mode-line. Used by vcs, checker, etc."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-warning
+ '((t (:inherit (warning bold))))
+ "Face for warnings in the mode-line. Used by vcs, checker, etc."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-urgent
+ '((t (:inherit (error bold))))
+ "Face for errors in the mode-line. Used by vcs, checker, etc."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-notification
+ '((t (:inherit doom-modeline-warning)))
+ "Face for notifications in the mode-line. Used by GitHub, mu4e,
+etc. (also see the face `doom-modeline-unread-number')."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-unread-number
+ '((t (:slant italic :weight normal)))
+ "Face for unread number in the mode-line. Used by GitHub, mu4e, etc."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-bar
+ '((t (:inherit highlight)))
+ "The face used for the left-most bar in the mode-line of an active window."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-bar-inactive
+ `((t (:background ,(face-foreground 'mode-line-inactive))))
+ "The face used for the left-most bar in the mode-line of an inactive window."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-debug-visual
+ `((((class color) (background light))
+ (:background ,(face-foreground 'all-the-icons-orange)))
+ (((class color) (background dark))
+ (:background ,(face-foreground 'all-the-icons-dorange))))
+ "Face to use for the mode-line while debugging."
+ :group 'doom-modeline)
+
+(defface doom-modeline-evil-emacs-state
+ '((t (:inherit (font-lock-builtin-face bold))))
+ "Face for the Emacs state tag in evil state indicator."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-evil-insert-state
+ '((t (:inherit (font-lock-keyword-face bold))))
+ "Face for the insert state tag in evil state indicator."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-evil-motion-state
+ '((t :inherit (font-lock-doc-face bold) :slant normal))
+ "Face for the motion state tag in evil state indicator."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-evil-normal-state
+ '((t (:inherit doom-modeline-info)))
+ "Face for the normal state tag in evil state indicator."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-evil-operator-state
+ '((t (:inherit doom-modeline-buffer-file)))
+ "Face for the operator state tag in evil state indicator."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-evil-visual-state
+ '((t (:inherit doom-modeline-warning)))
+ "Face for the visual state tag in evil state indicator."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-evil-replace-state
+ '((t (:inherit doom-modeline-urgent)))
+ "Face for the replace state tag in evil state indicator."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-persp-name
+ '((t (:inherit (font-lock-comment-face italic))))
+ "Face for the persp name."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-persp-buffer-not-in-persp
+ '((t (:inherit (font-lock-doc-face bold italic))))
+ "Face for the buffers which are not in the persp."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-repl-success
+ '((t (:inherit success :weight normal)))
+ "Face for REPL success state."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-repl-warning
+ '((t (:inherit warning :weight normal)))
+ "Face for REPL warning state."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-lsp-success
+ '((t (:inherit success :weight normal)))
+ "Face for LSP success state."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-lsp-warning
+ '((t (:inherit warning :weight normal)))
+ "Face for LSP warning state."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-lsp-error
+ '((t (:inherit error :weight normal)))
+ "Face for LSP error state."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-lsp-running
+ '((t (:inherit compilation-mode-line-run :weight normal :slant normal)))
+ "Face for LSP running state."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-battery-charging
+ '((t (:inherit success :weight normal)))
+ "Face for battery charging status."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-battery-full
+ '((t (:inherit success :weight normal)))
+ "Face for battery full status."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-battery-normal
+ '((t (:inherit mode-line :weight normal)))
+ "Face for battery normal status."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-battery-warning
+ '((t (:inherit warning :weight normal)))
+ "Face for battery warning status."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-battery-critical
+ '((t (:inherit error :weight normal)))
+ "Face for battery critical status."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-battery-error
+ '((t (:inherit error :weight normal)))
+ "Face for battery error status."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-buffer-timemachine
+ '((t (:inherit doom-modeline-buffer-file :slant italic)))
+ "Face for timemachine status."
+ :group 'doom-modeline-faces)
+
+
+;;
+;; Externals
+;;
+
+(declare-function face-remap-remove-relative "face-remap")
+(declare-function ffip-get-project-root-directory "ext:find-file-in-project")
+(declare-function project-root "ext:project")
+(declare-function projectile-project-root "ext:projectile")
+
+
+;;
+;; Utilities
+;;
+
+(defun doom-modeline-add-font-lock ()
+ "Fontify `doom-modeline-def-*' statements."
+ (font-lock-add-keywords
+ 'emacs-lisp-mode
+ '(("(\\(doom-modeline-def-.+\\)\\_> +\\(.*?\\)\\_>"
+ (1 font-lock-keyword-face)
+ (2 font-lock-constant-face)))))
+(doom-modeline-add-font-lock)
+
+(defun doom-modeline-add-imenu ()
+ "Add to `imenu' index."
+ (add-to-list
+ 'imenu-generic-expression
+ '("Modelines"
+ "^\\s-*(\\(doom-modeline-def-modeline\\)\\s-+\\(\\(?:\\sw\\|\\s_\\|\\s'\\|\\\\.\\)+\\)"
+ 2))
+ (add-to-list
+ 'imenu-generic-expression
+ '("Segments"
+ "^\\s-*(\\(doom-modeline-def-segment\\)\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)"
+ 2))
+ (add-to-list
+ 'imenu-generic-expression
+ '("Envs"
+ "^\\s-*(\\(doom-modeline-def-env\\)\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)"
+ 2)))
+
+
+;;
+;; Core helpers
+;;
+
+;; FIXME #183: Force to calculate mode-line height
+;; @see https://github.com/seagle0128/doom-modeline/issues/183
+;; @see https://github.com/seagle0128/doom-modeline/issues/483
+(defun doom-modeline-redisplay (&rest _)
+ "Call `redisplay' to trigger mode-line height calculations.
+
+Certain functions, including e.g. `fit-window-to-buffer', base
+their size calculations on values which are incorrect if the
+mode-line has a height different from that of the `default' face
+and certain other calculations have not yet taken place for the
+window in question.
+
+These calculations can be triggered by calling `redisplay'
+explicitly at the appropriate time and this functions purpose
+is to make it easier to do so.
+
+This function is like `redisplay' with non-nil FORCE argument,
+but it will only trigger a redisplay when there is a non nil
+`mode-line-format' and the height of the mode-line is different
+from that of the `default' face. This function is intended to be
+used as an advice to window creation functions."
+ (when (and (bound-and-true-p doom-modeline-mode)
+ mode-line-format
+ (/= (frame-char-height) (window-mode-line-height)))
+ (redisplay t)))
+(unless (>= emacs-major-version 29)
+ (advice-add #'fit-window-to-buffer :before #'doom-modeline-redisplay))
+
+;; Keep `doom-modeline-current-window' up-to-date
+(defun doom-modeline--get-current-window (&optional frame)
+ "Get the current window but should exclude the child windows."
+ (if (and (fboundp 'frame-parent) (frame-parent frame))
+ (frame-selected-window (frame-parent frame))
+ (frame-selected-window frame)))
+
+(defvar doom-modeline-current-window (doom-modeline--get-current-window))
+
+(defun doom-modeline--active ()
+ "Whether is an active window."
+ (unless (and (bound-and-true-p mini-frame-frame)
+ (and (frame-live-p mini-frame-frame)
+ (frame-visible-p mini-frame-frame)))
+ (and doom-modeline-current-window
+ (eq (doom-modeline--get-current-window) doom-modeline-current-window))))
+
+(defun doom-modeline-set-selected-window (&rest _)
+ "Set `doom-modeline-current-window' appropriately."
+ (let ((win (doom-modeline--get-current-window)))
+ (setq doom-modeline-current-window
+ (if (minibuffer-window-active-p win)
+ (minibuffer-selected-window)
+ win))))
+
+(defun doom-modeline-unset-selected-window ()
+ "Unset `doom-modeline-current-window' appropriately."
+ (setq doom-modeline-current-window nil))
+
+(add-hook 'pre-redisplay-functions #'doom-modeline-set-selected-window)
+
+;; Ensure modeline is inactive when Emacs is unfocused (and active otherwise)
+(defvar doom-modeline-remap-face-cookie nil)
+(defun doom-modeline-focus ()
+ "Focus mode-line."
+ (when doom-modeline-remap-face-cookie
+ (require 'face-remap)
+ (face-remap-remove-relative doom-modeline-remap-face-cookie)))
+(defun doom-modeline-unfocus ()
+ "Unfocus mode-line."
+ (setq doom-modeline-remap-face-cookie
+ (face-remap-add-relative 'mode-line 'mode-line-inactive)))
+
+(with-no-warnings
+ (if (boundp 'after-focus-change-function)
+ (progn
+ (defun doom-modeline-focus-change (&rest _)
+ (if (frame-focus-state)
+ (doom-modeline-focus)
+ (doom-modeline-unfocus)))
+ (advice-add #'handle-switch-frame :after #'doom-modeline-focus-change)
+ (add-function :after after-focus-change-function #'doom-modeline-focus-change))
+ (progn
+ (add-hook 'focus-in-hook #'doom-modeline-focus)
+ (add-hook 'focus-out-hook #'doom-modeline-unfocus))))
+
+
+;;
+;; Core
+;;
+
+(defvar doom-modeline-fn-alist ())
+(defvar doom-modeline-var-alist ())
+
+(defmacro doom-modeline-def-segment (name &rest body)
+ "Defines a modeline segment NAME with BODY and byte compiles it."
+ (declare (indent defun) (doc-string 2))
+ (let ((sym (intern (format "doom-modeline-segment--%s" name)))
+ (docstring (if (stringp (car body))
+ (pop body)
+ (format "%s modeline segment" name))))
+ (cond ((and (symbolp (car body))
+ (not (cdr body)))
+ (add-to-list 'doom-modeline-var-alist (cons name (car body)))
+ `(add-to-list 'doom-modeline-var-alist (cons ',name ',(car body))))
+ (t
+ (add-to-list 'doom-modeline-fn-alist (cons name sym))
+ `(progn
+ (fset ',sym (lambda () ,docstring ,@body))
+ (add-to-list 'doom-modeline-fn-alist (cons ',name ',sym))
+ ,(unless (bound-and-true-p byte-compile-current-file)
+ `(let (byte-compile-warnings)
+ (byte-compile #',sym))))))))
+
+(defun doom-modeline--prepare-segments (segments)
+ "Prepare mode-line `SEGMENTS'."
+ (let (forms it)
+ (dolist (seg segments)
+ (cond ((stringp seg)
+ (push seg forms))
+ ((symbolp seg)
+ (cond ((setq it (cdr (assq seg doom-modeline-fn-alist)))
+ (push (list :eval (list it)) forms))
+ ((setq it (cdr (assq seg doom-modeline-var-alist)))
+ (push it forms))
+ ((error "%s is not a defined segment" seg))))
+ ((error "%s is not a valid segment" seg))))
+ (nreverse forms)))
+
+(defvar doom-modeline--font-width-cache nil)
+(defun doom-modeline--font-width ()
+ "Cache the font width."
+ (if (display-graphic-p)
+ (let ((attributes (face-all-attributes 'mode-line)))
+ (or (cdr (assoc attributes doom-modeline--font-width-cache))
+ (let ((width (window-font-width nil 'mode-line)))
+ (push (cons attributes width) doom-modeline--font-width-cache)
+ width)))
+ 1))
+
+;; Refresh the font width after setting frame parameters
+;; to ensure the font width is correct.
+(defun doom-modeline-refresh-font-width-cache (&rest _)
+ "Refresh the font width cache."
+ (setq doom-modeline--font-width-cache nil)
+ (doom-modeline--font-width))
+(add-hook 'window-setup-hook #'doom-modeline-refresh-font-width-cache)
+(add-hook 'after-make-frame-functions #'doom-modeline-refresh-font-width-cache)
+(add-hook 'after-setting-font-hook #'doom-modeline-refresh-font-width-cache)
+(add-hook 'server-after-make-frame-hook #'doom-modeline-refresh-font-width-cache)
+
+(defun doom-modeline-def-modeline (name lhs &optional rhs)
+ "Defines a modeline format and byte-compiles it.
+NAME is a symbol to identify it (used by `doom-modeline' for retrieval).
+LHS and RHS are lists of symbols of modeline segments defined with
+`doom-modeline-def-segment'.
+
+Example:
+ (doom-modeline-def-modeline 'minimal
+ '(bar matches \" \" buffer-info)
+ '(media-info major-mode))
+ (doom-modeline-set-modeline 'minimal t)"
+ (let ((sym (intern (format "doom-modeline-format--%s" name)))
+ (lhs-forms (doom-modeline--prepare-segments lhs))
+ (rhs-forms (doom-modeline--prepare-segments rhs)))
+ (defalias sym
+ (lambda ()
+ (list lhs-forms
+ (propertize
+ " "
+ 'face (if (doom-modeline--active) 'mode-line 'mode-line-inactive)
+ 'display `((space
+ :align-to
+ (- (+ right right-fringe right-margin scroll-bar)
+ ,(* (let ((width (doom-modeline--font-width)))
+ (or (and (= width 1) 1)
+ (/ width (frame-char-width) 1.0)))
+ (string-width
+ (format-mode-line (cons "" rhs-forms))))))))
+ rhs-forms))
+ (concat "Modeline:\n"
+ (format " %s\n %s"
+ (prin1-to-string lhs)
+ (prin1-to-string rhs))))))
+(put 'doom-modeline-def-modeline 'lisp-indent-function 'defun)
+
+(defun doom-modeline (key)
+ "Return a mode-line configuration associated with KEY (a symbol).
+Throws an error if it doesn't exist."
+ (let ((fn (intern-soft (format "doom-modeline-format--%s" key))))
+ (when (functionp fn)
+ `(:eval (,fn)))))
+
+(defun doom-modeline-set-modeline (key &optional default)
+ "Set the modeline format. Does nothing if the modeline KEY doesn't exist.
+If DEFAULT is non-nil, set the default mode-line for all buffers."
+ (when-let ((modeline (doom-modeline key)))
+ (setf (if default
+ (default-value 'mode-line-format)
+ (buffer-local-value 'mode-line-format (current-buffer)))
+ (list "%e" modeline))))
+
+
+;;
+;; Helpers
+;;
+
+(defsubst doom-modeline-spc ()
+ "Text style with whitespace."
+ (propertize " " 'face (if (doom-modeline--active)
+ 'doom-modeline-spc-face
+ 'doom-modeline-spc-inactive-face)))
+
+(defsubst doom-modeline-wspc ()
+ "Text style with wide whitespace."
+ (propertize " " 'face (if (doom-modeline--active)
+ 'doom-modeline-spc-face
+ 'doom-modeline-spc-inactive-face)))
+
+(defsubst doom-modeline-vspc ()
+ "Text style with icons in mode-line."
+ (propertize " " 'face (if (doom-modeline--active)
+ 'doom-modeline-vspc-face
+ 'doom-modeline-vspc-inactive-face)))
+
+(defun doom-modeline--font-height ()
+ "Calculate the actual char height of the mode-line."
+ (let ((height (face-attribute 'mode-line :height)))
+ ;; WORKAROUND: Fix tall issue of 27 on Linux
+ ;; @see https://github.com/seagle0128/doom-modeline/issues/271
+ (round
+ (* (if (or (<= doom-modeline-height 0)
+ (and (>= emacs-major-version 27)
+ (not (eq system-type 'darwin))))
+ 1.0
+ (if doom-modeline-icon 1.68 1.25))
+ (cond ((integerp height) (/ height 10))
+ ((floatp height) (* height (frame-char-height)))
+ (t (frame-char-height)))))))
+
+(defun doom-modeline--original-value (sym)
+ "Return the original value for SYM, if any.
+
+If SYM has an original value, return it in a list. Return nil
+otherwise."
+ (let* ((orig-val-expr (get sym 'standard-value)))
+ (when (consp orig-val-expr)
+ (ignore-errors
+ (list
+ (eval (car orig-val-expr)))))))
+
+(defun doom-modeline-add-variable-watcher (symbol watch-function)
+ "Cause WATCH-FUNCTION to be called when SYMBOL is set if possible.
+
+See docs of `add-variable-watcher'."
+ (when (fboundp 'add-variable-watcher)
+ (add-variable-watcher symbol watch-function)))
+
+(defun doom-modeline-propertize-icon (icon &optional face)
+ "Propertize the ICON with the specified FACE.
+
+The face should be the first attribute, or the font family may be overridden.
+So convert the face \":family XXX :height XXX :inherit XXX\" to
+\":inherit XXX :family XXX :height XXX\".
+See https://github.com/seagle0128/doom-modeline/issues/301."
+ (if (and doom-modeline-icon (display-graphic-p))
+ (when-let ((props (get-text-property 0 'face icon)))
+ (cl-destructuring-bind (&key family height inherit &allow-other-keys) props
+ (propertize icon 'face `(:inherit ,(or face inherit props)
+ :family ,family
+ :height ,height))))
+ (propertize icon 'face face)))
+
+(defun doom-modeline-icon (icon-set icon-name unicode text &rest args)
+ "Display icon of ICON-NAME with ARGS in mode-line.
+
+ICON-SET includes `octicon', `faicon', `material', `alltheicons' and `fileicon',
+etc.
+UNICODE is the unicode char fallback. TEXT is the ASCII char fallback.
+ARGS is same as `all-the-icons-octicon' and others."
+ (let ((face (or (plist-get args :face) 'mode-line)))
+ (or
+ ;; Icons
+ (when (and (display-graphic-p)
+ doom-modeline-icon
+ icon-name
+ (not (string-empty-p icon-name)))
+ (when-let* ((func (all-the-icons--function-name icon-set))
+ (icon (and (fboundp func) (apply func icon-name args))))
+ (doom-modeline-propertize-icon icon face)))
+ ;; Unicode fallback
+ (and doom-modeline-unicode-fallback
+ unicode
+ (not (string-empty-p unicode))
+ (char-displayable-p (string-to-char unicode))
+ (propertize unicode 'face face))
+ ;; ASCII text
+ (and text (propertize text 'face face))
+ "")))
+
+(defun doom-modeline--create-bar-image (face width height)
+ "Create the bar image.
+Use FACE1 for the bar, FACE2 for the background.
+WIDTH and HEIGHT are the image size in pixels."
+ (when (and (display-graphic-p)
+ (image-type-available-p 'pbm))
+ (propertize
+ " " 'display
+ (let ((color (or (face-background face nil t) "None")))
+ (ignore-errors
+ (create-image
+ (concat (format "P1\n%i %i\n" width height)
+ (make-string (* width height) ?1)
+ "\n")
+ 'pbm t :foreground color :ascent 'center))))))
+
+(defun doom-modeline--create-hud-image
+ (face1 face2 width height top-margin bottom-margin)
+ "Create the hud image.
+Use FACE1 for the bar, FACE2 for the background.
+WIDTH and HEIGHT are the image size in pixels.
+TOP-MARGIN and BOTTOM-MARGIN are the size of the margin above and below the bar,
+respectively."
+ (when (and (display-graphic-p)
+ (image-type-available-p 'pbm))
+ (let ((min-height (min height doom-modeline-hud-min-height)))
+ (unless (> (- height top-margin bottom-margin) min-height)
+ (let ((margin (- height min-height)))
+ (setq top-margin (/ (* margin top-margin) (+ top-margin bottom-margin))
+ bottom-margin (- margin top-margin)))))
+ (propertize
+ " " 'display
+ (let ((color1 (or (face-background face1 nil t) "None"))
+ (color2 (or (face-background face2 nil t) "None")))
+ (create-image
+ (concat
+ (format "P1\n%i %i\n" width height)
+ (make-string (* top-margin width) ?0)
+ (make-string (* (- height top-margin bottom-margin) width) ?1)
+ (make-string (* bottom-margin width) ?0)
+ "\n")
+ 'pbm t :foreground color1 :background color2 :ascent 'center)))))
+
+;; Check whether `window-total-width' is smaller than the limit
+(defvar-local doom-modeline--limited-width-p nil)
+(defun doom-modeline-window-size-change-function (&rest _)
+ "Function for `window-size-change-functions'."
+ (setq doom-modeline--limited-width-p
+ (cond
+ ((integerp doom-modeline-window-width-limit)
+ (<= (window-total-width) doom-modeline-window-width-limit))
+ ((floatp doom-modeline-window-width-limit)
+ (<= (/ (window-total-width) (frame-width) 1.0)
+ doom-modeline-window-width-limit)))))
+
+(add-hook 'window-size-change-functions #'doom-modeline-window-size-change-function)
+(add-hook 'buffer-list-update-hook #'doom-modeline-window-size-change-function)
+
+(defvar-local doom-modeline--project-root nil)
+(defun doom-modeline--project-root ()
+ "Get the path to the root of your project.
+Return nil if no project was found."
+ (or doom-modeline--project-root
+ (setq doom-modeline--project-root
+ (pcase (if (eq doom-modeline-project-detection 'auto)
+ (cond
+ ((fboundp 'ffip-get-project-root-directory) 'ffip)
+ ((fboundp 'projectile-project-root) 'projectile)
+ ((fboundp 'project-current) 'project)
+ (t 'default))
+ doom-modeline-project-detection)
+ ('ffip
+ (let ((inhibit-message t))
+ (ffip-get-project-root-directory)))
+ ('projectile
+ (projectile-project-root))
+ ('project
+ (when-let ((project (project-current)))
+ (expand-file-name (if (fboundp 'project-root)
+ (project-root project)
+ (cdr project)))))))))
+
+(defun doom-modeline-project-p ()
+ "Check if the file is in a project."
+ (doom-modeline--project-root))
+
+(defun doom-modeline-project-root ()
+ "Get the path to the root of your project.
+Return `default-directory' if no project was found."
+ (or (doom-modeline--project-root) default-directory))
+
+(defun doom-modeline-buffer-file-name ()
+ "Propertized variable `buffer-file-name' based on
+`doom-modeline-buffer-file-name-style'."
+ (let* ((buffer-file-name (file-local-name (or (buffer-file-name (buffer-base-buffer)) "")))
+ (buffer-file-truename (file-local-name
+ (or buffer-file-truename (file-truename buffer-file-name) "")))
+ (file-name
+ (pcase doom-modeline-buffer-file-name-style
+ ('auto
+ (if (doom-modeline-project-p)
+ (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename nil nil 'hide)
+ (propertize "%b" 'face 'doom-modeline-buffer-file)))
+ ('truncate-upto-project
+ (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename 'shrink))
+ ('truncate-from-project
+ (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename nil 'shrink))
+ ('truncate-with-project
+ (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename 'shrink 'shink 'hide))
+ ('truncate-except-project
+ (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename 'shrink 'shink))
+ ('truncate-upto-root
+ (doom-modeline--buffer-file-name-truncate buffer-file-name buffer-file-truename))
+ ('truncate-all
+ (doom-modeline--buffer-file-name-truncate buffer-file-name buffer-file-truename t))
+ ('truncate-nil
+ (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename))
+ ('relative-to-project
+ (doom-modeline--buffer-file-name-relative buffer-file-name buffer-file-truename))
+ ('relative-from-project
+ (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename nil nil 'hide))
+ ('file-name
+ (propertize (file-name-nondirectory buffer-file-name)
+ 'face 'doom-modeline-buffer-file))
+ ((or 'buffer-name _)
+ (propertize "%b" 'face 'doom-modeline-buffer-file)))))
+ (propertize (if (string-empty-p file-name)
+ (propertize "%b" 'face 'doom-modeline-buffer-file)
+ file-name)
+ 'mouse-face 'mode-line-highlight
+ 'help-echo (concat buffer-file-truename
+ (unless (string= (file-name-nondirectory buffer-file-truename)
+ (buffer-name))
+ (concat "\n" (buffer-name)))
+ "\nmouse-1: Previous buffer\nmouse-3: Next buffer")
+ 'local-map mode-line-buffer-identification-keymap)))
+
+(defun doom-modeline--buffer-file-name-truncate (file-path true-file-path &optional truncate-tail)
+ "Propertized variable `buffer-file-name' that truncates every dir along path.
+If TRUNCATE-TAIL is t also truncate the parent directory of the file."
+ (let ((dirs (shrink-path-prompt (file-name-directory true-file-path))))
+ (if (null dirs)
+ (propertize "%b" 'face 'doom-modeline-buffer-file)
+ (let ((dirname (car dirs))
+ (basename (cdr dirs)))
+ (concat (propertize (concat dirname
+ (if truncate-tail (substring basename 0 1) basename)
+ "/")
+ 'face 'doom-modeline-project-root-dir)
+ (propertize (file-name-nondirectory file-path)
+ 'face 'doom-modeline-buffer-file))))))
+
+(defun doom-modeline--buffer-file-name-relative (_file-path true-file-path &optional include-project)
+ "Propertized variable `buffer-file-name' showing directories relative to
+project's root only."
+ (let ((root (file-local-name (doom-modeline-project-root))))
+ (if (null root)
+ (propertize "%b" 'face 'doom-modeline-buffer-file)
+ (let ((relative-dirs (file-relative-name (file-name-directory true-file-path)
+ (if include-project (concat root "../") root))))
+ (and (equal "./" relative-dirs) (setq relative-dirs ""))
+ (concat (propertize relative-dirs 'face 'doom-modeline-buffer-path)
+ (propertize (file-name-nondirectory true-file-path)
+ 'face 'doom-modeline-buffer-file))))))
+
+(defun doom-modeline--buffer-file-name (file-path
+ _true-file-path
+ &optional
+ truncate-project-root-parent
+ truncate-project-relative-path
+ hide-project-root-parent)
+ "Propertized variable `buffer-file-name' given by FILE-PATH.
+If TRUNCATE-PROJECT-ROOT-PARENT is non-nil will be saved by truncating project
+root parent down fish-shell style.
+
+Example:
+ ~/Projects/FOSS/emacs/lisp/comint.el => ~/P/F/emacs/lisp/comint.el
+
+If TRUNCATE-PROJECT-RELATIVE-PATH is non-nil will be saved by truncating project
+relative path down fish-shell style.
+
+Example:
+ ~/Projects/FOSS/emacs/lisp/comint.el => ~/Projects/FOSS/emacs/l/comint.el
+
+If HIDE-PROJECT-ROOT-PARENT is non-nil will hide project root parent.
+
+Example:
+ ~/Projects/FOSS/emacs/lisp/comint.el => emacs/lisp/comint.el"
+ (let ((project-root (file-local-name (doom-modeline-project-root))))
+ (concat
+ ;; Project root parent
+ (unless hide-project-root-parent
+ (when-let (root-path-parent
+ (file-name-directory (directory-file-name project-root)))
+ (propertize
+ (if (and truncate-project-root-parent
+ (not (string-empty-p root-path-parent))
+ (not (string= root-path-parent "/")))
+ (shrink-path--dirs-internal root-path-parent t)
+ (abbreviate-file-name root-path-parent))
+ 'face 'doom-modeline-project-parent-dir)))
+ ;; Project directory
+ (propertize
+ (concat (file-name-nondirectory (directory-file-name project-root)) "/")
+ 'face 'doom-modeline-project-dir)
+ ;; relative path
+ (propertize
+ (when-let (relative-path (file-relative-name
+ (or (file-name-directory file-path) "./")
+ project-root))
+ (if (string= relative-path "./")
+ ""
+ (if truncate-project-relative-path
+ (substring (shrink-path--dirs-internal relative-path t) 1)
+ relative-path)))
+ 'face 'doom-modeline-buffer-path)
+ ;; File name
+ (propertize (file-name-nondirectory file-path)
+ 'face 'doom-modeline-buffer-file))))
+
+(provide 'doom-modeline-core)
+
+;;; doom-modeline-core.el ends here
diff --git a/code/elpa/doom-modeline-20220412.853/doom-modeline-env.el b/code/elpa/doom-modeline-20220412.853/doom-modeline-env.el
new file mode 100644
index 0000000..87c8c50
--- /dev/null
+++ b/code/elpa/doom-modeline-20220412.853/doom-modeline-env.el
@@ -0,0 +1,275 @@
+;;; doom-modeline-env.el --- A environment parser for doom-modeline -*- lexical-binding: t -*-
+
+;; Copyright (C) 2019-2020 Justin Barclay, Vincent Zhang
+
+;; This file is not part of GNU Emacs.
+
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see .
+;;
+;;; Commentary:
+;;
+;; Parse programming environment.
+;;
+
+;;; Code:
+
+(require 'subr-x)
+(require 'doom-modeline-core)
+
+
+;; Externals
+(defvar python-shell-interpreter)
+
+
+;; Customizations
+
+(defgroup doom-modeline-env nil
+ "The environment parser for doom-modeline."
+ :group 'doom-modeline
+ :link '(url-link :tag "Homepage" "https://github.com/seagle0128/doom-modeline"))
+
+(defcustom doom-modeline-env-load-string "..."
+ "What to display as the version while a new one is being loaded."
+ :type 'string
+ :group 'doom-modeline-env)
+
+(defcustom doom-modeline-before-update-env-hook nil
+ "Hooks that run before the modeline version string is updated."
+ :type 'hook
+ :group 'doom-modeline-env)
+
+(defcustom doom-modeline-after-update-env-hook nil
+ "Hooks that run after the modeline version string is updated."
+ :type 'hook
+ :group 'doom-modeline-env)
+
+
+;; Variables
+
+;; Show version string for multi-version managers like rvm, rbenv, pyenv, etc.
+(defvar-local doom-modeline-env--version nil
+ "The version to display with major-mode in mode-line.
+Example: \"2.6.0\"")
+
+(defvar-local doom-modeline-env--command nil
+ "A program that we're looking to extract version information from.
+Example: \"ruby\"")
+
+(defvar-local doom-modeline-env--command-args nil
+ "A list of arguments for the command to extract the version from.
+Example: '(\"--version\") ")
+
+(defvar-local doom-modeline-env--parser nil
+ "A function that returns version number from a command --version (or similar).
+Example: 'doom-modeline-env--ruby")
+
+
+;; Functions & Macros
+
+(defun doom-modeline-update-env ()
+ "Update environment info on mode-line."
+ (when (and doom-modeline-env-version
+ doom-modeline-env--command
+ (executable-find doom-modeline-env--command)
+ doom-modeline-env--command-args
+ doom-modeline-env--parser)
+ (let ((default-directory (doom-modeline-project-root))
+ (buffer (current-buffer)))
+ (run-hooks 'doom-modeline-before-update-env-hook)
+ (setq doom-modeline-env--version doom-modeline-env-load-string)
+ (doom-modeline-env--get
+ doom-modeline-env--command
+ doom-modeline-env--command-args
+ (lambda (prog-version)
+ (with-current-buffer buffer
+ (setq doom-modeline-env--version
+ (funcall doom-modeline-env--parser prog-version))
+ (run-hooks 'doom-modeline-after-update-env-hook)))))))
+
+(add-hook 'find-file-hook #'doom-modeline-update-env)
+(with-no-warnings
+ (if (boundp 'after-focus-change-function)
+ (add-function
+ :after after-focus-change-function
+ (lambda ()
+ (if (frame-focus-state)
+ (doom-modeline-update-env))))
+ (add-hook 'focus-in-hook #'doom-modeline-update-env)))
+
+(defun doom-modeline-env--get (prog args callback)
+ "Start a sub process using PROG and apply the ARGS to the sub process.
+Once it receives information from STDOUT, it closes off the subprocess and
+passes on the information into the CALLBACK.
+Example:
+ (doom-modeline-env--get
+ \"ruby\"
+ '(\"--version\")
+ (lambda (line)
+ (message (doom-modeline-parser--ruby line)))"
+ (let ((proc (apply 'start-process
+ ;; Flaten process-args into a single list so we can handle
+ ;; variadic length args
+ (append
+ (list "doom-modeline-env" nil prog)
+ args)))
+ (parser callback))
+ (set-process-filter proc
+ (lambda (_proc line)
+ (ignore-errors
+ (funcall parser line))))))
+
+(cl-defmacro doom-modeline-def-env (name &key hooks command parser)
+ "Defines a handler for updating & displaying a version string for a language.
+
+NAME is an unquoted symbol representing the handler's unique ID.
+HOOKS is a list of hook symbols where this handler should be triggered.
+COMMAND should be a function that returns a shell command and its arguments (as
+ a list). It is run on HOOKS. It takes no arguments.
+PARSER should be a function for parsing COMMAND's output line-by-line, to
+ extract the version string."
+ (declare (indent defun))
+ (unless (and hooks command parser)
+ (error "'%s' env is missing either :hooks, :command or :parser" name))
+ (let ((parse-fn (intern (format "doom-modeline-env--%s-parse" name)))
+ (action-fn (intern (format "doom-modeline-env--%s-args" name)))
+ (setup-fn (intern (format "doom-modeline-env-setup-%s" name)))
+ (update-fn (intern (format "doom-modeline-env-update-%s" name)))
+ (enable-var (intern (format "doom-modeline-env-enable-%s" name)))
+ (command-var (intern (format "doom-modeline-env-%s-command" name)))
+ (parser-var (intern (format "doom-modeline-env-%s-parser-fn" name)))
+ (exe-var (intern (format "doom-modeline-env-%s-executable" name))))
+ (macroexp-progn
+ `((defcustom ,enable-var t
+ ,(format "Whether to display the version string for %s buffers." name)
+ :type 'boolean
+ :group 'doom-modeline-env)
+ (defvar ,command-var ',action-fn
+ ,(concat "A function that returns the shell command and arguments (as a list) to\n"
+ "produce a version string."))
+ (defvar ,parser-var ',parse-fn
+ ,(format "The function to parse each line of `%s'\'s output." command-var))
+ (defcustom ,exe-var nil
+ ,(format (concat "What executable to use for the version indicator in %s buffers.\n\n"
+ "If nil, the default binary for this language is used.")
+ name)
+ :type 'string
+ :group 'doom-modeline-env)
+ (defalias ',parse-fn ,parser
+ (format "The line parser for %s buffers.\n\nUsed by `%s'."
+ ',name ',update-fn))
+ (defalias ',action-fn ,command
+ (format "The command resolver for %s buffers.\n\nUsed by `%s'."
+ ',name ',update-fn))
+ (defalias ',setup-fn
+ (lambda ()
+ (if enable-local-variables
+ (add-hook 'hack-local-variables-hook #',update-fn nil t)
+ (,update-fn)))
+ (format "Prepares the modeline to later display the %s version string."
+ ',name))
+ (defalias ',update-fn
+ (lambda ()
+ (when ,enable-var
+ (when-let* ((command-list (funcall ,command-var))
+ (exe (executable-find (car command-list))))
+ (setq doom-modeline-env--command exe
+ doom-modeline-env--command-args (cdr command-list)
+ doom-modeline-env--parser ,parser-var)
+ (doom-modeline-update-env))))
+ (format "Updates the %s version string in the modeline." ',name))
+ (let ((hooks ',(eval hooks)))
+ (dolist (hook (if (listp hooks) hooks (list hooks)))
+ (add-hook hook #',setup-fn)))))))
+
+
+;; Bootstrap
+;; Versions, support Python, Ruby, Perl and Golang, etc.
+
+;;;###autoload (autoload 'doom-modeline-env-setup-python "doom-modeline-env")
+(doom-modeline-def-env python
+ :hooks 'python-mode-hook
+ :command (lambda () (cond ((and (fboundp 'pipenv-project-p)
+ (pipenv-project-p))
+ (list "pipenv" "run"
+ (or doom-modeline-env-python-executable
+ python-shell-interpreter
+ "python")
+ "--version"))
+ ((executable-find "pyenv") (list "pyenv" "version-name"))
+ ((list (or doom-modeline-env-python-executable
+ python-shell-interpreter
+ "python")
+ "--version"))))
+ :parser (lambda (line) (let ((version (split-string line)))
+ (if (>= (length version) 2)
+ (cadr version)
+ (car version)))))
+
+;;;###autoload (autoload 'doom-modeline-env-setup-ruby "doom-modeline-env")
+(doom-modeline-def-env ruby
+ :hooks '(ruby-mode-hook enh-ruby-mode-hook)
+ :command (lambda () (list (or doom-modeline-env-ruby-executable "ruby") "--version"))
+ :parser (lambda (line)
+ (car (split-string
+ (cadr
+ (split-string line))
+ "p"))))
+
+;;;###autoload (autoload 'doom-modeline-env-setup-perl "doom-modeline-env")
+(doom-modeline-def-env perl
+ :hooks 'perl-mode-hook
+ :command (lambda () (list (or doom-modeline-env-perl-executable "perl") "--version"))
+ :parser (lambda (line)
+ (cadr
+ (split-string
+ (car
+ (split-string
+ (cadr
+ (split-string line "("))
+ ")"))
+ "v"))))
+
+;;;###autoload (autoload 'doom-modeline-env-setup-go "doom-modeline-env")
+(doom-modeline-def-env go
+ :hooks 'go-mode-hook
+ :command (lambda () (list (or doom-modeline-env-go-executable "go") "version"))
+ :parser (lambda (line)
+ (cadr
+ (split-string
+ (cadr
+ (cdr
+ (split-string line)))
+ "go"))))
+
+;;;###autoload (autoload 'doom-modeline-env-setup-elixir "doom-modeline-env")
+(doom-modeline-def-env elixir
+ :hooks 'elixir-mode-hook
+ :command (lambda () (list (or doom-modeline-env-elixir-executable "elixir") "--version"))
+ :parser (lambda (line) (cadr (split-string line))))
+
+;;;###autoload (autoload 'doom-modeline-env-setup-rust "doom-modeline-env")
+(doom-modeline-def-env rust
+ :hooks 'rust-mode-hook
+ :command (lambda () (list (or doom-modeline-env-rust-executable "rustc") "--version"))
+ :parser (lambda (line)
+ (car
+ (split-string
+ (cadr
+ (split-string line))
+ "-"))))
+
+(provide 'doom-modeline-env)
+
+;;; doom-modeline-env.el ends here
diff --git a/code/elpa/doom-modeline-20220412.853/doom-modeline-pkg.el b/code/elpa/doom-modeline-20220412.853/doom-modeline-pkg.el
new file mode 100644
index 0000000..c289f03
--- /dev/null
+++ b/code/elpa/doom-modeline-20220412.853/doom-modeline-pkg.el
@@ -0,0 +1,15 @@
+(define-package "doom-modeline" "20220412.853" "A minimal and modern mode-line"
+ '((emacs "25.1")
+ (all-the-icons "2.2.0")
+ (shrink-path "0.2.0")
+ (dash "2.11.0"))
+ :commit "7d8eb7c44087a62d8dd6e8ba1afc26facd914fbc" :authors
+ '(("Vincent Zhang" . "seagle0128@gmail.com"))
+ :maintainer
+ '("Vincent Zhang" . "seagle0128@gmail.com")
+ :keywords
+ '("faces" "mode-line")
+ :url "https://github.com/seagle0128/doom-modeline")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/code/elpa/doom-modeline-20220412.853/doom-modeline-segments.el b/code/elpa/doom-modeline-20220412.853/doom-modeline-segments.el
new file mode 100644
index 0000000..d0970d1
--- /dev/null
+++ b/code/elpa/doom-modeline-20220412.853/doom-modeline-segments.el
@@ -0,0 +1,2969 @@
+;;; doom-modeline-segments.el --- The segments for doom-modeline -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2020 Vincent Zhang
+
+;; This file is not part of GNU Emacs.
+
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see .
+;;
+
+;;; Commentary:
+;;
+;; The segments for doom-modeline.
+;; Use `doom-modeline-def-segment' to create a new segment.
+;;
+
+;;; Code:
+
+(require 'all-the-icons)
+(require 'cl-lib)
+(require 'seq)
+(require 'subr-x)
+(require 'doom-modeline-core)
+(require 'doom-modeline-env)
+
+
+;;
+;; Externals
+;;
+
+(defvar Info-current-file)
+(defvar Info-current-node)
+(defvar Info-mode-line-node-keymap)
+(defvar anzu--cached-count)
+(defvar anzu--current-position)
+(defvar anzu--overflow-p)
+(defvar anzu--state)
+(defvar anzu--total-matched)
+(defvar anzu-cons-mode-line-p)
+(defvar aw-keys)
+(defvar battery-echo-area-format)
+(defvar battery-load-critical)
+(defvar battery-mode-line-format)
+(defvar battery-mode-line-limit)
+(defvar battery-status-function)
+(defvar boon-command-state)
+(defvar boon-insert-state)
+(defvar boon-off-state)
+(defvar boon-special-state)
+(defvar edebug-execution-mode)
+(defvar eglot--managed-mode)
+(defvar erc-modified-channels-alist)
+(defvar evil-ex-active-highlights-alist)
+(defvar evil-ex-argument)
+(defvar evil-ex-range)
+(defvar evil-mc-frozen)
+(defvar evil-state)
+(defvar evil-visual-beginning)
+(defvar evil-visual-end)
+(defvar evil-visual-selection)
+(defvar flycheck-current-errors)
+(defvar flycheck-mode-menu-map)
+(defvar flymake--mode-line-format)
+(defvar flymake--state)
+(defvar flymake-menu)
+(defvar gnus-newsrc-alist)
+(defvar gnus-newsrc-hashtb)
+(defvar grip--process)
+(defvar helm--mode-line-display-prefarg)
+(defvar iedit-occurrences-overlays)
+(defvar meow--indicator)
+(defvar minions-direct)
+(defvar minions-mode-line-lighter)
+(defvar minions-mode-line-minor-modes-map)
+(defvar mlscroll-minimum-current-width)
+(defvar mlscroll-right-align)
+(defvar mu4e-alert-mode-line)
+(defvar mu4e-alert-modeline-formatter)
+(defvar nyan-minimum-window-width)
+(defvar objed--obj-state)
+(defvar objed--object)
+(defvar objed-modeline-setup-func)
+(defvar persp-nil-name)
+(defvar phi-replace--mode-line-format)
+(defvar phi-search--selection)
+(defvar phi-search-mode-line-format)
+(defvar poke-line-minimum-window-width)
+(defvar rcirc-activity)
+(defvar sml-modeline-len)
+(defvar symbol-overlay-keywords-alist)
+(defvar symbol-overlay-temp-symbol)
+(defvar text-scale-mode-amount)
+(defvar tracking-buffers)
+(defvar winum-auto-setup-mode-line)
+(defvar xah-fly-insert-state-p)
+
+(declare-function anzu--reset-status "ext:anzu")
+(declare-function anzu--where-is-here "ext:anzu")
+(declare-function async-inject-variables "ext:async")
+(declare-function async-start "ext:async")
+(declare-function avy-traverse "ext:avy")
+(declare-function avy-tree "ext:avy")
+(declare-function aw-update "ext:ace-window")
+(declare-function aw-window-list "ext:ace-window")
+(declare-function battery-format "battery")
+(declare-function battery-update "battery")
+(declare-function boon-modeline-string "ext:boon")
+(declare-function boon-state-string "ext:boon")
+(declare-function cider--connection-info "ext:cider")
+(declare-function cider-connected-p "ext:cider")
+(declare-function cider-current-repl "ext:cider")
+(declare-function cider-jack-in "ext:cider")
+(declare-function cider-quit "ext:cider")
+(declare-function citre-mode "ext:citre-basic-tools")
+(declare-function dap--cur-session "ext:dap-mode")
+(declare-function dap--debug-session-name "ext:dap-mode")
+(declare-function dap--debug-session-state "ext:dap-mode")
+(declare-function dap--session-running "ext:dap-mode")
+(declare-function dap-debug-recent "ext:dap-mode")
+(declare-function dap-disconnect "ext:dap-mode")
+(declare-function dap-hydra "ext:dap-hydra")
+(declare-function edebug-help "edebug")
+(declare-function edebug-next-mode "edebug")
+(declare-function edebug-stop "edebug")
+(declare-function eglot "ext:eglot")
+(declare-function eglot--major-mode "ext:eglot" t t)
+(declare-function eglot--project-nickname "ext:eglot" t t)
+(declare-function eglot--spinner "ext:eglot" t t)
+(declare-function eglot-clear-status "ext:eglot")
+(declare-function eglot-current-server "ext:eglot")
+(declare-function eglot-events-buffer "ext:eglot")
+(declare-function eglot-forget-pending-continuations "ext:eglot")
+(declare-function eglot-managed-p "ext:glot")
+(declare-function eglot-reconnect "ext:eglot")
+(declare-function eglot-shutdown "ext:eglot")
+(declare-function eglot-stderr-buffer "ext:eglot")
+(declare-function erc-switch-to-buffer "erc")
+(declare-function erc-track-switch-buffer "erc-track")
+(declare-function evil-delimited-arguments "ext:evil-common")
+(declare-function evil-emacs-state-p "ext:evil-states" t t)
+(declare-function evil-force-normal-state "ext:evil-commands" t t)
+(declare-function evil-insert-state-p "ext:evil-states" t t)
+(declare-function evil-motion-state-p "ext:evil-states" t t)
+(declare-function evil-normal-state-p "ext:evil-states" t t)
+(declare-function evil-operator-state-p "ext:evil-states" t t)
+(declare-function evil-replace-state-p "ext:evil-states" t t)
+(declare-function evil-state-property "ext:evil-common")
+(declare-function evil-visual-state-p "ext:evil-states" t t)
+(declare-function eyebrowse--get "ext:eyebrowse")
+(declare-function face-remap-remove-relative "face-remap")
+(declare-function fancy-narrow-active-p "ext:fancy-narrow")
+(declare-function flycheck-buffer "ext:flycheck")
+(declare-function flycheck-count-errors "ext:flycheck")
+(declare-function flycheck-error-level-compilation-level "ext:flycheck")
+(declare-function flycheck-list-errors "ext:flycheck")
+(declare-function flycheck-next-error "ext:flycheck")
+(declare-function flycheck-previous-error "ext:flycheck")
+(declare-function flymake--diag-type "ext:flymake" t t)
+(declare-function flymake--handle-report "ext:flymake")
+(declare-function flymake--lookup-type-property "ext:flymake")
+(declare-function flymake--state-diags "ext:flymake" t t)
+(declare-function flymake-disabled-backends "ext:flymake")
+(declare-function flymake-goto-next-error "ext:flymake")
+(declare-function flymake-goto-prev-error "ext:flymake")
+(declare-function flymake-reporting-backends "ext:flymake")
+(declare-function flymake-running-backends "ext:flymake")
+(declare-function flymake-show-buffer-diagnostics "ext:flymake")
+(declare-function flymake-show-diagnostics-buffer "ext:flymake")
+(declare-function flymake-start "ext:flymake")
+(declare-function follow-all-followers "follow")
+(declare-function gnus-demon-add-handler "gnus-demon")
+(declare-function grip--preview-url "ext:grip-mode")
+(declare-function grip-browse-preview "ext:grip-mode")
+(declare-function grip-restart-preview "ext:grip-mode")
+(declare-function grip-stop-preview "ext:grip-mode")
+(declare-function helm-candidate-number-at-point "ext:helm-core")
+(declare-function helm-get-candidate-number "ext:helm-core")
+(declare-function iedit-find-current-occurrence-overlay "ext:iedit-lib")
+(declare-function iedit-prev-occurrence "ext:iedit-lib")
+(declare-function image-get-display-property "image-mode")
+(declare-function jsonrpc--request-continuations "ext:jsonrpc" t t)
+(declare-function jsonrpc-last-error "ext:jsonrpc" t t)
+(declare-function lsp--workspace-print "ext:lsp-mode")
+(declare-function lsp-describe-session "ext:lsp-mode")
+(declare-function lsp-workspace-folders-open "ext:lsp-mode")
+(declare-function lsp-workspace-restart "ext:lsp-mode")
+(declare-function lsp-workspace-shutdown "ext:lsp-mode")
+(declare-function lsp-workspaces "ext:lsp-mode")
+(declare-function lv-message "ext:lv")
+(declare-function mc/num-cursors "ext:multiple-cursors-core")
+(declare-function mlscroll-mode-line "ext:mlscroll")
+(declare-function mu4e-alert-default-mode-line-formatter "ext:mu4e-alert")
+(declare-function mu4e-alert-enable-mode-line-display "ext:mu4e-alert")
+(declare-function nyan-create "ext:nyan-mode")
+(declare-function org-edit-src-save "ext:org-src")
+(declare-function parrot-create "ext:parrot")
+(declare-function pdf-cache-number-of-pages "ext:pdf-cache" t t)
+(declare-function persp-add-buffer "ext:persp-mode")
+(declare-function persp-contain-buffer-p "ext:persp-mode")
+(declare-function persp-switch "ext:persp-mode")
+(declare-function phi-search--initialize "ext:phi-search")
+(declare-function poke-line-create "ext:poke-line")
+(declare-function popup-create "ext:popup")
+(declare-function popup-delete "ext:popup")
+(declare-function rcirc-next-active-buffer "rcirc")
+(declare-function rcirc-short-buffer-name "rcirc")
+(declare-function rcirc-switch-to-server-buffer "rcirc")
+(declare-function rcirc-window-configuration-change "rcirc")
+(declare-function rime--should-enable-p "ext:rime")
+(declare-function rime--should-inline-ascii-p "ext:rime")
+(declare-function sml-modeline-create "ext:sml-modeline")
+(declare-function symbol-overlay-assoc "ext:symbol-overlay")
+(declare-function symbol-overlay-get-list "ext:symbol-overlay")
+(declare-function symbol-overlay-get-symbol "ext:symbol-overlay")
+(declare-function symbol-overlay-rename "ext:symbol-overlay")
+(declare-function tab-bar--current-tab "tab-bar")
+(declare-function tab-bar--current-tab-index "tab-bar")
+(declare-function tracking-next-buffer "ext:tracking")
+(declare-function tracking-previous-buffer "ext:tracking")
+(declare-function tracking-shorten "ext:tracking")
+(declare-function undo-tree-redo-1 "ext:undo-tree")
+(declare-function undo-tree-undo-1 "ext:undo-tree")
+(declare-function warning-numeric-level "warnings")
+(declare-function window-numbering-clear-mode-line "ext:window-numbering")
+(declare-function window-numbering-get-number-string "ext:window-numbering")
+(declare-function window-numbering-install-mode-line "ext:window-numbering")
+(declare-function winum--clear-mode-line "ext:winum")
+(declare-function winum--install-mode-line "ext:winum")
+(declare-function winum-get-number-string "ext:winum")
+
+
+
+;;
+;; Buffer information
+;;
+
+(defvar-local doom-modeline--buffer-file-icon nil)
+(defun doom-modeline-update-buffer-file-icon (&rest _)
+ "Update file icon in mode-line."
+ (setq doom-modeline--buffer-file-icon
+ (when (and (display-graphic-p)
+ doom-modeline-icon
+ doom-modeline-major-mode-icon)
+ (let ((icon (all-the-icons-icon-for-buffer)))
+ (propertize (if (or (null icon) (symbolp icon))
+ (doom-modeline-icon 'faicon "file-o" nil nil
+ :face 'all-the-icons-dsilver
+ :height 0.9
+ :v-adjust 0.0)
+ icon)
+ 'help-echo (format "Major-mode: %s" (format-mode-line mode-name))
+ 'display '(raise -0.135))))))
+(add-hook 'find-file-hook #'doom-modeline-update-buffer-file-icon)
+(add-hook 'after-change-major-mode-hook #'doom-modeline-update-buffer-file-icon)
+(add-hook 'clone-indirect-buffer-hook #'doom-modeline-update-buffer-file-icon)
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-icon
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-icon val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (doom-modeline-update-buffer-file-icon))))))
+
+(defun doom-modeline-buffer-file-state-icon (icon unicode text face)
+ "Displays an ICON of buffer state with FACE.
+UNICODE and TEXT are the alternatives if it is not applicable.
+Uses `all-the-icons-material' to fetch the icon."
+ (doom-modeline-icon 'material icon unicode text
+ :face face
+ :height 1.1
+ :v-adjust -0.225))
+
+(defvar-local doom-modeline--buffer-file-state-icon nil)
+(defun doom-modeline-update-buffer-file-state-icon (&rest _)
+ "Update the buffer or file state in mode-line."
+ (setq doom-modeline--buffer-file-state-icon
+ (when doom-modeline-buffer-state-icon
+ (ignore-errors
+ (concat
+ (cond (buffer-read-only
+ (doom-modeline-buffer-file-state-icon
+ "lock" "π" "%1*" `(:inherit doom-modeline-warning
+ :weight ,(if doom-modeline-icon
+ 'normal
+ 'bold))))
+ ((and buffer-file-name (buffer-modified-p)
+ doom-modeline-buffer-modification-icon)
+ (doom-modeline-buffer-file-state-icon
+ "save" "πΎ" "%1*" `(:inherit doom-modeline-buffer-modified
+ :weight ,(if doom-modeline-icon
+ 'normal
+ 'bold))))
+ ((and buffer-file-name
+ (not (file-remote-p buffer-file-name)) ; Avoid freezing while connection is lost
+ (not (file-exists-p buffer-file-name)))
+ (doom-modeline-buffer-file-state-icon
+ "do_not_disturb_alt" "π«" "!" 'doom-modeline-urgent))
+ (t ""))
+ (when (or (buffer-narrowed-p)
+ (and (bound-and-true-p fancy-narrow-mode)
+ (fancy-narrow-active-p))
+ (bound-and-true-p dired-narrow-mode))
+ (doom-modeline-buffer-file-state-icon
+ "vertical_align_center" "β" "><" 'doom-modeline-warning)))))))
+
+(defvar-local doom-modeline--buffer-file-name nil)
+(defun doom-modeline-update-buffer-file-name (&rest _)
+ "Update buffer file name in mode-line."
+ (setq doom-modeline--buffer-file-name
+ (ignore-errors
+ (save-match-data
+ (if buffer-file-name
+ (doom-modeline-buffer-file-name)
+ (propertize "%b"
+ 'face 'doom-modeline-buffer-file
+ 'mouse-face 'mode-line-highlight
+ 'help-echo "Buffer name
+mouse-1: Previous buffer\nmouse-3: Next buffer"
+ 'local-map mode-line-buffer-identification-keymap))))))
+(add-hook 'find-file-hook #'doom-modeline-update-buffer-file-name)
+(add-hook 'after-save-hook #'doom-modeline-update-buffer-file-name)
+(add-hook 'clone-indirect-buffer-hook #'doom-modeline-update-buffer-file-name)
+(add-hook 'evil-insert-state-exit-hook #'doom-modeline-update-buffer-file-name)
+(advice-add #'not-modified :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'rename-buffer :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'set-visited-file-name :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'pop-to-buffer :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'undo :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'undo-tree-undo-1 :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'undo-tree-redo-1 :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'fill-paragraph :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'popup-create :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'popup-delete :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'org-edit-src-save :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'symbol-overlay-rename :after #'doom-modeline-update-buffer-file-name)
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-buffer-file-name-style
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-buffer-file-name-style val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when buffer-file-name
+ (doom-modeline-update-buffer-file-name)))))))
+
+(defsubst doom-modeline--buffer-mode-icon ()
+ "The icon of the current major mode."
+ (when (and doom-modeline-icon doom-modeline-major-mode-icon)
+ (when-let ((icon (or doom-modeline--buffer-file-icon
+ (doom-modeline-update-buffer-file-icon))))
+ (concat
+ (let ((active (doom-modeline--active)))
+ (if (and active doom-modeline-major-mode-color-icon)
+ icon
+ (doom-modeline-propertize-icon icon (if active
+ 'mode-line
+ 'mode-line-inactive))))
+ (doom-modeline-vspc)))))
+
+(defsubst doom-modeline--buffer-state-icon ()
+ "The icon of the current buffer state."
+ (when doom-modeline-buffer-state-icon
+ (when-let ((icon (doom-modeline-update-buffer-file-state-icon)))
+ (concat
+ (if (doom-modeline--active)
+ icon
+ (doom-modeline-propertize-icon icon 'mode-line-inactive))
+ (doom-modeline-vspc)))))
+
+(defsubst doom-modeline--buffer-name ()
+ "The current buffer name."
+ (when doom-modeline-buffer-name
+ (if (and (not (eq doom-modeline-buffer-file-name-style 'file-name))
+ doom-modeline--limited-width-p)
+ ;; Only display the buffer name if the window is small, and doesn't need to
+ ;; respect file-name style.
+ (propertize "%b"
+ 'face (cond ((and buffer-file-name (buffer-modified-p))
+ 'doom-modeline-buffer-modified)
+ ((doom-modeline--active) 'doom-modeline-buffer-file)
+ (t 'mode-line-inactive))
+ 'mouse-face 'mode-line-highlight
+ 'help-echo "Buffer name
+mouse-1: Previous buffer\nmouse-3: Next buffer"
+ 'local-map mode-line-buffer-identification-keymap)
+ (when-let ((name (or doom-modeline--buffer-file-name
+ (doom-modeline-update-buffer-file-name))))
+ (if (doom-modeline--active)
+ ;; Check if the buffer is modified
+ (if (and buffer-file-name (buffer-modified-p))
+ (propertize name 'face 'doom-modeline-buffer-modified)
+ name)
+ (propertize name 'face 'mode-line-inactive))))))
+
+(doom-modeline-def-segment buffer-info
+ "Combined information about the current buffer, including the current working
+directory, the file name, and its state (modified, read-only or non-existent)."
+ (concat
+ (doom-modeline-spc)
+ (doom-modeline--buffer-mode-icon)
+ (doom-modeline--buffer-state-icon)
+ (doom-modeline--buffer-name)))
+
+(doom-modeline-def-segment buffer-info-simple
+ "Display only the current buffer's name, but with fontification."
+ (concat
+ (doom-modeline-spc)
+ (doom-modeline--buffer-mode-icon)
+ (doom-modeline--buffer-state-icon)
+ (propertize "%b"
+ 'face (cond ((and buffer-file-name (buffer-modified-p))
+ 'doom-modeline-buffer-modified)
+ ((doom-modeline--active) 'doom-modeline-buffer-file)
+ (t 'mode-line-inactive))
+ 'mouse-face 'mode-line-highlight
+ 'help-echo "Buffer name
+mouse-1: Previous buffer\nmouse-3: Next buffer"
+ 'local-map mode-line-buffer-identification-keymap)))
+
+(doom-modeline-def-segment buffer-default-directory
+ "Displays `default-directory' with the icon and state . This is for special
+buffers like the scratch buffer where knowing the current project directory is
+important."
+ (let ((face (cond ((buffer-modified-p)
+ 'doom-modeline-buffer-modified)
+ ((doom-modeline--active) 'doom-modeline-buffer-path)
+ (t 'mode-line-inactive))))
+ (concat (doom-modeline-spc)
+ (and doom-modeline-major-mode-icon
+ (concat (doom-modeline-icon
+ 'octicon "file-directory" "πΏ" ""
+ :face face :v-adjust -0.05 :height 1.25)
+ (doom-modeline-vspc)))
+ (doom-modeline--buffer-state-icon)
+ (propertize (abbreviate-file-name default-directory) 'face face))))
+
+(doom-modeline-def-segment buffer-default-directory-simple
+ "Displays `default-directory'. This is for special buffers like the scratch
+buffer where knowing the current project directory is important."
+ (let ((face (if (doom-modeline--active) 'doom-modeline-buffer-path 'mode-line-inactive)))
+ (concat (doom-modeline-spc)
+ (and doom-modeline-major-mode-icon
+ (concat (doom-modeline-icon
+ 'octicon "file-directory" "πΏ" ""
+ :face face :v-adjust -0.05 :height 1.25)
+ (doom-modeline-vspc)))
+ (propertize (abbreviate-file-name default-directory) 'face face))))
+
+
+;;
+;; Encoding
+;;
+
+(doom-modeline-def-segment buffer-encoding
+ "Displays the eol and the encoding style of the buffer the same way Atom does."
+ (when doom-modeline-buffer-encoding
+ (let ((face (if (doom-modeline--active) 'mode-line 'mode-line-inactive))
+ (mouse-face 'mode-line-highlight))
+ (concat
+ (doom-modeline-spc)
+
+ ;; eol type
+ (let ((eol (coding-system-eol-type buffer-file-coding-system)))
+ (when (or (eq doom-modeline-buffer-encoding t)
+ (and (eq doom-modeline-buffer-encoding 'nondefault)
+ (not (equal eol doom-modeline-default-eol-type))))
+ (propertize
+ (pcase eol
+ (0 "LF ")
+ (1 "CRLF ")
+ (2 "CR ")
+ (_ ""))
+ 'face face
+ 'mouse-face mouse-face
+ 'help-echo (format "End-of-line style: %s\nmouse-1: Cycle"
+ (pcase eol
+ (0 "Unix-style LF")
+ (1 "DOS-style CRLF")
+ (2 "Mac-style CR")
+ (_ "Undecided")))
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1] 'mode-line-change-eol)
+ map))))
+
+ ;; coding system
+ (let* ((sys (coding-system-plist buffer-file-coding-system))
+ (cat (plist-get sys :category))
+ (sym (if (memq cat
+ '(coding-category-undecided coding-category-utf-8))
+ 'utf-8
+ (plist-get sys :name))))
+ (when (or (eq doom-modeline-buffer-encoding t)
+ (and (eq doom-modeline-buffer-encoding 'nondefault)
+ (not (eq cat 'coding-category-undecided))
+ (not (eq sym doom-modeline-default-coding-system))))
+ (propertize
+ (upcase (symbol-name sym))
+ 'face face
+ 'mouse-face mouse-face
+ 'help-echo 'mode-line-mule-info-help-echo
+ 'local-map mode-line-coding-system-map)))
+
+ (doom-modeline-spc)))))
+
+
+;;
+;; Indentation
+;;
+
+(doom-modeline-def-segment indent-info
+ "Displays the indentation information."
+ (when doom-modeline-indent-info
+ (let ((do-propertize
+ (lambda (mode size)
+ (propertize
+ (format " %s %d " mode size)
+ 'face (if (doom-modeline--active) 'mode-line 'mode-line-inactive)))))
+ (if indent-tabs-mode
+ (funcall do-propertize "TAB" tab-width)
+ (let ((lookup-var
+ (seq-find (lambda (var)
+ (and var (boundp var) (symbol-value var)))
+ (cdr (assoc major-mode doom-modeline-indent-alist)) nil)))
+ (funcall do-propertize "SPC"
+ (if lookup-var
+ (symbol-value lookup-var)
+ tab-width)))))))
+
+;;
+;; Remote host
+;;
+
+(doom-modeline-def-segment remote-host
+ "Hostname for remote buffers."
+ (when default-directory
+ (when-let ((host (file-remote-p default-directory 'host)))
+ (propertize
+ (concat "@" host)
+ 'face (if (doom-modeline--active) 'doom-modeline-host 'mode-line-inactive)))))
+
+
+;;
+;; Major mode
+;;
+
+(doom-modeline-def-segment major-mode
+ "The major mode, including environment and text-scale info."
+ (propertize
+ (concat
+ (doom-modeline-spc)
+ (propertize (format-mode-line
+ (or (and (boundp 'delighted-modes)
+ (cadr (assq major-mode delighted-modes)))
+ mode-name))
+ 'help-echo "Major mode\n\
+ mouse-1: Display major mode menu\n\
+ mouse-2: Show help for major mode\n\
+ mouse-3: Toggle minor modes"
+ 'mouse-face 'mode-line-highlight
+ 'local-map mode-line-major-mode-keymap)
+ (when (and doom-modeline-env-version doom-modeline-env--version)
+ (format " %s" doom-modeline-env--version))
+ (and (boundp 'text-scale-mode-amount)
+ (/= text-scale-mode-amount 0)
+ (format
+ (if (> text-scale-mode-amount 0)
+ " (%+d)"
+ " (%-d)")
+ text-scale-mode-amount))
+ (doom-modeline-spc))
+ 'face (if (doom-modeline--active)
+ 'doom-modeline-buffer-major-mode
+ 'mode-line-inactive)))
+
+
+;;
+;; Process
+;;
+
+(doom-modeline-def-segment process
+ "The process info."
+ (if (doom-modeline--active)
+ mode-line-process
+ (propertize (format-mode-line mode-line-process)
+ 'face 'mode-line-inactive)))
+
+
+;;
+;; Minor modes
+;;
+
+(doom-modeline-def-segment minor-modes
+ (when doom-modeline-minor-modes
+ (let ((face (if (doom-modeline--active)
+ 'doom-modeline-buffer-minor-mode
+ 'mode-line-inactive))
+ (mouse-face 'mode-line-highlight)
+ (help-echo "Minor mode
+ mouse-1: Display minor mode menu
+ mouse-2: Show help for minor mode
+ mouse-3: Toggle minor modes"))
+ (if (bound-and-true-p minions-mode)
+ `((:propertize ("" ,(--filter (memq (car it) minions-direct)
+ minor-mode-alist))
+ face ,face
+ mouse-face ,mouse-face
+ help-echo ,help-echo
+ local-map ,mode-line-minor-mode-keymap)
+ ,(doom-modeline-spc)
+ (:propertize ("" ,(doom-modeline-icon 'octicon "gear" "β"
+ minions-mode-line-lighter
+ :face face :v-adjust -0.05))
+ mouse-face ,mouse-face
+ help-echo "Minions
+mouse-1: Display minor modes menu"
+ local-map ,minions-mode-line-minor-modes-map)
+ ,(doom-modeline-spc))
+ `((:propertize ("" minor-mode-alist)
+ face ,face
+ mouse-face ,mouse-face
+ help-echo ,help-echo
+ local-map ,mode-line-minor-mode-keymap)
+ ,(doom-modeline-spc))))))
+
+
+;;
+;; VCS
+;;
+
+(defun doom-modeline-vcs-icon (icon &optional unicode text face voffset)
+ "Displays the vcs ICON with FACE and VOFFSET.
+
+UNICODE and TEXT are fallbacks.
+Uses `all-the-icons-octicon' to fetch the icon."
+ (doom-modeline-icon 'octicon icon unicode text
+ :face face :v-adjust (or voffset -0.1)))
+
+(defvar-local doom-modeline--vcs-icon nil)
+(defun doom-modeline-update-vcs-icon (&rest _)
+ "Update icon of vcs state in mode-line."
+ (setq doom-modeline--vcs-icon
+ (when (and vc-mode buffer-file-name)
+ (let* ((backend (vc-backend buffer-file-name))
+ (state (vc-state (file-local-name buffer-file-name) backend)))
+ (cond ((memq state '(edited added))
+ (doom-modeline-vcs-icon "git-compare" "β" "*" 'doom-modeline-info -0.05))
+ ((eq state 'needs-merge)
+ (doom-modeline-vcs-icon "git-merge" "β" "?" 'doom-modeline-info))
+ ((eq state 'needs-update)
+ (doom-modeline-vcs-icon "arrow-down" "β" "!" 'doom-modeline-warning))
+ ((memq state '(removed conflict unregistered))
+ (doom-modeline-vcs-icon "alert" "β " "!" 'doom-modeline-urgent))
+ (t
+ (doom-modeline-vcs-icon "git-branch" "ξ " "@" 'doom-modeline-info -0.05)))))))
+(add-hook 'find-file-hook #'doom-modeline-update-vcs-icon)
+(add-hook 'after-save-hook #'doom-modeline-update-vcs-icon)
+(advice-add #'vc-refresh-state :after #'doom-modeline-update-vcs-icon)
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-icon
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-icon val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (doom-modeline-update-vcs-icon))))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-unicode-fallback
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-unicode-fallback val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (doom-modeline-update-vcs-icon))))))
+
+(defvar-local doom-modeline--vcs-text nil)
+(defun doom-modeline-update-vcs-text (&rest _)
+ "Update text of vcs state in mode-line."
+ (setq doom-modeline--vcs-text
+ (when (and vc-mode buffer-file-name)
+ (let* ((backend (vc-backend buffer-file-name))
+ (state (vc-state (file-local-name buffer-file-name) backend))
+ (str (if vc-display-status
+ (substring vc-mode (+ (if (eq backend 'Hg) 2 3) 2))
+ "")))
+ (propertize (if (> (length str) doom-modeline-vcs-max-length)
+ (concat
+ (substring str 0 (- doom-modeline-vcs-max-length 3))
+ "...")
+ str)
+ 'mouse-face 'mode-line-highlight
+ 'face (cond ((eq state 'needs-update)
+ 'doom-modeline-warning)
+ ((memq state '(removed conflict unregistered))
+ 'doom-modeline-urgent)
+ (t 'doom-modeline-info)))))))
+(add-hook 'find-file-hook #'doom-modeline-update-vcs-text)
+(add-hook 'after-save-hook #'doom-modeline-update-vcs-text)
+(advice-add #'vc-refresh-state :after #'doom-modeline-update-vcs-text)
+
+(doom-modeline-def-segment vcs
+ "Displays the current branch, colored based on its state."
+ (let ((active (doom-modeline--active)))
+ (when-let ((icon doom-modeline--vcs-icon)
+ (text doom-modeline--vcs-text))
+ (concat
+ (doom-modeline-spc)
+ (propertize
+ (concat
+ (if active
+ icon
+ (doom-modeline-propertize-icon icon 'mode-line-inactive))
+ (doom-modeline-vspc))
+ 'mouse-face 'mode-line-highlight
+ 'help-echo (get-text-property 1 'help-echo vc-mode)
+ 'local-map (get-text-property 1 'local-map vc-mode))
+ (if active
+ text
+ (propertize text 'face 'mode-line-inactive))
+ (doom-modeline-spc)))))
+
+
+;;
+;; Checker
+;;
+
+(defun doom-modeline-checker-icon (icon unicode text face)
+ "Displays the checker ICON with FACE.
+
+UNICODE and TEXT are fallbacks.
+Uses `all-the-icons-material' to fetch the icon."
+ (doom-modeline-icon 'material icon unicode text
+ :face face :height 1.1 :v-adjust -0.225))
+
+(defun doom-modeline-checker-text (text &optional face)
+ "Displays TEXT with FACE."
+ (propertize text 'face (or face 'mode-line)))
+
+;; Flycheck
+
+(defun doom-modeline--flycheck-count-errors ()
+ "Count the number of ERRORS, grouped by level.
+
+Return an alist, where each ITEM is a cons cell whose `car' is an
+error level, and whose `cdr' is the number of errors of that
+level."
+ (let ((info 0) (warning 0) (error 0))
+ (mapc
+ (lambda (item)
+ (let ((count (cdr item)))
+ (pcase (flycheck-error-level-compilation-level (car item))
+ (0 (cl-incf info count))
+ (1 (cl-incf warning count))
+ (2 (cl-incf error count)))))
+ (flycheck-count-errors flycheck-current-errors))
+ `((info . ,info) (warning . ,warning) (error . ,error))))
+
+(defvar-local doom-modeline--flycheck-icon nil)
+(defun doom-modeline-update-flycheck-icon (&optional status)
+ "Update flycheck icon via STATUS."
+ (setq doom-modeline--flycheck-icon
+ (when-let
+ ((icon
+ (pcase status
+ ('finished (if flycheck-current-errors
+ (let-alist (doom-modeline--flycheck-count-errors)
+ (doom-modeline-checker-icon
+ "block" "π«" "!"
+ (cond ((> .error 0) 'doom-modeline-urgent)
+ ((> .warning 0) 'doom-modeline-warning)
+ (t 'doom-modeline-info))))
+ (doom-modeline-checker-icon "check" "β" "-" 'doom-modeline-info)))
+ ('running (doom-modeline-checker-icon "access_time" "β±" "*" 'doom-modeline-debug))
+ ('no-checker (doom-modeline-checker-icon "sim_card_alert" "β " "-" 'doom-modeline-debug))
+ ('errored (doom-modeline-checker-icon "sim_card_alert" "β " "-" 'doom-modeline-urgent))
+ ('interrupted (doom-modeline-checker-icon "pause" "βΈ" "=" 'doom-modeline-debug))
+ ('suspicious (doom-modeline-checker-icon "priority_high" "β" "!" 'doom-modeline-urgent))
+ (_ nil))))
+ (propertize icon
+ 'help-echo (concat "Flycheck\n"
+ (pcase status
+ ('finished "mouse-1: Display minor mode menu
+mouse-2: Show help for minor mode")
+ ('running "Running...")
+ ('no-checker "No Checker")
+ ('errored "Error")
+ ('interrupted "Interrupted")
+ ('suspicious "Suspicious")))
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line down-mouse-1]
+ flycheck-mode-menu-map)
+ (define-key map [mode-line mouse-2]
+ (lambda ()
+ (interactive)
+ (describe-function 'flycheck-mode)))
+ map)))))
+(add-hook 'flycheck-status-changed-functions #'doom-modeline-update-flycheck-icon)
+(add-hook 'flycheck-mode-hook #'doom-modeline-update-flycheck-icon)
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-icon
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-icon val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when (bound-and-true-p flycheck-mode)
+ (flycheck-buffer)))))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-unicode-fallback
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-unicode-fallback val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when (bound-and-true-p flycheck-mode)
+ (flycheck-buffer)))))))
+
+(defvar-local doom-modeline--flycheck-text nil)
+(defun doom-modeline-update-flycheck-text (&optional status)
+ "Update flycheck text via STATUS."
+ (setq doom-modeline--flycheck-text
+ (when-let
+ ((text
+ (pcase status
+ ('finished (when flycheck-current-errors
+ (let-alist (doom-modeline--flycheck-count-errors)
+ (if doom-modeline-checker-simple-format
+ (doom-modeline-checker-text
+ (number-to-string (+ .error .warning .info))
+ (cond ((> .error 0) 'doom-modeline-urgent)
+ ((> .warning 0) 'doom-modeline-warning)
+ (t 'doom-modeline-info)))
+ (format "%s/%s/%s"
+ (doom-modeline-checker-text (number-to-string .error)
+ 'doom-modeline-urgent)
+ (doom-modeline-checker-text (number-to-string .warning)
+ 'doom-modeline-warning)
+ (doom-modeline-checker-text (number-to-string .info)
+ 'doom-modeline-info))))))
+ ('running nil)
+ ('no-checker nil)
+ ('errored (doom-modeline-checker-text "Error" 'doom-modeline-urgent))
+ ('interrupted (doom-modeline-checker-text "Interrupted" 'doom-modeline-debug))
+ ('suspicious (doom-modeline-checker-text "Suspicious" 'doom-modeline-urgent))
+ (_ nil))))
+ (propertize
+ text
+ 'help-echo (pcase status
+ ('finished
+ (concat
+ (when flycheck-current-errors
+ (let-alist (doom-modeline--flycheck-count-errors)
+ (format "error: %d, warning: %d, info: %d\n" .error .warning .info)))
+ "mouse-1: Show all errors
+mouse-3: Next error"
+ (if (featurep 'mwheel)
+ "\nwheel-up/wheel-down: Previous/next error")))
+ ('running "Running...")
+ ('no-checker "No Checker")
+ ('errored "Error")
+ ('interrupted "Interrupted")
+ ('suspicious "Suspicious"))
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1]
+ #'flycheck-list-errors)
+ (define-key map [mode-line mouse-3]
+ #'flycheck-next-error)
+ (when (featurep 'mwheel)
+ (define-key map [mode-line mouse-wheel-down-event]
+ (lambda (event)
+ (interactive "e")
+ (with-selected-window (posn-window (event-start event))
+ (flycheck-previous-error 1))))
+ (define-key map [mode-line mouse-wheel-up-event]
+ (lambda (event)
+ (interactive "e")
+ (with-selected-window (posn-window (event-start event))
+ (flycheck-next-error 1))))
+ map))))))
+(add-hook 'flycheck-status-changed-functions #'doom-modeline-update-flycheck-text)
+(add-hook 'flycheck-mode-hook #'doom-modeline-update-flycheck-text)
+
+;; Flymake
+
+;; Compatibility
+;; @see https://github.com/emacs-mirror/emacs/commit/6e100869012da9244679696634cab6b9cac96303.
+(with-eval-after-load 'flymake
+ (unless (boundp 'flymake--state)
+ (defvaralias 'flymake--state 'flymake--backend-state))
+ (unless (fboundp 'flymake--state-diags)
+ (defalias 'flymake--state-diags 'flymake--backend-state-diags)))
+
+(defvar-local doom-modeline--flymake-icon nil)
+(defun doom-modeline-update-flymake-icon (&rest _)
+ "Update flymake icon."
+ (setq flymake--mode-line-format nil) ; remove the lighter of minor mode
+ (setq doom-modeline--flymake-icon
+ (let* ((known (hash-table-keys flymake--state))
+ (running (flymake-running-backends))
+ (disabled (flymake-disabled-backends))
+ (reported (flymake-reporting-backends))
+ (all-disabled (and disabled (null running)))
+ (some-waiting (cl-set-difference running reported)))
+ (when-let
+ ((icon
+ (cond
+ (some-waiting (doom-modeline-checker-icon "access_time" "β°" "*" 'doom-modeline-debug))
+ ((null known) (doom-modeline-checker-icon "sim_card_alert" "β" "?" 'doom-modeline-debug))
+ (all-disabled (doom-modeline-checker-icon "sim_card_alert" "β" "!" 'doom-modeline-urgent))
+ (t (let ((.error 0)
+ (.warning 0)
+ (.note 0))
+ (progn
+ (cl-loop
+ with warning-level = (warning-numeric-level :warning)
+ with note-level = (warning-numeric-level :debug)
+ for state being the hash-values of flymake--state
+ do (cl-loop
+ with diags = (flymake--state-diags state)
+ for diag in diags do
+ (let ((severity (flymake--lookup-type-property (flymake--diag-type diag) 'severity
+ (warning-numeric-level :error))))
+ (cond ((> severity warning-level) (cl-incf .error))
+ ((> severity note-level) (cl-incf .warning))
+ (t (cl-incf .note))))))
+ (if (> (+ .error .warning .note) 0)
+ (doom-modeline-checker-icon "do_not_disturb_alt" "π«" "!"
+ (cond ((> .error 0) 'doom-modeline-urgent)
+ ((> .warning 0) 'doom-modeline-warning)
+ (t 'doom-modeline-info)))
+ (doom-modeline-checker-icon "check" "β" "-" 'doom-modeline-info))))))))
+ (propertize
+ icon
+ 'help-echo (concat "Flymake\n"
+ (cond
+ (some-waiting "Running...")
+ ((null known) "No Checker")
+ (all-disabled "All Checkers Disabled")
+ (t (format "%d/%d backends running
+mouse-1: Display minor mode menu
+mouse-2: Show help for minor mode"
+ (length running) (length known)))))
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line down-mouse-1]
+ flymake-menu)
+ (define-key map [mode-line mouse-2]
+ (lambda ()
+ (interactive)
+ (describe-function 'flymake-mode)))
+ map))))))
+(advice-add #'flymake--handle-report :after #'doom-modeline-update-flymake-icon)
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-icon
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-icon val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when (bound-and-true-p flymake-mode)
+ (flymake-start)))))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-unicode-fallback
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-unicode-fallback val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when (bound-and-true-p flymake-mode)
+ (flymake-start)))))))
+
+(defvar-local doom-modeline--flymake-text nil)
+(defun doom-modeline-update-flymake-text (&rest _)
+ "Update flymake text."
+ (setq flymake--mode-line-format nil) ; remove the lighter of minor mode
+ (setq doom-modeline--flymake-text
+ (let* ((known (hash-table-keys flymake--state))
+ (running (flymake-running-backends))
+ (disabled (flymake-disabled-backends))
+ (reported (flymake-reporting-backends))
+ (all-disabled (and disabled (null running)))
+ (some-waiting (cl-set-difference running reported))
+ (warning-level (warning-numeric-level :warning))
+ (note-level (warning-numeric-level :debug))
+ (.error 0)
+ (.warning 0)
+ (.note 0))
+ (maphash (lambda (_b state)
+ (cl-loop
+ with diags = (flymake--state-diags state)
+ for diag in diags do
+ (let ((severity (flymake--lookup-type-property (flymake--diag-type diag) 'severity
+ (warning-numeric-level :error))))
+ (cond ((> severity warning-level) (cl-incf .error))
+ ((> severity note-level) (cl-incf .warning))
+ (t (cl-incf .note))))))
+ flymake--state)
+ (when-let
+ ((text
+ (cond
+ (some-waiting doom-modeline--flymake-text)
+ ((null known) nil)
+ (all-disabled nil)
+ (t (let ((num (+ .error .warning .note)))
+ (when (> num 0)
+ (if doom-modeline-checker-simple-format
+ (doom-modeline-checker-text (number-to-string num)
+ (cond ((> .error 0) 'doom-modeline-urgent)
+ ((> .warning 0) 'doom-modeline-warning)
+ (t 'doom-modeline-info)))
+ (format "%s/%s/%s"
+ (doom-modeline-checker-text (number-to-string .error)
+ 'doom-modeline-urgent)
+ (doom-modeline-checker-text (number-to-string .warning)
+ 'doom-modeline-warning)
+ (doom-modeline-checker-text (number-to-string .note)
+ 'doom-modeline-info)))))))))
+ (propertize
+ text
+ 'help-echo (cond
+ (some-waiting "Running...")
+ ((null known) "No Checker")
+ (all-disabled "All Checkers Disabled")
+ (t (format "error: %d, warning: %d, note: %d
+mouse-1: List all problems%s"
+ .error .warning .note
+ (if (featurep 'mwheel)
+ "\nwheel-up/wheel-down: Previous/next problem"))))
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1]
+ #'flymake-show-diagnostics-buffer)
+ (when (featurep 'mwheel)
+ (define-key map (vector 'mode-line
+ mouse-wheel-down-event)
+ (lambda (event)
+ (interactive "e")
+ (with-selected-window (posn-window (event-start event))
+ (flymake-goto-prev-error 1 nil t))))
+ (define-key map (vector 'mode-line
+ mouse-wheel-up-event)
+ (lambda (event)
+ (interactive "e")
+ (with-selected-window (posn-window (event-start event))
+ (flymake-goto-next-error 1 nil t))))
+ map)))))))
+(advice-add #'flymake--handle-report :after #'doom-modeline-update-flymake-text)
+
+(doom-modeline-def-segment checker
+ "Displays color-coded error status in the current buffer with pretty icons."
+ (let ((active (doom-modeline--active))
+ (seg (cond ((and (bound-and-true-p flymake-mode)
+ (bound-and-true-p flymake--state)) ; only support 26+
+ `(,doom-modeline--flymake-icon . ,doom-modeline--flymake-text))
+ ((bound-and-true-p flycheck-mode)
+ `(,doom-modeline--flycheck-icon . ,doom-modeline--flycheck-text)))))
+ (let ((icon (car seg))
+ (text (cdr seg)))
+ (concat
+ (when icon
+ (concat
+ (doom-modeline-spc)
+ (if active
+ icon
+ (doom-modeline-propertize-icon icon 'mode-line-inactive))))
+ (when text
+ (concat
+ (if icon (doom-modeline-vspc) (doom-modeline-spc))
+ (if active
+ text
+ (propertize text 'face 'mode-line-inactive))))
+ (doom-modeline-spc)))))
+
+
+;;
+;; Word Count
+;;
+
+(doom-modeline-def-segment word-count
+ "The buffer word count.
+Displayed when in a major mode in `doom-modeline-continuous-word-count-modes'.
+Respects `doom-modeline-enable-word-count'."
+ (when (and doom-modeline-enable-word-count
+ (member major-mode doom-modeline-continuous-word-count-modes))
+ (propertize (format " %dW" (count-words (point-min) (point-max)))
+ 'face (if (doom-modeline--active)
+ 'mode-line
+ 'mode-line-inactive))))
+
+
+;;
+;; Selection
+;;
+
+(defsubst doom-modeline-column (pos)
+ "Get the column of the position `POS'."
+ (save-excursion (goto-char pos)
+ (current-column)))
+
+(doom-modeline-def-segment selection-info
+ "Information about the current selection, such as how many characters and
+lines are selected, or the NxM dimensions of a block selection."
+ (when (and (or mark-active (and (bound-and-true-p evil-local-mode)
+ (eq evil-state 'visual)))
+ (doom-modeline--active))
+ (cl-destructuring-bind (beg . end)
+ (if (and (bound-and-true-p evil-local-mode) (eq evil-state 'visual))
+ (cons evil-visual-beginning evil-visual-end)
+ (cons (region-beginning) (region-end)))
+ (propertize
+ (let ((lines (count-lines beg (min end (point-max)))))
+ (concat (doom-modeline-spc)
+ (cond ((or (bound-and-true-p rectangle-mark-mode)
+ (and (bound-and-true-p evil-visual-selection)
+ (eq 'block evil-visual-selection)))
+ (let ((cols (abs (- (doom-modeline-column end)
+ (doom-modeline-column beg)))))
+ (format "%dx%dB" lines cols)))
+ ((and (bound-and-true-p evil-visual-selection)
+ (eq evil-visual-selection 'line))
+ (format "%dL" lines))
+ ((> lines 1)
+ (format "%dC %dL" (- end beg) lines))
+ (t
+ (format "%dC" (- end beg))))
+ (when doom-modeline-enable-word-count
+ (format " %dW" (count-words beg end)))
+ (doom-modeline-spc)))
+ 'face 'doom-modeline-highlight))))
+
+
+;;
+;; Matches (macro, anzu, evil-substitute, iedit, symbol-overlay and multi-cursors)
+;;
+
+(defsubst doom-modeline--macro-recording ()
+ "Display current Emacs or evil macro being recorded."
+ (when (and (doom-modeline--active)
+ (or defining-kbd-macro executing-kbd-macro))
+ (let ((sep (propertize " " 'face 'doom-modeline-panel ))
+ (vsep (propertize " " 'face
+ '(:inherit (doom-modeline-panel variable-pitch)))))
+ (concat
+ sep
+ (doom-modeline-icon 'material "fiber_manual_record" "β"
+ (if (bound-and-true-p evil-this-macro)
+ (char-to-string evil-this-macro)
+ "Macro")
+ :face 'doom-modeline-panel
+ :v-adjust -0.225)
+ vsep
+ (doom-modeline-icon 'octicon "triangle-right" "βΆ" ">"
+ :face 'doom-modeline-panel
+ :v-adjust -0.05)
+ sep))))
+
+;; `anzu' and `evil-anzu' expose current/total state that can be displayed in the
+;; mode-line.
+(defun doom-modeline-fix-anzu-count (positions here)
+ "Calulate anzu count via POSITIONS and HERE."
+ (cl-loop for (start . end) in positions
+ collect t into before
+ when (and (>= here start) (<= here end))
+ return (length before)
+ finally return 0))
+
+(advice-add #'anzu--where-is-here :override #'doom-modeline-fix-anzu-count)
+
+(setq anzu-cons-mode-line-p nil) ; manage modeline segment ourselves
+;; Ensure anzu state is cleared when searches & iedit are done
+(with-eval-after-load 'anzu
+ (add-hook 'isearch-mode-end-hook #'anzu--reset-status t)
+ (add-hook 'iedit-mode-end-hook #'anzu--reset-status)
+ (advice-add #'evil-force-normal-state :after #'anzu--reset-status)
+ ;; Fix matches segment mirroring across all buffers
+ (mapc #'make-variable-buffer-local
+ '(anzu--total-matched
+ anzu--current-position anzu--state anzu--cached-count
+ anzu--cached-positions anzu--last-command
+ anzu--last-isearch-string anzu--overflow-p)))
+
+(defsubst doom-modeline--anzu ()
+ "Show the match index and total number thereof.
+Requires `anzu', also `evil-anzu' if using `evil-mode' for compatibility with
+`evil-search'."
+ (when (and (bound-and-true-p anzu--state)
+ (not (bound-and-true-p iedit-mode)))
+ (propertize
+ (let ((here anzu--current-position)
+ (total anzu--total-matched))
+ (cond ((eq anzu--state 'replace-query)
+ (format " %d replace " anzu--cached-count))
+ ((eq anzu--state 'replace)
+ (format " %d/%d " here total))
+ (anzu--overflow-p
+ (format " %s+ " total))
+ (t
+ (format " %s/%d " here total))))
+ 'face (if (doom-modeline--active) 'doom-modeline-panel 'mode-line-inactive))))
+
+(defsubst doom-modeline--evil-substitute ()
+ "Show number of matches for evil-ex substitutions and highlights in real time."
+ (when (and (bound-and-true-p evil-local-mode)
+ (or (assq 'evil-ex-substitute evil-ex-active-highlights-alist)
+ (assq 'evil-ex-global-match evil-ex-active-highlights-alist)
+ (assq 'evil-ex-buffer-match evil-ex-active-highlights-alist)))
+ (propertize
+ (let ((range (if evil-ex-range
+ (cons (car evil-ex-range) (cadr evil-ex-range))
+ (cons (line-beginning-position) (line-end-position))))
+ (pattern (car-safe (evil-delimited-arguments evil-ex-argument 2))))
+ (if pattern
+ (format " %s matches " (how-many pattern (car range) (cdr range)))
+ " - "))
+ 'face (if (doom-modeline--active) 'doom-modeline-panel 'mode-line-inactive))))
+
+(defun doom-modeline-themes--overlay-sort (a b)
+ "Sort overlay A and B."
+ (< (overlay-start a) (overlay-start b)))
+
+(defsubst doom-modeline--iedit ()
+ "Show the number of iedit regions matches + what match you're on."
+ (when (and (bound-and-true-p iedit-mode)
+ (bound-and-true-p iedit-occurrences-overlays))
+ (propertize
+ (let ((this-oc (or (let ((inhibit-message t))
+ (iedit-find-current-occurrence-overlay))
+ (save-excursion (iedit-prev-occurrence)
+ (iedit-find-current-occurrence-overlay))))
+ (length (length iedit-occurrences-overlays)))
+ (format " %s/%d "
+ (if this-oc
+ (- length
+ (length (memq this-oc (sort (append iedit-occurrences-overlays nil)
+ #'doom-modeline-themes--overlay-sort)))
+ -1)
+ "-")
+ length))
+ 'face (if (doom-modeline--active) 'doom-modeline-panel 'mode-line-inactive))))
+
+(defsubst doom-modeline--symbol-overlay ()
+ "Show the number of matches for symbol overlay."
+ (when-let ((active (doom-modeline--active)))
+ (when (and (bound-and-true-p symbol-overlay-keywords-alist)
+ (not (bound-and-true-p symbol-overlay-temp-symbol))
+ (not (bound-and-true-p iedit-mode)))
+ (let* ((keyword (symbol-overlay-assoc (symbol-overlay-get-symbol t)))
+ (symbol (car keyword))
+ (before (symbol-overlay-get-list -1 symbol))
+ (after (symbol-overlay-get-list 1 symbol))
+ (count (length before)))
+ (if (symbol-overlay-assoc symbol)
+ (propertize
+ (format (concat " %d/%d " (and (cadr keyword) "in scope "))
+ (+ count 1)
+ (+ count (length after)))
+ 'face (if active 'doom-modeline-panel 'mode-line-inactive)))))))
+
+(defsubst doom-modeline--multiple-cursors ()
+ "Show the number of multiple cursors."
+ (cl-destructuring-bind (count . face)
+ (cond ((bound-and-true-p multiple-cursors-mode)
+ (cons (mc/num-cursors)
+ (if (doom-modeline--active)
+ 'doom-modeline-panel
+ 'mode-line-inactive)))
+ ((bound-and-true-p evil-mc-cursor-list)
+ (cons (length evil-mc-cursor-list)
+ (cond ((not (doom-modeline--active)) 'mode-line-inactive)
+ (evil-mc-frozen 'doom-modeline-bar)
+ ('doom-modeline-panel))))
+ ((cons nil nil)))
+ (when count
+ (concat (propertize " " 'face face)
+ (or (doom-modeline-icon 'faicon "i-cursor" nil nil
+ :face face :v-adjust -0.0575)
+ (propertize "I"
+ 'face `(:inherit ,face :height 1.4 :weight normal)
+ 'display '(raise -0.1)))
+ (propertize (doom-modeline-vspc)
+ 'face `(:inherit (variable-pitch ,face)))
+ (propertize (format "%d " count)
+ 'face face)))))
+
+(defsubst doom-modeline--phi-search ()
+ "Show the number of matches for `phi-search' and `phi-replace'."
+ (when-let ((active (doom-modeline--active)))
+ (when (bound-and-true-p phi-search--overlays)
+ (let ((total (length phi-search--overlays))
+ (selection phi-search--selection))
+ (when selection
+ (propertize
+ (format " %d/%d " (1+ selection) total)
+ 'face (if active 'doom-modeline-panel 'mode-line-inactive)))))))
+
+(defun doom-modeline--override-phi-search-mode-line (orig-fun &rest args)
+ "Override the mode-line of `phi-search' and `phi-replace'."
+ (if (bound-and-true-p doom-modeline-mode)
+ (apply orig-fun mode-line-format (cdr args))
+ (apply orig-fun args)))
+(advice-add #'phi-search--initialize :around #'doom-modeline--override-phi-search-mode-line)
+
+(defsubst doom-modeline--buffer-size ()
+ "Show buffer size."
+ (when size-indication-mode
+ (concat (doom-modeline-spc)
+ (propertize "%I"
+ 'face (if (doom-modeline--active) 'mode-line 'mode-line-inactive)
+ 'help-echo "Buffer size
+mouse-1: Display Line and Column Mode Menu"
+ 'mouse-face 'mode-line-highlight
+ 'local-map mode-line-column-line-number-mode-map)
+ (doom-modeline-spc))))
+
+(doom-modeline-def-segment matches
+ "Displays: 1. the currently recording macro, 2. A current/total for the
+current search term (with `anzu'), 3. The number of substitutions being
+conducted with `evil-ex-substitute', and/or 4. The number of active `iedit'
+regions, 5. The current/total for the highlight term (with `symbol-overlay'),
+6. The number of active `multiple-cursors'."
+ (let ((meta (concat (doom-modeline--macro-recording)
+ (doom-modeline--anzu)
+ (doom-modeline--phi-search)
+ (doom-modeline--evil-substitute)
+ (doom-modeline--iedit)
+ (doom-modeline--symbol-overlay)
+ (doom-modeline--multiple-cursors))))
+ (or (and (not (string-empty-p meta)) meta)
+ (doom-modeline--buffer-size))))
+
+(doom-modeline-def-segment buffer-size
+ "Display buffer size."
+ (doom-modeline--buffer-size))
+
+;;
+;; Media
+;;
+
+(doom-modeline-def-segment media-info
+ "Metadata regarding the current file, such as dimensions for images."
+ ;; TODO Include other information
+ (cond ((eq major-mode 'image-mode)
+ (cl-destructuring-bind (width . height)
+ (when (fboundp 'image-size)
+ (image-size (image-get-display-property) :pixels))
+ (propertize
+ (format " %dx%d " width height)
+ 'face (if (doom-modeline--active) 'mode-line 'mode-line-inactive))))))
+
+
+;;
+;; Bars
+;;
+
+(defvar doom-modeline--bar-active nil)
+(defvar doom-modeline--bar-inactive nil)
+
+(defsubst doom-modeline--bar ()
+ "The default bar regulates the height of the mode-line in GUI."
+ (unless (and doom-modeline--bar-active doom-modeline--bar-inactive)
+ (let ((width doom-modeline-bar-width)
+ (height (max doom-modeline-height
+ (doom-modeline--font-height))))
+ (when (and (numberp width) (numberp height))
+ (setq doom-modeline--bar-active
+ (doom-modeline--create-bar-image 'doom-modeline-bar width height)
+ doom-modeline--bar-inactive
+ (doom-modeline--create-bar-image
+ 'doom-modeline-bar-inactive width height)))))
+ (if (doom-modeline--active)
+ doom-modeline--bar-active
+ doom-modeline--bar-inactive))
+
+(defun doom-modeline-refresh-bars ()
+ "Refresh mode-line bars on next redraw."
+ (setq doom-modeline--bar-active nil
+ doom-modeline--bar-inactive nil))
+
+(cl-defstruct doom-modeline--hud-cache active inactive top-margin bottom-margin)
+
+(defsubst doom-modeline--hud ()
+ "Powerline's hud segment reimplemented in the style of Doom's bar segment."
+ (let* ((ws (window-start))
+ (we (window-end))
+ (bs (buffer-size))
+ (height (max doom-modeline-height
+ (doom-modeline--font-height)))
+ (top-margin (if (zerop bs)
+ 0
+ (/ (* height (1- ws)) bs)))
+ (bottom-margin (if (zerop bs)
+ 0
+ (max 0 (/ (* height (- bs we 1)) bs))))
+ (cache (or (window-parameter nil 'doom-modeline--hud-cache)
+ (set-window-parameter nil 'doom-modeline--hud-cache
+ (make-doom-modeline--hud-cache)))))
+ (unless (and (doom-modeline--hud-cache-active cache)
+ (doom-modeline--hud-cache-inactive cache)
+ (= top-margin (doom-modeline--hud-cache-top-margin cache))
+ (= bottom-margin
+ (doom-modeline--hud-cache-bottom-margin cache)))
+ (setf (doom-modeline--hud-cache-active cache)
+ (doom-modeline--create-hud-image
+ 'doom-modeline-bar 'default doom-modeline-bar-width
+ height top-margin bottom-margin)
+ (doom-modeline--hud-cache-inactive cache)
+ (doom-modeline--create-hud-image
+ 'doom-modeline-bar-inactive 'default doom-modeline-bar-width
+ height top-margin bottom-margin)
+ (doom-modeline--hud-cache-top-margin cache) top-margin
+ (doom-modeline--hud-cache-bottom-margin cache) bottom-margin))
+ (if (doom-modeline--active)
+ (doom-modeline--hud-cache-active cache)
+ (doom-modeline--hud-cache-inactive cache))))
+
+(defun doom-modeline-invalidate-huds ()
+ "Invalidate all cached hud images."
+ (dolist (frame (frame-list))
+ (dolist (window (window-list frame))
+ (set-window-parameter window 'doom-modeline--hud-cache nil))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-height
+ (lambda (_sym val op _where)
+ (when (and (eq op 'set) (integerp val))
+ (doom-modeline-refresh-bars)
+ (doom-modeline-invalidate-huds))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-bar-width
+ (lambda (_sym val op _where)
+ (when (and (eq op 'set) (integerp val))
+ (doom-modeline-refresh-bars)
+ (doom-modeline-invalidate-huds))))
+
+(add-hook 'after-setting-font-hook #'doom-modeline-refresh-bars)
+(add-hook 'after-setting-font-hook #'doom-modeline-invalidate-huds)
+
+(doom-modeline-def-segment bar
+ "The bar regulates the height of the mode-line in GUI."
+ (if doom-modeline-hud
+ (doom-modeline--hud)
+ (doom-modeline--bar)))
+
+(doom-modeline-def-segment hud
+ "Powerline's hud segment reimplemented in the style of Doom's bar segment."
+ (doom-modeline--hud))
+
+
+;;
+;; Window number
+;;
+
+;; HACK: `ace-window-display-mode' should respect the ignore buffers.
+(defun doom-modeline-aw-update ()
+ "Update ace-window-path window parameter for all windows.
+Ensure all windows are labeled so the user can select a specific
+one. The ignored buffers are excluded unless `aw-ignore-on' is nil."
+ (let ((ignore-window-parameters t))
+ (avy-traverse
+ (avy-tree (aw-window-list) aw-keys)
+ (lambda (path leaf)
+ (set-window-parameter
+ leaf 'ace-window-path
+ (propertize
+ (apply #'string (reverse path))
+ 'face 'aw-mode-line-face))))))
+(advice-add #'aw-update :override #'doom-modeline-aw-update)
+
+;; Remove original window number of `ace-window-display-mode'.
+(add-hook 'ace-window-display-mode-hook
+ (lambda ()
+ (setq-default mode-line-format
+ (assq-delete-all 'ace-window-display-mode
+ (default-value 'mode-line-format)))))
+
+(advice-add #'window-numbering-install-mode-line :override #'ignore)
+(advice-add #'window-numbering-clear-mode-line :override #'ignore)
+(advice-add #'winum--install-mode-line :override #'ignore)
+(advice-add #'winum--clear-mode-line :override #'ignore)
+
+(doom-modeline-def-segment window-number
+ "The current window number."
+ (let ((num (cond
+ ((bound-and-true-p ace-window-display-mode)
+ (aw-update)
+ (window-parameter (selected-window) 'ace-window-path))
+ ((bound-and-true-p winum-mode)
+ (setq winum-auto-setup-mode-line nil)
+ (winum-get-number-string))
+ ((bound-and-true-p window-numbering-mode)
+ (window-numbering-get-number-string))
+ (t ""))))
+ (if (and (< 0 (length num))
+ (< 1 (length (cl-mapcan
+ (lambda (frame)
+ ;; Exclude minibuffer and child frames
+ (unless (and (fboundp 'frame-parent)
+ (frame-parent frame))
+ (window-list frame 'never)))
+ (visible-frame-list)))))
+ (propertize (format " %s " num)
+ 'face (if (doom-modeline--active)
+ 'doom-modeline-buffer-major-mode
+ 'mode-line-inactive))
+ (doom-modeline-spc))))
+
+
+;;
+;; Workspace
+;;
+
+(doom-modeline-def-segment workspace-name
+ "The current workspace name or number.
+Requires `eyebrowse-mode' to be enabled or `tab-bar-mode' tabs to be created."
+ (when doom-modeline-workspace-name
+ (when-let
+ ((name (cond
+ ((and (bound-and-true-p eyebrowse-mode)
+ (< 1 (length (eyebrowse--get 'window-configs))))
+ (assq-delete-all 'eyebrowse-mode mode-line-misc-info)
+ (when-let*
+ ((num (eyebrowse--get 'current-slot))
+ (tag (nth 2 (assoc num (eyebrowse--get 'window-configs)))))
+ (if (< 0 (length tag)) tag (int-to-string num))))
+ ((and (fboundp 'tab-bar-mode)
+ (< 1 (length (frame-parameter nil 'tabs))))
+ (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)))))))
+ (propertize (format " %s " name) 'face
+ (if (doom-modeline--active)
+ 'doom-modeline-buffer-major-mode
+ 'mode-line-inactive)))))
+
+
+;;
+;; Perspective
+;;
+
+(defvar-local doom-modeline--persp-name nil)
+(defun doom-modeline-update-persp-name (&rest _)
+ "Update perspective name in mode-line."
+ (setq doom-modeline--persp-name
+ ;; Support `persp-mode', while not support `perspective'
+ (when (and doom-modeline-persp-name
+ (bound-and-true-p persp-mode)
+ (fboundp 'safe-persp-name)
+ (fboundp 'get-current-persp))
+ (let* ((persp (get-current-persp))
+ (name (safe-persp-name persp))
+ (face (if (and persp
+ (not (persp-contain-buffer-p (current-buffer) persp)))
+ 'doom-modeline-persp-buffer-not-in-persp
+ 'doom-modeline-persp-name))
+ (icon (doom-modeline-icon 'material "folder" "πΏ" "#"
+ :face `(:inherit ,face :slant normal)
+ :height 1.1
+ :v-adjust -0.225)))
+ (when (or doom-modeline-display-default-persp-name
+ (not (string-equal persp-nil-name name)))
+ (concat (doom-modeline-spc)
+ (propertize (concat (and doom-modeline-persp-icon
+ (concat icon (doom-modeline-vspc)))
+ (propertize name 'face face))
+ 'help-echo "mouse-1: Switch perspective
+mouse-2: Show help for minor mode"
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1]
+ #'persp-switch)
+ (define-key map [mode-line mouse-2]
+ (lambda ()
+ (interactive)
+ (describe-function 'persp-mode)))
+ map))
+ (doom-modeline-spc)))))))
+
+(add-hook 'buffer-list-update-hook #'doom-modeline-update-persp-name)
+(add-hook 'find-file-hook #'doom-modeline-update-persp-name)
+(add-hook 'persp-activated-functions #'doom-modeline-update-persp-name)
+(add-hook 'persp-renamed-functions #'doom-modeline-update-persp-name)
+(advice-add #'lv-message :after #'doom-modeline-update-persp-name)
+
+(doom-modeline-def-segment persp-name
+ "The current perspective name."
+ (when (and (doom-modeline--active)
+ (not doom-modeline--limited-width-p))
+ doom-modeline--persp-name))
+
+
+;;
+;; Misc info
+;;
+
+(doom-modeline-def-segment misc-info
+ "Mode line construct for miscellaneous information.
+By default, this shows the information specified by `global-mode-string'."
+ (when (and (doom-modeline--active)
+ (not doom-modeline--limited-width-p))
+ '("" mode-line-misc-info)))
+
+
+;;
+;; Position
+;;
+
+;; Be compatible with Emacs 25.
+(defvar doom-modeline-column-zero-based
+ (if (boundp 'column-number-indicator-zero-based)
+ column-number-indicator-zero-based
+ t)
+ "When non-nil, mode line displays column numbers zero-based.
+See `column-number-indicator-zero-based'.")
+
+(defvar doom-modeline-percent-position
+ (if (boundp 'mode-line-percent-position)
+ mode-line-percent-position
+ '(-3 "%p"))
+ "Specification of \"percentage offset\" of window through buffer.
+See `mode-line-percent-position'.")
+
+(doom-modeline-add-variable-watcher
+ 'column-number-indicator-zero-based
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-column-zero-based val))))
+
+(doom-modeline-add-variable-watcher
+ 'mode-line-percent-position
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-percent-position val))))
+
+(doom-modeline-def-segment buffer-position
+ "The buffer position information."
+ (let* ((active (doom-modeline--active))
+ (lc '(line-number-mode
+ (column-number-mode
+ (doom-modeline-column-zero-based "%l:%c" "%l:%C")
+ "%l")
+ (column-number-mode (doom-modeline-column-zero-based ":%c" ":%C"))))
+ (face (if active 'mode-line 'mode-line-inactive))
+ (mouse-face 'mode-line-highlight)
+ (local-map mode-line-column-line-number-mode-map))
+ (concat
+ (doom-modeline-wspc)
+
+ ;; Line and column
+ (propertize (format-mode-line lc)
+ 'face face
+ 'help-echo "Buffer position\n\
+mouse-1: Display Line and Column Mode Menu"
+ 'mouse-face mouse-face
+ 'local-map local-map)
+
+ ;; Position
+ (cond ((and active
+ (bound-and-true-p nyan-mode)
+ (not doom-modeline--limited-width-p)
+ (>= (window-width) nyan-minimum-window-width))
+ (concat
+ (doom-modeline-wspc)
+ (propertize (nyan-create) 'mouse-face mouse-face)))
+ ((and active
+ (bound-and-true-p poke-line-mode)
+ (not doom-modeline--limited-width-p)
+ (>= (window-width) poke-line-minimum-window-width))
+ (concat
+ (doom-modeline-wspc)
+ (propertize (poke-line-create) 'mouse-face mouse-face)))
+ ((and active
+ (bound-and-true-p mlscroll-mode)
+ (not doom-modeline--limited-width-p)
+ (>= (window-width) mlscroll-minimum-current-width))
+ (concat
+ (doom-modeline-wspc)
+ (let ((mlscroll-right-align nil))
+ (format-mode-line (mlscroll-mode-line)))))
+ ((and active
+ (bound-and-true-p sml-modeline-mode)
+ (not doom-modeline--limited-width-p)
+ (>= (window-width) sml-modeline-len))
+ (concat
+ (doom-modeline-wspc)
+ (propertize (sml-modeline-create) 'mouse-face mouse-face)))
+ (t ""))
+
+ ;; Percent position
+ (when doom-modeline-percent-position
+ (concat
+ (doom-modeline-spc)
+ (propertize (format-mode-line '("" doom-modeline-percent-position "%%"))
+ 'face face
+ 'help-echo "Buffer percentage\n\
+mouse-1: Display Line and Column Mode Menu"
+ 'mouse-face mouse-face
+ 'local-map local-map)))
+
+ (when (or line-number-mode column-number-mode doom-modeline-percent-position)
+ (doom-modeline-spc)))))
+
+;;
+;; Party parrot
+;;
+(doom-modeline-def-segment parrot
+ "The party parrot animated icon. Requires `parrot-mode' to be enabled."
+ (when (and (doom-modeline--active)
+ (not doom-modeline--limited-width-p)
+ (bound-and-true-p parrot-mode))
+ (concat (doom-modeline-wspc)
+ (parrot-create)
+ (doom-modeline-spc))))
+
+;;
+;; Modals (evil, overwrite, god, ryo and xah-fly-keys, etc.)
+;;
+
+(defun doom-modeline--modal-icon (text face help-echo)
+ "Display the model icon with FACE and HELP-ECHO.
+TEXT is alternative if icon is not available."
+ (propertize (doom-modeline-icon
+ 'material
+ (when doom-modeline-modal-icon "fiber_manual_record")
+ "β"
+ text
+ :face (if (doom-modeline--active) face 'mode-line-inactive)
+ :v-adjust -0.225)
+ 'help-echo help-echo))
+
+(defsubst doom-modeline--evil ()
+ "The current evil state. Requires `evil-mode' to be enabled."
+ (when (bound-and-true-p evil-local-mode)
+ (doom-modeline--modal-icon
+ (let ((tag (evil-state-property evil-state :tag t)))
+ (if (stringp tag) tag (funcall tag)))
+ (cond
+ ((evil-normal-state-p) 'doom-modeline-evil-normal-state)
+ ((evil-emacs-state-p) 'doom-modeline-evil-emacs-state)
+ ((evil-insert-state-p) 'doom-modeline-evil-insert-state)
+ ((evil-motion-state-p) 'doom-modeline-evil-motion-state)
+ ((evil-visual-state-p) 'doom-modeline-evil-visual-state)
+ ((evil-operator-state-p) 'doom-modeline-evil-operator-state)
+ ((evil-replace-state-p) 'doom-modeline-evil-replace-state)
+ (t 'doom-modeline-evil-normal-state))
+ (evil-state-property evil-state :name t))))
+
+(defsubst doom-modeline--overwrite ()
+ "The current overwrite state which is enabled by command `overwrite-mode'."
+ (when (and (bound-and-true-p overwrite-mode)
+ (not (bound-and-true-p evil-local-mode)))
+ (doom-modeline--modal-icon " " 'doom-modeline-urgent "Overwrite mode")))
+
+(defsubst doom-modeline--god ()
+ "The current god state which is enabled by the command `god-mode'."
+ (when (bound-and-true-p god-local-mode)
+ (doom-modeline--modal-icon " " 'doom-modeline-evil-normal-state "God mode")))
+
+(defsubst doom-modeline--ryo ()
+ "The current ryo-modal state which is enabled by the command `ryo-modal-mode'."
+ (when (bound-and-true-p ryo-modal-mode)
+ (doom-modeline--modal-icon "" 'doom-modeline-evil-normal-state "Ryo modal")))
+
+(defsubst doom-modeline--xah-fly-keys ()
+ "The current `xah-fly-keys' state."
+ (when (bound-and-true-p xah-fly-keys)
+ (if xah-fly-insert-state-p
+ (doom-modeline--modal-icon " "
+ 'doom-modeline-evil-insert-state
+ (format "Xah-fly insert mode"))
+ (doom-modeline--modal-icon " "
+ 'doom-modeline-evil-normal-state
+ (format "Xah-fly command mode")))))
+
+(defsubst doom-modeline--boon ()
+ "The current Boon state. Requires `boon-mode' to be enabled."
+ (when (bound-and-true-p boon-local-mode)
+ (doom-modeline--modal-icon
+ (boon-state-string)
+ (cond
+ (boon-command-state 'doom-modeline-evil-normal-state)
+ (boon-insert-state 'doom-modeline-evil-insert-state)
+ (boon-special-state 'doom-modeline-evil-emacs-state)
+ (boon-off-state 'doom-modeline-evil-operator-state)
+ (t 'doom-modeline-evil-operator-state))
+ (boon-modeline-string))))
+
+(defsubst doom-modeline--meow ()
+ "The current Meow state. Requires `meow-mode' to be enabled."
+ (when (bound-and-true-p meow-mode)
+ meow--indicator))
+
+(doom-modeline-def-segment modals
+ "Displays modal editing states, including `evil', `overwrite', `god', `ryo'
+and `xha-fly-kyes', etc."
+ (let* ((evil (doom-modeline--evil))
+ (ow (doom-modeline--overwrite))
+ (god (doom-modeline--god))
+ (ryo (doom-modeline--ryo))
+ (xf (doom-modeline--xah-fly-keys))
+ (boon (doom-modeline--boon))
+ (vsep (doom-modeline-vspc))
+ (meow (doom-modeline--meow))
+ (sep (and (or evil ow god ryo xf boon) (doom-modeline-spc))))
+ (concat sep
+ (and evil (concat evil (and (or ow god ryo xf boon meow) vsep)))
+ (and ow (concat ow (and (or god ryo xf boon meow) vsep)))
+ (and god (concat god (and (or ryo xf boon meow) vsep)))
+ (and ryo (concat ryo (and (or xf boon meow) vsep)))
+ (and xf (concat xf (and (or boon meow) vsep)))
+ (and boon (concat boon (and meow vsep)))
+ meow
+ sep)))
+
+;;
+;; Objed state
+;;
+
+(defvar doom-modeline--objed-active nil)
+
+(defun doom-modeline-update-objed (_ &optional reset)
+ "Update `objed' status, inactive when RESET is true."
+ (setq doom-modeline--objed-active (not reset)))
+
+(setq objed-modeline-setup-func #'doom-modeline-update-objed)
+
+(doom-modeline-def-segment objed-state ()
+ "The current objed state."
+ (when (and doom-modeline--objed-active
+ (doom-modeline--active))
+ (propertize (format " %s(%s) "
+ (symbol-name objed--object)
+ (char-to-string (aref (symbol-name objed--obj-state) 0)))
+ 'face 'doom-modeline-evil-emacs-state
+ 'help-echo (format "Objed object: %s (%s)"
+ (symbol-name objed--object)
+ (symbol-name objed--obj-state)))))
+
+
+;;
+;; Input method
+;;
+
+(doom-modeline-def-segment input-method
+ "The current input method."
+ (propertize (cond (current-input-method
+ (concat (doom-modeline-spc)
+ current-input-method-title
+ (doom-modeline-spc)))
+ ((and (bound-and-true-p evil-local-mode)
+ (bound-and-true-p evil-input-method))
+ (concat
+ (doom-modeline-spc)
+ (nth 3 (assoc default-input-method input-method-alist))
+ (doom-modeline-spc)))
+ (t ""))
+ 'face (if (doom-modeline--active)
+ (if (and (bound-and-true-p rime-mode)
+ (equal current-input-method "rime"))
+ (if (and (rime--should-enable-p)
+ (not (rime--should-inline-ascii-p)))
+ 'doom-modeline-input-method
+ 'doom-modeline-input-method-alt)
+ 'doom-modeline-input-method)
+ 'mode-line-inactive)
+ 'help-echo (concat
+ "Current input method: "
+ current-input-method
+ "\n\
+mouse-2: Disable input method\n\
+mouse-3: Describe current input method")
+ 'mouse-face 'mode-line-highlight
+ 'local-map mode-line-input-method-map))
+
+
+;;
+;; Info
+;;
+
+(doom-modeline-def-segment info-nodes
+ "The topic and nodes in the Info buffer."
+ (let ((active (doom-modeline--active)))
+ (concat
+ (propertize " (" 'face (if active 'mode-line 'mode-line-inactive))
+ ;; topic
+ (propertize (if (stringp Info-current-file)
+ (replace-regexp-in-string
+ "%" "%%"
+ (file-name-sans-extension
+ (file-name-nondirectory Info-current-file)))
+ (format "*%S*" Info-current-file))
+ 'face (if active 'doom-modeline-info 'mode-line-inactive))
+ (propertize ") " 'face (if active 'mode-line 'mode-line-inactive))
+ ;; node
+ (when Info-current-node
+ (propertize (replace-regexp-in-string
+ "%" "%%" Info-current-node)
+ 'face (if active 'doom-modeline-buffer-path 'mode-line-inactive)
+ 'help-echo
+ "mouse-1: scroll forward, mouse-3: scroll back"
+ 'mouse-face 'mode-line-highlight
+ 'local-map Info-mode-line-node-keymap)))))
+
+
+;;
+;; REPL
+;;
+
+(defun doom-modeline-repl-icon (text face)
+ "Display REPL icon (or TEXT in terminal) with FACE."
+ (doom-modeline-icon 'faicon "terminal" "$" text
+ :face face :height 1.0 :v-adjust -0.0575))
+
+(defvar doom-modeline--cider nil)
+
+(defun doom-modeline-update-cider ()
+ "Update cider repl state."
+ (setq doom-modeline--cider
+ (let* ((connected (cider-connected-p))
+ (face (if connected 'doom-modeline-repl-success 'doom-modeline-repl-warning))
+ (repl-buffer (cider-current-repl nil nil))
+ (cider-info (when repl-buffer
+ (cider--connection-info repl-buffer t)))
+ (icon (doom-modeline-repl-icon "REPL" face)))
+ (propertize icon
+ 'help-echo
+ (if connected
+ (format "CIDER Connected %s\nmouse-2: CIDER quit" cider-info)
+ "CIDER Disconnected\nmouse-1: CIDER jack-in")
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (if connected
+ (define-key map [mode-line mouse-2]
+ #'cider-quit)
+ (define-key map [mode-line mouse-1]
+ #'cider-jack-in))
+ map)))))
+
+(add-hook 'cider-connected-hook #'doom-modeline-update-cider)
+(add-hook 'cider-disconnected-hook #'doom-modeline-update-cider)
+(add-hook 'cider-mode-hook #'doom-modeline-update-cider)
+
+(doom-modeline-def-segment repl
+ "The REPL state."
+ (when doom-modeline-repl
+ (when-let (icon (when (bound-and-true-p cider-mode)
+ doom-modeline--cider))
+ (concat
+ (doom-modeline-spc)
+ (if (doom-modeline--active)
+ icon
+ (doom-modeline-propertize-icon icon 'mode-line-inactive))
+ (doom-modeline-spc)))))
+
+
+;;
+;; LSP
+;;
+
+(defun doom-modeline-lsp-icon (text face)
+ "Display LSP icon (or TEXT in terminal) with FACE."
+ (doom-modeline-icon 'faicon "rocket" "π" text
+ :face face :height 1.0 :v-adjust -0.0575))
+
+(defvar-local doom-modeline--lsp nil)
+(defun doom-modeline-update-lsp (&rest _)
+ "Update `lsp-mode' state."
+ (setq doom-modeline--lsp
+ (let* ((workspaces (lsp-workspaces))
+ (face (if workspaces 'doom-modeline-lsp-success 'doom-modeline-lsp-warning))
+ (icon (doom-modeline-lsp-icon "LSP" face)))
+ (propertize icon
+ 'help-echo
+ (if workspaces
+ (concat "LSP Connected "
+ (string-join
+ (mapcar (lambda (w)
+ (format "[%s]\n" (lsp--workspace-print w)))
+ workspaces))
+ "C-mouse-1: Switch to another workspace folder
+mouse-1: Describe current session
+mouse-2: Quit server
+mouse-3: Reconnect to server")
+ "LSP Disconnected
+mouse-1: Reload to start server")
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (if workspaces
+ (progn
+ (define-key map [mode-line C-mouse-1]
+ #'lsp-workspace-folders-open)
+ (define-key map [mode-line mouse-1]
+ #'lsp-describe-session)
+ (define-key map [mode-line mouse-2]
+ #'lsp-workspace-shutdown)
+ (define-key map [mode-line mouse-3]
+ #'lsp-workspace-restart))
+ (progn
+ (define-key map [mode-line mouse-1]
+ (lambda ()
+ (interactive)
+ (ignore-errors (revert-buffer t t))))))
+ map)))))
+(add-hook 'lsp-before-initialize-hook #'doom-modeline-update-lsp)
+(add-hook 'lsp-after-initialize-hook #'doom-modeline-update-lsp)
+(add-hook 'lsp-after-uninitialized-functions #'doom-modeline-update-lsp)
+(add-hook 'lsp-before-open-hook #'doom-modeline-update-lsp)
+(add-hook 'lsp-after-open-hook #'doom-modeline-update-lsp)
+
+(defvar-local doom-modeline--eglot nil)
+(defun doom-modeline-update-eglot ()
+ "Update `eglot' state."
+ (setq doom-modeline--eglot
+ (pcase-let* ((server (and (eglot-managed-p) (eglot-current-server)))
+ (nick (and server (eglot--project-nickname server)))
+ (pending (and server (hash-table-count
+ (jsonrpc--request-continuations server))))
+ (`(,_id ,doing ,done-p ,detail) (and server (eglot--spinner server)))
+ (last-error (and server (jsonrpc-last-error server)))
+ (face (cond (last-error 'doom-modeline-lsp-error)
+ ((and doing (not done-p)) 'doom-modeline-lsp-running)
+ ((and pending (cl-plusp pending)) 'doom-modeline-lsp-warning)
+ (nick 'doom-modeline-lsp-success)
+ (t 'doom-modeline-lsp-warning)))
+ (icon (doom-modeline-lsp-icon "EGLOT" face)))
+ (propertize icon
+ 'help-echo (cond
+ (last-error
+ (format "EGLOT\nAn error occured: %s
+mouse-3: Clear this status" (plist-get last-error :message)))
+ ((and doing (not done-p))
+ (format "EGLOT\n%s%s" doing
+ (if detail (format "%s" detail) "")))
+ ((and pending (cl-plusp pending))
+ (format "EGLOT\n%d outstanding requests" pending))
+ (nick (format "EGLOT Connected (%s/%s)
+C-mouse-1: Go to server errors
+mouse-1: Go to server events
+mouse-2: Quit server
+mouse-3: Reconnect to server" nick (eglot--major-mode server)))
+ (t "EGLOT Disconnected
+mouse-1: Start server"))
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (cond (last-error
+ (define-key map [mode-line mouse-3]
+ #'eglot-clear-status))
+ ((and pending (cl-plusp pending))
+ (define-key map [mode-line mouse-3]
+ #'eglot-forget-pending-continuations))
+ (nick
+ (define-key map [mode-line C-mouse-1]
+ #'eglot-stderr-buffer)
+ (define-key map [mode-line mouse-1]
+ #'eglot-events-buffer)
+ (define-key map [mode-line mouse-2]
+ #'eglot-shutdown)
+ (define-key map [mode-line mouse-3]
+ #'eglot-reconnect))
+ (t (define-key map [mode-line mouse-1]
+ #'eglot)))
+ map)))))
+(add-hook 'eglot-managed-mode-hook #'doom-modeline-update-eglot)
+
+(defvar-local doom-modeline--tags nil)
+(defun doom-modeline-update-tags ()
+ "Update tags state."
+ (setq doom-modeline--tags
+ (propertize
+ (doom-modeline-lsp-icon "LSP" 'doom-modeline-lsp-success)
+ 'help-echo "TAGS: Citre mode
+mouse-1: Toggle citre mode"
+ 'mouse-face 'mode-line-highlight
+ 'local-map (make-mode-line-mouse-map 'mouse-1 #'citre-mode))))
+(add-hook 'citre-mode-hook #'doom-modeline-update-tags)
+
+(defun doom-modeline-update-lsp-icon ()
+ "Update lsp icon."
+ (cond ((bound-and-true-p lsp-mode)
+ (doom-modeline-update-lsp))
+ ((bound-and-true-p eglot--managed-mode)
+ (doom-modeline-update-eglot))
+ ((bound-and-true-p citre-mode)
+ (doom-modeline-update-tags))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-icon
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-icon val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (doom-modeline-update-lsp-icon))))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-unicode-fallback
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-unicode-fallback val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (doom-modeline-update-lsp-icon))))))
+
+(doom-modeline-def-segment lsp
+ "The LSP server state."
+ (when (and doom-modeline-lsp
+ (not doom-modeline--limited-width-p))
+ (let ((active (doom-modeline--active))
+ (icon (cond ((bound-and-true-p lsp-mode)
+ doom-modeline--lsp)
+ ((bound-and-true-p eglot--managed-mode)
+ doom-modeline--eglot)
+ ((bound-and-true-p citre-mode)
+ doom-modeline--tags))))
+ (when icon
+ (concat
+ (doom-modeline-spc)
+ (if active
+ icon
+ (doom-modeline-propertize-icon icon 'mode-line-inactive))
+ (doom-modeline-spc))))))
+
+(defun doom-modeline-override-eglot-modeline ()
+ "Override `eglot' mode-line."
+ (if (bound-and-true-p doom-modeline-mode)
+ (setq mode-line-misc-info
+ (delq (assq 'eglot--managed-mode mode-line-misc-info) mode-line-misc-info))
+ (add-to-list 'mode-line-misc-info
+ `(eglot--managed-mode (" [" eglot--mode-line-format "] ")))))
+(add-hook 'eglot-managed-mode-hook #'doom-modeline-override-eglot-modeline)
+(add-hook 'doom-modeline-mode-hook #'doom-modeline-override-eglot-modeline)
+
+
+;;
+;; GitHub
+;;
+
+(defvar doom-modeline--github-notification-number 0)
+(defvar doom-modeline-before-github-fetch-notification-hook nil
+ "Hooks before fetching GitHub notifications.
+Example:
+ (add-hook 'doom-modeline-before-github-fetch-notification-hook
+ #'auth-source-pass-enable)")
+(defun doom-modeline--github-fetch-notifications ()
+ "Fetch GitHub notifications."
+ (when (and doom-modeline-github
+ (require 'async nil t))
+ (async-start
+ `(lambda ()
+ ,(async-inject-variables
+ "\\`\\(load-path\\|auth-sources\\|doom-modeline-before-github-fetch-notification-hook\\)\\'")
+ (run-hooks 'doom-modeline-before-github-fetch-notification-hook)
+ (when (require 'ghub nil t)
+ (with-timeout (10)
+ (ignore-errors
+ (when-let* ((username (ghub--username ghub-default-host))
+ (token (ghub--token ghub-default-host username 'ghub t)))
+ (ghub-get "/notifications" nil
+ :query '((notifications . "true"))
+ :username username
+ :auth token
+ :noerror t))))))
+ (lambda (result)
+ (message "") ; suppress message
+ (setq doom-modeline--github-notification-number (length result))))))
+
+(defvar doom-modeline--github-timer nil)
+(defun doom-modeline-github-timer ()
+ "Start/Stop the timer for GitHub fetching."
+ (if (timerp doom-modeline--github-timer)
+ (cancel-timer doom-modeline--github-timer))
+ (setq doom-modeline--github-timer
+ (and doom-modeline-github
+ (run-with-idle-timer 30
+ doom-modeline-github-interval
+ #'doom-modeline--github-fetch-notifications))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-github
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-github val)
+ (doom-modeline-github-timer))))
+
+(doom-modeline-github-timer)
+
+(doom-modeline-def-segment github
+ "The GitHub notifications."
+ (when (and doom-modeline-github
+ (doom-modeline--active)
+ (not doom-modeline--limited-width-p)
+ (numberp doom-modeline--github-notification-number)
+ (> doom-modeline--github-notification-number 0))
+ (concat
+ (doom-modeline-spc)
+ (propertize
+ (concat
+ (doom-modeline-icon 'faicon "github" "π" "#"
+ :face 'doom-modeline-notification
+ :v-adjust -0.0575)
+ (doom-modeline-vspc)
+ ;; GitHub API is paged, and the limit is 50
+ (propertize
+ (if (>= doom-modeline--github-notification-number 50)
+ "50+"
+ (number-to-string doom-modeline--github-notification-number))
+ 'face '(:inherit
+ (doom-modeline-unread-number doom-modeline-notification))))
+ 'help-echo "Github Notifications
+mouse-1: Show notifications
+mouse-3: Fetch notifications"
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1]
+ (lambda ()
+ "Open GitHub notifications page."
+ (interactive)
+ (run-with-idle-timer 300 nil #'doom-modeline--github-fetch-notifications)
+ (browse-url "https://github.com/notifications")))
+ (define-key map [mode-line mouse-3]
+ (lambda ()
+ "Fetching GitHub notifications."
+ (interactive)
+ (message "Fetching GitHub notifications...")
+ (doom-modeline--github-fetch-notifications)))
+ map))
+ (doom-modeline-spc))))
+
+
+;;
+;; Debug states
+;;
+
+;; Highlight the mode-line while debugging.
+(defvar-local doom-modeline--debug-cookie nil)
+(defun doom-modeline--debug-visual (&rest _)
+ "Update the face of mode-line for debugging."
+ (mapc (lambda (buffer)
+ (with-current-buffer buffer
+ (setq doom-modeline--debug-cookie
+ (face-remap-add-relative 'mode-line 'doom-modeline-debug-visual))
+ (force-mode-line-update)))
+ (buffer-list)))
+
+(defun doom-modeline--normal-visual (&rest _)
+ "Restore the face of mode-line."
+ (mapc (lambda (buffer)
+ (with-current-buffer buffer
+ (when doom-modeline--debug-cookie
+ (face-remap-remove-relative doom-modeline--debug-cookie)
+ (force-mode-line-update))))
+ (buffer-list)))
+
+(add-hook 'dap-session-created-hook #'doom-modeline--debug-visual)
+(add-hook 'dap-terminated-hook #'doom-modeline--normal-visual)
+
+(defun doom-modeline-debug-icon (face &rest args)
+ "Display debug icon with FACE and ARGS."
+ (doom-modeline-icon 'faicon "bug" "π" "!" :face face :v-adjust -0.0575 args))
+
+(defun doom-modeline--debug-dap ()
+ "The current `dap-mode' state."
+ (when (and (bound-and-true-p dap-mode)
+ (bound-and-true-p lsp-mode))
+ (when-let ((session (dap--cur-session)))
+ (when (dap--session-running session)
+ (propertize (doom-modeline-debug-icon 'doom-modeline-info)
+ 'help-echo (format "DAP (%s - %s)
+mouse-1: Display debug hydra
+mouse-2: Display recent configurations
+mouse-3: Disconnect session"
+ (dap--debug-session-name session)
+ (dap--debug-session-state session))
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1]
+ #'dap-hydra)
+ (define-key map [mode-line mouse-2]
+ #'dap-debug-recent)
+ (define-key map [mode-line mouse-3]
+ #'dap-disconnect)
+ map))))))
+
+(defvar-local doom-modeline--debug-dap nil)
+(defun doom-modeline-update-debug-dap (&rest _)
+ "Update dap debug state."
+ (setq doom-modeline--debug-dap (doom-modeline--debug-dap)))
+
+(add-hook 'dap-session-created-hook #'doom-modeline-update-debug-dap)
+(add-hook 'dap-session-changed-hook #'doom-modeline-update-debug-dap)
+(add-hook 'dap-terminated-hook #'doom-modeline-update-debug-dap)
+
+(defsubst doom-modeline--debug-edebug ()
+ "The current `edebug' state."
+ (when (bound-and-true-p edebug-mode)
+ (propertize (doom-modeline-debug-icon 'doom-modeline-info)
+ 'help-echo (format "EDebug (%s)
+mouse-1: Show help
+mouse-2: Next
+mouse-3: Stop debugging"
+ edebug-execution-mode)
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1]
+ #'edebug-help)
+ (define-key map [mode-line mouse-2]
+ #'edebug-next-mode)
+ (define-key map [mode-line mouse-3]
+ #'edebug-stop)
+ map))))
+
+(defsubst doom-modeline--debug-on-error ()
+ "The current `debug-on-error' state."
+ (when debug-on-error
+ (propertize (doom-modeline-debug-icon 'doom-modeline-urgent)
+ 'help-echo "Debug on Error
+mouse-1: Toggle Debug on Error"
+ 'mouse-face 'mode-line-highlight
+ 'local-map (make-mode-line-mouse-map 'mouse-1 #'toggle-debug-on-error))))
+
+(defsubst doom-modeline--debug-on-quit ()
+ "The current `debug-on-quit' state."
+ (when debug-on-quit
+ (propertize (doom-modeline-debug-icon 'doom-modeline-warning)
+ 'help-echo "Debug on Quit
+mouse-1: Toggle Debug on Quit"
+ 'mouse-face 'mode-line-highlight
+ 'local-map (make-mode-line-mouse-map 'mouse-1 #'toggle-debug-on-quit))))
+
+(doom-modeline-def-segment debug
+ "The current debug state."
+ (when (and (doom-modeline--active)
+ (not doom-modeline--limited-width-p))
+ (let* ((dap doom-modeline--debug-dap)
+ (edebug (doom-modeline--debug-edebug))
+ (on-error (doom-modeline--debug-on-error))
+ (on-quit (doom-modeline--debug-on-quit))
+ (vsep (doom-modeline-vspc))
+ (sep (and (or dap edebug on-error on-quit) (doom-modeline-spc))))
+ (concat sep
+ (and dap (concat dap (and (or edebug on-error on-quit) vsep)))
+ (and edebug (concat edebug (and (or on-error on-quit) vsep)))
+ (and on-error (concat on-error (and on-quit vsep)))
+ on-quit
+ sep))))
+
+
+;;
+;; PDF pages
+;;
+
+(defvar-local doom-modeline--pdf-pages nil)
+(defun doom-modeline-update-pdf-pages ()
+ "Update PDF pages."
+ (setq doom-modeline--pdf-pages
+ (format " P%d/%d "
+ (or (eval `(pdf-view-current-page)) 0)
+ (pdf-cache-number-of-pages))))
+(add-hook 'pdf-view-change-page-hook #'doom-modeline-update-pdf-pages)
+
+(doom-modeline-def-segment pdf-pages
+ "Display PDF pages."
+ (propertize doom-modeline--pdf-pages
+ 'face (if (doom-modeline--active) 'mode-line 'mode-line-inactive)))
+
+
+;;
+;; `mu4e-alert' notifications
+;;
+
+(doom-modeline-def-segment mu4e
+ "Show notifications of any unread emails in `mu4e'."
+ (when (and doom-modeline-mu4e
+ (doom-modeline--active)
+ (not doom-modeline--limited-width-p)
+ (bound-and-true-p mu4e-alert-mode-line)
+ (numberp mu4e-alert-mode-line)
+ ;; don't display if the unread mails count is zero
+ (> mu4e-alert-mode-line 0))
+ (concat
+ (doom-modeline-spc)
+ (propertize
+ (concat
+ (doom-modeline-icon 'material "email" "π§" "#"
+ :face 'doom-modeline-notification
+ :height 1.1 :v-adjust -0.2)
+ (doom-modeline-vspc)
+ (propertize
+ (if (> mu4e-alert-mode-line doom-modeline-number-limit)
+ (format "%d+" doom-modeline-number-limit)
+ (number-to-string mu4e-alert-mode-line))
+ 'face '(:inherit
+ (doom-modeline-unread-number doom-modeline-notification))))
+ 'mouse-face 'mode-line-highlight
+ 'keymap '(mode-line keymap
+ (mouse-1 . mu4e-alert-view-unread-mails)
+ (mouse-2 . mu4e-alert-view-unread-mails)
+ (mouse-3 . mu4e-alert-view-unread-mails))
+ 'help-echo (concat (if (= mu4e-alert-mode-line 1)
+ "You have an unread email"
+ (format "You have %s unread emails" mu4e-alert-mode-line))
+ "\nClick here to view "
+ (if (= mu4e-alert-mode-line 1) "it" "them")))
+ (doom-modeline-spc))))
+
+(defun doom-modeline-override-mu4e-alert-modeline (&rest _)
+ "Delete `mu4e-alert-mode-line' from global modeline string."
+ (when (featurep 'mu4e-alert)
+ (if (and doom-modeline-mu4e
+ (bound-and-true-p doom-modeline-mode))
+ ;; Delete original modeline
+ (progn
+ (setq global-mode-string
+ (delete '(:eval mu4e-alert-mode-line) global-mode-string))
+ (setq mu4e-alert-modeline-formatter #'identity))
+ ;; Recover default settings
+ (setq mu4e-alert-modeline-formatter #'mu4e-alert-default-mode-line-formatter))))
+(advice-add #'mu4e-alert-enable-mode-line-display
+ :after #'doom-modeline-override-mu4e-alert-modeline)
+(add-hook 'doom-modeline-mode-hook #'doom-modeline-override-mu4e-alert-modeline)
+
+
+;;
+;; `gnus' notifications
+;;
+
+(defvar doom-modeline--gnus-unread-mail 0)
+(defvar doom-modeline--gnus-started nil
+ "Used to determine if gnus has started.")
+(defun doom-modeline-update-gnus-status (&rest _)
+ "Get the total number of unread news of gnus group."
+ (setq doom-modeline--gnus-unread-mail
+ (when (and doom-modeline-gnus
+ doom-modeline--gnus-started)
+ (let ((total-unread-news-number 0))
+ (mapc (lambda (g)
+ (let* ((group (car g))
+ (unread (eval `(gnus-group-unread ,group))))
+ (when (and (not (seq-contains-p doom-modeline-gnus-excluded-groups group))
+ (numberp unread)
+ (> unread 0))
+ (setq total-unread-news-number (+ total-unread-news-number unread)))))
+ gnus-newsrc-alist)
+ total-unread-news-number))))
+
+;; Update the modeline after changes have been made
+(add-hook 'gnus-group-update-hook #'doom-modeline-update-gnus-status)
+(add-hook 'gnus-summary-update-hook #'doom-modeline-update-gnus-status)
+(add-hook 'gnus-group-update-group-hook #'doom-modeline-update-gnus-status)
+(add-hook 'gnus-after-getting-new-news-hook #'doom-modeline-update-gnus-status)
+
+;; Only start to listen to gnus when gnus is actually running
+(defun doom-modeline-start-gnus-listener ()
+ "Start GNUS listener."
+ (when (and doom-modeline-gnus
+ (not doom-modeline--gnus-started))
+ (setq doom-modeline--gnus-started t)
+ ;; Scan gnus in the background if the timer is higher than 0
+ (doom-modeline-update-gnus-status)
+ (if (> doom-modeline-gnus-timer 0)
+ (gnus-demon-add-handler 'gnus-demon-scan-news doom-modeline-gnus-timer doom-modeline-gnus-idle))))
+(add-hook 'gnus-started-hook #'doom-modeline-start-gnus-listener)
+
+;; Stop the listener if gnus isn't running
+(defun doom-modeline-stop-gnus-listener ()
+ "Stop GNUS listener."
+ (setq doom-modeline--gnus-started nil))
+(add-hook 'gnus-exit-gnus-hook #'doom-modeline-stop-gnus-listener)
+
+(doom-modeline-def-segment gnus
+ "Show notifications of any unread emails in `gnus'."
+ (when (and (doom-modeline--active)
+ (not doom-modeline--limited-width-p)
+ doom-modeline-gnus
+ doom-modeline--gnus-started
+ ;; Don't display if the unread mails count is zero
+ (numberp doom-modeline--gnus-unread-mail)
+ (> doom-modeline--gnus-unread-mail 0))
+ (concat
+ (doom-modeline-spc)
+ (propertize
+ (concat
+ (doom-modeline-icon 'material "email" "π§" "#"
+ :face 'doom-modeline-notification
+ :height 1.1 :v-adjust -0.2)
+ (doom-modeline-vspc)
+ (propertize
+ (if (> doom-modeline--gnus-unread-mail doom-modeline-number-limit)
+ (format "%d+" doom-modeline-number-limit)
+ (number-to-string doom-modeline--gnus-unread-mail))
+ 'face '(:inherit
+ (doom-modeline-unread-number doom-modeline-notification))))
+ 'mouse-face 'mode-line-highlight
+ 'help-echo (if (= doom-modeline--gnus-unread-mail 1)
+ "You have an unread email"
+ (format "You have %s unread emails" doom-modeline--gnus-unread-mail)))
+ (doom-modeline-spc))))
+
+
+;;
+;; IRC notifications
+;;
+
+(defun doom-modeline--shorten-irc (name)
+ "Wrapper for `tracking-shorten' and `erc-track-shorten-function' with NAME.
+
+One key difference is that when `tracking-shorten' and
+`erc-track-shorten-function' returns nil we will instead return the original
+value of name. This is necessary in cases where the user has stylized the name
+to be an icon and we don't want to remove that so we just return the original."
+ (or (and (boundp 'tracking-shorten)
+ (car (tracking-shorten (list name))))
+ (and (boundp 'erc-track-shorten-function)
+ (functionp erc-track-shorten-function)
+ (car (funcall erc-track-shorten-function (list name))))
+ (and (boundp 'rcirc-short-buffer-name)
+ (rcirc-short-buffer-name name))
+ name))
+
+(defun doom-modeline--tracking-buffers (buffers)
+ "Logic to convert some irc BUFFERS to their font-awesome icon."
+ (mapconcat
+ (lambda (b)
+ (propertize
+ (doom-modeline--shorten-irc (funcall doom-modeline-irc-stylize b))
+ 'face '(:inherit (doom-modeline-unread-number doom-modeline-notification))
+ 'help-echo (format "IRC Notification: %s\nmouse-1: Switch to buffer" b)
+ 'mouse-face 'mode-line-highlight
+ 'local-map (make-mode-line-mouse-map 'mouse-1
+ (lambda ()
+ (interactive)
+ (when (buffer-live-p (get-buffer b))
+ (switch-to-buffer b))))))
+ buffers
+ (doom-modeline-vspc)))
+
+(defun doom-modeline--circe-p ()
+ "Check if `circe' is in use."
+ (boundp 'tracking-mode-line-buffers))
+
+(defun doom-modeline--erc-p ()
+ "Check if `erc' is in use."
+ (boundp 'erc-modified-channels-alist))
+
+(defun doom-modeline--rcirc-p ()
+ "Check if `rcirc' is in use."
+ (bound-and-true-p rcirc-track-minor-mode))
+
+(defun doom-modeline--get-buffers ()
+ "Gets the buffers that have activity."
+ (cond
+ ((doom-modeline--circe-p)
+ tracking-buffers)
+ ((doom-modeline--erc-p)
+ (mapcar (lambda (l)
+ (buffer-name (car l)))
+ erc-modified-channels-alist))
+ ((doom-modeline--rcirc-p)
+ (mapcar (lambda (b)
+ (buffer-name b))
+ rcirc-activity))))
+
+;; Create a modeline segment that contains all the irc tracked buffers
+(doom-modeline-def-segment irc-buffers
+ "The list of shortened, unread irc buffers."
+ (when (and doom-modeline-irc
+ (doom-modeline--active)
+ (not doom-modeline--limited-width-p))
+ (let* ((buffers (doom-modeline--get-buffers))
+ (number (length buffers)))
+ (when (> number 0)
+ (concat
+ (doom-modeline-spc)
+ (doom-modeline--tracking-buffers buffers)
+ (doom-modeline-spc))))))
+
+(doom-modeline-def-segment irc
+ "A notification icon for any unread irc buffer."
+ (when (and doom-modeline-irc
+ (doom-modeline--active)
+ (not doom-modeline--limited-width-p))
+ (let* ((buffers (doom-modeline--get-buffers))
+ (number (length buffers)))
+ (when (> number 0)
+ (concat
+ (doom-modeline-spc)
+
+ (propertize (concat
+ (doom-modeline-icon 'material "message" "π" "#"
+ :face 'doom-modeline-notification
+ :height 1.0 :v-adjust -0.225)
+ (doom-modeline-vspc)
+ ;; Display the number of unread buffers
+ (propertize (number-to-string number)
+ 'face '(:inherit
+ (doom-modeline-unread-number
+ doom-modeline-notification))))
+ 'help-echo (format "IRC Notifications: %s\n%s"
+ (mapconcat
+ (lambda (b) (funcall doom-modeline-irc-stylize b))
+ buffers
+ ", ")
+ (cond
+ ((doom-modeline--circe-p)
+ "mouse-1: Switch to previous unread buffer
+mouse-3: Switch to next unread buffer")
+ ((doom-modeline--erc-p)
+ "mouse-1: Switch to buffer
+mouse-3: Switch to next unread buffer")
+ ((doom-modeline--rcirc-p)
+ "mouse-1: Switch to server buffer
+mouse-3: Switch to next unread buffer")))
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (cond
+ ((doom-modeline--circe-p)
+ (define-key map [mode-line mouse-1]
+ #'tracking-previous-buffer)
+ (define-key map [mode-line mouse-3]
+ #'tracking-next-buffer))
+ ((doom-modeline--erc-p)
+ (define-key map [mode-line mouse-1]
+ #'erc-switch-to-buffer)
+ (define-key map [mode-line mouse-3]
+ #'erc-track-switch-buffer))
+ ((doom-modeline--rcirc-p)
+ (define-key map [mode-line mouse-1]
+ #'rcirc-switch-to-server-buffer)
+ (define-key map [mode-line mouse-3]
+ #'rcirc-next-active-buffer)))
+ map))
+
+ ;; Display the unread irc buffers as well
+ (when doom-modeline-irc-buffers
+ (concat (doom-modeline-spc)
+ (doom-modeline--tracking-buffers buffers)))
+
+ (doom-modeline-spc))))))
+
+(defun doom-modeline-override-rcirc-modeline ()
+ "Override default `rcirc' mode-line."
+ (if (bound-and-true-p doom-modeline-mode)
+ (setq global-mode-string
+ (delq 'rcirc-activity-string global-mode-string))
+ (when (and rcirc-track-minor-mode
+ (not (memq 'rcirc-activity-string global-mode-string)))
+ (setq global-mode-string
+ (append global-mode-string '(rcirc-activity-string))))))
+(add-hook 'rcirc-track-minor-mode-hook #'doom-modeline-override-rcirc-modeline)
+(add-hook 'doom-modeline-mode-hook #'doom-modeline-override-rcirc-modeline)
+
+
+;;
+;; Battery status
+;;
+
+(defvar doom-modeline--battery-status nil)
+(defun doom-modeline-update-battery-status ()
+ "Update battery status."
+ (setq doom-modeline--battery-status
+ (when (bound-and-true-p display-battery-mode)
+ (let* ((data (and battery-status-function
+ (functionp battery-status-function)
+ (funcall battery-status-function)))
+ (charging? (string-equal "AC" (cdr (assoc ?L data))))
+ (percentage (car (read-from-string (or (cdr (assq ?p data)) "ERR"))))
+ (valid-percentage? (and (numberp percentage)
+ (>= percentage 0)
+ (<= percentage battery-mode-line-limit)))
+ (face (if valid-percentage?
+ (cond (charging? 'doom-modeline-battery-charging)
+ ((< percentage battery-load-critical) 'doom-modeline-battery-critical)
+ ((< percentage 25) 'doom-modeline-battery-warning)
+ ((< percentage 95) 'doom-modeline-battery-normal)
+ (t 'doom-modeline-battery-full))
+ 'doom-modeline-battery-error))
+ (icon (if valid-percentage?
+ (cond (charging?
+ (doom-modeline-icon 'alltheicon "battery-charging" "π" "+"
+ :face face :height 1.4 :v-adjust -0.1))
+ ((> percentage 95)
+ (doom-modeline-icon 'faicon "battery-full" "π" "-"
+ :face face :v-adjust -0.0575))
+ ((> percentage 70)
+ (doom-modeline-icon 'faicon "battery-three-quarters" "π" "-"
+ :face face :v-adjust -0.0575))
+ ((> percentage 40)
+ (doom-modeline-icon 'faicon "battery-half" "π" "-"
+ :face face :v-adjust -0.0575))
+ ((> percentage battery-load-critical)
+ (doom-modeline-icon 'faicon "battery-quarter" "π" "-"
+ :face face :v-adjust -0.0575))
+ (t (doom-modeline-icon 'faicon "battery-empty" "π" "!"
+ :face face :v-adjust -0.0575)))
+ (doom-modeline-icon 'faicon "battery-empty" "β " "N/A"
+ :face face :v-adjust -0.0575)))
+ (text (if valid-percentage? (format "%d%%%%" percentage) ""))
+ (help-echo (if (and battery-echo-area-format data valid-percentage?)
+ (battery-format battery-echo-area-format data)
+ "Battery status not available")))
+ (cons (propertize icon 'help-echo help-echo)
+ (propertize text 'face face 'help-echo help-echo))))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-icon
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-icon val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (doom-modeline-update-battery-status))))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-unicode-fallback
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-unicode-fallback val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (doom-modeline-update-battery-status))))))
+
+(doom-modeline-def-segment battery
+ "Display battery status."
+ (when (and (doom-modeline--active)
+ (not doom-modeline--limited-width-p)
+ (bound-and-true-p display-battery-mode))
+ (concat (doom-modeline-spc)
+ (concat
+ (car doom-modeline--battery-status)
+ (doom-modeline-vspc)
+ (cdr doom-modeline--battery-status))
+ (doom-modeline-spc))))
+
+(defun doom-modeline-override-battery-modeline ()
+ "Override default battery mode-line."
+ (if (bound-and-true-p doom-modeline-mode)
+ (progn
+ (advice-add #'battery-update :override #'doom-modeline-update-battery-status)
+ (setq global-mode-string
+ (delq 'battery-mode-line-string global-mode-string))
+ (and (bound-and-true-p display-battery-mode) (battery-update)))
+ (progn
+ (advice-remove #'battery-update #'doom-modeline-update-battery-status)
+ (when (and display-battery-mode battery-status-function battery-mode-line-format
+ (not (memq 'battery-mode-line-string global-mode-string)))
+ (setq global-mode-string
+ (append global-mode-string '(battery-mode-line-string)))))))
+(add-hook 'display-battery-mode-hook #'doom-modeline-override-battery-modeline)
+(add-hook 'doom-modeline-mode-hook #'doom-modeline-override-battery-modeline)
+
+
+;;
+;; Package information
+;;
+
+(doom-modeline-def-segment package
+ "Show package information via `paradox'."
+ (let ((active (doom-modeline--active)))
+ (concat
+ (let ((front (format-mode-line 'mode-line-front-space)))
+ (if active
+ front
+ (propertize front 'face 'mode-line-inactive)))
+
+ (when (and doom-modeline-icon doom-modeline-major-mode-icon)
+ (concat
+ (doom-modeline-spc)
+ (doom-modeline-icon 'faicon "archive" nil nil
+ :face (if active
+ (if doom-modeline-major-mode-color-icon
+ 'all-the-icons-silver
+ 'mode-line)
+ 'mode-line-inactive)
+ :height 1.0
+ :v-adjust -0.0575)))
+ (let ((info (format-mode-line 'mode-line-buffer-identification)))
+ (if active
+ info
+ (propertize info 'face 'mode-line-inactive))))))
+
+
+;;
+;; Helm
+;;
+
+(defvar doom-modeline--helm-buffer-ids
+ '(("*helm*" . "HELM")
+ ("*helm M-x*" . "HELM M-x")
+ ("*swiper*" . "SWIPER")
+ ("*Projectile Perspectives*" . "HELM Projectile Perspectives")
+ ("*Projectile Layouts*" . "HELM Projectile Layouts")
+ ("*helm-ag*" . (lambda ()
+ (format "HELM Ag: Using %s"
+ (car (split-string helm-ag-base-command))))))
+ "Alist of custom helm buffer names to use.
+The cdr can also be a function that returns a name to use.")
+
+(doom-modeline-def-segment helm-buffer-id
+ "Helm session identifier."
+ (when (bound-and-true-p helm-alive-p)
+ (let ((active (doom-modeline--active)))
+ (concat
+ (doom-modeline-spc)
+ (when doom-modeline-icon
+ (concat
+ (doom-modeline-icon 'fileicon "elisp" nil nil
+ :face (if active
+ (if doom-modeline-major-mode-color-icon
+ 'all-the-icons-blue
+ 'mode-line)
+ 'mode-line-inactive)
+ :height 1.0
+ :v-adjust -0.15)
+ (doom-modeline-spc)))
+ (propertize
+ (let ((custom (cdr (assoc (buffer-name) doom-modeline--helm-buffer-ids)))
+ (case-fold-search t)
+ (name (replace-regexp-in-string "-" " " (buffer-name))))
+ (cond ((stringp custom) custom)
+ ((functionp custom) (funcall custom))
+ (t
+ (string-match "\\*helm:? \\(mode \\)?\\([^\\*]+\\)\\*" name)
+ (concat "HELM " (capitalize (match-string 2 name))))))
+ 'face (if active' doom-modeline-buffer-file 'mode-line-inactive))
+ (doom-modeline-spc)))))
+
+(doom-modeline-def-segment helm-number
+ "Number of helm candidates."
+ (when (bound-and-true-p helm-alive-p)
+ (let ((active (doom-modeline--active)))
+ (concat
+ (propertize (format " %d/%d"
+ (helm-candidate-number-at-point)
+ (helm-get-candidate-number t))
+ 'face (if active 'doom-modeline-buffer-path 'mode-line-inactive))
+ (propertize (format " (%d total) " (helm-get-candidate-number))
+ 'face (if active 'doom-modeline-info 'mode-line-inactive))))))
+
+(doom-modeline-def-segment helm-help
+ "Helm keybindings help."
+ (when (bound-and-true-p helm-alive-p)
+ (let ((active (doom-modeline--active)))
+ (-interleave
+ (mapcar (lambda (s)
+ (propertize (substitute-command-keys s)
+ 'face (if active
+ 'doom-modeline-buffer-file
+ 'mode-line-inactive)))
+ '("\\\\[helm-help]"
+ "\\\\[helm-select-action]"
+ "\\\\[helm-maybe-exit-minibuffer]/F1/F2..."))
+ (mapcar (lambda (s)
+ (propertize s 'face (if active 'mode-line 'mode-line-inactive)))
+ '("(help) " "(actions) " "(action) "))))))
+
+(doom-modeline-def-segment helm-prefix-argument
+ "Helm prefix argument."
+ (when (and (bound-and-true-p helm-alive-p)
+ helm--mode-line-display-prefarg)
+ (let ((arg (prefix-numeric-value (or prefix-arg current-prefix-arg))))
+ (unless (= arg 1)
+ (propertize (format "C-u %s" arg)
+ 'face (if (doom-modeline--active)
+ 'doom-modeline-info
+ 'mode-line-inactive))))))
+
+(defvar doom-modeline--helm-current-source nil
+ "The currently active helm source.")
+(doom-modeline-def-segment helm-follow
+ "Helm follow indicator."
+ (when (and (bound-and-true-p helm-alive-p)
+ doom-modeline--helm-current-source
+ (eq 1 (cdr (assq 'follow doom-modeline--helm-current-source))))
+ (propertize "HF" 'face (if (doom-modeline--active)
+ 'mode-line
+ 'mode-line-inactive))))
+
+;;
+;; Git timemachine
+;;
+
+(doom-modeline-def-segment git-timemachine
+ (let ((active (doom-modeline--active)))
+ (concat
+ (doom-modeline-spc)
+ (doom-modeline--buffer-mode-icon)
+ (doom-modeline--buffer-state-icon)
+ (propertize "*%b*" 'face (if active
+ 'doom-modeline-buffer-timemachine
+ 'mode-line-inactive)))))
+
+;;
+;; Markdown/Org preview
+;;
+
+(doom-modeline-def-segment grip
+ (when (bound-and-true-p grip-mode)
+ (concat
+ (doom-modeline-spc)
+ (let ((face (if (doom-modeline--active)
+ (if grip--process
+ (pcase (process-status grip--process)
+ ('run 'doom-modeline-buffer-path)
+ ('exit 'doom-modeline-warning)
+ (_ 'doom-modeline-urgent))
+ 'doom-modeline-urgent)
+ 'mode-line-inactive)))
+ (propertize (doom-modeline-icon 'material "pageview" "π" "@"
+ :face (if doom-modeline-icon
+ `(:inherit ,face :weight normal)
+ face)
+ :height 1.2 :v-adjust -0.2)
+ 'help-echo (format "Preview on %s
+mouse-1: Preview in browser
+mouse-2: Stop preview
+mouse-3: Restart preview"
+ (grip--preview-url))
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1]
+ #'grip-browse-preview)
+ (define-key map [mode-line mouse-2]
+ #'grip-stop-preview)
+ (define-key map [mode-line mouse-3]
+ #'grip-restart-preview)
+ map)))
+ (doom-modeline-spc))))
+
+;;
+;; Follow mode
+;;
+
+(doom-modeline-def-segment follow
+ (when (bound-and-true-p follow-mode)
+ (let* ((windows (follow-all-followers))
+ (nwindows (length windows))
+ (nfollowing (- (length (memq (selected-window) windows))
+ 1)))
+ (concat
+ (doom-modeline-spc)
+ (propertize (format "Follow %d/%d" (- nwindows nfollowing) nwindows)
+ 'face 'doom-modeline-buffer-minor-mode)))))
+
+(provide 'doom-modeline-segments)
+
+;;; doom-modeline-segments.el ends here
diff --git a/code/elpa/doom-modeline-20220412.853/doom-modeline.el b/code/elpa/doom-modeline-20220412.853/doom-modeline.el
new file mode 100644
index 0000000..b48bda5
--- /dev/null
+++ b/code/elpa/doom-modeline-20220412.853/doom-modeline.el
@@ -0,0 +1,311 @@
+;;; doom-modeline.el --- A minimal and modern mode-line -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2020 Vincent Zhang
+
+;; Author: Vincent Zhang
+;; Homepage: https://github.com/seagle0128/doom-modeline
+;; Version: 3.3.0
+;; Package-Requires: ((emacs "25.1") (all-the-icons "2.2.0") (shrink-path "0.2.0") (dash "2.11.0"))
+;; Keywords: faces mode-line
+
+;; This file is not part of GNU Emacs.
+
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see .
+;;
+
+;;; Commentary:
+;;
+;; This package offers a fancy and fast mode-line inspired by minimalism design.
+;;
+;; It's integrated into Doom Emacs (https://github.com/hlissner/doom-emacs) and
+;; Centaur Emacs (https://github.com/seagle0128/.emacs.d).
+;;
+;; The doom-modeline offers:
+;; - A match count panel (for anzu, iedit, multiple-cursors, symbol-overlay,
+;; evil-search and evil-substitute)
+;; - An indicator for recording a macro
+;; - Current environment version (e.g. python, ruby, go, etc.) in the major-mode
+;; - A customizable mode-line height (see doom-modeline-height)
+;; - A minor modes segment which is compatible with minions
+;; - An error/warning count segment for flymake/flycheck
+;; - A workspace number segment for eyebrowse
+;; - A perspective name segment for persp-mode
+;; - A window number segment for winum and window-numbering
+;; - An indicator for modal editing state, including evil, overwrite, god, ryo
+;; and xah-fly-keys, etc.
+;; - An indicator for battery status
+;; - An indicator for current input method
+;; - An indicator for debug state
+;; - An indicator for remote host
+;; - An indicator for LSP state with lsp-mode or eglot
+;; - An indicator for github notifications
+;; - An indicator for unread emails with mu4e-alert
+;; - An indicator for unread emails with gnus (basically builtin)
+;; - An indicator for irc notifications with circe, rcirc or erc.
+;; - An indicator for buffer position which is compatible with nyan-mode or poke-line
+;; - An indicator for party parrot
+;; - An indicator for PDF page number with pdf-tools
+;; - An indicator for markdown/org previews with grip
+;; - Truncated file name, file icon, buffer state and project name in buffer
+;; information segment, which is compatible with project, find-file-in-project
+;; and projectile
+;; - New mode-line for Info-mode buffers
+;; - New package mode-line for paradox
+;; - New mode-line for helm buffers
+;; - New mode-line for git-timemachine buffers
+;;
+;; Installation:
+;; From melpa, `M-x package-install RET doom-modeline RET`.
+;; In `init.el`,
+;; (require 'doom-modeline)
+;; (doom-modeline-mode 1)
+;; or
+;; (use-package doom-modeline
+;; :ensure t
+;; :hook (after-init . doom-modeline-mode))
+;;
+
+;;; Code:
+
+(require 'doom-modeline-core)
+(require 'doom-modeline-segments)
+
+
+;;
+;; Mode lines
+;;
+
+(doom-modeline-def-modeline 'main
+ '(bar workspace-name window-number modals matches follow buffer-info remote-host buffer-position word-count parrot selection-info)
+ '(objed-state misc-info persp-name battery grip irc mu4e gnus github debug repl lsp minor-modes input-method indent-info buffer-encoding major-mode process vcs checker))
+
+(doom-modeline-def-modeline 'minimal
+ '(bar matches buffer-info-simple)
+ '(media-info major-mode))
+
+(doom-modeline-def-modeline 'special
+ '(bar window-number modals matches buffer-info buffer-position word-count parrot selection-info)
+ '(objed-state misc-info battery irc-buffers debug minor-modes input-method indent-info buffer-encoding major-mode process))
+
+(doom-modeline-def-modeline 'project
+ '(bar window-number modals buffer-default-directory)
+ '(misc-info battery irc mu4e gnus github debug minor-modes input-method major-mode process))
+
+(doom-modeline-def-modeline 'dashboard
+ '(bar window-number buffer-default-directory-simple)
+ '(misc-info battery irc mu4e gnus github debug minor-modes input-method major-mode process))
+
+(doom-modeline-def-modeline 'vcs
+ '(bar window-number modals matches buffer-info buffer-position parrot selection-info)
+ '(misc-info battery irc mu4e gnus github debug minor-modes buffer-encoding major-mode process))
+
+(doom-modeline-def-modeline 'package
+ '(bar window-number package)
+ '(misc-info major-mode process))
+
+(doom-modeline-def-modeline 'info
+ '(bar window-number buffer-info info-nodes buffer-position parrot selection-info)
+ '(misc-info buffer-encoding major-mode))
+
+(doom-modeline-def-modeline 'media
+ '(bar window-number buffer-size buffer-info)
+ '(misc-info media-info major-mode process vcs))
+
+(doom-modeline-def-modeline 'message
+ '(bar window-number modals matches buffer-info-simple buffer-position word-count parrot selection-info)
+ '(objed-state misc-info battery debug minor-modes input-method indent-info buffer-encoding major-mode))
+
+(doom-modeline-def-modeline 'pdf
+ '(bar window-number matches buffer-info pdf-pages)
+ '(misc-info major-mode process vcs))
+
+(doom-modeline-def-modeline 'org-src
+ '(bar window-number modals matches buffer-info-simple buffer-position word-count parrot selection-info)
+ '(objed-state misc-info debug lsp minor-modes input-method indent-info buffer-encoding major-mode process checker))
+
+(doom-modeline-def-modeline 'helm
+ '(bar helm-buffer-id helm-number helm-follow helm-prefix-argument)
+ '(helm-help))
+
+(doom-modeline-def-modeline 'timemachine
+ '(bar window-number modals matches git-timemachine buffer-position word-count parrot selection-info)
+ '(misc-info minor-modes indent-info buffer-encoding major-mode))
+
+
+;;
+;; Interfaces
+;;
+
+;;;###autoload
+(defun doom-modeline-init ()
+ "Initialize doom mode-line."
+ (doom-modeline-mode 1))
+(make-obsolete 'doom-modeline-init 'doom-modeline-mode "1.6.0")
+
+;;;###autoload
+(defun doom-modeline-set-main-modeline (&optional default)
+ "Set main mode-line.
+If DEFAULT is non-nil, set the default mode-line for all buffers."
+ (doom-modeline-set-modeline 'main default))
+
+;;;###autoload
+(defun doom-modeline-set-minimal-modeline ()
+ "Set minimal mode-line."
+ (doom-modeline-set-modeline 'minimal))
+
+;;;###autoload
+(defun doom-modeline-set-special-modeline ()
+ "Set special mode-line."
+ (doom-modeline-set-modeline 'special))
+
+;;;###autoload
+(defun doom-modeline-set-project-modeline ()
+ "Set project mode-line."
+ (doom-modeline-set-modeline 'project))
+
+;;;###autoload
+(defun doom-modeline-set-dashboard-modeline ()
+ "Set dashboard mode-line."
+ (doom-modeline-set-modeline 'dashboard))
+
+;;;###autoload
+(defun doom-modeline-set-vcs-modeline ()
+ "Set vcs mode-line."
+ (doom-modeline-set-modeline 'vcs))
+
+;;;###autoload
+(defun doom-modeline-set-info-modeline ()
+ "Set Info mode-line."
+ (doom-modeline-set-modeline 'info))
+
+;;;###autoload
+(defun doom-modeline-set-package-modeline ()
+ "Set package mode-line."
+ (doom-modeline-set-modeline 'package))
+
+;;;###autoload
+(defun doom-modeline-set-media-modeline ()
+ "Set media mode-line."
+ (doom-modeline-set-modeline 'media))
+
+;;;###autoload
+(defun doom-modeline-set-message-modeline ()
+ "Set message mode-line."
+ (doom-modeline-set-modeline 'message))
+
+;;;###autoload
+(defun doom-modeline-set-pdf-modeline ()
+ "Set pdf mode-line."
+ (doom-modeline-set-modeline 'pdf))
+
+;;;###autoload
+(defun doom-modeline-set-org-src-modeline ()
+ "Set org-src mode-line."
+ (doom-modeline-set-modeline 'org-src))
+
+;;;###autoload
+(defun doom-modeline-set-helm-modeline (&rest _) ; To advice helm
+ "Set helm mode-line."
+ (doom-modeline-set-modeline 'helm))
+
+;;;###autoload
+(defun doom-modeline-set-timemachine-modeline ()
+ "Set timemachine mode-line."
+ (doom-modeline-set-modeline 'timemachine))
+
+
+;;
+;; Minor mode
+;;
+
+(defvar doom-modeline-mode-map (make-sparse-keymap))
+
+;; Suppress warnings
+(defvar 2C-mode-line-format)
+(declare-function helm-display-mode-line "ext:helm-core")
+
+;;;###autoload
+(define-minor-mode doom-modeline-mode
+ "Toggle doom-modeline on or off."
+ :group 'doom-modeline
+ :global t
+ :lighter nil
+ :keymap doom-modeline-mode-map
+ (if doom-modeline-mode
+ (progn
+ (doom-modeline-refresh-bars) ; Create bars
+ (doom-modeline-set-main-modeline t) ; Set default mode-line
+
+ ;; Apply to all existing buffers.
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (doom-modeline-set-main-modeline)))
+
+ ;; For two-column editing
+ (setq 2C-mode-line-format (doom-modeline 'special))
+
+ ;; Add hooks
+ (add-hook 'Info-mode-hook #'doom-modeline-set-info-modeline)
+ (add-hook 'dired-mode-hook #'doom-modeline-set-project-modeline)
+ (add-hook 'dashboard-mode-hook #'doom-modeline-set-dashboard-modeline)
+ (add-hook 'image-mode-hook #'doom-modeline-set-media-modeline)
+ (add-hook 'message-mode-hook #'doom-modeline-set-message-modeline)
+ (add-hook 'git-commit-mode-hook #'doom-modeline-set-message-modeline)
+ (add-hook 'magit-mode-hook #'doom-modeline-set-vcs-modeline)
+ (add-hook 'circe-mode-hook #'doom-modeline-set-special-modeline)
+ (add-hook 'erc-mode-hook #'doom-modeline-set-special-modeline)
+ (add-hook 'rcirc-mode-hook #'doom-modeline-set-special-modeline)
+ (add-hook 'pdf-view-mode-hook #'doom-modeline-set-pdf-modeline)
+ (add-hook 'org-src-mode-hook #'doom-modeline-set-org-src-modeline)
+ (add-hook 'git-timemachine-mode-hook #'doom-modeline-set-timemachine-modeline)
+ (add-hook 'paradox-menu-mode-hook #'doom-modeline-set-package-modeline)
+ (add-hook 'xwidget-webkit-mode-hook #'doom-modeline-set-minimal-modeline)
+
+ ;; Add advices
+ (advice-add #'helm-display-mode-line :after #'doom-modeline-set-helm-modeline))
+ (progn
+ ;; Restore mode-line
+ (let ((original-format (doom-modeline--original-value 'mode-line-format)))
+ (setq-default mode-line-format original-format)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (setq mode-line-format original-format))))
+
+ ;; For two-column editing
+ (setq 2C-mode-line-format (doom-modeline--original-value '2C-mode-line-format))
+
+ ;; Remove hooks
+ (remove-hook 'Info-mode-hook #'doom-modeline-set-info-modeline)
+ (remove-hook 'dired-mode-hook #'doom-modeline-set-project-modeline)
+ (remove-hook 'dashboard-mode-hook #'doom-modeline-set-dashboard-modeline)
+ (remove-hook 'image-mode-hook #'doom-modeline-set-media-modeline)
+ (remove-hook 'message-mode-hook #'doom-modeline-set-message-modeline)
+ (remove-hook 'git-commit-mode-hook #'doom-modeline-set-message-modeline)
+ (remove-hook 'magit-mode-hook #'doom-modeline-set-vcs-modeline)
+ (remove-hook 'circe-mode-hook #'doom-modeline-set-special-modeline)
+ (remove-hook 'erc-mode-hook #'doom-modeline-set-special-modeline)
+ (remove-hook 'rcirc-mode-hook #'doom-modeline-set-special-modeline)
+ (remove-hook 'pdf-view-mode-hook #'doom-modeline-set-pdf-modeline)
+ (remove-hook 'org-src-mode-hook #'doom-modeline-set-org-src-modeline)
+ (remove-hook 'git-timemachine-mode-hook #'doom-modeline-set-timemachine-modeline)
+ (remove-hook 'paradox-menu-mode-hook #'doom-modeline-set-package-modeline)
+ (remove-hook 'xwidget-webkit-mode-hook #'doom-modeline-set-minimal-modeline)
+
+ ;; Remove advices
+ (advice-remove #'helm-display-mode-line #'doom-modeline-set-helm-modeline))))
+
+(provide 'doom-modeline)
+
+;;; doom-modeline.el ends here
diff --git a/code/elpa/shrink-path-20190208.1335/shrink-path-autoloads.el b/code/elpa/shrink-path-20190208.1335/shrink-path-autoloads.el
new file mode 100644
index 0000000..776b017
--- /dev/null
+++ b/code/elpa/shrink-path-20190208.1335/shrink-path-autoloads.el
@@ -0,0 +1,22 @@
+;;; shrink-path-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "shrink-path" "shrink-path.el" (0 0 0 0))
+;;; Generated autoloads from shrink-path.el
+
+(register-definition-prefixes "shrink-path" '("shrink-path-"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; shrink-path-autoloads.el ends here
diff --git a/code/elpa/shrink-path-20190208.1335/shrink-path-pkg.el b/code/elpa/shrink-path-20190208.1335/shrink-path-pkg.el
new file mode 100644
index 0000000..c568bd0
--- /dev/null
+++ b/code/elpa/shrink-path-20190208.1335/shrink-path-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from shrink-path.el -*- no-byte-compile: t -*-
+(define-package "shrink-path" "20190208.1335" "fish-style path" '((emacs "24") (s "1.6.1") (dash "1.8.0") (f "0.10.0")) :commit "c14882c8599aec79a6e8ef2d06454254bb3e1e41" :authors '(("Benjamin Andresen")) :maintainer '("Benjamin Andresen") :url "https://gitlab.com/bennya/shrink-path.el")
diff --git a/code/elpa/shrink-path-20190208.1335/shrink-path.el b/code/elpa/shrink-path-20190208.1335/shrink-path.el
new file mode 100644
index 0000000..154bfd6
--- /dev/null
+++ b/code/elpa/shrink-path-20190208.1335/shrink-path.el
@@ -0,0 +1,150 @@
+;;; shrink-path.el --- fish-style path -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017 Benjamin Andresen
+
+;; Author: Benjamin Andresen
+;; Version: 0.3.1
+;; Package-Version: 20190208.1335
+;; Package-Commit: c14882c8599aec79a6e8ef2d06454254bb3e1e41
+;; URL: https://gitlab.com/bennya/shrink-path.el
+;; Package-Requires: ((emacs "24") (s "1.6.1") (dash "1.8.0") (f "0.10.0"))
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file LICENSE. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Provides functions that offer fish shell[1] path truncation.
+;; Directory /usr/share/emacs/site-lisp => /u/s/e/site-lisp
+;;
+;; Also includes utility functions that make integration in eshell or the
+;; modeline easier.
+;;
+;; [1] https://fishshell.com/
+
+
+;;; Code:
+(require 'dash)
+(require 's)
+(require 'f)
+(require 'rx)
+
+(defun shrink-path--truncate (str)
+ "Return STR's first character or first two characters if hidden."
+ (substring str 0 (if (s-starts-with? "." str) 2 1)))
+
+(defun shrink-path--dirs-internal (full-path &optional truncate-all)
+ "Return fish-style truncated string based on FULL-PATH.
+Optional parameter TRUNCATE-ALL will cause the function to truncate the last
+directory too."
+ (let* ((home (expand-file-name "~"))
+ (path (replace-regexp-in-string
+ (s-concat "^" home) "~" full-path))
+ (split (s-split "/" path 'omit-nulls))
+ (split-len (length split))
+ shrunk)
+ (->> split
+ (--map-indexed (if (= it-index (1- split-len))
+ (if truncate-all (shrink-path--truncate it) it)
+ (shrink-path--truncate it)))
+ (s-join "/")
+ (setq shrunk))
+ (s-concat (unless (s-matches? (rx bos (or "~" "/")) shrunk) "/")
+ shrunk
+ (unless (s-ends-with? "/" shrunk) "/"))))
+
+
+(defun shrink-path-dirs (&optional path truncate-tail)
+ "Given PATH return fish-styled shrunken down path.
+TRUNCATE-TAIL will cause the function to truncate the last directory too."
+ (let* ((path (or path default-directory))
+ (path (f-full path)))
+ (cond
+ ((s-equals? (f-short path) "/") "/")
+ ((s-matches? (rx bos (or "~" "/") eos) "~/"))
+ (t (shrink-path--dirs-internal path truncate-tail)))))
+
+(defun shrink-path-expand (str &optional absolute-p)
+ "Return expanded path from STR if found or list of matches on multiple.
+The path referred to by STR has to exist for this to work.
+If ABSOLUTE-P is t the returned path will be absolute."
+ (let* ((str-split (s-split "/" str 'omit-nulls))
+ (head (car str-split)))
+ (if (= (length str-split) 1)
+ (s-concat "/" str-split)
+ (--> (-drop 1 str-split) ;; drop head
+ (-map (lambda (e) (s-concat e "*")) it)
+ (-drop-last 1 it) ;; drop tail as it may not exist
+ (s-join "/" it)
+ (s-concat (if (s-equals? head "~") "~/" head) it)
+ (f-glob it)
+ (-map (lambda (e) (s-concat e "/" (-last-item str-split))) it)
+ (if absolute-p (-map #'f-full it) (-map #'f-abbrev it))
+ (if (= (length it) 1) (car it) it)))))
+
+(defun shrink-path-prompt (&optional pwd)
+ "Return cons of BASE and DIR for PWD.
+If PWD isn't provided will default to `default-directory'."
+ (let* ((pwd (or pwd default-directory))
+ (shrunk (shrink-path-dirs pwd))
+ (split (--> shrunk (s-split "/" it 'omit-nulls)))
+ base dir)
+ (setq dir (or (-last-item split) "/"))
+ (setq base (if (s-equals? dir "/") ""
+ (s-chop-suffix (s-concat dir "/") shrunk)))
+ (cons base dir)))
+
+(defun shrink-path-file (file &optional truncate-tail)
+ "Return FILE's shrunk down path and filename.
+TRUNCATE-TAIL controls if the last directory should also be shortened."
+ (let ((filename (f-filename file))
+ (dirname (f-dirname file)))
+ (s-concat (shrink-path-dirs dirname truncate-tail) filename)))
+
+(defun shrink-path-file-expand (str &optional exists-p absolute-p)
+ "Return STR's expanded filename.
+The path referred to by STR has to exist for this to work.
+If EXISTS-P is t the filename also has to exist.
+If ABSOLUTE-P is t the returned path will be absolute."
+ (let ((expanded (shrink-path-expand str absolute-p)))
+ (if (and expanded exists-p)
+ (if (f-exists? expanded) expanded)
+ expanded)))
+
+(defun shrink-path-file-mixed (shrink-path rel-path filename)
+ "Returns list of mixed truncated file name locations.
+
+Consists of SHRINK-PATH's parent, SHRINK-PATH basename, relative REL-PATH and
+FILENAME.
+For use in modeline or prompts, etc."
+ (let ((shrunk-dirs (shrink-path-prompt shrink-path))
+ sp-parent sp-rel rel-rel nd-file)
+
+ (when (f-descendant-of? filename shrink-path)
+ (when shrunk-dirs
+ (setq sp-parent (car shrunk-dirs)
+ sp-rel (cdr shrunk-dirs)))
+ (setq rel-rel (if (or (f-same? rel-path shrink-path)
+ (s-equals? (f-relative rel-path shrink-path) "."))
+ nil
+ (f-relative rel-path shrink-path)))
+ (setq nd-file (file-name-nondirectory filename))
+
+ (list sp-parent sp-rel rel-rel nd-file))))
+
+(provide 'shrink-path)
+;;; shrink-path.el ends here
diff --git a/common/fonts/all-the-icons.ttf b/common/fonts/all-the-icons.ttf
new file mode 100644
index 0000000..634d48e
Binary files /dev/null and b/common/fonts/all-the-icons.ttf differ
diff --git a/common/fonts/file-icons.ttf b/common/fonts/file-icons.ttf
new file mode 100644
index 0000000..dd42225
Binary files /dev/null and b/common/fonts/file-icons.ttf differ
diff --git a/common/fonts/fontawesome.ttf b/common/fonts/fontawesome.ttf
new file mode 100644
index 0000000..f221e50
Binary files /dev/null and b/common/fonts/fontawesome.ttf differ
diff --git a/common/fonts/material-design-icons.ttf b/common/fonts/material-design-icons.ttf
new file mode 100644
index 0000000..7015564
Binary files /dev/null and b/common/fonts/material-design-icons.ttf differ
diff --git a/common/fonts/octicons.ttf b/common/fonts/octicons.ttf
new file mode 100644
index 0000000..6f3edd6
Binary files /dev/null and b/common/fonts/octicons.ttf differ
diff --git a/common/fonts/weathericons.ttf b/common/fonts/weathericons.ttf
new file mode 100644
index 0000000..948f0a5
Binary files /dev/null and b/common/fonts/weathericons.ttf differ
diff --git a/org/elpa/doom-modeline-20220412.853/doom-modeline-autoloads.el b/org/elpa/doom-modeline-20220412.853/doom-modeline-autoloads.el
new file mode 100644
index 0000000..481641c
--- /dev/null
+++ b/org/elpa/doom-modeline-20220412.853/doom-modeline-autoloads.el
@@ -0,0 +1,135 @@
+;;; doom-modeline-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "doom-modeline" "doom-modeline.el" (0 0 0 0))
+;;; Generated autoloads from doom-modeline.el
+
+(autoload 'doom-modeline-init "doom-modeline" "\
+Initialize doom mode-line." nil nil)
+
+(autoload 'doom-modeline-set-main-modeline "doom-modeline" "\
+Set main mode-line.
+If DEFAULT is non-nil, set the default mode-line for all buffers.
+
+\(fn &optional DEFAULT)" nil nil)
+
+(autoload 'doom-modeline-set-minimal-modeline "doom-modeline" "\
+Set minimal mode-line." nil nil)
+
+(autoload 'doom-modeline-set-special-modeline "doom-modeline" "\
+Set special mode-line." nil nil)
+
+(autoload 'doom-modeline-set-project-modeline "doom-modeline" "\
+Set project mode-line." nil nil)
+
+(autoload 'doom-modeline-set-dashboard-modeline "doom-modeline" "\
+Set dashboard mode-line." nil nil)
+
+(autoload 'doom-modeline-set-vcs-modeline "doom-modeline" "\
+Set vcs mode-line." nil nil)
+
+(autoload 'doom-modeline-set-info-modeline "doom-modeline" "\
+Set Info mode-line." nil nil)
+
+(autoload 'doom-modeline-set-package-modeline "doom-modeline" "\
+Set package mode-line." nil nil)
+
+(autoload 'doom-modeline-set-media-modeline "doom-modeline" "\
+Set media mode-line." nil nil)
+
+(autoload 'doom-modeline-set-message-modeline "doom-modeline" "\
+Set message mode-line." nil nil)
+
+(autoload 'doom-modeline-set-pdf-modeline "doom-modeline" "\
+Set pdf mode-line." nil nil)
+
+(autoload 'doom-modeline-set-org-src-modeline "doom-modeline" "\
+Set org-src mode-line." nil nil)
+
+(autoload 'doom-modeline-set-helm-modeline "doom-modeline" "\
+Set helm mode-line.
+
+\(fn &rest _)" nil nil)
+
+(autoload 'doom-modeline-set-timemachine-modeline "doom-modeline" "\
+Set timemachine mode-line." nil nil)
+
+(defvar doom-modeline-mode nil "\
+Non-nil if Doom-Modeline mode is enabled.
+See the `doom-modeline-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `doom-modeline-mode'.")
+
+(custom-autoload 'doom-modeline-mode "doom-modeline" nil)
+
+(autoload 'doom-modeline-mode "doom-modeline" "\
+Toggle doom-modeline on or off.
+
+This is a minor mode. If called interactively, toggle the
+`Doom-Modeline mode' mode. If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable
+the mode if ARG is nil, omitted, or is a positive number.
+Disable the mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value \\='doom-modeline-mode)'.
+
+The mode's hook is called both when the mode is enabled and when
+it is disabled.
+
+\(fn &optional ARG)" t nil)
+
+(register-definition-prefixes "doom-modeline" '("doom-modeline-mode-map"))
+
+;;;***
+
+;;;### (autoloads nil "doom-modeline-core" "doom-modeline-core.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-modeline-core.el
+
+(register-definition-prefixes "doom-modeline-core" '("doom-modeline"))
+
+;;;***
+
+;;;### (autoloads nil "doom-modeline-env" "doom-modeline-env.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-modeline-env.el
+ (autoload 'doom-modeline-env-setup-python "doom-modeline-env")
+ (autoload 'doom-modeline-env-setup-ruby "doom-modeline-env")
+ (autoload 'doom-modeline-env-setup-perl "doom-modeline-env")
+ (autoload 'doom-modeline-env-setup-go "doom-modeline-env")
+ (autoload 'doom-modeline-env-setup-elixir "doom-modeline-env")
+ (autoload 'doom-modeline-env-setup-rust "doom-modeline-env")
+
+(register-definition-prefixes "doom-modeline-env" '("doom-modeline-"))
+
+;;;***
+
+;;;### (autoloads nil "doom-modeline-segments" "doom-modeline-segments.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from doom-modeline-segments.el
+
+(register-definition-prefixes "doom-modeline-segments" '("doom-modeline-"))
+
+;;;***
+
+;;;### (autoloads nil nil ("doom-modeline-pkg.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; doom-modeline-autoloads.el ends here
diff --git a/org/elpa/doom-modeline-20220412.853/doom-modeline-core.el b/org/elpa/doom-modeline-20220412.853/doom-modeline-core.el
new file mode 100644
index 0000000..86360f1
--- /dev/null
+++ b/org/elpa/doom-modeline-20220412.853/doom-modeline-core.el
@@ -0,0 +1,1394 @@
+;;; doom-modeline-core.el --- The core libraries for doom-modeline -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2020 Vincent Zhang
+
+;; This file is not part of GNU Emacs.
+
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see .
+;;
+
+;;; Commentary:
+;;
+;; The core libraries for doom-modeline.
+;;
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'subr-x)
+(require 'dash)
+(require 'all-the-icons)
+(require 'shrink-path)
+
+
+;;
+;; Compatibility
+;;
+
+(eval-and-compile
+ (when (< emacs-major-version 26)
+ ;; Define `if-let*' and `when-let*' variants for 25 users.
+ (unless (fboundp 'if-let*) (defalias 'if-let* #'if-let))
+ (unless (fboundp 'when-let*) (defalias 'when-let* #'when-let))))
+
+;; Donβt compact font caches during GC.
+(when (eq system-type 'windows-nt)
+ (setq inhibit-compacting-font-caches t))
+
+;;`file-local-name' is introduced in 25.2.2.
+(unless (fboundp 'file-local-name)
+ (defun file-local-name (file)
+ "Return the local name component of FILE.
+It returns a file name which can be used directly as argument of
+`process-file', `start-file-process', or `shell-command'."
+ (or (file-remote-p file 'localname) file)))
+
+;; Set correct font width for `all-the-icons' for appropriate mode-line width.
+;; @see https://emacs.stackexchange.com/questions/14420/how-can-i-fix-incorrect-character-width
+(defun doom-modeline--set-char-widths (alist)
+ "Set correct widths of icons characters in ALIST."
+ (while (char-table-parent char-width-table)
+ (setq char-width-table (char-table-parent char-width-table)))
+ (dolist (pair alist)
+ (let ((width (car pair))
+ (chars (cdr pair))
+ (table (make-char-table nil)))
+ (dolist (char chars)
+ (set-char-table-range table char width))
+ (optimize-char-table table)
+ (set-char-table-parent table char-width-table)
+ (setq char-width-table table))))
+
+(defconst doom-modeline-rhs-icons-alist
+ '((2 . (;; VCS
+ ?\xf0ac ; git-compare
+ ?\xf023 ; git-merge
+ ?\xf03f ; arrow-down
+ ?\xf02d ; alert
+ ?\xf020 ; git-branch
+
+ ;; Checker
+ ?\xe611 ; do_not_disturb_alt
+ ?\xe5ca ; check
+ ?\xe192 ; access_time
+ ?\xe624 ; sim_card_alert
+ ?\xe034 ; pause
+ ?\xe645 ; priority_high
+
+ ;; Minor modes
+ ?\xf02f ; gear
+
+ ;; Persp
+ ?\xe2c7 ; folder
+
+ ;; Preview
+ ?\xe8a0 ; pageview
+
+ ;; REPL
+ ?\xf155 ; dollar-sign
+
+ ;; LSP
+ ?\xf135 ; rocket
+
+ ;; GitHub
+ ?\xf09b ; github
+
+ ;; Debug
+ ?\xf188 ; bug
+
+ ;; Mail
+ ?\xe0be ; email
+
+ ;; IRC
+ ?\xe0c9 ; message
+
+ ;; Battery
+ ?\xe939 ; battery-charging
+ ?\xf244 ; battery-empty
+ ?\xf240 ; battery-full
+ ?\xf242 ; battery-half
+ ?\xf243 ; battery-quarter
+ ?\xf241 ; battery-three-quarters
+ ))))
+
+(defun doom-modeline-set-char-widths (&rest _)
+ "Set char widths for the unicode icons."
+ (doom-modeline--set-char-widths doom-modeline-rhs-icons-alist))
+
+(if (and (daemonp)
+ (not (frame-parameter nil 'client)))
+ (add-hook 'after-make-frame-functions #'doom-modeline-set-char-widths)
+ (and (display-graphic-p) (doom-modeline-set-char-widths)))
+
+
+;;
+;; Customization
+;;
+
+(defgroup doom-modeline nil
+ "A minimal and modern mode-line."
+ :group 'mode-line
+ :link '(url-link :tag "Homepage" "https://github.com/seagle0128/doom-modeline"))
+
+(defcustom doom-modeline-support-imenu nil
+ "If non-nil, cause imenu to see `doom-modeline' declarations.
+This is done by adjusting `lisp-imenu-generic-expression' to
+include support for finding `doom-modeline-def-*' forms.
+
+Must be set before loading doom-modeline."
+ :type 'boolean
+ :set (lambda (_sym val)
+ (if val
+ (add-hook 'emacs-lisp-mode-hook #'doom-modeline-add-imenu)
+ (remove-hook 'emacs-lisp-mode-hook #'doom-modeline-add-imenu)))
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-height 25
+ "How tall the mode-line should be. It's only respected in GUI.
+If the actual char height is larger, it respects the actual char height.
+If `doom-modeline-height' is <= 0 the modeline will have default height."
+ :type 'integer
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-bar-width 4
+ "How wide the mode-line bar should be. It's only respected in GUI."
+ :type 'integer
+ :set (lambda (sym val)
+ (set sym (if (> val 0) val 1)))
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-hud nil
+ "Whether to use hud instead of default bar. It's only respected in GUI."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-hud-min-height 2
+ "Minimum height in pixels of the \"thumb\" of the hud.
+Only respected in GUI."
+ :type 'integer
+ :set (lambda (sym val)
+ (set sym (if (> val 1) val 1)))
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-window-width-limit 0.25
+ "The limit of the window width.
+
+If `window-width' is smaller than the limit, some information won't be
+displayed. It can be an integer or a float number. `nil' means no limit."
+ :type '(choice integer
+ float
+ (const :tag "Disable" nil))
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-project-detection 'auto
+ "How to detect the project root.
+
+nil means to use `default-directory'.
+
+The project management packages have some issues on detecting project root.
+e.g. `projectile' doesn't handle symlink folders well, while `project' is
+unable to handle sub-projects.
+Specify another one if you encounter the issue."
+ :type '(choice (const :tag "Auto-detect" auto)
+ (const :tag "Find File in Project" ffip)
+ (const :tag "Projectile" projectile)
+ (const :tag "Built-in Project" project)
+ (const :tag "Disable" nil))
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-buffer-file-name-style 'auto
+ "Determines the style used by `doom-modeline-buffer-file-name'.
+
+Given ~/Projects/FOSS/emacs/lisp/comint.el
+ auto => emacs/lisp/comint.el (in a project) or comint.el
+ truncate-upto-project => ~/P/F/emacs/lisp/comint.el
+ truncate-from-project => ~/Projects/FOSS/emacs/l/comint.el
+ truncate-with-project => emacs/l/comint.el
+ truncate-except-project => ~/P/F/emacs/l/comint.el
+ truncate-upto-root => ~/P/F/e/lisp/comint.el
+ truncate-all => ~/P/F/e/l/comint.el
+ truncate-nil => ~/Projects/FOSS/emacs/lisp/comint.el
+ relative-from-project => emacs/lisp/comint.el
+ relative-to-project => lisp/comint.el
+ file-name => comint.el
+ buffer-name => comint.el<2> (uniquify buffer name)"
+ :type '(choice (const auto)
+ (const truncate-upto-project)
+ (const truncate-upto-project)
+ (const truncate-from-project)
+ (const truncate-with-project)
+ (const truncate-except-project)
+ (const truncate-upto-root)
+ (const truncate-all)
+ (const truncate-nil)
+ (const relative-from-project)
+ (const relative-to-project)
+ (const file-name)
+ (const buffer-name))
+ :group'doom-modeline)
+
+(defcustom doom-modeline-icon t
+ "Whether display the icons in the mode-line.
+
+While using the server mode in GUI, should set the value explicitly."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-major-mode-icon t
+ "Whether display the icon for `major-mode'.
+
+It respects `doom-modeline-icon'."
+ :type 'boolean
+ :group'doom-modeline)
+
+(defcustom doom-modeline-major-mode-color-icon t
+ "Whether display the colorful icon for `major-mode'.
+
+It respects `all-the-icons-color-icons'."
+ :type 'boolean
+ :group'doom-modeline)
+
+(defcustom doom-modeline-buffer-state-icon t
+ "Whether display the icon for the buffer state.
+
+It respects `doom-modeline-icon'."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-buffer-modification-icon t
+ "Whether display the modification icon for the buffer.
+
+It respects `doom-modeline-icon' and `doom-modeline-buffer-state-icon'."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-unicode-fallback nil
+ "Whether to use unicode as a fallback (instead of ASCII) when not using icons."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-buffer-name t
+ "Whether display the buffer name."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-minor-modes nil
+ "Whether display the minor modes in the mode-line."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-enable-word-count nil
+ "If non-nil, a word count will be added to the selection-info modeline segment."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-continuous-word-count-modes
+ '(markdown-mode gfm-mode org-mode)
+ "Major modes in which to display word count continuously.
+
+It respects `doom-modeline-enable-word-count'."
+ :type '(repeat (symbol :tag "Major-Mode") )
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-buffer-encoding t
+ "Whether display the buffer encoding."
+ :type '(choice (const :tag "Always" t)
+ (const :tag "When non-default" nondefault)
+ (const :tag "Never" nil))
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-default-coding-system 'utf-8
+ "Default coding system for `doom-modeline-buffer-encoding' `nondefault'."
+ :type 'coding-system
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-default-eol-type 0
+ "Default EOL type for `doom-modeline-buffer-encoding' `nondefault'."
+ :type '(choice (const :tag "Unix-style LF" 0)
+ (const :tag "DOS-style CRLF" 1)
+ (const :tag "Mac-style CR" 2))
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-indent-info nil
+ "Whether display the indentation information."
+ :type 'boolean
+ :group 'doom-modeline)
+
+;; It is based upon `editorconfig-indentation-alist' but is used to read indentation levels instead
+;; of setting them. (https://github.com/editorconfig/editorconfig-emacs)
+(defcustom doom-modeline-indent-alist
+ '((apache-mode apache-indent-level)
+ (awk-mode c-basic-offset)
+ (bpftrace-mode c-basic-offset)
+ (c++-mode c-basic-offset)
+ (c-mode c-basic-offset)
+ (cmake-mode cmake-tab-width)
+ (coffee-mode coffee-tab-width)
+ (cperl-mode cperl-indent-level)
+ (crystal-mode crystal-indent-level)
+ (csharp-mode c-basic-offset)
+ (css-mode css-indent-offset)
+ (d-mode c-basic-offset)
+ (emacs-lisp-mode lisp-indent-offset)
+ (enh-ruby-mode enh-ruby-indent-level)
+ (erlang-mode erlang-indent-level)
+ (ess-mode ess-indent-offset)
+ (f90-mode f90-associate-indent
+ f90-continuation-indent
+ f90-critical-indent
+ f90-do-indent
+ f90-if-indent
+ f90-program-indent
+ f90-type-indent)
+ (feature-mode feature-indent-offset
+ feature-indent-level)
+ (fsharp-mode fsharp-continuation-offset
+ fsharp-indent-level
+ fsharp-indent-offset)
+ (groovy-mode groovy-indent-offset)
+ (haskell-mode haskell-indent-spaces
+ haskell-indent-offset
+ haskell-indentation-layout-offset
+ haskell-indentation-left-offset
+ haskell-indentation-starter-offset
+ haskell-indentation-where-post-offset
+ haskell-indentation-where-pre-offset
+ shm-indent-spaces)
+ (haxor-mode haxor-tab-width)
+ (idl-mode c-basic-offset)
+ (jade-mode jade-tab-width)
+ (java-mode c-basic-offset)
+ (js-mode js-indent-level)
+ (js-jsx-mode js-indent-level
+ sgml-basic-offset)
+ (js2-mode js2-basic-offset)
+ (js2-jsx-mode js2-basic-offset
+ sgml-basic-offset)
+ (js3-mode js3-indent-level)
+ (json-mode js-indent-level)
+ (julia-mode julia-indent-offset)
+ (kotlin-mode kotlin-tab-width)
+ (latex-mode tex-indent-basic)
+ (lisp-mode lisp-indent-offset)
+ (livescript-mode livescript-tab-width)
+ (lua-mode lua-indent-level)
+ (matlab-mode matlab-indent-level)
+ (mips-mode mips-tab-width)
+ (mustache-mode mustache-basic-offset)
+ (nasm-mode nasm-basic-offset)
+ (nginx-mode nginx-indent-level)
+ (nxml-mode nxml-child-indent)
+ (objc-mode c-basic-offset)
+ (octave-mode octave-block-offset)
+ (perl-mode perl-indent-level)
+ (php-mode c-basic-offset)
+ (pike-mode c-basic-offset)
+ (ps-mode ps-mode-tab)
+ (pug-mode pug-tab-width)
+ (puppet-mode puppet-indent-level)
+ (python-mode python-indent-offset)
+ (ruby-mode ruby-indent-level)
+ (rust-mode rust-indent-offset)
+ (rustic-mode rustic-indent-offset)
+ (scala-mode scala-indent:step)
+ (scss-mode css-indent-offset)
+ (sgml-mode sgml-basic-offset)
+ (sh-mode sh-basic-offset
+ sh-indentation)
+ (slim-mode slim-indent-offset)
+ (sml-mode sml-indent-level)
+ (tcl-mode tcl-indent-level
+ tcl-continued-indent-level)
+ (terra-mode terra-indent-level)
+ (typescript-mode typescript-indent-level)
+ (verilog-mode verilog-indent-level
+ verilog-indent-level-behavioral
+ verilog-indent-level-declaration
+ verilog-indent-level-module
+ verilog-cexp-indent
+ verilog-case-indent)
+ (web-mode web-mode-attr-indent-offset
+ web-mode-attr-value-indent-offset
+ web-mode-code-indent-offset
+ web-mode-css-indent-offset
+ web-mode-markup-indent-offset
+ web-mode-sql-indent-offset
+ web-mode-block-padding
+ web-mode-script-padding
+ web-mode-style-padding)
+ (yaml-mode yaml-indent-offset))
+ "Indentation retrieving variables matched to major modes used
+ when `doom-modeline-indent-info' is non-nil. When multiple
+ variables are specified for a mode, they will be tried resolved
+ in the given order."
+ :type '(alist :key-type symbol :value-type sexp)
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-checker-simple-format t
+ "If non-nil, only display one number for checker information if applicable."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-number-limit 99
+ "The maximum number displayed for notifications."
+ :type 'integer
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-vcs-max-length 12
+ "The maximum displayed length of the branch name of version control."
+ :type 'integer
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-workspace-name t
+ "Whether display the workspace name.
+
+Non-nil to display in the mode-line."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-persp-name t
+ "Whether display the perspective name.
+
+Non-nil to display in the mode-line."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-display-default-persp-name nil
+ "If non nil the default perspective name is displayed in the mode-line."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-persp-icon t
+ "If non nil the perspective name is displayed alongside a folder icon."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-repl t
+ "Whether display the `repl' state.
+
+Non-nil to display in the mode-line."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-lsp t
+ "Whether display the `lsp' state.
+
+Non-nil to display in the mode-line."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-github nil
+ "Whether display the GitHub notifications.
+
+It requires `ghub' and `async' packages."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-github-interval 1800 ; (* 30 60)
+ "The interval of checking GitHub."
+ :type 'integer
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-env-version t
+ "Whether display the environment version."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-modal-icon t
+ "Whether display the modal state icon.
+
+Including `evil', `overwrite', `god', `ryo' and `xah-fly-keys', etc."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-mu4e nil
+ "Whether display the mu4e notifications.
+
+It requires `mu4e-alert' package."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-gnus nil
+ "Whether to display notifications from gnus.
+
+It requires `gnus' to be setup"
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-gnus-timer 2
+ "The wait time in minutes before gnus fetches mail.
+
+If nil, don't set up a hook."
+ :type 'integer
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-gnus-idle nil
+ "Whether to wait an idle time to scan for news.
+
+When t, sets `doom-modeline-gnus-timer' as an idle timer. If a
+number, Emacs must have been idle this given time, checked after
+reach the defined timer, to fetch news. The time step can be
+configured in `gnus-demon-timestep'."
+ :type '(choice
+ (boolean :tag "Set `doom-modeline-gnus-timer' as an idle timer")
+ (number :tag "Set a custom idle timer"))
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-gnus-excluded-groups nil
+ "A list of groups to be excluded from the unread count.
+Groups' names list in `gnus-newsrc-alist'`"
+ :type '(repeat string)
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-irc t
+ "Whether display the irc notifications.
+
+It requires `circe' or `erc' package."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-irc-buffers nil
+ "Whether display the unread irc buffers."
+ :type 'boolean
+ :group 'doom-modeline)
+
+(defcustom doom-modeline-irc-stylize 'identity
+ "Function to stylize the irc buffer names."
+ :type 'function
+ :group 'doom-modeline)
+
+
+;;
+;; Faces
+;;
+
+(defgroup doom-modeline-faces nil
+ "The faces of `doom-modeline'."
+ :group 'doom-modeline
+ :group 'faces
+ :link '(url-link :tag "Homepage" "https://github.com/seagle0128/doom-modeline"))
+
+(defface doom-modeline-spc-face
+ '((t (:inherit mode-line)))
+ "Face used for the white space."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-spc-inactive-face
+ '((t (:inherit mode-line-inactive)))
+ "Face used for the inactive white space."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-vspc-face
+ '((t (:inherit variable-pitch)))
+ "Face used for the variable white space."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-vspc-inactive-face
+ '((t (:inherit (mode-line-inactive doom-modeline-vspc-face))))
+ "Face used for the variable white space."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-buffer-path
+ '((t (:inherit (mode-line-emphasis bold))))
+ "Face used for the dirname part of the buffer path."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-buffer-file
+ '((t (:inherit (mode-line-buffer-id bold))))
+ "Face used for the filename part of the mode-line buffer path."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-buffer-modified
+ '((t (:inherit (error bold) :background nil)))
+ "Face used for the 'unsaved' symbol in the mode-line."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-buffer-major-mode
+ '((t (:inherit (mode-line-emphasis bold))))
+ "Face used for the major-mode segment in the mode-line."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-buffer-minor-mode
+ '((t (:inherit font-lock-doc-face :slant normal)))
+ "Face used for the minor-modes segment in the mode-line."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-project-parent-dir
+ '((t (:inherit (font-lock-comment-face bold))))
+ "Face used for the project parent directory of the mode-line buffer path."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-project-dir
+ '((t (:inherit (font-lock-string-face bold))))
+ "Face used for the project directory of the mode-line buffer path."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-project-root-dir
+ '((t (:inherit (mode-line-emphasis bold))))
+ "Face used for the project part of the mode-line buffer path."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-highlight
+ '((t (:inherit mode-line-emphasis)))
+ "Face for bright segments of the mode-line."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-panel
+ '((t (:inherit mode-line-highlight)))
+ "Face for 'X out of Y' segments, such as `anzu', `evil-substitute' and`iedit', etc."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-host
+ '((t (:inherit italic)))
+ "Face for remote hosts in the mode-line."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-input-method
+ '((t (:inherit (mode-line-emphasis bold))))
+ "Face for input method in the mode-line."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-input-method-alt
+ '((t (:inherit (font-lock-doc-face bold) :slant normal)))
+ "Alternative face for input method in the mode-line."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-debug
+ '((t (:inherit (font-lock-doc-face bold) :slant normal)))
+ "Face for debug-level messages in the mode-line. Used by vcs, checker, etc."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-info
+ '((t (:inherit (success bold))))
+ "Face for info-level messages in the mode-line. Used by vcs, checker, etc."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-warning
+ '((t (:inherit (warning bold))))
+ "Face for warnings in the mode-line. Used by vcs, checker, etc."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-urgent
+ '((t (:inherit (error bold))))
+ "Face for errors in the mode-line. Used by vcs, checker, etc."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-notification
+ '((t (:inherit doom-modeline-warning)))
+ "Face for notifications in the mode-line. Used by GitHub, mu4e,
+etc. (also see the face `doom-modeline-unread-number')."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-unread-number
+ '((t (:slant italic :weight normal)))
+ "Face for unread number in the mode-line. Used by GitHub, mu4e, etc."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-bar
+ '((t (:inherit highlight)))
+ "The face used for the left-most bar in the mode-line of an active window."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-bar-inactive
+ `((t (:background ,(face-foreground 'mode-line-inactive))))
+ "The face used for the left-most bar in the mode-line of an inactive window."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-debug-visual
+ `((((class color) (background light))
+ (:background ,(face-foreground 'all-the-icons-orange)))
+ (((class color) (background dark))
+ (:background ,(face-foreground 'all-the-icons-dorange))))
+ "Face to use for the mode-line while debugging."
+ :group 'doom-modeline)
+
+(defface doom-modeline-evil-emacs-state
+ '((t (:inherit (font-lock-builtin-face bold))))
+ "Face for the Emacs state tag in evil state indicator."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-evil-insert-state
+ '((t (:inherit (font-lock-keyword-face bold))))
+ "Face for the insert state tag in evil state indicator."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-evil-motion-state
+ '((t :inherit (font-lock-doc-face bold) :slant normal))
+ "Face for the motion state tag in evil state indicator."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-evil-normal-state
+ '((t (:inherit doom-modeline-info)))
+ "Face for the normal state tag in evil state indicator."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-evil-operator-state
+ '((t (:inherit doom-modeline-buffer-file)))
+ "Face for the operator state tag in evil state indicator."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-evil-visual-state
+ '((t (:inherit doom-modeline-warning)))
+ "Face for the visual state tag in evil state indicator."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-evil-replace-state
+ '((t (:inherit doom-modeline-urgent)))
+ "Face for the replace state tag in evil state indicator."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-persp-name
+ '((t (:inherit (font-lock-comment-face italic))))
+ "Face for the persp name."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-persp-buffer-not-in-persp
+ '((t (:inherit (font-lock-doc-face bold italic))))
+ "Face for the buffers which are not in the persp."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-repl-success
+ '((t (:inherit success :weight normal)))
+ "Face for REPL success state."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-repl-warning
+ '((t (:inherit warning :weight normal)))
+ "Face for REPL warning state."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-lsp-success
+ '((t (:inherit success :weight normal)))
+ "Face for LSP success state."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-lsp-warning
+ '((t (:inherit warning :weight normal)))
+ "Face for LSP warning state."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-lsp-error
+ '((t (:inherit error :weight normal)))
+ "Face for LSP error state."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-lsp-running
+ '((t (:inherit compilation-mode-line-run :weight normal :slant normal)))
+ "Face for LSP running state."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-battery-charging
+ '((t (:inherit success :weight normal)))
+ "Face for battery charging status."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-battery-full
+ '((t (:inherit success :weight normal)))
+ "Face for battery full status."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-battery-normal
+ '((t (:inherit mode-line :weight normal)))
+ "Face for battery normal status."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-battery-warning
+ '((t (:inherit warning :weight normal)))
+ "Face for battery warning status."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-battery-critical
+ '((t (:inherit error :weight normal)))
+ "Face for battery critical status."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-battery-error
+ '((t (:inherit error :weight normal)))
+ "Face for battery error status."
+ :group 'doom-modeline-faces)
+
+(defface doom-modeline-buffer-timemachine
+ '((t (:inherit doom-modeline-buffer-file :slant italic)))
+ "Face for timemachine status."
+ :group 'doom-modeline-faces)
+
+
+;;
+;; Externals
+;;
+
+(declare-function face-remap-remove-relative "face-remap")
+(declare-function ffip-get-project-root-directory "ext:find-file-in-project")
+(declare-function project-root "ext:project")
+(declare-function projectile-project-root "ext:projectile")
+
+
+;;
+;; Utilities
+;;
+
+(defun doom-modeline-add-font-lock ()
+ "Fontify `doom-modeline-def-*' statements."
+ (font-lock-add-keywords
+ 'emacs-lisp-mode
+ '(("(\\(doom-modeline-def-.+\\)\\_> +\\(.*?\\)\\_>"
+ (1 font-lock-keyword-face)
+ (2 font-lock-constant-face)))))
+(doom-modeline-add-font-lock)
+
+(defun doom-modeline-add-imenu ()
+ "Add to `imenu' index."
+ (add-to-list
+ 'imenu-generic-expression
+ '("Modelines"
+ "^\\s-*(\\(doom-modeline-def-modeline\\)\\s-+\\(\\(?:\\sw\\|\\s_\\|\\s'\\|\\\\.\\)+\\)"
+ 2))
+ (add-to-list
+ 'imenu-generic-expression
+ '("Segments"
+ "^\\s-*(\\(doom-modeline-def-segment\\)\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)"
+ 2))
+ (add-to-list
+ 'imenu-generic-expression
+ '("Envs"
+ "^\\s-*(\\(doom-modeline-def-env\\)\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)"
+ 2)))
+
+
+;;
+;; Core helpers
+;;
+
+;; FIXME #183: Force to calculate mode-line height
+;; @see https://github.com/seagle0128/doom-modeline/issues/183
+;; @see https://github.com/seagle0128/doom-modeline/issues/483
+(defun doom-modeline-redisplay (&rest _)
+ "Call `redisplay' to trigger mode-line height calculations.
+
+Certain functions, including e.g. `fit-window-to-buffer', base
+their size calculations on values which are incorrect if the
+mode-line has a height different from that of the `default' face
+and certain other calculations have not yet taken place for the
+window in question.
+
+These calculations can be triggered by calling `redisplay'
+explicitly at the appropriate time and this functions purpose
+is to make it easier to do so.
+
+This function is like `redisplay' with non-nil FORCE argument,
+but it will only trigger a redisplay when there is a non nil
+`mode-line-format' and the height of the mode-line is different
+from that of the `default' face. This function is intended to be
+used as an advice to window creation functions."
+ (when (and (bound-and-true-p doom-modeline-mode)
+ mode-line-format
+ (/= (frame-char-height) (window-mode-line-height)))
+ (redisplay t)))
+(unless (>= emacs-major-version 29)
+ (advice-add #'fit-window-to-buffer :before #'doom-modeline-redisplay))
+
+;; Keep `doom-modeline-current-window' up-to-date
+(defun doom-modeline--get-current-window (&optional frame)
+ "Get the current window but should exclude the child windows."
+ (if (and (fboundp 'frame-parent) (frame-parent frame))
+ (frame-selected-window (frame-parent frame))
+ (frame-selected-window frame)))
+
+(defvar doom-modeline-current-window (doom-modeline--get-current-window))
+
+(defun doom-modeline--active ()
+ "Whether is an active window."
+ (unless (and (bound-and-true-p mini-frame-frame)
+ (and (frame-live-p mini-frame-frame)
+ (frame-visible-p mini-frame-frame)))
+ (and doom-modeline-current-window
+ (eq (doom-modeline--get-current-window) doom-modeline-current-window))))
+
+(defun doom-modeline-set-selected-window (&rest _)
+ "Set `doom-modeline-current-window' appropriately."
+ (let ((win (doom-modeline--get-current-window)))
+ (setq doom-modeline-current-window
+ (if (minibuffer-window-active-p win)
+ (minibuffer-selected-window)
+ win))))
+
+(defun doom-modeline-unset-selected-window ()
+ "Unset `doom-modeline-current-window' appropriately."
+ (setq doom-modeline-current-window nil))
+
+(add-hook 'pre-redisplay-functions #'doom-modeline-set-selected-window)
+
+;; Ensure modeline is inactive when Emacs is unfocused (and active otherwise)
+(defvar doom-modeline-remap-face-cookie nil)
+(defun doom-modeline-focus ()
+ "Focus mode-line."
+ (when doom-modeline-remap-face-cookie
+ (require 'face-remap)
+ (face-remap-remove-relative doom-modeline-remap-face-cookie)))
+(defun doom-modeline-unfocus ()
+ "Unfocus mode-line."
+ (setq doom-modeline-remap-face-cookie
+ (face-remap-add-relative 'mode-line 'mode-line-inactive)))
+
+(with-no-warnings
+ (if (boundp 'after-focus-change-function)
+ (progn
+ (defun doom-modeline-focus-change (&rest _)
+ (if (frame-focus-state)
+ (doom-modeline-focus)
+ (doom-modeline-unfocus)))
+ (advice-add #'handle-switch-frame :after #'doom-modeline-focus-change)
+ (add-function :after after-focus-change-function #'doom-modeline-focus-change))
+ (progn
+ (add-hook 'focus-in-hook #'doom-modeline-focus)
+ (add-hook 'focus-out-hook #'doom-modeline-unfocus))))
+
+
+;;
+;; Core
+;;
+
+(defvar doom-modeline-fn-alist ())
+(defvar doom-modeline-var-alist ())
+
+(defmacro doom-modeline-def-segment (name &rest body)
+ "Defines a modeline segment NAME with BODY and byte compiles it."
+ (declare (indent defun) (doc-string 2))
+ (let ((sym (intern (format "doom-modeline-segment--%s" name)))
+ (docstring (if (stringp (car body))
+ (pop body)
+ (format "%s modeline segment" name))))
+ (cond ((and (symbolp (car body))
+ (not (cdr body)))
+ (add-to-list 'doom-modeline-var-alist (cons name (car body)))
+ `(add-to-list 'doom-modeline-var-alist (cons ',name ',(car body))))
+ (t
+ (add-to-list 'doom-modeline-fn-alist (cons name sym))
+ `(progn
+ (fset ',sym (lambda () ,docstring ,@body))
+ (add-to-list 'doom-modeline-fn-alist (cons ',name ',sym))
+ ,(unless (bound-and-true-p byte-compile-current-file)
+ `(let (byte-compile-warnings)
+ (byte-compile #',sym))))))))
+
+(defun doom-modeline--prepare-segments (segments)
+ "Prepare mode-line `SEGMENTS'."
+ (let (forms it)
+ (dolist (seg segments)
+ (cond ((stringp seg)
+ (push seg forms))
+ ((symbolp seg)
+ (cond ((setq it (cdr (assq seg doom-modeline-fn-alist)))
+ (push (list :eval (list it)) forms))
+ ((setq it (cdr (assq seg doom-modeline-var-alist)))
+ (push it forms))
+ ((error "%s is not a defined segment" seg))))
+ ((error "%s is not a valid segment" seg))))
+ (nreverse forms)))
+
+(defvar doom-modeline--font-width-cache nil)
+(defun doom-modeline--font-width ()
+ "Cache the font width."
+ (if (display-graphic-p)
+ (let ((attributes (face-all-attributes 'mode-line)))
+ (or (cdr (assoc attributes doom-modeline--font-width-cache))
+ (let ((width (window-font-width nil 'mode-line)))
+ (push (cons attributes width) doom-modeline--font-width-cache)
+ width)))
+ 1))
+
+;; Refresh the font width after setting frame parameters
+;; to ensure the font width is correct.
+(defun doom-modeline-refresh-font-width-cache (&rest _)
+ "Refresh the font width cache."
+ (setq doom-modeline--font-width-cache nil)
+ (doom-modeline--font-width))
+(add-hook 'window-setup-hook #'doom-modeline-refresh-font-width-cache)
+(add-hook 'after-make-frame-functions #'doom-modeline-refresh-font-width-cache)
+(add-hook 'after-setting-font-hook #'doom-modeline-refresh-font-width-cache)
+(add-hook 'server-after-make-frame-hook #'doom-modeline-refresh-font-width-cache)
+
+(defun doom-modeline-def-modeline (name lhs &optional rhs)
+ "Defines a modeline format and byte-compiles it.
+NAME is a symbol to identify it (used by `doom-modeline' for retrieval).
+LHS and RHS are lists of symbols of modeline segments defined with
+`doom-modeline-def-segment'.
+
+Example:
+ (doom-modeline-def-modeline 'minimal
+ '(bar matches \" \" buffer-info)
+ '(media-info major-mode))
+ (doom-modeline-set-modeline 'minimal t)"
+ (let ((sym (intern (format "doom-modeline-format--%s" name)))
+ (lhs-forms (doom-modeline--prepare-segments lhs))
+ (rhs-forms (doom-modeline--prepare-segments rhs)))
+ (defalias sym
+ (lambda ()
+ (list lhs-forms
+ (propertize
+ " "
+ 'face (if (doom-modeline--active) 'mode-line 'mode-line-inactive)
+ 'display `((space
+ :align-to
+ (- (+ right right-fringe right-margin scroll-bar)
+ ,(* (let ((width (doom-modeline--font-width)))
+ (or (and (= width 1) 1)
+ (/ width (frame-char-width) 1.0)))
+ (string-width
+ (format-mode-line (cons "" rhs-forms))))))))
+ rhs-forms))
+ (concat "Modeline:\n"
+ (format " %s\n %s"
+ (prin1-to-string lhs)
+ (prin1-to-string rhs))))))
+(put 'doom-modeline-def-modeline 'lisp-indent-function 'defun)
+
+(defun doom-modeline (key)
+ "Return a mode-line configuration associated with KEY (a symbol).
+Throws an error if it doesn't exist."
+ (let ((fn (intern-soft (format "doom-modeline-format--%s" key))))
+ (when (functionp fn)
+ `(:eval (,fn)))))
+
+(defun doom-modeline-set-modeline (key &optional default)
+ "Set the modeline format. Does nothing if the modeline KEY doesn't exist.
+If DEFAULT is non-nil, set the default mode-line for all buffers."
+ (when-let ((modeline (doom-modeline key)))
+ (setf (if default
+ (default-value 'mode-line-format)
+ (buffer-local-value 'mode-line-format (current-buffer)))
+ (list "%e" modeline))))
+
+
+;;
+;; Helpers
+;;
+
+(defsubst doom-modeline-spc ()
+ "Text style with whitespace."
+ (propertize " " 'face (if (doom-modeline--active)
+ 'doom-modeline-spc-face
+ 'doom-modeline-spc-inactive-face)))
+
+(defsubst doom-modeline-wspc ()
+ "Text style with wide whitespace."
+ (propertize " " 'face (if (doom-modeline--active)
+ 'doom-modeline-spc-face
+ 'doom-modeline-spc-inactive-face)))
+
+(defsubst doom-modeline-vspc ()
+ "Text style with icons in mode-line."
+ (propertize " " 'face (if (doom-modeline--active)
+ 'doom-modeline-vspc-face
+ 'doom-modeline-vspc-inactive-face)))
+
+(defun doom-modeline--font-height ()
+ "Calculate the actual char height of the mode-line."
+ (let ((height (face-attribute 'mode-line :height)))
+ ;; WORKAROUND: Fix tall issue of 27 on Linux
+ ;; @see https://github.com/seagle0128/doom-modeline/issues/271
+ (round
+ (* (if (or (<= doom-modeline-height 0)
+ (and (>= emacs-major-version 27)
+ (not (eq system-type 'darwin))))
+ 1.0
+ (if doom-modeline-icon 1.68 1.25))
+ (cond ((integerp height) (/ height 10))
+ ((floatp height) (* height (frame-char-height)))
+ (t (frame-char-height)))))))
+
+(defun doom-modeline--original-value (sym)
+ "Return the original value for SYM, if any.
+
+If SYM has an original value, return it in a list. Return nil
+otherwise."
+ (let* ((orig-val-expr (get sym 'standard-value)))
+ (when (consp orig-val-expr)
+ (ignore-errors
+ (list
+ (eval (car orig-val-expr)))))))
+
+(defun doom-modeline-add-variable-watcher (symbol watch-function)
+ "Cause WATCH-FUNCTION to be called when SYMBOL is set if possible.
+
+See docs of `add-variable-watcher'."
+ (when (fboundp 'add-variable-watcher)
+ (add-variable-watcher symbol watch-function)))
+
+(defun doom-modeline-propertize-icon (icon &optional face)
+ "Propertize the ICON with the specified FACE.
+
+The face should be the first attribute, or the font family may be overridden.
+So convert the face \":family XXX :height XXX :inherit XXX\" to
+\":inherit XXX :family XXX :height XXX\".
+See https://github.com/seagle0128/doom-modeline/issues/301."
+ (if (and doom-modeline-icon (display-graphic-p))
+ (when-let ((props (get-text-property 0 'face icon)))
+ (cl-destructuring-bind (&key family height inherit &allow-other-keys) props
+ (propertize icon 'face `(:inherit ,(or face inherit props)
+ :family ,family
+ :height ,height))))
+ (propertize icon 'face face)))
+
+(defun doom-modeline-icon (icon-set icon-name unicode text &rest args)
+ "Display icon of ICON-NAME with ARGS in mode-line.
+
+ICON-SET includes `octicon', `faicon', `material', `alltheicons' and `fileicon',
+etc.
+UNICODE is the unicode char fallback. TEXT is the ASCII char fallback.
+ARGS is same as `all-the-icons-octicon' and others."
+ (let ((face (or (plist-get args :face) 'mode-line)))
+ (or
+ ;; Icons
+ (when (and (display-graphic-p)
+ doom-modeline-icon
+ icon-name
+ (not (string-empty-p icon-name)))
+ (when-let* ((func (all-the-icons--function-name icon-set))
+ (icon (and (fboundp func) (apply func icon-name args))))
+ (doom-modeline-propertize-icon icon face)))
+ ;; Unicode fallback
+ (and doom-modeline-unicode-fallback
+ unicode
+ (not (string-empty-p unicode))
+ (char-displayable-p (string-to-char unicode))
+ (propertize unicode 'face face))
+ ;; ASCII text
+ (and text (propertize text 'face face))
+ "")))
+
+(defun doom-modeline--create-bar-image (face width height)
+ "Create the bar image.
+Use FACE1 for the bar, FACE2 for the background.
+WIDTH and HEIGHT are the image size in pixels."
+ (when (and (display-graphic-p)
+ (image-type-available-p 'pbm))
+ (propertize
+ " " 'display
+ (let ((color (or (face-background face nil t) "None")))
+ (ignore-errors
+ (create-image
+ (concat (format "P1\n%i %i\n" width height)
+ (make-string (* width height) ?1)
+ "\n")
+ 'pbm t :foreground color :ascent 'center))))))
+
+(defun doom-modeline--create-hud-image
+ (face1 face2 width height top-margin bottom-margin)
+ "Create the hud image.
+Use FACE1 for the bar, FACE2 for the background.
+WIDTH and HEIGHT are the image size in pixels.
+TOP-MARGIN and BOTTOM-MARGIN are the size of the margin above and below the bar,
+respectively."
+ (when (and (display-graphic-p)
+ (image-type-available-p 'pbm))
+ (let ((min-height (min height doom-modeline-hud-min-height)))
+ (unless (> (- height top-margin bottom-margin) min-height)
+ (let ((margin (- height min-height)))
+ (setq top-margin (/ (* margin top-margin) (+ top-margin bottom-margin))
+ bottom-margin (- margin top-margin)))))
+ (propertize
+ " " 'display
+ (let ((color1 (or (face-background face1 nil t) "None"))
+ (color2 (or (face-background face2 nil t) "None")))
+ (create-image
+ (concat
+ (format "P1\n%i %i\n" width height)
+ (make-string (* top-margin width) ?0)
+ (make-string (* (- height top-margin bottom-margin) width) ?1)
+ (make-string (* bottom-margin width) ?0)
+ "\n")
+ 'pbm t :foreground color1 :background color2 :ascent 'center)))))
+
+;; Check whether `window-total-width' is smaller than the limit
+(defvar-local doom-modeline--limited-width-p nil)
+(defun doom-modeline-window-size-change-function (&rest _)
+ "Function for `window-size-change-functions'."
+ (setq doom-modeline--limited-width-p
+ (cond
+ ((integerp doom-modeline-window-width-limit)
+ (<= (window-total-width) doom-modeline-window-width-limit))
+ ((floatp doom-modeline-window-width-limit)
+ (<= (/ (window-total-width) (frame-width) 1.0)
+ doom-modeline-window-width-limit)))))
+
+(add-hook 'window-size-change-functions #'doom-modeline-window-size-change-function)
+(add-hook 'buffer-list-update-hook #'doom-modeline-window-size-change-function)
+
+(defvar-local doom-modeline--project-root nil)
+(defun doom-modeline--project-root ()
+ "Get the path to the root of your project.
+Return nil if no project was found."
+ (or doom-modeline--project-root
+ (setq doom-modeline--project-root
+ (pcase (if (eq doom-modeline-project-detection 'auto)
+ (cond
+ ((fboundp 'ffip-get-project-root-directory) 'ffip)
+ ((fboundp 'projectile-project-root) 'projectile)
+ ((fboundp 'project-current) 'project)
+ (t 'default))
+ doom-modeline-project-detection)
+ ('ffip
+ (let ((inhibit-message t))
+ (ffip-get-project-root-directory)))
+ ('projectile
+ (projectile-project-root))
+ ('project
+ (when-let ((project (project-current)))
+ (expand-file-name (if (fboundp 'project-root)
+ (project-root project)
+ (cdr project)))))))))
+
+(defun doom-modeline-project-p ()
+ "Check if the file is in a project."
+ (doom-modeline--project-root))
+
+(defun doom-modeline-project-root ()
+ "Get the path to the root of your project.
+Return `default-directory' if no project was found."
+ (or (doom-modeline--project-root) default-directory))
+
+(defun doom-modeline-buffer-file-name ()
+ "Propertized variable `buffer-file-name' based on
+`doom-modeline-buffer-file-name-style'."
+ (let* ((buffer-file-name (file-local-name (or (buffer-file-name (buffer-base-buffer)) "")))
+ (buffer-file-truename (file-local-name
+ (or buffer-file-truename (file-truename buffer-file-name) "")))
+ (file-name
+ (pcase doom-modeline-buffer-file-name-style
+ ('auto
+ (if (doom-modeline-project-p)
+ (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename nil nil 'hide)
+ (propertize "%b" 'face 'doom-modeline-buffer-file)))
+ ('truncate-upto-project
+ (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename 'shrink))
+ ('truncate-from-project
+ (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename nil 'shrink))
+ ('truncate-with-project
+ (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename 'shrink 'shink 'hide))
+ ('truncate-except-project
+ (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename 'shrink 'shink))
+ ('truncate-upto-root
+ (doom-modeline--buffer-file-name-truncate buffer-file-name buffer-file-truename))
+ ('truncate-all
+ (doom-modeline--buffer-file-name-truncate buffer-file-name buffer-file-truename t))
+ ('truncate-nil
+ (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename))
+ ('relative-to-project
+ (doom-modeline--buffer-file-name-relative buffer-file-name buffer-file-truename))
+ ('relative-from-project
+ (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename nil nil 'hide))
+ ('file-name
+ (propertize (file-name-nondirectory buffer-file-name)
+ 'face 'doom-modeline-buffer-file))
+ ((or 'buffer-name _)
+ (propertize "%b" 'face 'doom-modeline-buffer-file)))))
+ (propertize (if (string-empty-p file-name)
+ (propertize "%b" 'face 'doom-modeline-buffer-file)
+ file-name)
+ 'mouse-face 'mode-line-highlight
+ 'help-echo (concat buffer-file-truename
+ (unless (string= (file-name-nondirectory buffer-file-truename)
+ (buffer-name))
+ (concat "\n" (buffer-name)))
+ "\nmouse-1: Previous buffer\nmouse-3: Next buffer")
+ 'local-map mode-line-buffer-identification-keymap)))
+
+(defun doom-modeline--buffer-file-name-truncate (file-path true-file-path &optional truncate-tail)
+ "Propertized variable `buffer-file-name' that truncates every dir along path.
+If TRUNCATE-TAIL is t also truncate the parent directory of the file."
+ (let ((dirs (shrink-path-prompt (file-name-directory true-file-path))))
+ (if (null dirs)
+ (propertize "%b" 'face 'doom-modeline-buffer-file)
+ (let ((dirname (car dirs))
+ (basename (cdr dirs)))
+ (concat (propertize (concat dirname
+ (if truncate-tail (substring basename 0 1) basename)
+ "/")
+ 'face 'doom-modeline-project-root-dir)
+ (propertize (file-name-nondirectory file-path)
+ 'face 'doom-modeline-buffer-file))))))
+
+(defun doom-modeline--buffer-file-name-relative (_file-path true-file-path &optional include-project)
+ "Propertized variable `buffer-file-name' showing directories relative to
+project's root only."
+ (let ((root (file-local-name (doom-modeline-project-root))))
+ (if (null root)
+ (propertize "%b" 'face 'doom-modeline-buffer-file)
+ (let ((relative-dirs (file-relative-name (file-name-directory true-file-path)
+ (if include-project (concat root "../") root))))
+ (and (equal "./" relative-dirs) (setq relative-dirs ""))
+ (concat (propertize relative-dirs 'face 'doom-modeline-buffer-path)
+ (propertize (file-name-nondirectory true-file-path)
+ 'face 'doom-modeline-buffer-file))))))
+
+(defun doom-modeline--buffer-file-name (file-path
+ _true-file-path
+ &optional
+ truncate-project-root-parent
+ truncate-project-relative-path
+ hide-project-root-parent)
+ "Propertized variable `buffer-file-name' given by FILE-PATH.
+If TRUNCATE-PROJECT-ROOT-PARENT is non-nil will be saved by truncating project
+root parent down fish-shell style.
+
+Example:
+ ~/Projects/FOSS/emacs/lisp/comint.el => ~/P/F/emacs/lisp/comint.el
+
+If TRUNCATE-PROJECT-RELATIVE-PATH is non-nil will be saved by truncating project
+relative path down fish-shell style.
+
+Example:
+ ~/Projects/FOSS/emacs/lisp/comint.el => ~/Projects/FOSS/emacs/l/comint.el
+
+If HIDE-PROJECT-ROOT-PARENT is non-nil will hide project root parent.
+
+Example:
+ ~/Projects/FOSS/emacs/lisp/comint.el => emacs/lisp/comint.el"
+ (let ((project-root (file-local-name (doom-modeline-project-root))))
+ (concat
+ ;; Project root parent
+ (unless hide-project-root-parent
+ (when-let (root-path-parent
+ (file-name-directory (directory-file-name project-root)))
+ (propertize
+ (if (and truncate-project-root-parent
+ (not (string-empty-p root-path-parent))
+ (not (string= root-path-parent "/")))
+ (shrink-path--dirs-internal root-path-parent t)
+ (abbreviate-file-name root-path-parent))
+ 'face 'doom-modeline-project-parent-dir)))
+ ;; Project directory
+ (propertize
+ (concat (file-name-nondirectory (directory-file-name project-root)) "/")
+ 'face 'doom-modeline-project-dir)
+ ;; relative path
+ (propertize
+ (when-let (relative-path (file-relative-name
+ (or (file-name-directory file-path) "./")
+ project-root))
+ (if (string= relative-path "./")
+ ""
+ (if truncate-project-relative-path
+ (substring (shrink-path--dirs-internal relative-path t) 1)
+ relative-path)))
+ 'face 'doom-modeline-buffer-path)
+ ;; File name
+ (propertize (file-name-nondirectory file-path)
+ 'face 'doom-modeline-buffer-file))))
+
+(provide 'doom-modeline-core)
+
+;;; doom-modeline-core.el ends here
diff --git a/org/elpa/doom-modeline-20220412.853/doom-modeline-env.el b/org/elpa/doom-modeline-20220412.853/doom-modeline-env.el
new file mode 100644
index 0000000..87c8c50
--- /dev/null
+++ b/org/elpa/doom-modeline-20220412.853/doom-modeline-env.el
@@ -0,0 +1,275 @@
+;;; doom-modeline-env.el --- A environment parser for doom-modeline -*- lexical-binding: t -*-
+
+;; Copyright (C) 2019-2020 Justin Barclay, Vincent Zhang
+
+;; This file is not part of GNU Emacs.
+
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see .
+;;
+;;; Commentary:
+;;
+;; Parse programming environment.
+;;
+
+;;; Code:
+
+(require 'subr-x)
+(require 'doom-modeline-core)
+
+
+;; Externals
+(defvar python-shell-interpreter)
+
+
+;; Customizations
+
+(defgroup doom-modeline-env nil
+ "The environment parser for doom-modeline."
+ :group 'doom-modeline
+ :link '(url-link :tag "Homepage" "https://github.com/seagle0128/doom-modeline"))
+
+(defcustom doom-modeline-env-load-string "..."
+ "What to display as the version while a new one is being loaded."
+ :type 'string
+ :group 'doom-modeline-env)
+
+(defcustom doom-modeline-before-update-env-hook nil
+ "Hooks that run before the modeline version string is updated."
+ :type 'hook
+ :group 'doom-modeline-env)
+
+(defcustom doom-modeline-after-update-env-hook nil
+ "Hooks that run after the modeline version string is updated."
+ :type 'hook
+ :group 'doom-modeline-env)
+
+
+;; Variables
+
+;; Show version string for multi-version managers like rvm, rbenv, pyenv, etc.
+(defvar-local doom-modeline-env--version nil
+ "The version to display with major-mode in mode-line.
+Example: \"2.6.0\"")
+
+(defvar-local doom-modeline-env--command nil
+ "A program that we're looking to extract version information from.
+Example: \"ruby\"")
+
+(defvar-local doom-modeline-env--command-args nil
+ "A list of arguments for the command to extract the version from.
+Example: '(\"--version\") ")
+
+(defvar-local doom-modeline-env--parser nil
+ "A function that returns version number from a command --version (or similar).
+Example: 'doom-modeline-env--ruby")
+
+
+;; Functions & Macros
+
+(defun doom-modeline-update-env ()
+ "Update environment info on mode-line."
+ (when (and doom-modeline-env-version
+ doom-modeline-env--command
+ (executable-find doom-modeline-env--command)
+ doom-modeline-env--command-args
+ doom-modeline-env--parser)
+ (let ((default-directory (doom-modeline-project-root))
+ (buffer (current-buffer)))
+ (run-hooks 'doom-modeline-before-update-env-hook)
+ (setq doom-modeline-env--version doom-modeline-env-load-string)
+ (doom-modeline-env--get
+ doom-modeline-env--command
+ doom-modeline-env--command-args
+ (lambda (prog-version)
+ (with-current-buffer buffer
+ (setq doom-modeline-env--version
+ (funcall doom-modeline-env--parser prog-version))
+ (run-hooks 'doom-modeline-after-update-env-hook)))))))
+
+(add-hook 'find-file-hook #'doom-modeline-update-env)
+(with-no-warnings
+ (if (boundp 'after-focus-change-function)
+ (add-function
+ :after after-focus-change-function
+ (lambda ()
+ (if (frame-focus-state)
+ (doom-modeline-update-env))))
+ (add-hook 'focus-in-hook #'doom-modeline-update-env)))
+
+(defun doom-modeline-env--get (prog args callback)
+ "Start a sub process using PROG and apply the ARGS to the sub process.
+Once it receives information from STDOUT, it closes off the subprocess and
+passes on the information into the CALLBACK.
+Example:
+ (doom-modeline-env--get
+ \"ruby\"
+ '(\"--version\")
+ (lambda (line)
+ (message (doom-modeline-parser--ruby line)))"
+ (let ((proc (apply 'start-process
+ ;; Flaten process-args into a single list so we can handle
+ ;; variadic length args
+ (append
+ (list "doom-modeline-env" nil prog)
+ args)))
+ (parser callback))
+ (set-process-filter proc
+ (lambda (_proc line)
+ (ignore-errors
+ (funcall parser line))))))
+
+(cl-defmacro doom-modeline-def-env (name &key hooks command parser)
+ "Defines a handler for updating & displaying a version string for a language.
+
+NAME is an unquoted symbol representing the handler's unique ID.
+HOOKS is a list of hook symbols where this handler should be triggered.
+COMMAND should be a function that returns a shell command and its arguments (as
+ a list). It is run on HOOKS. It takes no arguments.
+PARSER should be a function for parsing COMMAND's output line-by-line, to
+ extract the version string."
+ (declare (indent defun))
+ (unless (and hooks command parser)
+ (error "'%s' env is missing either :hooks, :command or :parser" name))
+ (let ((parse-fn (intern (format "doom-modeline-env--%s-parse" name)))
+ (action-fn (intern (format "doom-modeline-env--%s-args" name)))
+ (setup-fn (intern (format "doom-modeline-env-setup-%s" name)))
+ (update-fn (intern (format "doom-modeline-env-update-%s" name)))
+ (enable-var (intern (format "doom-modeline-env-enable-%s" name)))
+ (command-var (intern (format "doom-modeline-env-%s-command" name)))
+ (parser-var (intern (format "doom-modeline-env-%s-parser-fn" name)))
+ (exe-var (intern (format "doom-modeline-env-%s-executable" name))))
+ (macroexp-progn
+ `((defcustom ,enable-var t
+ ,(format "Whether to display the version string for %s buffers." name)
+ :type 'boolean
+ :group 'doom-modeline-env)
+ (defvar ,command-var ',action-fn
+ ,(concat "A function that returns the shell command and arguments (as a list) to\n"
+ "produce a version string."))
+ (defvar ,parser-var ',parse-fn
+ ,(format "The function to parse each line of `%s'\'s output." command-var))
+ (defcustom ,exe-var nil
+ ,(format (concat "What executable to use for the version indicator in %s buffers.\n\n"
+ "If nil, the default binary for this language is used.")
+ name)
+ :type 'string
+ :group 'doom-modeline-env)
+ (defalias ',parse-fn ,parser
+ (format "The line parser for %s buffers.\n\nUsed by `%s'."
+ ',name ',update-fn))
+ (defalias ',action-fn ,command
+ (format "The command resolver for %s buffers.\n\nUsed by `%s'."
+ ',name ',update-fn))
+ (defalias ',setup-fn
+ (lambda ()
+ (if enable-local-variables
+ (add-hook 'hack-local-variables-hook #',update-fn nil t)
+ (,update-fn)))
+ (format "Prepares the modeline to later display the %s version string."
+ ',name))
+ (defalias ',update-fn
+ (lambda ()
+ (when ,enable-var
+ (when-let* ((command-list (funcall ,command-var))
+ (exe (executable-find (car command-list))))
+ (setq doom-modeline-env--command exe
+ doom-modeline-env--command-args (cdr command-list)
+ doom-modeline-env--parser ,parser-var)
+ (doom-modeline-update-env))))
+ (format "Updates the %s version string in the modeline." ',name))
+ (let ((hooks ',(eval hooks)))
+ (dolist (hook (if (listp hooks) hooks (list hooks)))
+ (add-hook hook #',setup-fn)))))))
+
+
+;; Bootstrap
+;; Versions, support Python, Ruby, Perl and Golang, etc.
+
+;;;###autoload (autoload 'doom-modeline-env-setup-python "doom-modeline-env")
+(doom-modeline-def-env python
+ :hooks 'python-mode-hook
+ :command (lambda () (cond ((and (fboundp 'pipenv-project-p)
+ (pipenv-project-p))
+ (list "pipenv" "run"
+ (or doom-modeline-env-python-executable
+ python-shell-interpreter
+ "python")
+ "--version"))
+ ((executable-find "pyenv") (list "pyenv" "version-name"))
+ ((list (or doom-modeline-env-python-executable
+ python-shell-interpreter
+ "python")
+ "--version"))))
+ :parser (lambda (line) (let ((version (split-string line)))
+ (if (>= (length version) 2)
+ (cadr version)
+ (car version)))))
+
+;;;###autoload (autoload 'doom-modeline-env-setup-ruby "doom-modeline-env")
+(doom-modeline-def-env ruby
+ :hooks '(ruby-mode-hook enh-ruby-mode-hook)
+ :command (lambda () (list (or doom-modeline-env-ruby-executable "ruby") "--version"))
+ :parser (lambda (line)
+ (car (split-string
+ (cadr
+ (split-string line))
+ "p"))))
+
+;;;###autoload (autoload 'doom-modeline-env-setup-perl "doom-modeline-env")
+(doom-modeline-def-env perl
+ :hooks 'perl-mode-hook
+ :command (lambda () (list (or doom-modeline-env-perl-executable "perl") "--version"))
+ :parser (lambda (line)
+ (cadr
+ (split-string
+ (car
+ (split-string
+ (cadr
+ (split-string line "("))
+ ")"))
+ "v"))))
+
+;;;###autoload (autoload 'doom-modeline-env-setup-go "doom-modeline-env")
+(doom-modeline-def-env go
+ :hooks 'go-mode-hook
+ :command (lambda () (list (or doom-modeline-env-go-executable "go") "version"))
+ :parser (lambda (line)
+ (cadr
+ (split-string
+ (cadr
+ (cdr
+ (split-string line)))
+ "go"))))
+
+;;;###autoload (autoload 'doom-modeline-env-setup-elixir "doom-modeline-env")
+(doom-modeline-def-env elixir
+ :hooks 'elixir-mode-hook
+ :command (lambda () (list (or doom-modeline-env-elixir-executable "elixir") "--version"))
+ :parser (lambda (line) (cadr (split-string line))))
+
+;;;###autoload (autoload 'doom-modeline-env-setup-rust "doom-modeline-env")
+(doom-modeline-def-env rust
+ :hooks 'rust-mode-hook
+ :command (lambda () (list (or doom-modeline-env-rust-executable "rustc") "--version"))
+ :parser (lambda (line)
+ (car
+ (split-string
+ (cadr
+ (split-string line))
+ "-"))))
+
+(provide 'doom-modeline-env)
+
+;;; doom-modeline-env.el ends here
diff --git a/org/elpa/doom-modeline-20220412.853/doom-modeline-pkg.el b/org/elpa/doom-modeline-20220412.853/doom-modeline-pkg.el
new file mode 100644
index 0000000..c289f03
--- /dev/null
+++ b/org/elpa/doom-modeline-20220412.853/doom-modeline-pkg.el
@@ -0,0 +1,15 @@
+(define-package "doom-modeline" "20220412.853" "A minimal and modern mode-line"
+ '((emacs "25.1")
+ (all-the-icons "2.2.0")
+ (shrink-path "0.2.0")
+ (dash "2.11.0"))
+ :commit "7d8eb7c44087a62d8dd6e8ba1afc26facd914fbc" :authors
+ '(("Vincent Zhang" . "seagle0128@gmail.com"))
+ :maintainer
+ '("Vincent Zhang" . "seagle0128@gmail.com")
+ :keywords
+ '("faces" "mode-line")
+ :url "https://github.com/seagle0128/doom-modeline")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/org/elpa/doom-modeline-20220412.853/doom-modeline-segments.el b/org/elpa/doom-modeline-20220412.853/doom-modeline-segments.el
new file mode 100644
index 0000000..d0970d1
--- /dev/null
+++ b/org/elpa/doom-modeline-20220412.853/doom-modeline-segments.el
@@ -0,0 +1,2969 @@
+;;; doom-modeline-segments.el --- The segments for doom-modeline -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2020 Vincent Zhang
+
+;; This file is not part of GNU Emacs.
+
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see .
+;;
+
+;;; Commentary:
+;;
+;; The segments for doom-modeline.
+;; Use `doom-modeline-def-segment' to create a new segment.
+;;
+
+;;; Code:
+
+(require 'all-the-icons)
+(require 'cl-lib)
+(require 'seq)
+(require 'subr-x)
+(require 'doom-modeline-core)
+(require 'doom-modeline-env)
+
+
+;;
+;; Externals
+;;
+
+(defvar Info-current-file)
+(defvar Info-current-node)
+(defvar Info-mode-line-node-keymap)
+(defvar anzu--cached-count)
+(defvar anzu--current-position)
+(defvar anzu--overflow-p)
+(defvar anzu--state)
+(defvar anzu--total-matched)
+(defvar anzu-cons-mode-line-p)
+(defvar aw-keys)
+(defvar battery-echo-area-format)
+(defvar battery-load-critical)
+(defvar battery-mode-line-format)
+(defvar battery-mode-line-limit)
+(defvar battery-status-function)
+(defvar boon-command-state)
+(defvar boon-insert-state)
+(defvar boon-off-state)
+(defvar boon-special-state)
+(defvar edebug-execution-mode)
+(defvar eglot--managed-mode)
+(defvar erc-modified-channels-alist)
+(defvar evil-ex-active-highlights-alist)
+(defvar evil-ex-argument)
+(defvar evil-ex-range)
+(defvar evil-mc-frozen)
+(defvar evil-state)
+(defvar evil-visual-beginning)
+(defvar evil-visual-end)
+(defvar evil-visual-selection)
+(defvar flycheck-current-errors)
+(defvar flycheck-mode-menu-map)
+(defvar flymake--mode-line-format)
+(defvar flymake--state)
+(defvar flymake-menu)
+(defvar gnus-newsrc-alist)
+(defvar gnus-newsrc-hashtb)
+(defvar grip--process)
+(defvar helm--mode-line-display-prefarg)
+(defvar iedit-occurrences-overlays)
+(defvar meow--indicator)
+(defvar minions-direct)
+(defvar minions-mode-line-lighter)
+(defvar minions-mode-line-minor-modes-map)
+(defvar mlscroll-minimum-current-width)
+(defvar mlscroll-right-align)
+(defvar mu4e-alert-mode-line)
+(defvar mu4e-alert-modeline-formatter)
+(defvar nyan-minimum-window-width)
+(defvar objed--obj-state)
+(defvar objed--object)
+(defvar objed-modeline-setup-func)
+(defvar persp-nil-name)
+(defvar phi-replace--mode-line-format)
+(defvar phi-search--selection)
+(defvar phi-search-mode-line-format)
+(defvar poke-line-minimum-window-width)
+(defvar rcirc-activity)
+(defvar sml-modeline-len)
+(defvar symbol-overlay-keywords-alist)
+(defvar symbol-overlay-temp-symbol)
+(defvar text-scale-mode-amount)
+(defvar tracking-buffers)
+(defvar winum-auto-setup-mode-line)
+(defvar xah-fly-insert-state-p)
+
+(declare-function anzu--reset-status "ext:anzu")
+(declare-function anzu--where-is-here "ext:anzu")
+(declare-function async-inject-variables "ext:async")
+(declare-function async-start "ext:async")
+(declare-function avy-traverse "ext:avy")
+(declare-function avy-tree "ext:avy")
+(declare-function aw-update "ext:ace-window")
+(declare-function aw-window-list "ext:ace-window")
+(declare-function battery-format "battery")
+(declare-function battery-update "battery")
+(declare-function boon-modeline-string "ext:boon")
+(declare-function boon-state-string "ext:boon")
+(declare-function cider--connection-info "ext:cider")
+(declare-function cider-connected-p "ext:cider")
+(declare-function cider-current-repl "ext:cider")
+(declare-function cider-jack-in "ext:cider")
+(declare-function cider-quit "ext:cider")
+(declare-function citre-mode "ext:citre-basic-tools")
+(declare-function dap--cur-session "ext:dap-mode")
+(declare-function dap--debug-session-name "ext:dap-mode")
+(declare-function dap--debug-session-state "ext:dap-mode")
+(declare-function dap--session-running "ext:dap-mode")
+(declare-function dap-debug-recent "ext:dap-mode")
+(declare-function dap-disconnect "ext:dap-mode")
+(declare-function dap-hydra "ext:dap-hydra")
+(declare-function edebug-help "edebug")
+(declare-function edebug-next-mode "edebug")
+(declare-function edebug-stop "edebug")
+(declare-function eglot "ext:eglot")
+(declare-function eglot--major-mode "ext:eglot" t t)
+(declare-function eglot--project-nickname "ext:eglot" t t)
+(declare-function eglot--spinner "ext:eglot" t t)
+(declare-function eglot-clear-status "ext:eglot")
+(declare-function eglot-current-server "ext:eglot")
+(declare-function eglot-events-buffer "ext:eglot")
+(declare-function eglot-forget-pending-continuations "ext:eglot")
+(declare-function eglot-managed-p "ext:glot")
+(declare-function eglot-reconnect "ext:eglot")
+(declare-function eglot-shutdown "ext:eglot")
+(declare-function eglot-stderr-buffer "ext:eglot")
+(declare-function erc-switch-to-buffer "erc")
+(declare-function erc-track-switch-buffer "erc-track")
+(declare-function evil-delimited-arguments "ext:evil-common")
+(declare-function evil-emacs-state-p "ext:evil-states" t t)
+(declare-function evil-force-normal-state "ext:evil-commands" t t)
+(declare-function evil-insert-state-p "ext:evil-states" t t)
+(declare-function evil-motion-state-p "ext:evil-states" t t)
+(declare-function evil-normal-state-p "ext:evil-states" t t)
+(declare-function evil-operator-state-p "ext:evil-states" t t)
+(declare-function evil-replace-state-p "ext:evil-states" t t)
+(declare-function evil-state-property "ext:evil-common")
+(declare-function evil-visual-state-p "ext:evil-states" t t)
+(declare-function eyebrowse--get "ext:eyebrowse")
+(declare-function face-remap-remove-relative "face-remap")
+(declare-function fancy-narrow-active-p "ext:fancy-narrow")
+(declare-function flycheck-buffer "ext:flycheck")
+(declare-function flycheck-count-errors "ext:flycheck")
+(declare-function flycheck-error-level-compilation-level "ext:flycheck")
+(declare-function flycheck-list-errors "ext:flycheck")
+(declare-function flycheck-next-error "ext:flycheck")
+(declare-function flycheck-previous-error "ext:flycheck")
+(declare-function flymake--diag-type "ext:flymake" t t)
+(declare-function flymake--handle-report "ext:flymake")
+(declare-function flymake--lookup-type-property "ext:flymake")
+(declare-function flymake--state-diags "ext:flymake" t t)
+(declare-function flymake-disabled-backends "ext:flymake")
+(declare-function flymake-goto-next-error "ext:flymake")
+(declare-function flymake-goto-prev-error "ext:flymake")
+(declare-function flymake-reporting-backends "ext:flymake")
+(declare-function flymake-running-backends "ext:flymake")
+(declare-function flymake-show-buffer-diagnostics "ext:flymake")
+(declare-function flymake-show-diagnostics-buffer "ext:flymake")
+(declare-function flymake-start "ext:flymake")
+(declare-function follow-all-followers "follow")
+(declare-function gnus-demon-add-handler "gnus-demon")
+(declare-function grip--preview-url "ext:grip-mode")
+(declare-function grip-browse-preview "ext:grip-mode")
+(declare-function grip-restart-preview "ext:grip-mode")
+(declare-function grip-stop-preview "ext:grip-mode")
+(declare-function helm-candidate-number-at-point "ext:helm-core")
+(declare-function helm-get-candidate-number "ext:helm-core")
+(declare-function iedit-find-current-occurrence-overlay "ext:iedit-lib")
+(declare-function iedit-prev-occurrence "ext:iedit-lib")
+(declare-function image-get-display-property "image-mode")
+(declare-function jsonrpc--request-continuations "ext:jsonrpc" t t)
+(declare-function jsonrpc-last-error "ext:jsonrpc" t t)
+(declare-function lsp--workspace-print "ext:lsp-mode")
+(declare-function lsp-describe-session "ext:lsp-mode")
+(declare-function lsp-workspace-folders-open "ext:lsp-mode")
+(declare-function lsp-workspace-restart "ext:lsp-mode")
+(declare-function lsp-workspace-shutdown "ext:lsp-mode")
+(declare-function lsp-workspaces "ext:lsp-mode")
+(declare-function lv-message "ext:lv")
+(declare-function mc/num-cursors "ext:multiple-cursors-core")
+(declare-function mlscroll-mode-line "ext:mlscroll")
+(declare-function mu4e-alert-default-mode-line-formatter "ext:mu4e-alert")
+(declare-function mu4e-alert-enable-mode-line-display "ext:mu4e-alert")
+(declare-function nyan-create "ext:nyan-mode")
+(declare-function org-edit-src-save "ext:org-src")
+(declare-function parrot-create "ext:parrot")
+(declare-function pdf-cache-number-of-pages "ext:pdf-cache" t t)
+(declare-function persp-add-buffer "ext:persp-mode")
+(declare-function persp-contain-buffer-p "ext:persp-mode")
+(declare-function persp-switch "ext:persp-mode")
+(declare-function phi-search--initialize "ext:phi-search")
+(declare-function poke-line-create "ext:poke-line")
+(declare-function popup-create "ext:popup")
+(declare-function popup-delete "ext:popup")
+(declare-function rcirc-next-active-buffer "rcirc")
+(declare-function rcirc-short-buffer-name "rcirc")
+(declare-function rcirc-switch-to-server-buffer "rcirc")
+(declare-function rcirc-window-configuration-change "rcirc")
+(declare-function rime--should-enable-p "ext:rime")
+(declare-function rime--should-inline-ascii-p "ext:rime")
+(declare-function sml-modeline-create "ext:sml-modeline")
+(declare-function symbol-overlay-assoc "ext:symbol-overlay")
+(declare-function symbol-overlay-get-list "ext:symbol-overlay")
+(declare-function symbol-overlay-get-symbol "ext:symbol-overlay")
+(declare-function symbol-overlay-rename "ext:symbol-overlay")
+(declare-function tab-bar--current-tab "tab-bar")
+(declare-function tab-bar--current-tab-index "tab-bar")
+(declare-function tracking-next-buffer "ext:tracking")
+(declare-function tracking-previous-buffer "ext:tracking")
+(declare-function tracking-shorten "ext:tracking")
+(declare-function undo-tree-redo-1 "ext:undo-tree")
+(declare-function undo-tree-undo-1 "ext:undo-tree")
+(declare-function warning-numeric-level "warnings")
+(declare-function window-numbering-clear-mode-line "ext:window-numbering")
+(declare-function window-numbering-get-number-string "ext:window-numbering")
+(declare-function window-numbering-install-mode-line "ext:window-numbering")
+(declare-function winum--clear-mode-line "ext:winum")
+(declare-function winum--install-mode-line "ext:winum")
+(declare-function winum-get-number-string "ext:winum")
+
+
+
+;;
+;; Buffer information
+;;
+
+(defvar-local doom-modeline--buffer-file-icon nil)
+(defun doom-modeline-update-buffer-file-icon (&rest _)
+ "Update file icon in mode-line."
+ (setq doom-modeline--buffer-file-icon
+ (when (and (display-graphic-p)
+ doom-modeline-icon
+ doom-modeline-major-mode-icon)
+ (let ((icon (all-the-icons-icon-for-buffer)))
+ (propertize (if (or (null icon) (symbolp icon))
+ (doom-modeline-icon 'faicon "file-o" nil nil
+ :face 'all-the-icons-dsilver
+ :height 0.9
+ :v-adjust 0.0)
+ icon)
+ 'help-echo (format "Major-mode: %s" (format-mode-line mode-name))
+ 'display '(raise -0.135))))))
+(add-hook 'find-file-hook #'doom-modeline-update-buffer-file-icon)
+(add-hook 'after-change-major-mode-hook #'doom-modeline-update-buffer-file-icon)
+(add-hook 'clone-indirect-buffer-hook #'doom-modeline-update-buffer-file-icon)
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-icon
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-icon val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (doom-modeline-update-buffer-file-icon))))))
+
+(defun doom-modeline-buffer-file-state-icon (icon unicode text face)
+ "Displays an ICON of buffer state with FACE.
+UNICODE and TEXT are the alternatives if it is not applicable.
+Uses `all-the-icons-material' to fetch the icon."
+ (doom-modeline-icon 'material icon unicode text
+ :face face
+ :height 1.1
+ :v-adjust -0.225))
+
+(defvar-local doom-modeline--buffer-file-state-icon nil)
+(defun doom-modeline-update-buffer-file-state-icon (&rest _)
+ "Update the buffer or file state in mode-line."
+ (setq doom-modeline--buffer-file-state-icon
+ (when doom-modeline-buffer-state-icon
+ (ignore-errors
+ (concat
+ (cond (buffer-read-only
+ (doom-modeline-buffer-file-state-icon
+ "lock" "π" "%1*" `(:inherit doom-modeline-warning
+ :weight ,(if doom-modeline-icon
+ 'normal
+ 'bold))))
+ ((and buffer-file-name (buffer-modified-p)
+ doom-modeline-buffer-modification-icon)
+ (doom-modeline-buffer-file-state-icon
+ "save" "πΎ" "%1*" `(:inherit doom-modeline-buffer-modified
+ :weight ,(if doom-modeline-icon
+ 'normal
+ 'bold))))
+ ((and buffer-file-name
+ (not (file-remote-p buffer-file-name)) ; Avoid freezing while connection is lost
+ (not (file-exists-p buffer-file-name)))
+ (doom-modeline-buffer-file-state-icon
+ "do_not_disturb_alt" "π«" "!" 'doom-modeline-urgent))
+ (t ""))
+ (when (or (buffer-narrowed-p)
+ (and (bound-and-true-p fancy-narrow-mode)
+ (fancy-narrow-active-p))
+ (bound-and-true-p dired-narrow-mode))
+ (doom-modeline-buffer-file-state-icon
+ "vertical_align_center" "β" "><" 'doom-modeline-warning)))))))
+
+(defvar-local doom-modeline--buffer-file-name nil)
+(defun doom-modeline-update-buffer-file-name (&rest _)
+ "Update buffer file name in mode-line."
+ (setq doom-modeline--buffer-file-name
+ (ignore-errors
+ (save-match-data
+ (if buffer-file-name
+ (doom-modeline-buffer-file-name)
+ (propertize "%b"
+ 'face 'doom-modeline-buffer-file
+ 'mouse-face 'mode-line-highlight
+ 'help-echo "Buffer name
+mouse-1: Previous buffer\nmouse-3: Next buffer"
+ 'local-map mode-line-buffer-identification-keymap))))))
+(add-hook 'find-file-hook #'doom-modeline-update-buffer-file-name)
+(add-hook 'after-save-hook #'doom-modeline-update-buffer-file-name)
+(add-hook 'clone-indirect-buffer-hook #'doom-modeline-update-buffer-file-name)
+(add-hook 'evil-insert-state-exit-hook #'doom-modeline-update-buffer-file-name)
+(advice-add #'not-modified :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'rename-buffer :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'set-visited-file-name :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'pop-to-buffer :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'undo :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'undo-tree-undo-1 :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'undo-tree-redo-1 :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'fill-paragraph :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'popup-create :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'popup-delete :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'org-edit-src-save :after #'doom-modeline-update-buffer-file-name)
+(advice-add #'symbol-overlay-rename :after #'doom-modeline-update-buffer-file-name)
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-buffer-file-name-style
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-buffer-file-name-style val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when buffer-file-name
+ (doom-modeline-update-buffer-file-name)))))))
+
+(defsubst doom-modeline--buffer-mode-icon ()
+ "The icon of the current major mode."
+ (when (and doom-modeline-icon doom-modeline-major-mode-icon)
+ (when-let ((icon (or doom-modeline--buffer-file-icon
+ (doom-modeline-update-buffer-file-icon))))
+ (concat
+ (let ((active (doom-modeline--active)))
+ (if (and active doom-modeline-major-mode-color-icon)
+ icon
+ (doom-modeline-propertize-icon icon (if active
+ 'mode-line
+ 'mode-line-inactive))))
+ (doom-modeline-vspc)))))
+
+(defsubst doom-modeline--buffer-state-icon ()
+ "The icon of the current buffer state."
+ (when doom-modeline-buffer-state-icon
+ (when-let ((icon (doom-modeline-update-buffer-file-state-icon)))
+ (concat
+ (if (doom-modeline--active)
+ icon
+ (doom-modeline-propertize-icon icon 'mode-line-inactive))
+ (doom-modeline-vspc)))))
+
+(defsubst doom-modeline--buffer-name ()
+ "The current buffer name."
+ (when doom-modeline-buffer-name
+ (if (and (not (eq doom-modeline-buffer-file-name-style 'file-name))
+ doom-modeline--limited-width-p)
+ ;; Only display the buffer name if the window is small, and doesn't need to
+ ;; respect file-name style.
+ (propertize "%b"
+ 'face (cond ((and buffer-file-name (buffer-modified-p))
+ 'doom-modeline-buffer-modified)
+ ((doom-modeline--active) 'doom-modeline-buffer-file)
+ (t 'mode-line-inactive))
+ 'mouse-face 'mode-line-highlight
+ 'help-echo "Buffer name
+mouse-1: Previous buffer\nmouse-3: Next buffer"
+ 'local-map mode-line-buffer-identification-keymap)
+ (when-let ((name (or doom-modeline--buffer-file-name
+ (doom-modeline-update-buffer-file-name))))
+ (if (doom-modeline--active)
+ ;; Check if the buffer is modified
+ (if (and buffer-file-name (buffer-modified-p))
+ (propertize name 'face 'doom-modeline-buffer-modified)
+ name)
+ (propertize name 'face 'mode-line-inactive))))))
+
+(doom-modeline-def-segment buffer-info
+ "Combined information about the current buffer, including the current working
+directory, the file name, and its state (modified, read-only or non-existent)."
+ (concat
+ (doom-modeline-spc)
+ (doom-modeline--buffer-mode-icon)
+ (doom-modeline--buffer-state-icon)
+ (doom-modeline--buffer-name)))
+
+(doom-modeline-def-segment buffer-info-simple
+ "Display only the current buffer's name, but with fontification."
+ (concat
+ (doom-modeline-spc)
+ (doom-modeline--buffer-mode-icon)
+ (doom-modeline--buffer-state-icon)
+ (propertize "%b"
+ 'face (cond ((and buffer-file-name (buffer-modified-p))
+ 'doom-modeline-buffer-modified)
+ ((doom-modeline--active) 'doom-modeline-buffer-file)
+ (t 'mode-line-inactive))
+ 'mouse-face 'mode-line-highlight
+ 'help-echo "Buffer name
+mouse-1: Previous buffer\nmouse-3: Next buffer"
+ 'local-map mode-line-buffer-identification-keymap)))
+
+(doom-modeline-def-segment buffer-default-directory
+ "Displays `default-directory' with the icon and state . This is for special
+buffers like the scratch buffer where knowing the current project directory is
+important."
+ (let ((face (cond ((buffer-modified-p)
+ 'doom-modeline-buffer-modified)
+ ((doom-modeline--active) 'doom-modeline-buffer-path)
+ (t 'mode-line-inactive))))
+ (concat (doom-modeline-spc)
+ (and doom-modeline-major-mode-icon
+ (concat (doom-modeline-icon
+ 'octicon "file-directory" "πΏ" ""
+ :face face :v-adjust -0.05 :height 1.25)
+ (doom-modeline-vspc)))
+ (doom-modeline--buffer-state-icon)
+ (propertize (abbreviate-file-name default-directory) 'face face))))
+
+(doom-modeline-def-segment buffer-default-directory-simple
+ "Displays `default-directory'. This is for special buffers like the scratch
+buffer where knowing the current project directory is important."
+ (let ((face (if (doom-modeline--active) 'doom-modeline-buffer-path 'mode-line-inactive)))
+ (concat (doom-modeline-spc)
+ (and doom-modeline-major-mode-icon
+ (concat (doom-modeline-icon
+ 'octicon "file-directory" "πΏ" ""
+ :face face :v-adjust -0.05 :height 1.25)
+ (doom-modeline-vspc)))
+ (propertize (abbreviate-file-name default-directory) 'face face))))
+
+
+;;
+;; Encoding
+;;
+
+(doom-modeline-def-segment buffer-encoding
+ "Displays the eol and the encoding style of the buffer the same way Atom does."
+ (when doom-modeline-buffer-encoding
+ (let ((face (if (doom-modeline--active) 'mode-line 'mode-line-inactive))
+ (mouse-face 'mode-line-highlight))
+ (concat
+ (doom-modeline-spc)
+
+ ;; eol type
+ (let ((eol (coding-system-eol-type buffer-file-coding-system)))
+ (when (or (eq doom-modeline-buffer-encoding t)
+ (and (eq doom-modeline-buffer-encoding 'nondefault)
+ (not (equal eol doom-modeline-default-eol-type))))
+ (propertize
+ (pcase eol
+ (0 "LF ")
+ (1 "CRLF ")
+ (2 "CR ")
+ (_ ""))
+ 'face face
+ 'mouse-face mouse-face
+ 'help-echo (format "End-of-line style: %s\nmouse-1: Cycle"
+ (pcase eol
+ (0 "Unix-style LF")
+ (1 "DOS-style CRLF")
+ (2 "Mac-style CR")
+ (_ "Undecided")))
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1] 'mode-line-change-eol)
+ map))))
+
+ ;; coding system
+ (let* ((sys (coding-system-plist buffer-file-coding-system))
+ (cat (plist-get sys :category))
+ (sym (if (memq cat
+ '(coding-category-undecided coding-category-utf-8))
+ 'utf-8
+ (plist-get sys :name))))
+ (when (or (eq doom-modeline-buffer-encoding t)
+ (and (eq doom-modeline-buffer-encoding 'nondefault)
+ (not (eq cat 'coding-category-undecided))
+ (not (eq sym doom-modeline-default-coding-system))))
+ (propertize
+ (upcase (symbol-name sym))
+ 'face face
+ 'mouse-face mouse-face
+ 'help-echo 'mode-line-mule-info-help-echo
+ 'local-map mode-line-coding-system-map)))
+
+ (doom-modeline-spc)))))
+
+
+;;
+;; Indentation
+;;
+
+(doom-modeline-def-segment indent-info
+ "Displays the indentation information."
+ (when doom-modeline-indent-info
+ (let ((do-propertize
+ (lambda (mode size)
+ (propertize
+ (format " %s %d " mode size)
+ 'face (if (doom-modeline--active) 'mode-line 'mode-line-inactive)))))
+ (if indent-tabs-mode
+ (funcall do-propertize "TAB" tab-width)
+ (let ((lookup-var
+ (seq-find (lambda (var)
+ (and var (boundp var) (symbol-value var)))
+ (cdr (assoc major-mode doom-modeline-indent-alist)) nil)))
+ (funcall do-propertize "SPC"
+ (if lookup-var
+ (symbol-value lookup-var)
+ tab-width)))))))
+
+;;
+;; Remote host
+;;
+
+(doom-modeline-def-segment remote-host
+ "Hostname for remote buffers."
+ (when default-directory
+ (when-let ((host (file-remote-p default-directory 'host)))
+ (propertize
+ (concat "@" host)
+ 'face (if (doom-modeline--active) 'doom-modeline-host 'mode-line-inactive)))))
+
+
+;;
+;; Major mode
+;;
+
+(doom-modeline-def-segment major-mode
+ "The major mode, including environment and text-scale info."
+ (propertize
+ (concat
+ (doom-modeline-spc)
+ (propertize (format-mode-line
+ (or (and (boundp 'delighted-modes)
+ (cadr (assq major-mode delighted-modes)))
+ mode-name))
+ 'help-echo "Major mode\n\
+ mouse-1: Display major mode menu\n\
+ mouse-2: Show help for major mode\n\
+ mouse-3: Toggle minor modes"
+ 'mouse-face 'mode-line-highlight
+ 'local-map mode-line-major-mode-keymap)
+ (when (and doom-modeline-env-version doom-modeline-env--version)
+ (format " %s" doom-modeline-env--version))
+ (and (boundp 'text-scale-mode-amount)
+ (/= text-scale-mode-amount 0)
+ (format
+ (if (> text-scale-mode-amount 0)
+ " (%+d)"
+ " (%-d)")
+ text-scale-mode-amount))
+ (doom-modeline-spc))
+ 'face (if (doom-modeline--active)
+ 'doom-modeline-buffer-major-mode
+ 'mode-line-inactive)))
+
+
+;;
+;; Process
+;;
+
+(doom-modeline-def-segment process
+ "The process info."
+ (if (doom-modeline--active)
+ mode-line-process
+ (propertize (format-mode-line mode-line-process)
+ 'face 'mode-line-inactive)))
+
+
+;;
+;; Minor modes
+;;
+
+(doom-modeline-def-segment minor-modes
+ (when doom-modeline-minor-modes
+ (let ((face (if (doom-modeline--active)
+ 'doom-modeline-buffer-minor-mode
+ 'mode-line-inactive))
+ (mouse-face 'mode-line-highlight)
+ (help-echo "Minor mode
+ mouse-1: Display minor mode menu
+ mouse-2: Show help for minor mode
+ mouse-3: Toggle minor modes"))
+ (if (bound-and-true-p minions-mode)
+ `((:propertize ("" ,(--filter (memq (car it) minions-direct)
+ minor-mode-alist))
+ face ,face
+ mouse-face ,mouse-face
+ help-echo ,help-echo
+ local-map ,mode-line-minor-mode-keymap)
+ ,(doom-modeline-spc)
+ (:propertize ("" ,(doom-modeline-icon 'octicon "gear" "β"
+ minions-mode-line-lighter
+ :face face :v-adjust -0.05))
+ mouse-face ,mouse-face
+ help-echo "Minions
+mouse-1: Display minor modes menu"
+ local-map ,minions-mode-line-minor-modes-map)
+ ,(doom-modeline-spc))
+ `((:propertize ("" minor-mode-alist)
+ face ,face
+ mouse-face ,mouse-face
+ help-echo ,help-echo
+ local-map ,mode-line-minor-mode-keymap)
+ ,(doom-modeline-spc))))))
+
+
+;;
+;; VCS
+;;
+
+(defun doom-modeline-vcs-icon (icon &optional unicode text face voffset)
+ "Displays the vcs ICON with FACE and VOFFSET.
+
+UNICODE and TEXT are fallbacks.
+Uses `all-the-icons-octicon' to fetch the icon."
+ (doom-modeline-icon 'octicon icon unicode text
+ :face face :v-adjust (or voffset -0.1)))
+
+(defvar-local doom-modeline--vcs-icon nil)
+(defun doom-modeline-update-vcs-icon (&rest _)
+ "Update icon of vcs state in mode-line."
+ (setq doom-modeline--vcs-icon
+ (when (and vc-mode buffer-file-name)
+ (let* ((backend (vc-backend buffer-file-name))
+ (state (vc-state (file-local-name buffer-file-name) backend)))
+ (cond ((memq state '(edited added))
+ (doom-modeline-vcs-icon "git-compare" "β" "*" 'doom-modeline-info -0.05))
+ ((eq state 'needs-merge)
+ (doom-modeline-vcs-icon "git-merge" "β" "?" 'doom-modeline-info))
+ ((eq state 'needs-update)
+ (doom-modeline-vcs-icon "arrow-down" "β" "!" 'doom-modeline-warning))
+ ((memq state '(removed conflict unregistered))
+ (doom-modeline-vcs-icon "alert" "β " "!" 'doom-modeline-urgent))
+ (t
+ (doom-modeline-vcs-icon "git-branch" "ξ " "@" 'doom-modeline-info -0.05)))))))
+(add-hook 'find-file-hook #'doom-modeline-update-vcs-icon)
+(add-hook 'after-save-hook #'doom-modeline-update-vcs-icon)
+(advice-add #'vc-refresh-state :after #'doom-modeline-update-vcs-icon)
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-icon
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-icon val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (doom-modeline-update-vcs-icon))))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-unicode-fallback
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-unicode-fallback val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (doom-modeline-update-vcs-icon))))))
+
+(defvar-local doom-modeline--vcs-text nil)
+(defun doom-modeline-update-vcs-text (&rest _)
+ "Update text of vcs state in mode-line."
+ (setq doom-modeline--vcs-text
+ (when (and vc-mode buffer-file-name)
+ (let* ((backend (vc-backend buffer-file-name))
+ (state (vc-state (file-local-name buffer-file-name) backend))
+ (str (if vc-display-status
+ (substring vc-mode (+ (if (eq backend 'Hg) 2 3) 2))
+ "")))
+ (propertize (if (> (length str) doom-modeline-vcs-max-length)
+ (concat
+ (substring str 0 (- doom-modeline-vcs-max-length 3))
+ "...")
+ str)
+ 'mouse-face 'mode-line-highlight
+ 'face (cond ((eq state 'needs-update)
+ 'doom-modeline-warning)
+ ((memq state '(removed conflict unregistered))
+ 'doom-modeline-urgent)
+ (t 'doom-modeline-info)))))))
+(add-hook 'find-file-hook #'doom-modeline-update-vcs-text)
+(add-hook 'after-save-hook #'doom-modeline-update-vcs-text)
+(advice-add #'vc-refresh-state :after #'doom-modeline-update-vcs-text)
+
+(doom-modeline-def-segment vcs
+ "Displays the current branch, colored based on its state."
+ (let ((active (doom-modeline--active)))
+ (when-let ((icon doom-modeline--vcs-icon)
+ (text doom-modeline--vcs-text))
+ (concat
+ (doom-modeline-spc)
+ (propertize
+ (concat
+ (if active
+ icon
+ (doom-modeline-propertize-icon icon 'mode-line-inactive))
+ (doom-modeline-vspc))
+ 'mouse-face 'mode-line-highlight
+ 'help-echo (get-text-property 1 'help-echo vc-mode)
+ 'local-map (get-text-property 1 'local-map vc-mode))
+ (if active
+ text
+ (propertize text 'face 'mode-line-inactive))
+ (doom-modeline-spc)))))
+
+
+;;
+;; Checker
+;;
+
+(defun doom-modeline-checker-icon (icon unicode text face)
+ "Displays the checker ICON with FACE.
+
+UNICODE and TEXT are fallbacks.
+Uses `all-the-icons-material' to fetch the icon."
+ (doom-modeline-icon 'material icon unicode text
+ :face face :height 1.1 :v-adjust -0.225))
+
+(defun doom-modeline-checker-text (text &optional face)
+ "Displays TEXT with FACE."
+ (propertize text 'face (or face 'mode-line)))
+
+;; Flycheck
+
+(defun doom-modeline--flycheck-count-errors ()
+ "Count the number of ERRORS, grouped by level.
+
+Return an alist, where each ITEM is a cons cell whose `car' is an
+error level, and whose `cdr' is the number of errors of that
+level."
+ (let ((info 0) (warning 0) (error 0))
+ (mapc
+ (lambda (item)
+ (let ((count (cdr item)))
+ (pcase (flycheck-error-level-compilation-level (car item))
+ (0 (cl-incf info count))
+ (1 (cl-incf warning count))
+ (2 (cl-incf error count)))))
+ (flycheck-count-errors flycheck-current-errors))
+ `((info . ,info) (warning . ,warning) (error . ,error))))
+
+(defvar-local doom-modeline--flycheck-icon nil)
+(defun doom-modeline-update-flycheck-icon (&optional status)
+ "Update flycheck icon via STATUS."
+ (setq doom-modeline--flycheck-icon
+ (when-let
+ ((icon
+ (pcase status
+ ('finished (if flycheck-current-errors
+ (let-alist (doom-modeline--flycheck-count-errors)
+ (doom-modeline-checker-icon
+ "block" "π«" "!"
+ (cond ((> .error 0) 'doom-modeline-urgent)
+ ((> .warning 0) 'doom-modeline-warning)
+ (t 'doom-modeline-info))))
+ (doom-modeline-checker-icon "check" "β" "-" 'doom-modeline-info)))
+ ('running (doom-modeline-checker-icon "access_time" "β±" "*" 'doom-modeline-debug))
+ ('no-checker (doom-modeline-checker-icon "sim_card_alert" "β " "-" 'doom-modeline-debug))
+ ('errored (doom-modeline-checker-icon "sim_card_alert" "β " "-" 'doom-modeline-urgent))
+ ('interrupted (doom-modeline-checker-icon "pause" "βΈ" "=" 'doom-modeline-debug))
+ ('suspicious (doom-modeline-checker-icon "priority_high" "β" "!" 'doom-modeline-urgent))
+ (_ nil))))
+ (propertize icon
+ 'help-echo (concat "Flycheck\n"
+ (pcase status
+ ('finished "mouse-1: Display minor mode menu
+mouse-2: Show help for minor mode")
+ ('running "Running...")
+ ('no-checker "No Checker")
+ ('errored "Error")
+ ('interrupted "Interrupted")
+ ('suspicious "Suspicious")))
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line down-mouse-1]
+ flycheck-mode-menu-map)
+ (define-key map [mode-line mouse-2]
+ (lambda ()
+ (interactive)
+ (describe-function 'flycheck-mode)))
+ map)))))
+(add-hook 'flycheck-status-changed-functions #'doom-modeline-update-flycheck-icon)
+(add-hook 'flycheck-mode-hook #'doom-modeline-update-flycheck-icon)
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-icon
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-icon val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when (bound-and-true-p flycheck-mode)
+ (flycheck-buffer)))))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-unicode-fallback
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-unicode-fallback val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when (bound-and-true-p flycheck-mode)
+ (flycheck-buffer)))))))
+
+(defvar-local doom-modeline--flycheck-text nil)
+(defun doom-modeline-update-flycheck-text (&optional status)
+ "Update flycheck text via STATUS."
+ (setq doom-modeline--flycheck-text
+ (when-let
+ ((text
+ (pcase status
+ ('finished (when flycheck-current-errors
+ (let-alist (doom-modeline--flycheck-count-errors)
+ (if doom-modeline-checker-simple-format
+ (doom-modeline-checker-text
+ (number-to-string (+ .error .warning .info))
+ (cond ((> .error 0) 'doom-modeline-urgent)
+ ((> .warning 0) 'doom-modeline-warning)
+ (t 'doom-modeline-info)))
+ (format "%s/%s/%s"
+ (doom-modeline-checker-text (number-to-string .error)
+ 'doom-modeline-urgent)
+ (doom-modeline-checker-text (number-to-string .warning)
+ 'doom-modeline-warning)
+ (doom-modeline-checker-text (number-to-string .info)
+ 'doom-modeline-info))))))
+ ('running nil)
+ ('no-checker nil)
+ ('errored (doom-modeline-checker-text "Error" 'doom-modeline-urgent))
+ ('interrupted (doom-modeline-checker-text "Interrupted" 'doom-modeline-debug))
+ ('suspicious (doom-modeline-checker-text "Suspicious" 'doom-modeline-urgent))
+ (_ nil))))
+ (propertize
+ text
+ 'help-echo (pcase status
+ ('finished
+ (concat
+ (when flycheck-current-errors
+ (let-alist (doom-modeline--flycheck-count-errors)
+ (format "error: %d, warning: %d, info: %d\n" .error .warning .info)))
+ "mouse-1: Show all errors
+mouse-3: Next error"
+ (if (featurep 'mwheel)
+ "\nwheel-up/wheel-down: Previous/next error")))
+ ('running "Running...")
+ ('no-checker "No Checker")
+ ('errored "Error")
+ ('interrupted "Interrupted")
+ ('suspicious "Suspicious"))
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1]
+ #'flycheck-list-errors)
+ (define-key map [mode-line mouse-3]
+ #'flycheck-next-error)
+ (when (featurep 'mwheel)
+ (define-key map [mode-line mouse-wheel-down-event]
+ (lambda (event)
+ (interactive "e")
+ (with-selected-window (posn-window (event-start event))
+ (flycheck-previous-error 1))))
+ (define-key map [mode-line mouse-wheel-up-event]
+ (lambda (event)
+ (interactive "e")
+ (with-selected-window (posn-window (event-start event))
+ (flycheck-next-error 1))))
+ map))))))
+(add-hook 'flycheck-status-changed-functions #'doom-modeline-update-flycheck-text)
+(add-hook 'flycheck-mode-hook #'doom-modeline-update-flycheck-text)
+
+;; Flymake
+
+;; Compatibility
+;; @see https://github.com/emacs-mirror/emacs/commit/6e100869012da9244679696634cab6b9cac96303.
+(with-eval-after-load 'flymake
+ (unless (boundp 'flymake--state)
+ (defvaralias 'flymake--state 'flymake--backend-state))
+ (unless (fboundp 'flymake--state-diags)
+ (defalias 'flymake--state-diags 'flymake--backend-state-diags)))
+
+(defvar-local doom-modeline--flymake-icon nil)
+(defun doom-modeline-update-flymake-icon (&rest _)
+ "Update flymake icon."
+ (setq flymake--mode-line-format nil) ; remove the lighter of minor mode
+ (setq doom-modeline--flymake-icon
+ (let* ((known (hash-table-keys flymake--state))
+ (running (flymake-running-backends))
+ (disabled (flymake-disabled-backends))
+ (reported (flymake-reporting-backends))
+ (all-disabled (and disabled (null running)))
+ (some-waiting (cl-set-difference running reported)))
+ (when-let
+ ((icon
+ (cond
+ (some-waiting (doom-modeline-checker-icon "access_time" "β°" "*" 'doom-modeline-debug))
+ ((null known) (doom-modeline-checker-icon "sim_card_alert" "β" "?" 'doom-modeline-debug))
+ (all-disabled (doom-modeline-checker-icon "sim_card_alert" "β" "!" 'doom-modeline-urgent))
+ (t (let ((.error 0)
+ (.warning 0)
+ (.note 0))
+ (progn
+ (cl-loop
+ with warning-level = (warning-numeric-level :warning)
+ with note-level = (warning-numeric-level :debug)
+ for state being the hash-values of flymake--state
+ do (cl-loop
+ with diags = (flymake--state-diags state)
+ for diag in diags do
+ (let ((severity (flymake--lookup-type-property (flymake--diag-type diag) 'severity
+ (warning-numeric-level :error))))
+ (cond ((> severity warning-level) (cl-incf .error))
+ ((> severity note-level) (cl-incf .warning))
+ (t (cl-incf .note))))))
+ (if (> (+ .error .warning .note) 0)
+ (doom-modeline-checker-icon "do_not_disturb_alt" "π«" "!"
+ (cond ((> .error 0) 'doom-modeline-urgent)
+ ((> .warning 0) 'doom-modeline-warning)
+ (t 'doom-modeline-info)))
+ (doom-modeline-checker-icon "check" "β" "-" 'doom-modeline-info))))))))
+ (propertize
+ icon
+ 'help-echo (concat "Flymake\n"
+ (cond
+ (some-waiting "Running...")
+ ((null known) "No Checker")
+ (all-disabled "All Checkers Disabled")
+ (t (format "%d/%d backends running
+mouse-1: Display minor mode menu
+mouse-2: Show help for minor mode"
+ (length running) (length known)))))
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line down-mouse-1]
+ flymake-menu)
+ (define-key map [mode-line mouse-2]
+ (lambda ()
+ (interactive)
+ (describe-function 'flymake-mode)))
+ map))))))
+(advice-add #'flymake--handle-report :after #'doom-modeline-update-flymake-icon)
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-icon
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-icon val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when (bound-and-true-p flymake-mode)
+ (flymake-start)))))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-unicode-fallback
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-unicode-fallback val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when (bound-and-true-p flymake-mode)
+ (flymake-start)))))))
+
+(defvar-local doom-modeline--flymake-text nil)
+(defun doom-modeline-update-flymake-text (&rest _)
+ "Update flymake text."
+ (setq flymake--mode-line-format nil) ; remove the lighter of minor mode
+ (setq doom-modeline--flymake-text
+ (let* ((known (hash-table-keys flymake--state))
+ (running (flymake-running-backends))
+ (disabled (flymake-disabled-backends))
+ (reported (flymake-reporting-backends))
+ (all-disabled (and disabled (null running)))
+ (some-waiting (cl-set-difference running reported))
+ (warning-level (warning-numeric-level :warning))
+ (note-level (warning-numeric-level :debug))
+ (.error 0)
+ (.warning 0)
+ (.note 0))
+ (maphash (lambda (_b state)
+ (cl-loop
+ with diags = (flymake--state-diags state)
+ for diag in diags do
+ (let ((severity (flymake--lookup-type-property (flymake--diag-type diag) 'severity
+ (warning-numeric-level :error))))
+ (cond ((> severity warning-level) (cl-incf .error))
+ ((> severity note-level) (cl-incf .warning))
+ (t (cl-incf .note))))))
+ flymake--state)
+ (when-let
+ ((text
+ (cond
+ (some-waiting doom-modeline--flymake-text)
+ ((null known) nil)
+ (all-disabled nil)
+ (t (let ((num (+ .error .warning .note)))
+ (when (> num 0)
+ (if doom-modeline-checker-simple-format
+ (doom-modeline-checker-text (number-to-string num)
+ (cond ((> .error 0) 'doom-modeline-urgent)
+ ((> .warning 0) 'doom-modeline-warning)
+ (t 'doom-modeline-info)))
+ (format "%s/%s/%s"
+ (doom-modeline-checker-text (number-to-string .error)
+ 'doom-modeline-urgent)
+ (doom-modeline-checker-text (number-to-string .warning)
+ 'doom-modeline-warning)
+ (doom-modeline-checker-text (number-to-string .note)
+ 'doom-modeline-info)))))))))
+ (propertize
+ text
+ 'help-echo (cond
+ (some-waiting "Running...")
+ ((null known) "No Checker")
+ (all-disabled "All Checkers Disabled")
+ (t (format "error: %d, warning: %d, note: %d
+mouse-1: List all problems%s"
+ .error .warning .note
+ (if (featurep 'mwheel)
+ "\nwheel-up/wheel-down: Previous/next problem"))))
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1]
+ #'flymake-show-diagnostics-buffer)
+ (when (featurep 'mwheel)
+ (define-key map (vector 'mode-line
+ mouse-wheel-down-event)
+ (lambda (event)
+ (interactive "e")
+ (with-selected-window (posn-window (event-start event))
+ (flymake-goto-prev-error 1 nil t))))
+ (define-key map (vector 'mode-line
+ mouse-wheel-up-event)
+ (lambda (event)
+ (interactive "e")
+ (with-selected-window (posn-window (event-start event))
+ (flymake-goto-next-error 1 nil t))))
+ map)))))))
+(advice-add #'flymake--handle-report :after #'doom-modeline-update-flymake-text)
+
+(doom-modeline-def-segment checker
+ "Displays color-coded error status in the current buffer with pretty icons."
+ (let ((active (doom-modeline--active))
+ (seg (cond ((and (bound-and-true-p flymake-mode)
+ (bound-and-true-p flymake--state)) ; only support 26+
+ `(,doom-modeline--flymake-icon . ,doom-modeline--flymake-text))
+ ((bound-and-true-p flycheck-mode)
+ `(,doom-modeline--flycheck-icon . ,doom-modeline--flycheck-text)))))
+ (let ((icon (car seg))
+ (text (cdr seg)))
+ (concat
+ (when icon
+ (concat
+ (doom-modeline-spc)
+ (if active
+ icon
+ (doom-modeline-propertize-icon icon 'mode-line-inactive))))
+ (when text
+ (concat
+ (if icon (doom-modeline-vspc) (doom-modeline-spc))
+ (if active
+ text
+ (propertize text 'face 'mode-line-inactive))))
+ (doom-modeline-spc)))))
+
+
+;;
+;; Word Count
+;;
+
+(doom-modeline-def-segment word-count
+ "The buffer word count.
+Displayed when in a major mode in `doom-modeline-continuous-word-count-modes'.
+Respects `doom-modeline-enable-word-count'."
+ (when (and doom-modeline-enable-word-count
+ (member major-mode doom-modeline-continuous-word-count-modes))
+ (propertize (format " %dW" (count-words (point-min) (point-max)))
+ 'face (if (doom-modeline--active)
+ 'mode-line
+ 'mode-line-inactive))))
+
+
+;;
+;; Selection
+;;
+
+(defsubst doom-modeline-column (pos)
+ "Get the column of the position `POS'."
+ (save-excursion (goto-char pos)
+ (current-column)))
+
+(doom-modeline-def-segment selection-info
+ "Information about the current selection, such as how many characters and
+lines are selected, or the NxM dimensions of a block selection."
+ (when (and (or mark-active (and (bound-and-true-p evil-local-mode)
+ (eq evil-state 'visual)))
+ (doom-modeline--active))
+ (cl-destructuring-bind (beg . end)
+ (if (and (bound-and-true-p evil-local-mode) (eq evil-state 'visual))
+ (cons evil-visual-beginning evil-visual-end)
+ (cons (region-beginning) (region-end)))
+ (propertize
+ (let ((lines (count-lines beg (min end (point-max)))))
+ (concat (doom-modeline-spc)
+ (cond ((or (bound-and-true-p rectangle-mark-mode)
+ (and (bound-and-true-p evil-visual-selection)
+ (eq 'block evil-visual-selection)))
+ (let ((cols (abs (- (doom-modeline-column end)
+ (doom-modeline-column beg)))))
+ (format "%dx%dB" lines cols)))
+ ((and (bound-and-true-p evil-visual-selection)
+ (eq evil-visual-selection 'line))
+ (format "%dL" lines))
+ ((> lines 1)
+ (format "%dC %dL" (- end beg) lines))
+ (t
+ (format "%dC" (- end beg))))
+ (when doom-modeline-enable-word-count
+ (format " %dW" (count-words beg end)))
+ (doom-modeline-spc)))
+ 'face 'doom-modeline-highlight))))
+
+
+;;
+;; Matches (macro, anzu, evil-substitute, iedit, symbol-overlay and multi-cursors)
+;;
+
+(defsubst doom-modeline--macro-recording ()
+ "Display current Emacs or evil macro being recorded."
+ (when (and (doom-modeline--active)
+ (or defining-kbd-macro executing-kbd-macro))
+ (let ((sep (propertize " " 'face 'doom-modeline-panel ))
+ (vsep (propertize " " 'face
+ '(:inherit (doom-modeline-panel variable-pitch)))))
+ (concat
+ sep
+ (doom-modeline-icon 'material "fiber_manual_record" "β"
+ (if (bound-and-true-p evil-this-macro)
+ (char-to-string evil-this-macro)
+ "Macro")
+ :face 'doom-modeline-panel
+ :v-adjust -0.225)
+ vsep
+ (doom-modeline-icon 'octicon "triangle-right" "βΆ" ">"
+ :face 'doom-modeline-panel
+ :v-adjust -0.05)
+ sep))))
+
+;; `anzu' and `evil-anzu' expose current/total state that can be displayed in the
+;; mode-line.
+(defun doom-modeline-fix-anzu-count (positions here)
+ "Calulate anzu count via POSITIONS and HERE."
+ (cl-loop for (start . end) in positions
+ collect t into before
+ when (and (>= here start) (<= here end))
+ return (length before)
+ finally return 0))
+
+(advice-add #'anzu--where-is-here :override #'doom-modeline-fix-anzu-count)
+
+(setq anzu-cons-mode-line-p nil) ; manage modeline segment ourselves
+;; Ensure anzu state is cleared when searches & iedit are done
+(with-eval-after-load 'anzu
+ (add-hook 'isearch-mode-end-hook #'anzu--reset-status t)
+ (add-hook 'iedit-mode-end-hook #'anzu--reset-status)
+ (advice-add #'evil-force-normal-state :after #'anzu--reset-status)
+ ;; Fix matches segment mirroring across all buffers
+ (mapc #'make-variable-buffer-local
+ '(anzu--total-matched
+ anzu--current-position anzu--state anzu--cached-count
+ anzu--cached-positions anzu--last-command
+ anzu--last-isearch-string anzu--overflow-p)))
+
+(defsubst doom-modeline--anzu ()
+ "Show the match index and total number thereof.
+Requires `anzu', also `evil-anzu' if using `evil-mode' for compatibility with
+`evil-search'."
+ (when (and (bound-and-true-p anzu--state)
+ (not (bound-and-true-p iedit-mode)))
+ (propertize
+ (let ((here anzu--current-position)
+ (total anzu--total-matched))
+ (cond ((eq anzu--state 'replace-query)
+ (format " %d replace " anzu--cached-count))
+ ((eq anzu--state 'replace)
+ (format " %d/%d " here total))
+ (anzu--overflow-p
+ (format " %s+ " total))
+ (t
+ (format " %s/%d " here total))))
+ 'face (if (doom-modeline--active) 'doom-modeline-panel 'mode-line-inactive))))
+
+(defsubst doom-modeline--evil-substitute ()
+ "Show number of matches for evil-ex substitutions and highlights in real time."
+ (when (and (bound-and-true-p evil-local-mode)
+ (or (assq 'evil-ex-substitute evil-ex-active-highlights-alist)
+ (assq 'evil-ex-global-match evil-ex-active-highlights-alist)
+ (assq 'evil-ex-buffer-match evil-ex-active-highlights-alist)))
+ (propertize
+ (let ((range (if evil-ex-range
+ (cons (car evil-ex-range) (cadr evil-ex-range))
+ (cons (line-beginning-position) (line-end-position))))
+ (pattern (car-safe (evil-delimited-arguments evil-ex-argument 2))))
+ (if pattern
+ (format " %s matches " (how-many pattern (car range) (cdr range)))
+ " - "))
+ 'face (if (doom-modeline--active) 'doom-modeline-panel 'mode-line-inactive))))
+
+(defun doom-modeline-themes--overlay-sort (a b)
+ "Sort overlay A and B."
+ (< (overlay-start a) (overlay-start b)))
+
+(defsubst doom-modeline--iedit ()
+ "Show the number of iedit regions matches + what match you're on."
+ (when (and (bound-and-true-p iedit-mode)
+ (bound-and-true-p iedit-occurrences-overlays))
+ (propertize
+ (let ((this-oc (or (let ((inhibit-message t))
+ (iedit-find-current-occurrence-overlay))
+ (save-excursion (iedit-prev-occurrence)
+ (iedit-find-current-occurrence-overlay))))
+ (length (length iedit-occurrences-overlays)))
+ (format " %s/%d "
+ (if this-oc
+ (- length
+ (length (memq this-oc (sort (append iedit-occurrences-overlays nil)
+ #'doom-modeline-themes--overlay-sort)))
+ -1)
+ "-")
+ length))
+ 'face (if (doom-modeline--active) 'doom-modeline-panel 'mode-line-inactive))))
+
+(defsubst doom-modeline--symbol-overlay ()
+ "Show the number of matches for symbol overlay."
+ (when-let ((active (doom-modeline--active)))
+ (when (and (bound-and-true-p symbol-overlay-keywords-alist)
+ (not (bound-and-true-p symbol-overlay-temp-symbol))
+ (not (bound-and-true-p iedit-mode)))
+ (let* ((keyword (symbol-overlay-assoc (symbol-overlay-get-symbol t)))
+ (symbol (car keyword))
+ (before (symbol-overlay-get-list -1 symbol))
+ (after (symbol-overlay-get-list 1 symbol))
+ (count (length before)))
+ (if (symbol-overlay-assoc symbol)
+ (propertize
+ (format (concat " %d/%d " (and (cadr keyword) "in scope "))
+ (+ count 1)
+ (+ count (length after)))
+ 'face (if active 'doom-modeline-panel 'mode-line-inactive)))))))
+
+(defsubst doom-modeline--multiple-cursors ()
+ "Show the number of multiple cursors."
+ (cl-destructuring-bind (count . face)
+ (cond ((bound-and-true-p multiple-cursors-mode)
+ (cons (mc/num-cursors)
+ (if (doom-modeline--active)
+ 'doom-modeline-panel
+ 'mode-line-inactive)))
+ ((bound-and-true-p evil-mc-cursor-list)
+ (cons (length evil-mc-cursor-list)
+ (cond ((not (doom-modeline--active)) 'mode-line-inactive)
+ (evil-mc-frozen 'doom-modeline-bar)
+ ('doom-modeline-panel))))
+ ((cons nil nil)))
+ (when count
+ (concat (propertize " " 'face face)
+ (or (doom-modeline-icon 'faicon "i-cursor" nil nil
+ :face face :v-adjust -0.0575)
+ (propertize "I"
+ 'face `(:inherit ,face :height 1.4 :weight normal)
+ 'display '(raise -0.1)))
+ (propertize (doom-modeline-vspc)
+ 'face `(:inherit (variable-pitch ,face)))
+ (propertize (format "%d " count)
+ 'face face)))))
+
+(defsubst doom-modeline--phi-search ()
+ "Show the number of matches for `phi-search' and `phi-replace'."
+ (when-let ((active (doom-modeline--active)))
+ (when (bound-and-true-p phi-search--overlays)
+ (let ((total (length phi-search--overlays))
+ (selection phi-search--selection))
+ (when selection
+ (propertize
+ (format " %d/%d " (1+ selection) total)
+ 'face (if active 'doom-modeline-panel 'mode-line-inactive)))))))
+
+(defun doom-modeline--override-phi-search-mode-line (orig-fun &rest args)
+ "Override the mode-line of `phi-search' and `phi-replace'."
+ (if (bound-and-true-p doom-modeline-mode)
+ (apply orig-fun mode-line-format (cdr args))
+ (apply orig-fun args)))
+(advice-add #'phi-search--initialize :around #'doom-modeline--override-phi-search-mode-line)
+
+(defsubst doom-modeline--buffer-size ()
+ "Show buffer size."
+ (when size-indication-mode
+ (concat (doom-modeline-spc)
+ (propertize "%I"
+ 'face (if (doom-modeline--active) 'mode-line 'mode-line-inactive)
+ 'help-echo "Buffer size
+mouse-1: Display Line and Column Mode Menu"
+ 'mouse-face 'mode-line-highlight
+ 'local-map mode-line-column-line-number-mode-map)
+ (doom-modeline-spc))))
+
+(doom-modeline-def-segment matches
+ "Displays: 1. the currently recording macro, 2. A current/total for the
+current search term (with `anzu'), 3. The number of substitutions being
+conducted with `evil-ex-substitute', and/or 4. The number of active `iedit'
+regions, 5. The current/total for the highlight term (with `symbol-overlay'),
+6. The number of active `multiple-cursors'."
+ (let ((meta (concat (doom-modeline--macro-recording)
+ (doom-modeline--anzu)
+ (doom-modeline--phi-search)
+ (doom-modeline--evil-substitute)
+ (doom-modeline--iedit)
+ (doom-modeline--symbol-overlay)
+ (doom-modeline--multiple-cursors))))
+ (or (and (not (string-empty-p meta)) meta)
+ (doom-modeline--buffer-size))))
+
+(doom-modeline-def-segment buffer-size
+ "Display buffer size."
+ (doom-modeline--buffer-size))
+
+;;
+;; Media
+;;
+
+(doom-modeline-def-segment media-info
+ "Metadata regarding the current file, such as dimensions for images."
+ ;; TODO Include other information
+ (cond ((eq major-mode 'image-mode)
+ (cl-destructuring-bind (width . height)
+ (when (fboundp 'image-size)
+ (image-size (image-get-display-property) :pixels))
+ (propertize
+ (format " %dx%d " width height)
+ 'face (if (doom-modeline--active) 'mode-line 'mode-line-inactive))))))
+
+
+;;
+;; Bars
+;;
+
+(defvar doom-modeline--bar-active nil)
+(defvar doom-modeline--bar-inactive nil)
+
+(defsubst doom-modeline--bar ()
+ "The default bar regulates the height of the mode-line in GUI."
+ (unless (and doom-modeline--bar-active doom-modeline--bar-inactive)
+ (let ((width doom-modeline-bar-width)
+ (height (max doom-modeline-height
+ (doom-modeline--font-height))))
+ (when (and (numberp width) (numberp height))
+ (setq doom-modeline--bar-active
+ (doom-modeline--create-bar-image 'doom-modeline-bar width height)
+ doom-modeline--bar-inactive
+ (doom-modeline--create-bar-image
+ 'doom-modeline-bar-inactive width height)))))
+ (if (doom-modeline--active)
+ doom-modeline--bar-active
+ doom-modeline--bar-inactive))
+
+(defun doom-modeline-refresh-bars ()
+ "Refresh mode-line bars on next redraw."
+ (setq doom-modeline--bar-active nil
+ doom-modeline--bar-inactive nil))
+
+(cl-defstruct doom-modeline--hud-cache active inactive top-margin bottom-margin)
+
+(defsubst doom-modeline--hud ()
+ "Powerline's hud segment reimplemented in the style of Doom's bar segment."
+ (let* ((ws (window-start))
+ (we (window-end))
+ (bs (buffer-size))
+ (height (max doom-modeline-height
+ (doom-modeline--font-height)))
+ (top-margin (if (zerop bs)
+ 0
+ (/ (* height (1- ws)) bs)))
+ (bottom-margin (if (zerop bs)
+ 0
+ (max 0 (/ (* height (- bs we 1)) bs))))
+ (cache (or (window-parameter nil 'doom-modeline--hud-cache)
+ (set-window-parameter nil 'doom-modeline--hud-cache
+ (make-doom-modeline--hud-cache)))))
+ (unless (and (doom-modeline--hud-cache-active cache)
+ (doom-modeline--hud-cache-inactive cache)
+ (= top-margin (doom-modeline--hud-cache-top-margin cache))
+ (= bottom-margin
+ (doom-modeline--hud-cache-bottom-margin cache)))
+ (setf (doom-modeline--hud-cache-active cache)
+ (doom-modeline--create-hud-image
+ 'doom-modeline-bar 'default doom-modeline-bar-width
+ height top-margin bottom-margin)
+ (doom-modeline--hud-cache-inactive cache)
+ (doom-modeline--create-hud-image
+ 'doom-modeline-bar-inactive 'default doom-modeline-bar-width
+ height top-margin bottom-margin)
+ (doom-modeline--hud-cache-top-margin cache) top-margin
+ (doom-modeline--hud-cache-bottom-margin cache) bottom-margin))
+ (if (doom-modeline--active)
+ (doom-modeline--hud-cache-active cache)
+ (doom-modeline--hud-cache-inactive cache))))
+
+(defun doom-modeline-invalidate-huds ()
+ "Invalidate all cached hud images."
+ (dolist (frame (frame-list))
+ (dolist (window (window-list frame))
+ (set-window-parameter window 'doom-modeline--hud-cache nil))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-height
+ (lambda (_sym val op _where)
+ (when (and (eq op 'set) (integerp val))
+ (doom-modeline-refresh-bars)
+ (doom-modeline-invalidate-huds))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-bar-width
+ (lambda (_sym val op _where)
+ (when (and (eq op 'set) (integerp val))
+ (doom-modeline-refresh-bars)
+ (doom-modeline-invalidate-huds))))
+
+(add-hook 'after-setting-font-hook #'doom-modeline-refresh-bars)
+(add-hook 'after-setting-font-hook #'doom-modeline-invalidate-huds)
+
+(doom-modeline-def-segment bar
+ "The bar regulates the height of the mode-line in GUI."
+ (if doom-modeline-hud
+ (doom-modeline--hud)
+ (doom-modeline--bar)))
+
+(doom-modeline-def-segment hud
+ "Powerline's hud segment reimplemented in the style of Doom's bar segment."
+ (doom-modeline--hud))
+
+
+;;
+;; Window number
+;;
+
+;; HACK: `ace-window-display-mode' should respect the ignore buffers.
+(defun doom-modeline-aw-update ()
+ "Update ace-window-path window parameter for all windows.
+Ensure all windows are labeled so the user can select a specific
+one. The ignored buffers are excluded unless `aw-ignore-on' is nil."
+ (let ((ignore-window-parameters t))
+ (avy-traverse
+ (avy-tree (aw-window-list) aw-keys)
+ (lambda (path leaf)
+ (set-window-parameter
+ leaf 'ace-window-path
+ (propertize
+ (apply #'string (reverse path))
+ 'face 'aw-mode-line-face))))))
+(advice-add #'aw-update :override #'doom-modeline-aw-update)
+
+;; Remove original window number of `ace-window-display-mode'.
+(add-hook 'ace-window-display-mode-hook
+ (lambda ()
+ (setq-default mode-line-format
+ (assq-delete-all 'ace-window-display-mode
+ (default-value 'mode-line-format)))))
+
+(advice-add #'window-numbering-install-mode-line :override #'ignore)
+(advice-add #'window-numbering-clear-mode-line :override #'ignore)
+(advice-add #'winum--install-mode-line :override #'ignore)
+(advice-add #'winum--clear-mode-line :override #'ignore)
+
+(doom-modeline-def-segment window-number
+ "The current window number."
+ (let ((num (cond
+ ((bound-and-true-p ace-window-display-mode)
+ (aw-update)
+ (window-parameter (selected-window) 'ace-window-path))
+ ((bound-and-true-p winum-mode)
+ (setq winum-auto-setup-mode-line nil)
+ (winum-get-number-string))
+ ((bound-and-true-p window-numbering-mode)
+ (window-numbering-get-number-string))
+ (t ""))))
+ (if (and (< 0 (length num))
+ (< 1 (length (cl-mapcan
+ (lambda (frame)
+ ;; Exclude minibuffer and child frames
+ (unless (and (fboundp 'frame-parent)
+ (frame-parent frame))
+ (window-list frame 'never)))
+ (visible-frame-list)))))
+ (propertize (format " %s " num)
+ 'face (if (doom-modeline--active)
+ 'doom-modeline-buffer-major-mode
+ 'mode-line-inactive))
+ (doom-modeline-spc))))
+
+
+;;
+;; Workspace
+;;
+
+(doom-modeline-def-segment workspace-name
+ "The current workspace name or number.
+Requires `eyebrowse-mode' to be enabled or `tab-bar-mode' tabs to be created."
+ (when doom-modeline-workspace-name
+ (when-let
+ ((name (cond
+ ((and (bound-and-true-p eyebrowse-mode)
+ (< 1 (length (eyebrowse--get 'window-configs))))
+ (assq-delete-all 'eyebrowse-mode mode-line-misc-info)
+ (when-let*
+ ((num (eyebrowse--get 'current-slot))
+ (tag (nth 2 (assoc num (eyebrowse--get 'window-configs)))))
+ (if (< 0 (length tag)) tag (int-to-string num))))
+ ((and (fboundp 'tab-bar-mode)
+ (< 1 (length (frame-parameter nil 'tabs))))
+ (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)))))))
+ (propertize (format " %s " name) 'face
+ (if (doom-modeline--active)
+ 'doom-modeline-buffer-major-mode
+ 'mode-line-inactive)))))
+
+
+;;
+;; Perspective
+;;
+
+(defvar-local doom-modeline--persp-name nil)
+(defun doom-modeline-update-persp-name (&rest _)
+ "Update perspective name in mode-line."
+ (setq doom-modeline--persp-name
+ ;; Support `persp-mode', while not support `perspective'
+ (when (and doom-modeline-persp-name
+ (bound-and-true-p persp-mode)
+ (fboundp 'safe-persp-name)
+ (fboundp 'get-current-persp))
+ (let* ((persp (get-current-persp))
+ (name (safe-persp-name persp))
+ (face (if (and persp
+ (not (persp-contain-buffer-p (current-buffer) persp)))
+ 'doom-modeline-persp-buffer-not-in-persp
+ 'doom-modeline-persp-name))
+ (icon (doom-modeline-icon 'material "folder" "πΏ" "#"
+ :face `(:inherit ,face :slant normal)
+ :height 1.1
+ :v-adjust -0.225)))
+ (when (or doom-modeline-display-default-persp-name
+ (not (string-equal persp-nil-name name)))
+ (concat (doom-modeline-spc)
+ (propertize (concat (and doom-modeline-persp-icon
+ (concat icon (doom-modeline-vspc)))
+ (propertize name 'face face))
+ 'help-echo "mouse-1: Switch perspective
+mouse-2: Show help for minor mode"
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1]
+ #'persp-switch)
+ (define-key map [mode-line mouse-2]
+ (lambda ()
+ (interactive)
+ (describe-function 'persp-mode)))
+ map))
+ (doom-modeline-spc)))))))
+
+(add-hook 'buffer-list-update-hook #'doom-modeline-update-persp-name)
+(add-hook 'find-file-hook #'doom-modeline-update-persp-name)
+(add-hook 'persp-activated-functions #'doom-modeline-update-persp-name)
+(add-hook 'persp-renamed-functions #'doom-modeline-update-persp-name)
+(advice-add #'lv-message :after #'doom-modeline-update-persp-name)
+
+(doom-modeline-def-segment persp-name
+ "The current perspective name."
+ (when (and (doom-modeline--active)
+ (not doom-modeline--limited-width-p))
+ doom-modeline--persp-name))
+
+
+;;
+;; Misc info
+;;
+
+(doom-modeline-def-segment misc-info
+ "Mode line construct for miscellaneous information.
+By default, this shows the information specified by `global-mode-string'."
+ (when (and (doom-modeline--active)
+ (not doom-modeline--limited-width-p))
+ '("" mode-line-misc-info)))
+
+
+;;
+;; Position
+;;
+
+;; Be compatible with Emacs 25.
+(defvar doom-modeline-column-zero-based
+ (if (boundp 'column-number-indicator-zero-based)
+ column-number-indicator-zero-based
+ t)
+ "When non-nil, mode line displays column numbers zero-based.
+See `column-number-indicator-zero-based'.")
+
+(defvar doom-modeline-percent-position
+ (if (boundp 'mode-line-percent-position)
+ mode-line-percent-position
+ '(-3 "%p"))
+ "Specification of \"percentage offset\" of window through buffer.
+See `mode-line-percent-position'.")
+
+(doom-modeline-add-variable-watcher
+ 'column-number-indicator-zero-based
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-column-zero-based val))))
+
+(doom-modeline-add-variable-watcher
+ 'mode-line-percent-position
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-percent-position val))))
+
+(doom-modeline-def-segment buffer-position
+ "The buffer position information."
+ (let* ((active (doom-modeline--active))
+ (lc '(line-number-mode
+ (column-number-mode
+ (doom-modeline-column-zero-based "%l:%c" "%l:%C")
+ "%l")
+ (column-number-mode (doom-modeline-column-zero-based ":%c" ":%C"))))
+ (face (if active 'mode-line 'mode-line-inactive))
+ (mouse-face 'mode-line-highlight)
+ (local-map mode-line-column-line-number-mode-map))
+ (concat
+ (doom-modeline-wspc)
+
+ ;; Line and column
+ (propertize (format-mode-line lc)
+ 'face face
+ 'help-echo "Buffer position\n\
+mouse-1: Display Line and Column Mode Menu"
+ 'mouse-face mouse-face
+ 'local-map local-map)
+
+ ;; Position
+ (cond ((and active
+ (bound-and-true-p nyan-mode)
+ (not doom-modeline--limited-width-p)
+ (>= (window-width) nyan-minimum-window-width))
+ (concat
+ (doom-modeline-wspc)
+ (propertize (nyan-create) 'mouse-face mouse-face)))
+ ((and active
+ (bound-and-true-p poke-line-mode)
+ (not doom-modeline--limited-width-p)
+ (>= (window-width) poke-line-minimum-window-width))
+ (concat
+ (doom-modeline-wspc)
+ (propertize (poke-line-create) 'mouse-face mouse-face)))
+ ((and active
+ (bound-and-true-p mlscroll-mode)
+ (not doom-modeline--limited-width-p)
+ (>= (window-width) mlscroll-minimum-current-width))
+ (concat
+ (doom-modeline-wspc)
+ (let ((mlscroll-right-align nil))
+ (format-mode-line (mlscroll-mode-line)))))
+ ((and active
+ (bound-and-true-p sml-modeline-mode)
+ (not doom-modeline--limited-width-p)
+ (>= (window-width) sml-modeline-len))
+ (concat
+ (doom-modeline-wspc)
+ (propertize (sml-modeline-create) 'mouse-face mouse-face)))
+ (t ""))
+
+ ;; Percent position
+ (when doom-modeline-percent-position
+ (concat
+ (doom-modeline-spc)
+ (propertize (format-mode-line '("" doom-modeline-percent-position "%%"))
+ 'face face
+ 'help-echo "Buffer percentage\n\
+mouse-1: Display Line and Column Mode Menu"
+ 'mouse-face mouse-face
+ 'local-map local-map)))
+
+ (when (or line-number-mode column-number-mode doom-modeline-percent-position)
+ (doom-modeline-spc)))))
+
+;;
+;; Party parrot
+;;
+(doom-modeline-def-segment parrot
+ "The party parrot animated icon. Requires `parrot-mode' to be enabled."
+ (when (and (doom-modeline--active)
+ (not doom-modeline--limited-width-p)
+ (bound-and-true-p parrot-mode))
+ (concat (doom-modeline-wspc)
+ (parrot-create)
+ (doom-modeline-spc))))
+
+;;
+;; Modals (evil, overwrite, god, ryo and xah-fly-keys, etc.)
+;;
+
+(defun doom-modeline--modal-icon (text face help-echo)
+ "Display the model icon with FACE and HELP-ECHO.
+TEXT is alternative if icon is not available."
+ (propertize (doom-modeline-icon
+ 'material
+ (when doom-modeline-modal-icon "fiber_manual_record")
+ "β"
+ text
+ :face (if (doom-modeline--active) face 'mode-line-inactive)
+ :v-adjust -0.225)
+ 'help-echo help-echo))
+
+(defsubst doom-modeline--evil ()
+ "The current evil state. Requires `evil-mode' to be enabled."
+ (when (bound-and-true-p evil-local-mode)
+ (doom-modeline--modal-icon
+ (let ((tag (evil-state-property evil-state :tag t)))
+ (if (stringp tag) tag (funcall tag)))
+ (cond
+ ((evil-normal-state-p) 'doom-modeline-evil-normal-state)
+ ((evil-emacs-state-p) 'doom-modeline-evil-emacs-state)
+ ((evil-insert-state-p) 'doom-modeline-evil-insert-state)
+ ((evil-motion-state-p) 'doom-modeline-evil-motion-state)
+ ((evil-visual-state-p) 'doom-modeline-evil-visual-state)
+ ((evil-operator-state-p) 'doom-modeline-evil-operator-state)
+ ((evil-replace-state-p) 'doom-modeline-evil-replace-state)
+ (t 'doom-modeline-evil-normal-state))
+ (evil-state-property evil-state :name t))))
+
+(defsubst doom-modeline--overwrite ()
+ "The current overwrite state which is enabled by command `overwrite-mode'."
+ (when (and (bound-and-true-p overwrite-mode)
+ (not (bound-and-true-p evil-local-mode)))
+ (doom-modeline--modal-icon " " 'doom-modeline-urgent "Overwrite mode")))
+
+(defsubst doom-modeline--god ()
+ "The current god state which is enabled by the command `god-mode'."
+ (when (bound-and-true-p god-local-mode)
+ (doom-modeline--modal-icon " " 'doom-modeline-evil-normal-state "God mode")))
+
+(defsubst doom-modeline--ryo ()
+ "The current ryo-modal state which is enabled by the command `ryo-modal-mode'."
+ (when (bound-and-true-p ryo-modal-mode)
+ (doom-modeline--modal-icon "" 'doom-modeline-evil-normal-state "Ryo modal")))
+
+(defsubst doom-modeline--xah-fly-keys ()
+ "The current `xah-fly-keys' state."
+ (when (bound-and-true-p xah-fly-keys)
+ (if xah-fly-insert-state-p
+ (doom-modeline--modal-icon " "
+ 'doom-modeline-evil-insert-state
+ (format "Xah-fly insert mode"))
+ (doom-modeline--modal-icon " "
+ 'doom-modeline-evil-normal-state
+ (format "Xah-fly command mode")))))
+
+(defsubst doom-modeline--boon ()
+ "The current Boon state. Requires `boon-mode' to be enabled."
+ (when (bound-and-true-p boon-local-mode)
+ (doom-modeline--modal-icon
+ (boon-state-string)
+ (cond
+ (boon-command-state 'doom-modeline-evil-normal-state)
+ (boon-insert-state 'doom-modeline-evil-insert-state)
+ (boon-special-state 'doom-modeline-evil-emacs-state)
+ (boon-off-state 'doom-modeline-evil-operator-state)
+ (t 'doom-modeline-evil-operator-state))
+ (boon-modeline-string))))
+
+(defsubst doom-modeline--meow ()
+ "The current Meow state. Requires `meow-mode' to be enabled."
+ (when (bound-and-true-p meow-mode)
+ meow--indicator))
+
+(doom-modeline-def-segment modals
+ "Displays modal editing states, including `evil', `overwrite', `god', `ryo'
+and `xha-fly-kyes', etc."
+ (let* ((evil (doom-modeline--evil))
+ (ow (doom-modeline--overwrite))
+ (god (doom-modeline--god))
+ (ryo (doom-modeline--ryo))
+ (xf (doom-modeline--xah-fly-keys))
+ (boon (doom-modeline--boon))
+ (vsep (doom-modeline-vspc))
+ (meow (doom-modeline--meow))
+ (sep (and (or evil ow god ryo xf boon) (doom-modeline-spc))))
+ (concat sep
+ (and evil (concat evil (and (or ow god ryo xf boon meow) vsep)))
+ (and ow (concat ow (and (or god ryo xf boon meow) vsep)))
+ (and god (concat god (and (or ryo xf boon meow) vsep)))
+ (and ryo (concat ryo (and (or xf boon meow) vsep)))
+ (and xf (concat xf (and (or boon meow) vsep)))
+ (and boon (concat boon (and meow vsep)))
+ meow
+ sep)))
+
+;;
+;; Objed state
+;;
+
+(defvar doom-modeline--objed-active nil)
+
+(defun doom-modeline-update-objed (_ &optional reset)
+ "Update `objed' status, inactive when RESET is true."
+ (setq doom-modeline--objed-active (not reset)))
+
+(setq objed-modeline-setup-func #'doom-modeline-update-objed)
+
+(doom-modeline-def-segment objed-state ()
+ "The current objed state."
+ (when (and doom-modeline--objed-active
+ (doom-modeline--active))
+ (propertize (format " %s(%s) "
+ (symbol-name objed--object)
+ (char-to-string (aref (symbol-name objed--obj-state) 0)))
+ 'face 'doom-modeline-evil-emacs-state
+ 'help-echo (format "Objed object: %s (%s)"
+ (symbol-name objed--object)
+ (symbol-name objed--obj-state)))))
+
+
+;;
+;; Input method
+;;
+
+(doom-modeline-def-segment input-method
+ "The current input method."
+ (propertize (cond (current-input-method
+ (concat (doom-modeline-spc)
+ current-input-method-title
+ (doom-modeline-spc)))
+ ((and (bound-and-true-p evil-local-mode)
+ (bound-and-true-p evil-input-method))
+ (concat
+ (doom-modeline-spc)
+ (nth 3 (assoc default-input-method input-method-alist))
+ (doom-modeline-spc)))
+ (t ""))
+ 'face (if (doom-modeline--active)
+ (if (and (bound-and-true-p rime-mode)
+ (equal current-input-method "rime"))
+ (if (and (rime--should-enable-p)
+ (not (rime--should-inline-ascii-p)))
+ 'doom-modeline-input-method
+ 'doom-modeline-input-method-alt)
+ 'doom-modeline-input-method)
+ 'mode-line-inactive)
+ 'help-echo (concat
+ "Current input method: "
+ current-input-method
+ "\n\
+mouse-2: Disable input method\n\
+mouse-3: Describe current input method")
+ 'mouse-face 'mode-line-highlight
+ 'local-map mode-line-input-method-map))
+
+
+;;
+;; Info
+;;
+
+(doom-modeline-def-segment info-nodes
+ "The topic and nodes in the Info buffer."
+ (let ((active (doom-modeline--active)))
+ (concat
+ (propertize " (" 'face (if active 'mode-line 'mode-line-inactive))
+ ;; topic
+ (propertize (if (stringp Info-current-file)
+ (replace-regexp-in-string
+ "%" "%%"
+ (file-name-sans-extension
+ (file-name-nondirectory Info-current-file)))
+ (format "*%S*" Info-current-file))
+ 'face (if active 'doom-modeline-info 'mode-line-inactive))
+ (propertize ") " 'face (if active 'mode-line 'mode-line-inactive))
+ ;; node
+ (when Info-current-node
+ (propertize (replace-regexp-in-string
+ "%" "%%" Info-current-node)
+ 'face (if active 'doom-modeline-buffer-path 'mode-line-inactive)
+ 'help-echo
+ "mouse-1: scroll forward, mouse-3: scroll back"
+ 'mouse-face 'mode-line-highlight
+ 'local-map Info-mode-line-node-keymap)))))
+
+
+;;
+;; REPL
+;;
+
+(defun doom-modeline-repl-icon (text face)
+ "Display REPL icon (or TEXT in terminal) with FACE."
+ (doom-modeline-icon 'faicon "terminal" "$" text
+ :face face :height 1.0 :v-adjust -0.0575))
+
+(defvar doom-modeline--cider nil)
+
+(defun doom-modeline-update-cider ()
+ "Update cider repl state."
+ (setq doom-modeline--cider
+ (let* ((connected (cider-connected-p))
+ (face (if connected 'doom-modeline-repl-success 'doom-modeline-repl-warning))
+ (repl-buffer (cider-current-repl nil nil))
+ (cider-info (when repl-buffer
+ (cider--connection-info repl-buffer t)))
+ (icon (doom-modeline-repl-icon "REPL" face)))
+ (propertize icon
+ 'help-echo
+ (if connected
+ (format "CIDER Connected %s\nmouse-2: CIDER quit" cider-info)
+ "CIDER Disconnected\nmouse-1: CIDER jack-in")
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (if connected
+ (define-key map [mode-line mouse-2]
+ #'cider-quit)
+ (define-key map [mode-line mouse-1]
+ #'cider-jack-in))
+ map)))))
+
+(add-hook 'cider-connected-hook #'doom-modeline-update-cider)
+(add-hook 'cider-disconnected-hook #'doom-modeline-update-cider)
+(add-hook 'cider-mode-hook #'doom-modeline-update-cider)
+
+(doom-modeline-def-segment repl
+ "The REPL state."
+ (when doom-modeline-repl
+ (when-let (icon (when (bound-and-true-p cider-mode)
+ doom-modeline--cider))
+ (concat
+ (doom-modeline-spc)
+ (if (doom-modeline--active)
+ icon
+ (doom-modeline-propertize-icon icon 'mode-line-inactive))
+ (doom-modeline-spc)))))
+
+
+;;
+;; LSP
+;;
+
+(defun doom-modeline-lsp-icon (text face)
+ "Display LSP icon (or TEXT in terminal) with FACE."
+ (doom-modeline-icon 'faicon "rocket" "π" text
+ :face face :height 1.0 :v-adjust -0.0575))
+
+(defvar-local doom-modeline--lsp nil)
+(defun doom-modeline-update-lsp (&rest _)
+ "Update `lsp-mode' state."
+ (setq doom-modeline--lsp
+ (let* ((workspaces (lsp-workspaces))
+ (face (if workspaces 'doom-modeline-lsp-success 'doom-modeline-lsp-warning))
+ (icon (doom-modeline-lsp-icon "LSP" face)))
+ (propertize icon
+ 'help-echo
+ (if workspaces
+ (concat "LSP Connected "
+ (string-join
+ (mapcar (lambda (w)
+ (format "[%s]\n" (lsp--workspace-print w)))
+ workspaces))
+ "C-mouse-1: Switch to another workspace folder
+mouse-1: Describe current session
+mouse-2: Quit server
+mouse-3: Reconnect to server")
+ "LSP Disconnected
+mouse-1: Reload to start server")
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (if workspaces
+ (progn
+ (define-key map [mode-line C-mouse-1]
+ #'lsp-workspace-folders-open)
+ (define-key map [mode-line mouse-1]
+ #'lsp-describe-session)
+ (define-key map [mode-line mouse-2]
+ #'lsp-workspace-shutdown)
+ (define-key map [mode-line mouse-3]
+ #'lsp-workspace-restart))
+ (progn
+ (define-key map [mode-line mouse-1]
+ (lambda ()
+ (interactive)
+ (ignore-errors (revert-buffer t t))))))
+ map)))))
+(add-hook 'lsp-before-initialize-hook #'doom-modeline-update-lsp)
+(add-hook 'lsp-after-initialize-hook #'doom-modeline-update-lsp)
+(add-hook 'lsp-after-uninitialized-functions #'doom-modeline-update-lsp)
+(add-hook 'lsp-before-open-hook #'doom-modeline-update-lsp)
+(add-hook 'lsp-after-open-hook #'doom-modeline-update-lsp)
+
+(defvar-local doom-modeline--eglot nil)
+(defun doom-modeline-update-eglot ()
+ "Update `eglot' state."
+ (setq doom-modeline--eglot
+ (pcase-let* ((server (and (eglot-managed-p) (eglot-current-server)))
+ (nick (and server (eglot--project-nickname server)))
+ (pending (and server (hash-table-count
+ (jsonrpc--request-continuations server))))
+ (`(,_id ,doing ,done-p ,detail) (and server (eglot--spinner server)))
+ (last-error (and server (jsonrpc-last-error server)))
+ (face (cond (last-error 'doom-modeline-lsp-error)
+ ((and doing (not done-p)) 'doom-modeline-lsp-running)
+ ((and pending (cl-plusp pending)) 'doom-modeline-lsp-warning)
+ (nick 'doom-modeline-lsp-success)
+ (t 'doom-modeline-lsp-warning)))
+ (icon (doom-modeline-lsp-icon "EGLOT" face)))
+ (propertize icon
+ 'help-echo (cond
+ (last-error
+ (format "EGLOT\nAn error occured: %s
+mouse-3: Clear this status" (plist-get last-error :message)))
+ ((and doing (not done-p))
+ (format "EGLOT\n%s%s" doing
+ (if detail (format "%s" detail) "")))
+ ((and pending (cl-plusp pending))
+ (format "EGLOT\n%d outstanding requests" pending))
+ (nick (format "EGLOT Connected (%s/%s)
+C-mouse-1: Go to server errors
+mouse-1: Go to server events
+mouse-2: Quit server
+mouse-3: Reconnect to server" nick (eglot--major-mode server)))
+ (t "EGLOT Disconnected
+mouse-1: Start server"))
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (cond (last-error
+ (define-key map [mode-line mouse-3]
+ #'eglot-clear-status))
+ ((and pending (cl-plusp pending))
+ (define-key map [mode-line mouse-3]
+ #'eglot-forget-pending-continuations))
+ (nick
+ (define-key map [mode-line C-mouse-1]
+ #'eglot-stderr-buffer)
+ (define-key map [mode-line mouse-1]
+ #'eglot-events-buffer)
+ (define-key map [mode-line mouse-2]
+ #'eglot-shutdown)
+ (define-key map [mode-line mouse-3]
+ #'eglot-reconnect))
+ (t (define-key map [mode-line mouse-1]
+ #'eglot)))
+ map)))))
+(add-hook 'eglot-managed-mode-hook #'doom-modeline-update-eglot)
+
+(defvar-local doom-modeline--tags nil)
+(defun doom-modeline-update-tags ()
+ "Update tags state."
+ (setq doom-modeline--tags
+ (propertize
+ (doom-modeline-lsp-icon "LSP" 'doom-modeline-lsp-success)
+ 'help-echo "TAGS: Citre mode
+mouse-1: Toggle citre mode"
+ 'mouse-face 'mode-line-highlight
+ 'local-map (make-mode-line-mouse-map 'mouse-1 #'citre-mode))))
+(add-hook 'citre-mode-hook #'doom-modeline-update-tags)
+
+(defun doom-modeline-update-lsp-icon ()
+ "Update lsp icon."
+ (cond ((bound-and-true-p lsp-mode)
+ (doom-modeline-update-lsp))
+ ((bound-and-true-p eglot--managed-mode)
+ (doom-modeline-update-eglot))
+ ((bound-and-true-p citre-mode)
+ (doom-modeline-update-tags))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-icon
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-icon val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (doom-modeline-update-lsp-icon))))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-unicode-fallback
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-unicode-fallback val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (doom-modeline-update-lsp-icon))))))
+
+(doom-modeline-def-segment lsp
+ "The LSP server state."
+ (when (and doom-modeline-lsp
+ (not doom-modeline--limited-width-p))
+ (let ((active (doom-modeline--active))
+ (icon (cond ((bound-and-true-p lsp-mode)
+ doom-modeline--lsp)
+ ((bound-and-true-p eglot--managed-mode)
+ doom-modeline--eglot)
+ ((bound-and-true-p citre-mode)
+ doom-modeline--tags))))
+ (when icon
+ (concat
+ (doom-modeline-spc)
+ (if active
+ icon
+ (doom-modeline-propertize-icon icon 'mode-line-inactive))
+ (doom-modeline-spc))))))
+
+(defun doom-modeline-override-eglot-modeline ()
+ "Override `eglot' mode-line."
+ (if (bound-and-true-p doom-modeline-mode)
+ (setq mode-line-misc-info
+ (delq (assq 'eglot--managed-mode mode-line-misc-info) mode-line-misc-info))
+ (add-to-list 'mode-line-misc-info
+ `(eglot--managed-mode (" [" eglot--mode-line-format "] ")))))
+(add-hook 'eglot-managed-mode-hook #'doom-modeline-override-eglot-modeline)
+(add-hook 'doom-modeline-mode-hook #'doom-modeline-override-eglot-modeline)
+
+
+;;
+;; GitHub
+;;
+
+(defvar doom-modeline--github-notification-number 0)
+(defvar doom-modeline-before-github-fetch-notification-hook nil
+ "Hooks before fetching GitHub notifications.
+Example:
+ (add-hook 'doom-modeline-before-github-fetch-notification-hook
+ #'auth-source-pass-enable)")
+(defun doom-modeline--github-fetch-notifications ()
+ "Fetch GitHub notifications."
+ (when (and doom-modeline-github
+ (require 'async nil t))
+ (async-start
+ `(lambda ()
+ ,(async-inject-variables
+ "\\`\\(load-path\\|auth-sources\\|doom-modeline-before-github-fetch-notification-hook\\)\\'")
+ (run-hooks 'doom-modeline-before-github-fetch-notification-hook)
+ (when (require 'ghub nil t)
+ (with-timeout (10)
+ (ignore-errors
+ (when-let* ((username (ghub--username ghub-default-host))
+ (token (ghub--token ghub-default-host username 'ghub t)))
+ (ghub-get "/notifications" nil
+ :query '((notifications . "true"))
+ :username username
+ :auth token
+ :noerror t))))))
+ (lambda (result)
+ (message "") ; suppress message
+ (setq doom-modeline--github-notification-number (length result))))))
+
+(defvar doom-modeline--github-timer nil)
+(defun doom-modeline-github-timer ()
+ "Start/Stop the timer for GitHub fetching."
+ (if (timerp doom-modeline--github-timer)
+ (cancel-timer doom-modeline--github-timer))
+ (setq doom-modeline--github-timer
+ (and doom-modeline-github
+ (run-with-idle-timer 30
+ doom-modeline-github-interval
+ #'doom-modeline--github-fetch-notifications))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-github
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-github val)
+ (doom-modeline-github-timer))))
+
+(doom-modeline-github-timer)
+
+(doom-modeline-def-segment github
+ "The GitHub notifications."
+ (when (and doom-modeline-github
+ (doom-modeline--active)
+ (not doom-modeline--limited-width-p)
+ (numberp doom-modeline--github-notification-number)
+ (> doom-modeline--github-notification-number 0))
+ (concat
+ (doom-modeline-spc)
+ (propertize
+ (concat
+ (doom-modeline-icon 'faicon "github" "π" "#"
+ :face 'doom-modeline-notification
+ :v-adjust -0.0575)
+ (doom-modeline-vspc)
+ ;; GitHub API is paged, and the limit is 50
+ (propertize
+ (if (>= doom-modeline--github-notification-number 50)
+ "50+"
+ (number-to-string doom-modeline--github-notification-number))
+ 'face '(:inherit
+ (doom-modeline-unread-number doom-modeline-notification))))
+ 'help-echo "Github Notifications
+mouse-1: Show notifications
+mouse-3: Fetch notifications"
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1]
+ (lambda ()
+ "Open GitHub notifications page."
+ (interactive)
+ (run-with-idle-timer 300 nil #'doom-modeline--github-fetch-notifications)
+ (browse-url "https://github.com/notifications")))
+ (define-key map [mode-line mouse-3]
+ (lambda ()
+ "Fetching GitHub notifications."
+ (interactive)
+ (message "Fetching GitHub notifications...")
+ (doom-modeline--github-fetch-notifications)))
+ map))
+ (doom-modeline-spc))))
+
+
+;;
+;; Debug states
+;;
+
+;; Highlight the mode-line while debugging.
+(defvar-local doom-modeline--debug-cookie nil)
+(defun doom-modeline--debug-visual (&rest _)
+ "Update the face of mode-line for debugging."
+ (mapc (lambda (buffer)
+ (with-current-buffer buffer
+ (setq doom-modeline--debug-cookie
+ (face-remap-add-relative 'mode-line 'doom-modeline-debug-visual))
+ (force-mode-line-update)))
+ (buffer-list)))
+
+(defun doom-modeline--normal-visual (&rest _)
+ "Restore the face of mode-line."
+ (mapc (lambda (buffer)
+ (with-current-buffer buffer
+ (when doom-modeline--debug-cookie
+ (face-remap-remove-relative doom-modeline--debug-cookie)
+ (force-mode-line-update))))
+ (buffer-list)))
+
+(add-hook 'dap-session-created-hook #'doom-modeline--debug-visual)
+(add-hook 'dap-terminated-hook #'doom-modeline--normal-visual)
+
+(defun doom-modeline-debug-icon (face &rest args)
+ "Display debug icon with FACE and ARGS."
+ (doom-modeline-icon 'faicon "bug" "π" "!" :face face :v-adjust -0.0575 args))
+
+(defun doom-modeline--debug-dap ()
+ "The current `dap-mode' state."
+ (when (and (bound-and-true-p dap-mode)
+ (bound-and-true-p lsp-mode))
+ (when-let ((session (dap--cur-session)))
+ (when (dap--session-running session)
+ (propertize (doom-modeline-debug-icon 'doom-modeline-info)
+ 'help-echo (format "DAP (%s - %s)
+mouse-1: Display debug hydra
+mouse-2: Display recent configurations
+mouse-3: Disconnect session"
+ (dap--debug-session-name session)
+ (dap--debug-session-state session))
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1]
+ #'dap-hydra)
+ (define-key map [mode-line mouse-2]
+ #'dap-debug-recent)
+ (define-key map [mode-line mouse-3]
+ #'dap-disconnect)
+ map))))))
+
+(defvar-local doom-modeline--debug-dap nil)
+(defun doom-modeline-update-debug-dap (&rest _)
+ "Update dap debug state."
+ (setq doom-modeline--debug-dap (doom-modeline--debug-dap)))
+
+(add-hook 'dap-session-created-hook #'doom-modeline-update-debug-dap)
+(add-hook 'dap-session-changed-hook #'doom-modeline-update-debug-dap)
+(add-hook 'dap-terminated-hook #'doom-modeline-update-debug-dap)
+
+(defsubst doom-modeline--debug-edebug ()
+ "The current `edebug' state."
+ (when (bound-and-true-p edebug-mode)
+ (propertize (doom-modeline-debug-icon 'doom-modeline-info)
+ 'help-echo (format "EDebug (%s)
+mouse-1: Show help
+mouse-2: Next
+mouse-3: Stop debugging"
+ edebug-execution-mode)
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1]
+ #'edebug-help)
+ (define-key map [mode-line mouse-2]
+ #'edebug-next-mode)
+ (define-key map [mode-line mouse-3]
+ #'edebug-stop)
+ map))))
+
+(defsubst doom-modeline--debug-on-error ()
+ "The current `debug-on-error' state."
+ (when debug-on-error
+ (propertize (doom-modeline-debug-icon 'doom-modeline-urgent)
+ 'help-echo "Debug on Error
+mouse-1: Toggle Debug on Error"
+ 'mouse-face 'mode-line-highlight
+ 'local-map (make-mode-line-mouse-map 'mouse-1 #'toggle-debug-on-error))))
+
+(defsubst doom-modeline--debug-on-quit ()
+ "The current `debug-on-quit' state."
+ (when debug-on-quit
+ (propertize (doom-modeline-debug-icon 'doom-modeline-warning)
+ 'help-echo "Debug on Quit
+mouse-1: Toggle Debug on Quit"
+ 'mouse-face 'mode-line-highlight
+ 'local-map (make-mode-line-mouse-map 'mouse-1 #'toggle-debug-on-quit))))
+
+(doom-modeline-def-segment debug
+ "The current debug state."
+ (when (and (doom-modeline--active)
+ (not doom-modeline--limited-width-p))
+ (let* ((dap doom-modeline--debug-dap)
+ (edebug (doom-modeline--debug-edebug))
+ (on-error (doom-modeline--debug-on-error))
+ (on-quit (doom-modeline--debug-on-quit))
+ (vsep (doom-modeline-vspc))
+ (sep (and (or dap edebug on-error on-quit) (doom-modeline-spc))))
+ (concat sep
+ (and dap (concat dap (and (or edebug on-error on-quit) vsep)))
+ (and edebug (concat edebug (and (or on-error on-quit) vsep)))
+ (and on-error (concat on-error (and on-quit vsep)))
+ on-quit
+ sep))))
+
+
+;;
+;; PDF pages
+;;
+
+(defvar-local doom-modeline--pdf-pages nil)
+(defun doom-modeline-update-pdf-pages ()
+ "Update PDF pages."
+ (setq doom-modeline--pdf-pages
+ (format " P%d/%d "
+ (or (eval `(pdf-view-current-page)) 0)
+ (pdf-cache-number-of-pages))))
+(add-hook 'pdf-view-change-page-hook #'doom-modeline-update-pdf-pages)
+
+(doom-modeline-def-segment pdf-pages
+ "Display PDF pages."
+ (propertize doom-modeline--pdf-pages
+ 'face (if (doom-modeline--active) 'mode-line 'mode-line-inactive)))
+
+
+;;
+;; `mu4e-alert' notifications
+;;
+
+(doom-modeline-def-segment mu4e
+ "Show notifications of any unread emails in `mu4e'."
+ (when (and doom-modeline-mu4e
+ (doom-modeline--active)
+ (not doom-modeline--limited-width-p)
+ (bound-and-true-p mu4e-alert-mode-line)
+ (numberp mu4e-alert-mode-line)
+ ;; don't display if the unread mails count is zero
+ (> mu4e-alert-mode-line 0))
+ (concat
+ (doom-modeline-spc)
+ (propertize
+ (concat
+ (doom-modeline-icon 'material "email" "π§" "#"
+ :face 'doom-modeline-notification
+ :height 1.1 :v-adjust -0.2)
+ (doom-modeline-vspc)
+ (propertize
+ (if (> mu4e-alert-mode-line doom-modeline-number-limit)
+ (format "%d+" doom-modeline-number-limit)
+ (number-to-string mu4e-alert-mode-line))
+ 'face '(:inherit
+ (doom-modeline-unread-number doom-modeline-notification))))
+ 'mouse-face 'mode-line-highlight
+ 'keymap '(mode-line keymap
+ (mouse-1 . mu4e-alert-view-unread-mails)
+ (mouse-2 . mu4e-alert-view-unread-mails)
+ (mouse-3 . mu4e-alert-view-unread-mails))
+ 'help-echo (concat (if (= mu4e-alert-mode-line 1)
+ "You have an unread email"
+ (format "You have %s unread emails" mu4e-alert-mode-line))
+ "\nClick here to view "
+ (if (= mu4e-alert-mode-line 1) "it" "them")))
+ (doom-modeline-spc))))
+
+(defun doom-modeline-override-mu4e-alert-modeline (&rest _)
+ "Delete `mu4e-alert-mode-line' from global modeline string."
+ (when (featurep 'mu4e-alert)
+ (if (and doom-modeline-mu4e
+ (bound-and-true-p doom-modeline-mode))
+ ;; Delete original modeline
+ (progn
+ (setq global-mode-string
+ (delete '(:eval mu4e-alert-mode-line) global-mode-string))
+ (setq mu4e-alert-modeline-formatter #'identity))
+ ;; Recover default settings
+ (setq mu4e-alert-modeline-formatter #'mu4e-alert-default-mode-line-formatter))))
+(advice-add #'mu4e-alert-enable-mode-line-display
+ :after #'doom-modeline-override-mu4e-alert-modeline)
+(add-hook 'doom-modeline-mode-hook #'doom-modeline-override-mu4e-alert-modeline)
+
+
+;;
+;; `gnus' notifications
+;;
+
+(defvar doom-modeline--gnus-unread-mail 0)
+(defvar doom-modeline--gnus-started nil
+ "Used to determine if gnus has started.")
+(defun doom-modeline-update-gnus-status (&rest _)
+ "Get the total number of unread news of gnus group."
+ (setq doom-modeline--gnus-unread-mail
+ (when (and doom-modeline-gnus
+ doom-modeline--gnus-started)
+ (let ((total-unread-news-number 0))
+ (mapc (lambda (g)
+ (let* ((group (car g))
+ (unread (eval `(gnus-group-unread ,group))))
+ (when (and (not (seq-contains-p doom-modeline-gnus-excluded-groups group))
+ (numberp unread)
+ (> unread 0))
+ (setq total-unread-news-number (+ total-unread-news-number unread)))))
+ gnus-newsrc-alist)
+ total-unread-news-number))))
+
+;; Update the modeline after changes have been made
+(add-hook 'gnus-group-update-hook #'doom-modeline-update-gnus-status)
+(add-hook 'gnus-summary-update-hook #'doom-modeline-update-gnus-status)
+(add-hook 'gnus-group-update-group-hook #'doom-modeline-update-gnus-status)
+(add-hook 'gnus-after-getting-new-news-hook #'doom-modeline-update-gnus-status)
+
+;; Only start to listen to gnus when gnus is actually running
+(defun doom-modeline-start-gnus-listener ()
+ "Start GNUS listener."
+ (when (and doom-modeline-gnus
+ (not doom-modeline--gnus-started))
+ (setq doom-modeline--gnus-started t)
+ ;; Scan gnus in the background if the timer is higher than 0
+ (doom-modeline-update-gnus-status)
+ (if (> doom-modeline-gnus-timer 0)
+ (gnus-demon-add-handler 'gnus-demon-scan-news doom-modeline-gnus-timer doom-modeline-gnus-idle))))
+(add-hook 'gnus-started-hook #'doom-modeline-start-gnus-listener)
+
+;; Stop the listener if gnus isn't running
+(defun doom-modeline-stop-gnus-listener ()
+ "Stop GNUS listener."
+ (setq doom-modeline--gnus-started nil))
+(add-hook 'gnus-exit-gnus-hook #'doom-modeline-stop-gnus-listener)
+
+(doom-modeline-def-segment gnus
+ "Show notifications of any unread emails in `gnus'."
+ (when (and (doom-modeline--active)
+ (not doom-modeline--limited-width-p)
+ doom-modeline-gnus
+ doom-modeline--gnus-started
+ ;; Don't display if the unread mails count is zero
+ (numberp doom-modeline--gnus-unread-mail)
+ (> doom-modeline--gnus-unread-mail 0))
+ (concat
+ (doom-modeline-spc)
+ (propertize
+ (concat
+ (doom-modeline-icon 'material "email" "π§" "#"
+ :face 'doom-modeline-notification
+ :height 1.1 :v-adjust -0.2)
+ (doom-modeline-vspc)
+ (propertize
+ (if (> doom-modeline--gnus-unread-mail doom-modeline-number-limit)
+ (format "%d+" doom-modeline-number-limit)
+ (number-to-string doom-modeline--gnus-unread-mail))
+ 'face '(:inherit
+ (doom-modeline-unread-number doom-modeline-notification))))
+ 'mouse-face 'mode-line-highlight
+ 'help-echo (if (= doom-modeline--gnus-unread-mail 1)
+ "You have an unread email"
+ (format "You have %s unread emails" doom-modeline--gnus-unread-mail)))
+ (doom-modeline-spc))))
+
+
+;;
+;; IRC notifications
+;;
+
+(defun doom-modeline--shorten-irc (name)
+ "Wrapper for `tracking-shorten' and `erc-track-shorten-function' with NAME.
+
+One key difference is that when `tracking-shorten' and
+`erc-track-shorten-function' returns nil we will instead return the original
+value of name. This is necessary in cases where the user has stylized the name
+to be an icon and we don't want to remove that so we just return the original."
+ (or (and (boundp 'tracking-shorten)
+ (car (tracking-shorten (list name))))
+ (and (boundp 'erc-track-shorten-function)
+ (functionp erc-track-shorten-function)
+ (car (funcall erc-track-shorten-function (list name))))
+ (and (boundp 'rcirc-short-buffer-name)
+ (rcirc-short-buffer-name name))
+ name))
+
+(defun doom-modeline--tracking-buffers (buffers)
+ "Logic to convert some irc BUFFERS to their font-awesome icon."
+ (mapconcat
+ (lambda (b)
+ (propertize
+ (doom-modeline--shorten-irc (funcall doom-modeline-irc-stylize b))
+ 'face '(:inherit (doom-modeline-unread-number doom-modeline-notification))
+ 'help-echo (format "IRC Notification: %s\nmouse-1: Switch to buffer" b)
+ 'mouse-face 'mode-line-highlight
+ 'local-map (make-mode-line-mouse-map 'mouse-1
+ (lambda ()
+ (interactive)
+ (when (buffer-live-p (get-buffer b))
+ (switch-to-buffer b))))))
+ buffers
+ (doom-modeline-vspc)))
+
+(defun doom-modeline--circe-p ()
+ "Check if `circe' is in use."
+ (boundp 'tracking-mode-line-buffers))
+
+(defun doom-modeline--erc-p ()
+ "Check if `erc' is in use."
+ (boundp 'erc-modified-channels-alist))
+
+(defun doom-modeline--rcirc-p ()
+ "Check if `rcirc' is in use."
+ (bound-and-true-p rcirc-track-minor-mode))
+
+(defun doom-modeline--get-buffers ()
+ "Gets the buffers that have activity."
+ (cond
+ ((doom-modeline--circe-p)
+ tracking-buffers)
+ ((doom-modeline--erc-p)
+ (mapcar (lambda (l)
+ (buffer-name (car l)))
+ erc-modified-channels-alist))
+ ((doom-modeline--rcirc-p)
+ (mapcar (lambda (b)
+ (buffer-name b))
+ rcirc-activity))))
+
+;; Create a modeline segment that contains all the irc tracked buffers
+(doom-modeline-def-segment irc-buffers
+ "The list of shortened, unread irc buffers."
+ (when (and doom-modeline-irc
+ (doom-modeline--active)
+ (not doom-modeline--limited-width-p))
+ (let* ((buffers (doom-modeline--get-buffers))
+ (number (length buffers)))
+ (when (> number 0)
+ (concat
+ (doom-modeline-spc)
+ (doom-modeline--tracking-buffers buffers)
+ (doom-modeline-spc))))))
+
+(doom-modeline-def-segment irc
+ "A notification icon for any unread irc buffer."
+ (when (and doom-modeline-irc
+ (doom-modeline--active)
+ (not doom-modeline--limited-width-p))
+ (let* ((buffers (doom-modeline--get-buffers))
+ (number (length buffers)))
+ (when (> number 0)
+ (concat
+ (doom-modeline-spc)
+
+ (propertize (concat
+ (doom-modeline-icon 'material "message" "π" "#"
+ :face 'doom-modeline-notification
+ :height 1.0 :v-adjust -0.225)
+ (doom-modeline-vspc)
+ ;; Display the number of unread buffers
+ (propertize (number-to-string number)
+ 'face '(:inherit
+ (doom-modeline-unread-number
+ doom-modeline-notification))))
+ 'help-echo (format "IRC Notifications: %s\n%s"
+ (mapconcat
+ (lambda (b) (funcall doom-modeline-irc-stylize b))
+ buffers
+ ", ")
+ (cond
+ ((doom-modeline--circe-p)
+ "mouse-1: Switch to previous unread buffer
+mouse-3: Switch to next unread buffer")
+ ((doom-modeline--erc-p)
+ "mouse-1: Switch to buffer
+mouse-3: Switch to next unread buffer")
+ ((doom-modeline--rcirc-p)
+ "mouse-1: Switch to server buffer
+mouse-3: Switch to next unread buffer")))
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (cond
+ ((doom-modeline--circe-p)
+ (define-key map [mode-line mouse-1]
+ #'tracking-previous-buffer)
+ (define-key map [mode-line mouse-3]
+ #'tracking-next-buffer))
+ ((doom-modeline--erc-p)
+ (define-key map [mode-line mouse-1]
+ #'erc-switch-to-buffer)
+ (define-key map [mode-line mouse-3]
+ #'erc-track-switch-buffer))
+ ((doom-modeline--rcirc-p)
+ (define-key map [mode-line mouse-1]
+ #'rcirc-switch-to-server-buffer)
+ (define-key map [mode-line mouse-3]
+ #'rcirc-next-active-buffer)))
+ map))
+
+ ;; Display the unread irc buffers as well
+ (when doom-modeline-irc-buffers
+ (concat (doom-modeline-spc)
+ (doom-modeline--tracking-buffers buffers)))
+
+ (doom-modeline-spc))))))
+
+(defun doom-modeline-override-rcirc-modeline ()
+ "Override default `rcirc' mode-line."
+ (if (bound-and-true-p doom-modeline-mode)
+ (setq global-mode-string
+ (delq 'rcirc-activity-string global-mode-string))
+ (when (and rcirc-track-minor-mode
+ (not (memq 'rcirc-activity-string global-mode-string)))
+ (setq global-mode-string
+ (append global-mode-string '(rcirc-activity-string))))))
+(add-hook 'rcirc-track-minor-mode-hook #'doom-modeline-override-rcirc-modeline)
+(add-hook 'doom-modeline-mode-hook #'doom-modeline-override-rcirc-modeline)
+
+
+;;
+;; Battery status
+;;
+
+(defvar doom-modeline--battery-status nil)
+(defun doom-modeline-update-battery-status ()
+ "Update battery status."
+ (setq doom-modeline--battery-status
+ (when (bound-and-true-p display-battery-mode)
+ (let* ((data (and battery-status-function
+ (functionp battery-status-function)
+ (funcall battery-status-function)))
+ (charging? (string-equal "AC" (cdr (assoc ?L data))))
+ (percentage (car (read-from-string (or (cdr (assq ?p data)) "ERR"))))
+ (valid-percentage? (and (numberp percentage)
+ (>= percentage 0)
+ (<= percentage battery-mode-line-limit)))
+ (face (if valid-percentage?
+ (cond (charging? 'doom-modeline-battery-charging)
+ ((< percentage battery-load-critical) 'doom-modeline-battery-critical)
+ ((< percentage 25) 'doom-modeline-battery-warning)
+ ((< percentage 95) 'doom-modeline-battery-normal)
+ (t 'doom-modeline-battery-full))
+ 'doom-modeline-battery-error))
+ (icon (if valid-percentage?
+ (cond (charging?
+ (doom-modeline-icon 'alltheicon "battery-charging" "π" "+"
+ :face face :height 1.4 :v-adjust -0.1))
+ ((> percentage 95)
+ (doom-modeline-icon 'faicon "battery-full" "π" "-"
+ :face face :v-adjust -0.0575))
+ ((> percentage 70)
+ (doom-modeline-icon 'faicon "battery-three-quarters" "π" "-"
+ :face face :v-adjust -0.0575))
+ ((> percentage 40)
+ (doom-modeline-icon 'faicon "battery-half" "π" "-"
+ :face face :v-adjust -0.0575))
+ ((> percentage battery-load-critical)
+ (doom-modeline-icon 'faicon "battery-quarter" "π" "-"
+ :face face :v-adjust -0.0575))
+ (t (doom-modeline-icon 'faicon "battery-empty" "π" "!"
+ :face face :v-adjust -0.0575)))
+ (doom-modeline-icon 'faicon "battery-empty" "β " "N/A"
+ :face face :v-adjust -0.0575)))
+ (text (if valid-percentage? (format "%d%%%%" percentage) ""))
+ (help-echo (if (and battery-echo-area-format data valid-percentage?)
+ (battery-format battery-echo-area-format data)
+ "Battery status not available")))
+ (cons (propertize icon 'help-echo help-echo)
+ (propertize text 'face face 'help-echo help-echo))))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-icon
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-icon val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (doom-modeline-update-battery-status))))))
+
+(doom-modeline-add-variable-watcher
+ 'doom-modeline-unicode-fallback
+ (lambda (_sym val op _where)
+ (when (eq op 'set)
+ (setq doom-modeline-unicode-fallback val)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (doom-modeline-update-battery-status))))))
+
+(doom-modeline-def-segment battery
+ "Display battery status."
+ (when (and (doom-modeline--active)
+ (not doom-modeline--limited-width-p)
+ (bound-and-true-p display-battery-mode))
+ (concat (doom-modeline-spc)
+ (concat
+ (car doom-modeline--battery-status)
+ (doom-modeline-vspc)
+ (cdr doom-modeline--battery-status))
+ (doom-modeline-spc))))
+
+(defun doom-modeline-override-battery-modeline ()
+ "Override default battery mode-line."
+ (if (bound-and-true-p doom-modeline-mode)
+ (progn
+ (advice-add #'battery-update :override #'doom-modeline-update-battery-status)
+ (setq global-mode-string
+ (delq 'battery-mode-line-string global-mode-string))
+ (and (bound-and-true-p display-battery-mode) (battery-update)))
+ (progn
+ (advice-remove #'battery-update #'doom-modeline-update-battery-status)
+ (when (and display-battery-mode battery-status-function battery-mode-line-format
+ (not (memq 'battery-mode-line-string global-mode-string)))
+ (setq global-mode-string
+ (append global-mode-string '(battery-mode-line-string)))))))
+(add-hook 'display-battery-mode-hook #'doom-modeline-override-battery-modeline)
+(add-hook 'doom-modeline-mode-hook #'doom-modeline-override-battery-modeline)
+
+
+;;
+;; Package information
+;;
+
+(doom-modeline-def-segment package
+ "Show package information via `paradox'."
+ (let ((active (doom-modeline--active)))
+ (concat
+ (let ((front (format-mode-line 'mode-line-front-space)))
+ (if active
+ front
+ (propertize front 'face 'mode-line-inactive)))
+
+ (when (and doom-modeline-icon doom-modeline-major-mode-icon)
+ (concat
+ (doom-modeline-spc)
+ (doom-modeline-icon 'faicon "archive" nil nil
+ :face (if active
+ (if doom-modeline-major-mode-color-icon
+ 'all-the-icons-silver
+ 'mode-line)
+ 'mode-line-inactive)
+ :height 1.0
+ :v-adjust -0.0575)))
+ (let ((info (format-mode-line 'mode-line-buffer-identification)))
+ (if active
+ info
+ (propertize info 'face 'mode-line-inactive))))))
+
+
+;;
+;; Helm
+;;
+
+(defvar doom-modeline--helm-buffer-ids
+ '(("*helm*" . "HELM")
+ ("*helm M-x*" . "HELM M-x")
+ ("*swiper*" . "SWIPER")
+ ("*Projectile Perspectives*" . "HELM Projectile Perspectives")
+ ("*Projectile Layouts*" . "HELM Projectile Layouts")
+ ("*helm-ag*" . (lambda ()
+ (format "HELM Ag: Using %s"
+ (car (split-string helm-ag-base-command))))))
+ "Alist of custom helm buffer names to use.
+The cdr can also be a function that returns a name to use.")
+
+(doom-modeline-def-segment helm-buffer-id
+ "Helm session identifier."
+ (when (bound-and-true-p helm-alive-p)
+ (let ((active (doom-modeline--active)))
+ (concat
+ (doom-modeline-spc)
+ (when doom-modeline-icon
+ (concat
+ (doom-modeline-icon 'fileicon "elisp" nil nil
+ :face (if active
+ (if doom-modeline-major-mode-color-icon
+ 'all-the-icons-blue
+ 'mode-line)
+ 'mode-line-inactive)
+ :height 1.0
+ :v-adjust -0.15)
+ (doom-modeline-spc)))
+ (propertize
+ (let ((custom (cdr (assoc (buffer-name) doom-modeline--helm-buffer-ids)))
+ (case-fold-search t)
+ (name (replace-regexp-in-string "-" " " (buffer-name))))
+ (cond ((stringp custom) custom)
+ ((functionp custom) (funcall custom))
+ (t
+ (string-match "\\*helm:? \\(mode \\)?\\([^\\*]+\\)\\*" name)
+ (concat "HELM " (capitalize (match-string 2 name))))))
+ 'face (if active' doom-modeline-buffer-file 'mode-line-inactive))
+ (doom-modeline-spc)))))
+
+(doom-modeline-def-segment helm-number
+ "Number of helm candidates."
+ (when (bound-and-true-p helm-alive-p)
+ (let ((active (doom-modeline--active)))
+ (concat
+ (propertize (format " %d/%d"
+ (helm-candidate-number-at-point)
+ (helm-get-candidate-number t))
+ 'face (if active 'doom-modeline-buffer-path 'mode-line-inactive))
+ (propertize (format " (%d total) " (helm-get-candidate-number))
+ 'face (if active 'doom-modeline-info 'mode-line-inactive))))))
+
+(doom-modeline-def-segment helm-help
+ "Helm keybindings help."
+ (when (bound-and-true-p helm-alive-p)
+ (let ((active (doom-modeline--active)))
+ (-interleave
+ (mapcar (lambda (s)
+ (propertize (substitute-command-keys s)
+ 'face (if active
+ 'doom-modeline-buffer-file
+ 'mode-line-inactive)))
+ '("\\\\[helm-help]"
+ "\\\\[helm-select-action]"
+ "\\\\[helm-maybe-exit-minibuffer]/F1/F2..."))
+ (mapcar (lambda (s)
+ (propertize s 'face (if active 'mode-line 'mode-line-inactive)))
+ '("(help) " "(actions) " "(action) "))))))
+
+(doom-modeline-def-segment helm-prefix-argument
+ "Helm prefix argument."
+ (when (and (bound-and-true-p helm-alive-p)
+ helm--mode-line-display-prefarg)
+ (let ((arg (prefix-numeric-value (or prefix-arg current-prefix-arg))))
+ (unless (= arg 1)
+ (propertize (format "C-u %s" arg)
+ 'face (if (doom-modeline--active)
+ 'doom-modeline-info
+ 'mode-line-inactive))))))
+
+(defvar doom-modeline--helm-current-source nil
+ "The currently active helm source.")
+(doom-modeline-def-segment helm-follow
+ "Helm follow indicator."
+ (when (and (bound-and-true-p helm-alive-p)
+ doom-modeline--helm-current-source
+ (eq 1 (cdr (assq 'follow doom-modeline--helm-current-source))))
+ (propertize "HF" 'face (if (doom-modeline--active)
+ 'mode-line
+ 'mode-line-inactive))))
+
+;;
+;; Git timemachine
+;;
+
+(doom-modeline-def-segment git-timemachine
+ (let ((active (doom-modeline--active)))
+ (concat
+ (doom-modeline-spc)
+ (doom-modeline--buffer-mode-icon)
+ (doom-modeline--buffer-state-icon)
+ (propertize "*%b*" 'face (if active
+ 'doom-modeline-buffer-timemachine
+ 'mode-line-inactive)))))
+
+;;
+;; Markdown/Org preview
+;;
+
+(doom-modeline-def-segment grip
+ (when (bound-and-true-p grip-mode)
+ (concat
+ (doom-modeline-spc)
+ (let ((face (if (doom-modeline--active)
+ (if grip--process
+ (pcase (process-status grip--process)
+ ('run 'doom-modeline-buffer-path)
+ ('exit 'doom-modeline-warning)
+ (_ 'doom-modeline-urgent))
+ 'doom-modeline-urgent)
+ 'mode-line-inactive)))
+ (propertize (doom-modeline-icon 'material "pageview" "π" "@"
+ :face (if doom-modeline-icon
+ `(:inherit ,face :weight normal)
+ face)
+ :height 1.2 :v-adjust -0.2)
+ 'help-echo (format "Preview on %s
+mouse-1: Preview in browser
+mouse-2: Stop preview
+mouse-3: Restart preview"
+ (grip--preview-url))
+ 'mouse-face 'mode-line-highlight
+ 'local-map (let ((map (make-sparse-keymap)))
+ (define-key map [mode-line mouse-1]
+ #'grip-browse-preview)
+ (define-key map [mode-line mouse-2]
+ #'grip-stop-preview)
+ (define-key map [mode-line mouse-3]
+ #'grip-restart-preview)
+ map)))
+ (doom-modeline-spc))))
+
+;;
+;; Follow mode
+;;
+
+(doom-modeline-def-segment follow
+ (when (bound-and-true-p follow-mode)
+ (let* ((windows (follow-all-followers))
+ (nwindows (length windows))
+ (nfollowing (- (length (memq (selected-window) windows))
+ 1)))
+ (concat
+ (doom-modeline-spc)
+ (propertize (format "Follow %d/%d" (- nwindows nfollowing) nwindows)
+ 'face 'doom-modeline-buffer-minor-mode)))))
+
+(provide 'doom-modeline-segments)
+
+;;; doom-modeline-segments.el ends here
diff --git a/org/elpa/doom-modeline-20220412.853/doom-modeline.el b/org/elpa/doom-modeline-20220412.853/doom-modeline.el
new file mode 100644
index 0000000..b48bda5
--- /dev/null
+++ b/org/elpa/doom-modeline-20220412.853/doom-modeline.el
@@ -0,0 +1,311 @@
+;;; doom-modeline.el --- A minimal and modern mode-line -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2020 Vincent Zhang
+
+;; Author: Vincent Zhang
+;; Homepage: https://github.com/seagle0128/doom-modeline
+;; Version: 3.3.0
+;; Package-Requires: ((emacs "25.1") (all-the-icons "2.2.0") (shrink-path "0.2.0") (dash "2.11.0"))
+;; Keywords: faces mode-line
+
+;; This file is not part of GNU Emacs.
+
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see .
+;;
+
+;;; Commentary:
+;;
+;; This package offers a fancy and fast mode-line inspired by minimalism design.
+;;
+;; It's integrated into Doom Emacs (https://github.com/hlissner/doom-emacs) and
+;; Centaur Emacs (https://github.com/seagle0128/.emacs.d).
+;;
+;; The doom-modeline offers:
+;; - A match count panel (for anzu, iedit, multiple-cursors, symbol-overlay,
+;; evil-search and evil-substitute)
+;; - An indicator for recording a macro
+;; - Current environment version (e.g. python, ruby, go, etc.) in the major-mode
+;; - A customizable mode-line height (see doom-modeline-height)
+;; - A minor modes segment which is compatible with minions
+;; - An error/warning count segment for flymake/flycheck
+;; - A workspace number segment for eyebrowse
+;; - A perspective name segment for persp-mode
+;; - A window number segment for winum and window-numbering
+;; - An indicator for modal editing state, including evil, overwrite, god, ryo
+;; and xah-fly-keys, etc.
+;; - An indicator for battery status
+;; - An indicator for current input method
+;; - An indicator for debug state
+;; - An indicator for remote host
+;; - An indicator for LSP state with lsp-mode or eglot
+;; - An indicator for github notifications
+;; - An indicator for unread emails with mu4e-alert
+;; - An indicator for unread emails with gnus (basically builtin)
+;; - An indicator for irc notifications with circe, rcirc or erc.
+;; - An indicator for buffer position which is compatible with nyan-mode or poke-line
+;; - An indicator for party parrot
+;; - An indicator for PDF page number with pdf-tools
+;; - An indicator for markdown/org previews with grip
+;; - Truncated file name, file icon, buffer state and project name in buffer
+;; information segment, which is compatible with project, find-file-in-project
+;; and projectile
+;; - New mode-line for Info-mode buffers
+;; - New package mode-line for paradox
+;; - New mode-line for helm buffers
+;; - New mode-line for git-timemachine buffers
+;;
+;; Installation:
+;; From melpa, `M-x package-install RET doom-modeline RET`.
+;; In `init.el`,
+;; (require 'doom-modeline)
+;; (doom-modeline-mode 1)
+;; or
+;; (use-package doom-modeline
+;; :ensure t
+;; :hook (after-init . doom-modeline-mode))
+;;
+
+;;; Code:
+
+(require 'doom-modeline-core)
+(require 'doom-modeline-segments)
+
+
+;;
+;; Mode lines
+;;
+
+(doom-modeline-def-modeline 'main
+ '(bar workspace-name window-number modals matches follow buffer-info remote-host buffer-position word-count parrot selection-info)
+ '(objed-state misc-info persp-name battery grip irc mu4e gnus github debug repl lsp minor-modes input-method indent-info buffer-encoding major-mode process vcs checker))
+
+(doom-modeline-def-modeline 'minimal
+ '(bar matches buffer-info-simple)
+ '(media-info major-mode))
+
+(doom-modeline-def-modeline 'special
+ '(bar window-number modals matches buffer-info buffer-position word-count parrot selection-info)
+ '(objed-state misc-info battery irc-buffers debug minor-modes input-method indent-info buffer-encoding major-mode process))
+
+(doom-modeline-def-modeline 'project
+ '(bar window-number modals buffer-default-directory)
+ '(misc-info battery irc mu4e gnus github debug minor-modes input-method major-mode process))
+
+(doom-modeline-def-modeline 'dashboard
+ '(bar window-number buffer-default-directory-simple)
+ '(misc-info battery irc mu4e gnus github debug minor-modes input-method major-mode process))
+
+(doom-modeline-def-modeline 'vcs
+ '(bar window-number modals matches buffer-info buffer-position parrot selection-info)
+ '(misc-info battery irc mu4e gnus github debug minor-modes buffer-encoding major-mode process))
+
+(doom-modeline-def-modeline 'package
+ '(bar window-number package)
+ '(misc-info major-mode process))
+
+(doom-modeline-def-modeline 'info
+ '(bar window-number buffer-info info-nodes buffer-position parrot selection-info)
+ '(misc-info buffer-encoding major-mode))
+
+(doom-modeline-def-modeline 'media
+ '(bar window-number buffer-size buffer-info)
+ '(misc-info media-info major-mode process vcs))
+
+(doom-modeline-def-modeline 'message
+ '(bar window-number modals matches buffer-info-simple buffer-position word-count parrot selection-info)
+ '(objed-state misc-info battery debug minor-modes input-method indent-info buffer-encoding major-mode))
+
+(doom-modeline-def-modeline 'pdf
+ '(bar window-number matches buffer-info pdf-pages)
+ '(misc-info major-mode process vcs))
+
+(doom-modeline-def-modeline 'org-src
+ '(bar window-number modals matches buffer-info-simple buffer-position word-count parrot selection-info)
+ '(objed-state misc-info debug lsp minor-modes input-method indent-info buffer-encoding major-mode process checker))
+
+(doom-modeline-def-modeline 'helm
+ '(bar helm-buffer-id helm-number helm-follow helm-prefix-argument)
+ '(helm-help))
+
+(doom-modeline-def-modeline 'timemachine
+ '(bar window-number modals matches git-timemachine buffer-position word-count parrot selection-info)
+ '(misc-info minor-modes indent-info buffer-encoding major-mode))
+
+
+;;
+;; Interfaces
+;;
+
+;;;###autoload
+(defun doom-modeline-init ()
+ "Initialize doom mode-line."
+ (doom-modeline-mode 1))
+(make-obsolete 'doom-modeline-init 'doom-modeline-mode "1.6.0")
+
+;;;###autoload
+(defun doom-modeline-set-main-modeline (&optional default)
+ "Set main mode-line.
+If DEFAULT is non-nil, set the default mode-line for all buffers."
+ (doom-modeline-set-modeline 'main default))
+
+;;;###autoload
+(defun doom-modeline-set-minimal-modeline ()
+ "Set minimal mode-line."
+ (doom-modeline-set-modeline 'minimal))
+
+;;;###autoload
+(defun doom-modeline-set-special-modeline ()
+ "Set special mode-line."
+ (doom-modeline-set-modeline 'special))
+
+;;;###autoload
+(defun doom-modeline-set-project-modeline ()
+ "Set project mode-line."
+ (doom-modeline-set-modeline 'project))
+
+;;;###autoload
+(defun doom-modeline-set-dashboard-modeline ()
+ "Set dashboard mode-line."
+ (doom-modeline-set-modeline 'dashboard))
+
+;;;###autoload
+(defun doom-modeline-set-vcs-modeline ()
+ "Set vcs mode-line."
+ (doom-modeline-set-modeline 'vcs))
+
+;;;###autoload
+(defun doom-modeline-set-info-modeline ()
+ "Set Info mode-line."
+ (doom-modeline-set-modeline 'info))
+
+;;;###autoload
+(defun doom-modeline-set-package-modeline ()
+ "Set package mode-line."
+ (doom-modeline-set-modeline 'package))
+
+;;;###autoload
+(defun doom-modeline-set-media-modeline ()
+ "Set media mode-line."
+ (doom-modeline-set-modeline 'media))
+
+;;;###autoload
+(defun doom-modeline-set-message-modeline ()
+ "Set message mode-line."
+ (doom-modeline-set-modeline 'message))
+
+;;;###autoload
+(defun doom-modeline-set-pdf-modeline ()
+ "Set pdf mode-line."
+ (doom-modeline-set-modeline 'pdf))
+
+;;;###autoload
+(defun doom-modeline-set-org-src-modeline ()
+ "Set org-src mode-line."
+ (doom-modeline-set-modeline 'org-src))
+
+;;;###autoload
+(defun doom-modeline-set-helm-modeline (&rest _) ; To advice helm
+ "Set helm mode-line."
+ (doom-modeline-set-modeline 'helm))
+
+;;;###autoload
+(defun doom-modeline-set-timemachine-modeline ()
+ "Set timemachine mode-line."
+ (doom-modeline-set-modeline 'timemachine))
+
+
+;;
+;; Minor mode
+;;
+
+(defvar doom-modeline-mode-map (make-sparse-keymap))
+
+;; Suppress warnings
+(defvar 2C-mode-line-format)
+(declare-function helm-display-mode-line "ext:helm-core")
+
+;;;###autoload
+(define-minor-mode doom-modeline-mode
+ "Toggle doom-modeline on or off."
+ :group 'doom-modeline
+ :global t
+ :lighter nil
+ :keymap doom-modeline-mode-map
+ (if doom-modeline-mode
+ (progn
+ (doom-modeline-refresh-bars) ; Create bars
+ (doom-modeline-set-main-modeline t) ; Set default mode-line
+
+ ;; Apply to all existing buffers.
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (doom-modeline-set-main-modeline)))
+
+ ;; For two-column editing
+ (setq 2C-mode-line-format (doom-modeline 'special))
+
+ ;; Add hooks
+ (add-hook 'Info-mode-hook #'doom-modeline-set-info-modeline)
+ (add-hook 'dired-mode-hook #'doom-modeline-set-project-modeline)
+ (add-hook 'dashboard-mode-hook #'doom-modeline-set-dashboard-modeline)
+ (add-hook 'image-mode-hook #'doom-modeline-set-media-modeline)
+ (add-hook 'message-mode-hook #'doom-modeline-set-message-modeline)
+ (add-hook 'git-commit-mode-hook #'doom-modeline-set-message-modeline)
+ (add-hook 'magit-mode-hook #'doom-modeline-set-vcs-modeline)
+ (add-hook 'circe-mode-hook #'doom-modeline-set-special-modeline)
+ (add-hook 'erc-mode-hook #'doom-modeline-set-special-modeline)
+ (add-hook 'rcirc-mode-hook #'doom-modeline-set-special-modeline)
+ (add-hook 'pdf-view-mode-hook #'doom-modeline-set-pdf-modeline)
+ (add-hook 'org-src-mode-hook #'doom-modeline-set-org-src-modeline)
+ (add-hook 'git-timemachine-mode-hook #'doom-modeline-set-timemachine-modeline)
+ (add-hook 'paradox-menu-mode-hook #'doom-modeline-set-package-modeline)
+ (add-hook 'xwidget-webkit-mode-hook #'doom-modeline-set-minimal-modeline)
+
+ ;; Add advices
+ (advice-add #'helm-display-mode-line :after #'doom-modeline-set-helm-modeline))
+ (progn
+ ;; Restore mode-line
+ (let ((original-format (doom-modeline--original-value 'mode-line-format)))
+ (setq-default mode-line-format original-format)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (setq mode-line-format original-format))))
+
+ ;; For two-column editing
+ (setq 2C-mode-line-format (doom-modeline--original-value '2C-mode-line-format))
+
+ ;; Remove hooks
+ (remove-hook 'Info-mode-hook #'doom-modeline-set-info-modeline)
+ (remove-hook 'dired-mode-hook #'doom-modeline-set-project-modeline)
+ (remove-hook 'dashboard-mode-hook #'doom-modeline-set-dashboard-modeline)
+ (remove-hook 'image-mode-hook #'doom-modeline-set-media-modeline)
+ (remove-hook 'message-mode-hook #'doom-modeline-set-message-modeline)
+ (remove-hook 'git-commit-mode-hook #'doom-modeline-set-message-modeline)
+ (remove-hook 'magit-mode-hook #'doom-modeline-set-vcs-modeline)
+ (remove-hook 'circe-mode-hook #'doom-modeline-set-special-modeline)
+ (remove-hook 'erc-mode-hook #'doom-modeline-set-special-modeline)
+ (remove-hook 'rcirc-mode-hook #'doom-modeline-set-special-modeline)
+ (remove-hook 'pdf-view-mode-hook #'doom-modeline-set-pdf-modeline)
+ (remove-hook 'org-src-mode-hook #'doom-modeline-set-org-src-modeline)
+ (remove-hook 'git-timemachine-mode-hook #'doom-modeline-set-timemachine-modeline)
+ (remove-hook 'paradox-menu-mode-hook #'doom-modeline-set-package-modeline)
+ (remove-hook 'xwidget-webkit-mode-hook #'doom-modeline-set-minimal-modeline)
+
+ ;; Remove advices
+ (advice-remove #'helm-display-mode-line #'doom-modeline-set-helm-modeline))))
+
+(provide 'doom-modeline)
+
+;;; doom-modeline.el ends here
diff --git a/org/elpa/shrink-path-20190208.1335/shrink-path-autoloads.el b/org/elpa/shrink-path-20190208.1335/shrink-path-autoloads.el
new file mode 100644
index 0000000..776b017
--- /dev/null
+++ b/org/elpa/shrink-path-20190208.1335/shrink-path-autoloads.el
@@ -0,0 +1,22 @@
+;;; shrink-path-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "shrink-path" "shrink-path.el" (0 0 0 0))
+;;; Generated autoloads from shrink-path.el
+
+(register-definition-prefixes "shrink-path" '("shrink-path-"))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; shrink-path-autoloads.el ends here
diff --git a/org/elpa/shrink-path-20190208.1335/shrink-path-pkg.el b/org/elpa/shrink-path-20190208.1335/shrink-path-pkg.el
new file mode 100644
index 0000000..c568bd0
--- /dev/null
+++ b/org/elpa/shrink-path-20190208.1335/shrink-path-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from shrink-path.el -*- no-byte-compile: t -*-
+(define-package "shrink-path" "20190208.1335" "fish-style path" '((emacs "24") (s "1.6.1") (dash "1.8.0") (f "0.10.0")) :commit "c14882c8599aec79a6e8ef2d06454254bb3e1e41" :authors '(("Benjamin Andresen")) :maintainer '("Benjamin Andresen") :url "https://gitlab.com/bennya/shrink-path.el")
diff --git a/org/elpa/shrink-path-20190208.1335/shrink-path.el b/org/elpa/shrink-path-20190208.1335/shrink-path.el
new file mode 100644
index 0000000..154bfd6
--- /dev/null
+++ b/org/elpa/shrink-path-20190208.1335/shrink-path.el
@@ -0,0 +1,150 @@
+;;; shrink-path.el --- fish-style path -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017 Benjamin Andresen
+
+;; Author: Benjamin Andresen
+;; Version: 0.3.1
+;; Package-Version: 20190208.1335
+;; Package-Commit: c14882c8599aec79a6e8ef2d06454254bb3e1e41
+;; URL: https://gitlab.com/bennya/shrink-path.el
+;; Package-Requires: ((emacs "24") (s "1.6.1") (dash "1.8.0") (f "0.10.0"))
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file LICENSE. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Provides functions that offer fish shell[1] path truncation.
+;; Directory /usr/share/emacs/site-lisp => /u/s/e/site-lisp
+;;
+;; Also includes utility functions that make integration in eshell or the
+;; modeline easier.
+;;
+;; [1] https://fishshell.com/
+
+
+;;; Code:
+(require 'dash)
+(require 's)
+(require 'f)
+(require 'rx)
+
+(defun shrink-path--truncate (str)
+ "Return STR's first character or first two characters if hidden."
+ (substring str 0 (if (s-starts-with? "." str) 2 1)))
+
+(defun shrink-path--dirs-internal (full-path &optional truncate-all)
+ "Return fish-style truncated string based on FULL-PATH.
+Optional parameter TRUNCATE-ALL will cause the function to truncate the last
+directory too."
+ (let* ((home (expand-file-name "~"))
+ (path (replace-regexp-in-string
+ (s-concat "^" home) "~" full-path))
+ (split (s-split "/" path 'omit-nulls))
+ (split-len (length split))
+ shrunk)
+ (->> split
+ (--map-indexed (if (= it-index (1- split-len))
+ (if truncate-all (shrink-path--truncate it) it)
+ (shrink-path--truncate it)))
+ (s-join "/")
+ (setq shrunk))
+ (s-concat (unless (s-matches? (rx bos (or "~" "/")) shrunk) "/")
+ shrunk
+ (unless (s-ends-with? "/" shrunk) "/"))))
+
+
+(defun shrink-path-dirs (&optional path truncate-tail)
+ "Given PATH return fish-styled shrunken down path.
+TRUNCATE-TAIL will cause the function to truncate the last directory too."
+ (let* ((path (or path default-directory))
+ (path (f-full path)))
+ (cond
+ ((s-equals? (f-short path) "/") "/")
+ ((s-matches? (rx bos (or "~" "/") eos) "~/"))
+ (t (shrink-path--dirs-internal path truncate-tail)))))
+
+(defun shrink-path-expand (str &optional absolute-p)
+ "Return expanded path from STR if found or list of matches on multiple.
+The path referred to by STR has to exist for this to work.
+If ABSOLUTE-P is t the returned path will be absolute."
+ (let* ((str-split (s-split "/" str 'omit-nulls))
+ (head (car str-split)))
+ (if (= (length str-split) 1)
+ (s-concat "/" str-split)
+ (--> (-drop 1 str-split) ;; drop head
+ (-map (lambda (e) (s-concat e "*")) it)
+ (-drop-last 1 it) ;; drop tail as it may not exist
+ (s-join "/" it)
+ (s-concat (if (s-equals? head "~") "~/" head) it)
+ (f-glob it)
+ (-map (lambda (e) (s-concat e "/" (-last-item str-split))) it)
+ (if absolute-p (-map #'f-full it) (-map #'f-abbrev it))
+ (if (= (length it) 1) (car it) it)))))
+
+(defun shrink-path-prompt (&optional pwd)
+ "Return cons of BASE and DIR for PWD.
+If PWD isn't provided will default to `default-directory'."
+ (let* ((pwd (or pwd default-directory))
+ (shrunk (shrink-path-dirs pwd))
+ (split (--> shrunk (s-split "/" it 'omit-nulls)))
+ base dir)
+ (setq dir (or (-last-item split) "/"))
+ (setq base (if (s-equals? dir "/") ""
+ (s-chop-suffix (s-concat dir "/") shrunk)))
+ (cons base dir)))
+
+(defun shrink-path-file (file &optional truncate-tail)
+ "Return FILE's shrunk down path and filename.
+TRUNCATE-TAIL controls if the last directory should also be shortened."
+ (let ((filename (f-filename file))
+ (dirname (f-dirname file)))
+ (s-concat (shrink-path-dirs dirname truncate-tail) filename)))
+
+(defun shrink-path-file-expand (str &optional exists-p absolute-p)
+ "Return STR's expanded filename.
+The path referred to by STR has to exist for this to work.
+If EXISTS-P is t the filename also has to exist.
+If ABSOLUTE-P is t the returned path will be absolute."
+ (let ((expanded (shrink-path-expand str absolute-p)))
+ (if (and expanded exists-p)
+ (if (f-exists? expanded) expanded)
+ expanded)))
+
+(defun shrink-path-file-mixed (shrink-path rel-path filename)
+ "Returns list of mixed truncated file name locations.
+
+Consists of SHRINK-PATH's parent, SHRINK-PATH basename, relative REL-PATH and
+FILENAME.
+For use in modeline or prompts, etc."
+ (let ((shrunk-dirs (shrink-path-prompt shrink-path))
+ sp-parent sp-rel rel-rel nd-file)
+
+ (when (f-descendant-of? filename shrink-path)
+ (when shrunk-dirs
+ (setq sp-parent (car shrunk-dirs)
+ sp-rel (cdr shrunk-dirs)))
+ (setq rel-rel (if (or (f-same? rel-path shrink-path)
+ (s-equals? (f-relative rel-path shrink-path) "."))
+ nil
+ (f-relative rel-path shrink-path)))
+ (setq nd-file (file-name-nondirectory filename))
+
+ (list sp-parent sp-rel rel-rel nd-file))))
+
+(provide 'shrink-path)
+;;; shrink-path.el ends here