config

Personal configuration.
git clone git://code.dwrz.net/config
Log | Files | Refs

doom-modeline-core.el (62711B)


      1 ;;; doom-modeline-core.el --- The core libraries for doom-modeline -*- lexical-binding: t; -*-
      2 
      3 ;; Copyright (C) 2018-2024 Vincent Zhang
      4 
      5 ;; This file is not part of GNU Emacs.
      6 
      7 ;;
      8 ;; This program is free software; you can redistribute it and/or modify
      9 ;; it under the terms of the GNU General Public License as published by
     10 ;; the Free Software Foundation, either version 3 of the License, or
     11 ;; (at your option) any later version.
     12 ;;
     13 ;; This program is distributed in the hope that it will be useful,
     14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 ;; GNU General Public License for more details.
     17 ;;
     18 ;; You should have received a copy of the GNU General Public License
     19 ;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
     20 ;;
     21 
     22 ;;; Commentary:
     23 ;;
     24 ;; The core libraries for doom-modeline.
     25 ;;
     26 
     27 ;;; Code:
     28 
     29 (require 'compat)
     30 (eval-when-compile
     31   (require 'cl-lib)
     32   (require 'subr-x))
     33 (require 'nerd-icons)
     34 (require 'shrink-path)
     35 
     36 
     37 ;;
     38 ;; Compatibility
     39 ;;
     40 
     41 (unless (boundp 'mode-line-right-align-edge)
     42   (defcustom mode-line-right-align-edge 'window
     43     "Where mode-line should align to.
     44 Internally, that function uses `:align-to' in a display property,
     45 so aligns to the left edge of the given area.  See info node
     46 `(elisp)Pixel Specification'.
     47 
     48 Must be set to a symbol.  Acceptable values are:
     49 - `window': align to extreme right of window, regardless of margins
     50   or fringes
     51 - `right-fringe': align to right-fringe
     52 - `right-margin': align to right-margin"
     53     :type '(choice (const right-margin)
     54                    (const right-fringe)
     55                    (const window))
     56     :group 'mode-line))
     57 
     58 
     59 ;;
     60 ;; Optimization
     61 ;;
     62 
     63 ;; Don’t compact font caches during GC.
     64 (when (eq system-type 'windows-nt)
     65   (setq inhibit-compacting-font-caches t))
     66 
     67 
     68 ;;
     69 ;; Customization
     70 ;;
     71 
     72 (defgroup doom-modeline nil
     73   "A minimal and modern mode-line."
     74   :group 'mode-line
     75   :link '(url-link :tag "Homepage" "https://github.com/seagle0128/doom-modeline"))
     76 
     77 (defcustom doom-modeline-support-imenu nil
     78   "If non-nil, cause imenu to see `doom-modeline' declarations.
     79 This is done by adjusting `lisp-imenu-generic-expression' to
     80 include support for finding `doom-modeline-def-*' forms.
     81 
     82 Must be set before loading `doom-modeline'."
     83   :type 'boolean
     84   :set (lambda (_sym val)
     85          (if val
     86              (add-hook 'emacs-lisp-mode-hook #'doom-modeline-add-imenu)
     87            (remove-hook 'emacs-lisp-mode-hook #'doom-modeline-add-imenu)))
     88   :group 'doom-modeline)
     89 
     90 (defcustom doom-modeline-height (+ (frame-char-height) 4)
     91   "How tall the mode-line should be. It's only respected in GUI.
     92 If the actual char height is larger, it respects the actual char height."
     93   :type 'integer
     94   :group 'doom-modeline)
     95 
     96 (defcustom doom-modeline-bar-width 4
     97   "How wide the mode-line bar should be. It's only respected in GUI."
     98   :type 'integer
     99   :set (lambda (sym val)
    100          (set sym (if (> val 0) val 1)))
    101   :group 'doom-modeline)
    102 
    103 (defcustom doom-modeline-hud nil
    104   "Whether to use hud instead of default bar. It's only respected in GUI."
    105   :type 'boolean
    106   :group 'doom-modeline)
    107 
    108 (defcustom doom-modeline-hud-min-height 2
    109   "Minimum height in pixels of the \"thumb\" of the hud.
    110 Only respected in GUI."
    111   :type 'integer
    112   :set (lambda (sym val)
    113          (set sym (if (> val 1) val 1)))
    114   :group 'doom-modeline)
    115 
    116 (defcustom doom-modeline-window-width-limit 85
    117   "The limit of the window width.
    118 
    119 If `window-width' is smaller than the limit, some information won't be
    120 displayed. It can be an integer or a float number. nil means no limit."
    121   :type '(choice integer
    122                  float
    123                  (const :tag "Disable" nil))
    124   :group 'doom-modeline)
    125 
    126 (defcustom doom-modeline-project-detection 'auto
    127   "How to detect the project root.
    128 
    129 nil means to use `default-directory'.
    130 
    131 The project management packages have some issues on detecting project root.
    132 e.g. `projectile' doesn't handle symlink folders well, while `project' is
    133 unable to handle sub-projects.
    134 Specify another one if you encounter the issue."
    135   :type '(choice (const :tag "Auto-detect" auto)
    136                  (const :tag "Find File in Project" ffip)
    137                  (const :tag "Projectile" projectile)
    138                  (const :tag "Built-in Project" project)
    139                  (const :tag "Disable" nil))
    140   :group 'doom-modeline)
    141 
    142 (defcustom doom-modeline-buffer-file-name-style 'auto
    143   "Determines the style used by `doom-modeline-buffer-file-name'.
    144 
    145 Given ~/Projects/FOSS/emacs/lisp/comint.el
    146   auto => emacs/l/comint.el (in a project) or comint.el
    147   truncate-upto-project => ~/P/F/emacs/lisp/comint.el
    148   truncate-from-project => ~/Projects/FOSS/emacs/l/comint.el
    149   truncate-with-project => emacs/l/comint.el
    150   truncate-except-project => ~/P/F/emacs/l/comint.el
    151   truncate-upto-root => ~/P/F/e/lisp/comint.el
    152   truncate-all => ~/P/F/e/l/comint.el
    153   truncate-nil => ~/Projects/FOSS/emacs/lisp/comint.el
    154   relative-from-project => emacs/lisp/comint.el
    155   relative-to-project => lisp/comint.el
    156   file-name => comint.el
    157   file-name-with-project => FOSS|comint.el
    158   buffer-name => comint.el<2> (uniquify buffer name)"
    159   :type '(choice (const auto)
    160                  (const truncate-upto-project)
    161                  (const truncate-from-project)
    162                  (const truncate-with-project)
    163                  (const truncate-except-project)
    164                  (const truncate-upto-root)
    165                  (const truncate-all)
    166                  (const truncate-nil)
    167                  (const relative-from-project)
    168                  (const relative-to-project)
    169                  (const file-name)
    170                  (const file-name-with-project)
    171                  (const buffer-name))
    172   :group'doom-modeline)
    173 
    174 (defcustom doom-modeline-buffer-file-true-name nil
    175   "Use `file-truename' on buffer file name.
    176 
    177 Project detection(projectile.el) may uses `file-truename' on directory path.
    178 Turn on this to provide right relative path for buffer file name."
    179   :type 'boolean
    180   :group'doom-modeline)
    181 
    182 (defcustom doom-modeline-icon t
    183   "Whether display the icons in the mode-line.
    184 
    185 While using the server mode in GUI, should set the value explicitly."
    186   :type 'boolean
    187   :group 'doom-modeline)
    188 
    189 (defcustom doom-modeline-major-mode-icon t
    190   "Whether display the icon for `major-mode'.
    191 
    192 It respects option `doom-modeline-icon'."
    193   :type 'boolean
    194   :group'doom-modeline)
    195 
    196 (defcustom doom-modeline-major-mode-color-icon t
    197   "Whether display the colorful icon for `major-mode'.
    198 
    199 It respects option `nerd-icons-color-icons'."
    200   :type 'boolean
    201   :group'doom-modeline)
    202 
    203 (defcustom doom-modeline-buffer-state-icon t
    204   "Whether display the icon for the buffer state.
    205 
    206 It respects option `doom-modeline-icon'."
    207   :type 'boolean
    208   :group 'doom-modeline)
    209 
    210 (defcustom doom-modeline-buffer-modification-icon t
    211   "Whether display the modification icon for the buffer.
    212 
    213 It respects option `doom-modeline-icon' and `doom-modeline-buffer-state-icon'."
    214   :type 'boolean
    215   :group 'doom-modeline)
    216 
    217 (defcustom doom-modeline-lsp-icon t
    218   "Whether display the icon of lsp client.
    219 
    220 It respects option `doom-modeline-icon'."
    221   :type 'boolean
    222   :group 'doom-modeline)
    223 
    224 (defcustom doom-modeline-time-icon t
    225   "Whether display the icon of time.
    226 
    227 It respects option `doom-modeline-icon'."
    228   :type 'boolean
    229   :group 'doom-modeline)
    230 
    231 (defcustom doom-modeline-time-live-icon t
    232   "Whether display the live icons of time.
    233 
    234 It respects option `doom-modeline-icon' and option `doom-modeline-time-icon'."
    235   :type 'boolean
    236   :group 'doom-modeline)
    237 
    238 (defcustom doom-modeline-time-analogue-clock t
    239   "Whether to draw an analogue clock SVG as the live time icon.
    240 It respects the option `doom-modeline-icon', option `doom-modeline-time-icon',
    241 and option `doom-modeline-time-live-icon'."
    242   :type 'boolean
    243   :group 'doom-modeline)
    244 
    245 (defcustom doom-modeline-time-clock-minute-resolution 1
    246   "The clock will be updated every this many minutes, truncated.
    247 See `doom-modeline-time-analogue-clock'."
    248   :type 'natnum
    249   :group 'doom-modeline)
    250 
    251 (defcustom doom-modeline-time-clock-size 0.7
    252   "Size of the analogue clock drawn, either in pixels or as a proportional height.
    253 An integer value is used as the diameter of clock in pixels.
    254 A floating point value sets the diameter of the clock realtive to
    255 `doom-modeline-height'.
    256 
    257 Only relevant when `doom-modeline-time-analogue-clock' is non-nil, which see."
    258   :type 'number
    259   :group 'doom-modeline)
    260 
    261 (defcustom doom-modeline-unicode-fallback nil
    262   "Whether to use unicode as a fallback (instead of ASCII) when not using icons."
    263   :type 'boolean
    264   :group 'doom-modeline)
    265 
    266 (defcustom doom-modeline-buffer-name t
    267   "Whether display the buffer name."
    268   :type 'boolean
    269   :group 'doom-modeline)
    270 
    271 (defcustom doom-modeline-highlight-modified-buffer-name t
    272   "Whether highlight the modified buffer name."
    273   :type 'boolean
    274   :group 'doom-modeline)
    275 
    276 (defcustom doom-modeline-column-zero-based t
    277   "When non-nil, mode line displays column numbers zero-based.
    278 See `column-number-indicator-zero-based'."
    279   :type 'boolean
    280   :group 'doom-modeline)
    281 
    282 (defcustom doom-modeline-percent-position '(-3 "%p")
    283   "Specification of \"percentage offset\" of window through buffer.
    284 See `mode-line-percent-position'."
    285   :type '(radio
    286           (const :tag "nil:  No offset is displayed" nil)
    287           (const :tag "\"%o\": Proportion of \"travel\" of the window through the buffer"
    288             (-3 "%o"))
    289           (const :tag "\"%p\": Percentage offset of top of window"
    290             (-3 "%p"))
    291           (const :tag "\"%P\": Percentage offset of bottom of window"
    292             (-3 "%P"))
    293           (const :tag "\"%q\": Offsets of both top and bottom of window"
    294             (6 "%q")))
    295   :group 'doom-modeline)
    296 
    297 (defcustom doom-modeline-position-line-format '("L%l")
    298   "Format used to display line numbers in the mode line.
    299 See `mode-line-position-line-format'."
    300   :type '(list string)
    301   :group 'doom-modeline)
    302 
    303 (defcustom doom-modeline-position-column-format '("C%c")
    304   "Format used to display column numbers in the mode line.
    305 See `mode-line-position-column-format'."
    306   :type '(list string)
    307   :group 'doom-modeline)
    308 
    309 (defcustom doom-modeline-position-column-line-format '("%l:%c")
    310   "Format used to display combined line/column numbers in the mode line.
    311 See `mode-line-position-column-line-format'."
    312   :type '(list string)
    313   :group 'doom-modeline)
    314 
    315 (defcustom doom-modeline-minor-modes nil
    316   "Whether display the minor modes in the mode-line."
    317   :type 'boolean
    318   :group 'doom-modeline)
    319 
    320 (defcustom doom-modeline-enable-word-count nil
    321   "If non-nil, a word count will be added to the selection-info modeline segment."
    322   :type 'boolean
    323   :group 'doom-modeline)
    324 
    325 (defcustom doom-modeline-continuous-word-count-modes
    326   '(markdown-mode gfm-mode org-mode)
    327   "Major modes in which to display word count continuously.
    328 
    329 It respects `doom-modeline-enable-word-count'."
    330   :type '(repeat (symbol :tag "Major-Mode") )
    331   :group 'doom-modeline)
    332 
    333 (defcustom doom-modeline-buffer-encoding t
    334   "Whether display the buffer encoding."
    335   :type '(choice (const :tag "Always" t)
    336                  (const :tag "When non-default" nondefault)
    337                  (const :tag "Never" nil))
    338   :group 'doom-modeline)
    339 
    340 (defcustom doom-modeline-default-coding-system 'utf-8
    341   "Default coding system for `doom-modeline-buffer-encoding' `nondefault'."
    342   :type 'coding-system
    343   :group 'doom-modeline)
    344 
    345 (defcustom doom-modeline-default-eol-type 0
    346   "Default EOL type for `doom-modeline-buffer-encoding' `nondefault'."
    347   :type '(choice (const :tag "Unix-style LF" 0)
    348                  (const :tag "DOS-style CRLF" 1)
    349                  (const :tag "Mac-style CR" 2))
    350   :group 'doom-modeline)
    351 
    352 (defcustom doom-modeline-indent-info nil
    353   "Whether display the indentation information."
    354   :type 'boolean
    355   :group 'doom-modeline)
    356 
    357 (defcustom doom-modeline-total-line-number nil
    358   "Whether display the total line number."
    359   :type 'boolean
    360   :group 'doom-modeline)
    361 
    362 ;; It is based upon `editorconfig-indentation-alist' but is used to read indentation levels instead
    363 ;; of setting them. (https://github.com/editorconfig/editorconfig-emacs)
    364 (defcustom doom-modeline-indent-alist
    365   '((apache-mode apache-indent-level)
    366     (awk-mode c-basic-offset)
    367     (bpftrace-mode c-basic-offset)
    368     (c++-mode c-basic-offset)
    369     (c-mode c-basic-offset)
    370     (cmake-mode cmake-tab-width)
    371     (coffee-mode coffee-tab-width)
    372     (cperl-mode cperl-indent-level)
    373     (crystal-mode crystal-indent-level)
    374     (csharp-mode c-basic-offset)
    375     (css-mode css-indent-offset)
    376     (d-mode c-basic-offset)
    377     (emacs-lisp-mode lisp-indent-offset)
    378     (enh-ruby-mode enh-ruby-indent-level)
    379     (erlang-mode erlang-indent-level)
    380     (ess-mode ess-indent-offset)
    381     (f90-mode f90-associate-indent
    382               f90-continuation-indent
    383               f90-critical-indent
    384               f90-do-indent
    385               f90-if-indent
    386               f90-program-indent
    387               f90-type-indent)
    388     (feature-mode feature-indent-offset
    389                   feature-indent-level)
    390     (fsharp-mode fsharp-continuation-offset
    391                  fsharp-indent-level
    392                  fsharp-indent-offset)
    393     (groovy-mode groovy-indent-offset)
    394     (haskell-mode haskell-indent-spaces
    395                   haskell-indent-offset
    396                   haskell-indentation-layout-offset
    397                   haskell-indentation-left-offset
    398                   haskell-indentation-starter-offset
    399                   haskell-indentation-where-post-offset
    400                   haskell-indentation-where-pre-offset
    401                   shm-indent-spaces)
    402     (haxor-mode haxor-tab-width)
    403     (idl-mode c-basic-offset)
    404     (jade-mode jade-tab-width)
    405     (java-mode c-basic-offset)
    406     (js-mode js-indent-level)
    407     (js-jsx-mode js-indent-level
    408                  sgml-basic-offset)
    409     (js2-mode js2-basic-offset)
    410     (js2-jsx-mode js2-basic-offset
    411                   sgml-basic-offset)
    412     (js3-mode js3-indent-level)
    413     (json-mode js-indent-level)
    414     (julia-mode julia-indent-offset)
    415     (kotlin-mode kotlin-tab-width)
    416     (latex-mode tex-indent-basic)
    417     (lisp-mode lisp-indent-offset)
    418     (livescript-mode livescript-tab-width)
    419     (lua-mode lua-indent-level)
    420     (matlab-mode matlab-indent-level)
    421     (mips-mode mips-tab-width)
    422     (mustache-mode mustache-basic-offset)
    423     (nasm-mode nasm-basic-offset)
    424     (nginx-mode nginx-indent-level)
    425     (nxml-mode nxml-child-indent)
    426     (objc-mode c-basic-offset)
    427     (octave-mode octave-block-offset)
    428     (perl-mode perl-indent-level)
    429     (php-mode c-basic-offset)
    430     (pike-mode c-basic-offset)
    431     (ps-mode ps-mode-tab)
    432     (pug-mode pug-tab-width)
    433     (puppet-mode puppet-indent-level)
    434     (python-mode python-indent-offset)
    435     (ruby-mode ruby-indent-level)
    436     (rust-mode rust-indent-offset)
    437     (rustic-mode rustic-indent-offset)
    438     (scala-mode scala-indent:step)
    439     (scss-mode css-indent-offset)
    440     (sgml-mode sgml-basic-offset)
    441     (sh-mode sh-basic-offset
    442              sh-indentation)
    443     (slim-mode slim-indent-offset)
    444     (sml-mode sml-indent-level)
    445     (tcl-mode tcl-indent-level
    446               tcl-continued-indent-level)
    447     (terra-mode terra-indent-level)
    448     (typescript-mode typescript-indent-level)
    449     (verilog-mode verilog-indent-level
    450                   verilog-indent-level-behavioral
    451                   verilog-indent-level-declaration
    452                   verilog-indent-level-module
    453                   verilog-cexp-indent
    454                   verilog-case-indent)
    455     (web-mode web-mode-attr-indent-offset
    456               web-mode-attr-value-indent-offset
    457               web-mode-code-indent-offset
    458               web-mode-css-indent-offset
    459               web-mode-markup-indent-offset
    460               web-mode-sql-indent-offset
    461               web-mode-block-padding
    462               web-mode-script-padding
    463               web-mode-style-padding)
    464     (yaml-mode yaml-indent-offset))
    465   "Indentation retrieving variables matched to major modes.
    466 
    467 Which is used when `doom-modeline-indent-info' is non-nil.
    468 When multiple variables are specified for a mode, they will be tried resolved
    469 in the given order."
    470   :type '(alist :key-type symbol :value-type sexp)
    471   :group 'doom-modeline)
    472 
    473 (defcustom doom-modeline-vcs-icon t
    474   "Whether display the icon of vcs segment.
    475 
    476 It respects option `doom-modeline-icon'."
    477   :type 'boolean
    478   :group 'doom-modeline)
    479 
    480 (defcustom doom-modeline-vcs-max-length 15
    481   "The maximum displayed length of the branch name of version control."
    482   :type 'integer
    483   :group 'doom-modeline)
    484 
    485 (defcustom doom-modeline-vcs-display-function #'doom-modeline-vcs-name
    486   "The function to display the branch name."
    487   :type 'function
    488   :group 'doom-modeline)
    489 
    490 (defcustom doom-modeline-check-icon t
    491   "Whether display the icon of check segment.
    492 
    493 It respects option `doom-modeline-icon'."
    494   :type 'boolean
    495   :group 'doom-modeline)
    496 
    497 (define-obsolete-variable-alias
    498   'doom-modeline-checker-simple-format
    499   'doom-modeline-check-simple-format
    500   "4.2.0")
    501 
    502 (defcustom doom-modeline-check-simple-format nil
    503   "If non-nil, only display one number for check information if applicable."
    504   :type 'boolean
    505   :group 'doom-modeline)
    506 
    507 (defcustom doom-modeline-number-limit 99
    508   "The maximum number displayed for notifications."
    509   :type 'integer
    510   :group 'doom-modeline)
    511 
    512 (defcustom doom-modeline-workspace-name t
    513   "Whether display the workspace name.
    514 
    515 Non-nil to display in the mode-line."
    516   :type 'boolean
    517   :group 'doom-modeline)
    518 
    519 (defcustom doom-modeline-persp-name t
    520   "Whether display the perspective name.
    521 
    522 Non-nil to display in the mode-line."
    523   :type 'boolean
    524   :group 'doom-modeline)
    525 
    526 (defcustom doom-modeline-display-default-persp-name nil
    527   "If non nil the default perspective name is displayed in the mode-line."
    528   :type 'boolean
    529   :group 'doom-modeline)
    530 
    531 (defcustom doom-modeline-persp-icon t
    532   "If non nil the perspective name is displayed alongside a folder icon."
    533   :type 'boolean
    534   :group 'doom-modeline)
    535 
    536 (defcustom doom-modeline-repl t
    537   "Whether display the `repl' state.
    538 
    539 Non-nil to display in the mode-line."
    540   :type 'boolean
    541   :group 'doom-modeline)
    542 
    543 (defcustom doom-modeline-lsp t
    544   "Whether display the `lsp' state.
    545 
    546 Non-nil to display in the mode-line."
    547   :type 'boolean
    548   :group 'doom-modeline)
    549 
    550 (defcustom doom-modeline-github nil
    551   "Whether display the GitHub notifications.
    552 
    553 It requires `ghub' and `async' packages. Additionally, your GitHub personal
    554 access token must have `notifications' permissions.
    555 
    556 If you use `pass' to manage your secrets, you also need to add this hook:
    557   (add-hook \\='doom-modeline-before-github-fetch-notification-hook
    558 	   #\\='auth-source-pass-enable)"
    559   :type 'boolean
    560   :group 'doom-modeline)
    561 
    562 (defcustom doom-modeline-github-interval 1800 ; (* 30 60)
    563   "The interval of checking GitHub."
    564   :type 'integer
    565   :group 'doom-modeline)
    566 
    567 (defcustom doom-modeline-env-version t
    568   "Whether display the environment version."
    569   :type 'boolean
    570   :group 'doom-modeline)
    571 
    572 (defcustom doom-modeline-modal t
    573   "Whether display the modal state.
    574 
    575 Including `evil', `overwrite', `god', `ryo' and `xah-fly-keys', etc."
    576   :type 'boolean
    577   :group 'doom-modeline)
    578 
    579 (defcustom doom-modeline-modal-icon t
    580   "Whether display the modal state icon.
    581 
    582 Including `evil', `overwrite', `god', `ryo' and `xah-fly-keys', etc."
    583   :type 'boolean
    584   :group 'doom-modeline)
    585 
    586 (defcustom doom-modeline-modal-modern-icon t
    587   "Whether display the modern icons for modals."
    588   :type 'boolean
    589   :group 'doom-modeline)
    590 
    591 (defcustom doom-modeline-always-show-macro-register nil
    592   "When non-nil, always show the register name when recording an evil macro."
    593   :type 'boolean
    594   :group 'doom-modeline)
    595 
    596 (defcustom doom-modeline-mu4e nil
    597   "Whether display the mu4e notifications.
    598 
    599 It requires `mu4e-alert' package."
    600   :type 'boolean
    601   :group 'doom-modeline)
    602 
    603 (defcustom doom-modeline-gnus nil
    604   "Whether to display notifications from gnus.
    605 
    606 It requires `gnus' to be setup"
    607   :type 'boolean
    608   :group 'doom-modeline)
    609 
    610 (defcustom doom-modeline-gnus-timer 2
    611   "The wait time in minutes before gnus fetches mail.
    612 
    613 If nil, don't set up a hook."
    614   :type 'integer
    615   :group 'doom-modeline)
    616 
    617 (defcustom doom-modeline-gnus-idle nil
    618   "Whether to wait an idle time to scan for news.
    619 
    620 When t, sets `doom-modeline-gnus-timer' as an idle timer.  If a
    621 number, Emacs must have been idle this given time, checked after
    622 reach the defined timer, to fetch news.  The time step can be
    623 configured in `gnus-demon-timestep'."
    624   :type '(choice
    625 	  (boolean :tag "Set `doom-modeline-gnus-timer' as an idle timer")
    626 	  (number :tag "Set a custom idle timer"))
    627   :group 'doom-modeline)
    628 
    629 (defcustom doom-modeline-gnus-excluded-groups nil
    630   "A list of groups to be excluded from the unread count.
    631 Groups' names list in `gnus-newsrc-alist'`"
    632   :type '(repeat string)
    633   :group 'doom-modeline)
    634 
    635 (defcustom doom-modeline-irc t
    636   "Whether display the irc notifications.
    637 
    638 It requires either `circe' , `erc' or `rcirc' package."
    639   :type 'boolean
    640   :group 'doom-modeline)
    641 
    642 (defcustom doom-modeline-irc-buffers nil
    643   "Whether display the unread irc buffers."
    644   :type 'boolean
    645   :group 'doom-modeline)
    646 
    647 (defcustom doom-modeline-irc-stylize #'doom-modeline-shorten-irc
    648   "Which function to call to stylize IRC buffer names.
    649 
    650 Buffer names are stylized using the selected `function'.
    651 By default buffer names are shortened, you may want to disable or call
    652 your own function.
    653 The function must accept `buffer-name' and return `shortened-name'."
    654   :type '(radio (function-item :tag "Shorten"
    655                                :format "%t: %v\n %h"
    656                                doom-modeline-shorten-irc)
    657                 (function-item
    658                  :tag "Leave unchanged"
    659                  :format "%t: %v\n"
    660                  identity)
    661                 (function
    662                  :tag "Other function"))
    663   :group 'doom-modeline)
    664 
    665 (defcustom doom-modeline-battery t
    666   "Whether display the battery status.
    667 
    668 It respects `display-battery-mode'."
    669   :type 'boolean
    670   :group 'doom-modeline)
    671 
    672 (defcustom doom-modeline-time t
    673   "Whether display the time.
    674 
    675 It respects `display-time-mode'."
    676   :type 'boolean
    677   :group 'doom-modeline)
    678 
    679 (defcustom doom-modeline-display-misc-in-all-mode-lines t
    680   "Whether display the misc segment on all mode lines.
    681 
    682 If nil, display only if the mode line is active."
    683   :type 'boolean
    684   :group 'doom-modeline)
    685 
    686 (defcustom doom-modeline-always-visible-segments nil
    687   "A list of segments that should be visible even in inactive windows."
    688   :type '(repeat symbol)
    689   :group 'doom-modeline)
    690 
    691 (defcustom doom-modeline-buffer-file-name-function #'identity
    692   "The function to handle variable `buffer-file-name'."
    693   :type 'function
    694   :group 'doom-modeline)
    695 
    696 (defcustom doom-modeline-buffer-file-truename-function #'identity
    697   "The function to handle `buffer-file-truename'."
    698   :type 'function
    699   :group 'doom-modeline)
    700 
    701 (defcustom doom-modeline-k8s-show-namespace t
    702   "Whether to show the current Kubernetes context's default namespace."
    703   :type 'boolean
    704   :group 'doom-modeline)
    705 
    706 
    707 ;;
    708 ;; Faces
    709 ;;
    710 
    711 (defgroup doom-modeline-faces nil
    712   "The faces of `doom-modeline'."
    713   :group 'doom-modeline
    714   :group 'faces
    715   :link '(url-link :tag "Homepage" "https://github.com/seagle0128/doom-modeline"))
    716 
    717 (defface doom-modeline
    718   '((t ()))
    719   "Default face."
    720   :group 'doom-modeline-faces)
    721 
    722 (defface doom-modeline-emphasis
    723   '((t (:inherit (doom-modeline mode-line-emphasis))))
    724   "Face used for emphasis."
    725   :group 'doom-modeline-faces)
    726 
    727 (defface doom-modeline-highlight
    728   '((t (:inherit (doom-modeline mode-line-highlight))))
    729   "Face used for highlighting."
    730   :group 'doom-modeline-faces)
    731 
    732 (defface doom-modeline-buffer-path
    733   '((t (:inherit (doom-modeline-emphasis bold))))
    734   "Face used for the dirname part of the buffer path."
    735   :group 'doom-modeline-faces)
    736 
    737 (defface doom-modeline-buffer-file
    738   '((t (:inherit (doom-modeline mode-line-buffer-id bold))))
    739   "Face used for the filename part of the mode-line buffer path."
    740   :group 'doom-modeline-faces)
    741 
    742 (defface doom-modeline-buffer-modified
    743   '((t (:inherit (doom-modeline warning bold) :background unspecified)))
    744   "Face used for the \\='unsaved\\=' symbol in the mode-line."
    745   :group 'doom-modeline-faces)
    746 
    747 (defface doom-modeline-buffer-major-mode
    748   '((t (:inherit (doom-modeline-emphasis bold))))
    749   "Face used for the major-mode segment in the mode-line."
    750   :group 'doom-modeline-faces)
    751 
    752 (defface doom-modeline-buffer-minor-mode
    753   '((t (:inherit (doom-modeline font-lock-doc-face) :weight normal :slant normal)))
    754   "Face used for the minor-modes segment in the mode-line."
    755   :group 'doom-modeline-faces)
    756 
    757 (defface doom-modeline-project-parent-dir
    758   '((t (:inherit (doom-modeline font-lock-comment-face bold))))
    759   "Face used for the project parent directory of the mode-line buffer path."
    760   :group 'doom-modeline-faces)
    761 
    762 (defface doom-modeline-project-dir
    763   '((t (:inherit (doom-modeline font-lock-string-face bold))))
    764   "Face used for the project directory of the mode-line buffer path."
    765   :group 'doom-modeline-faces)
    766 
    767 (defface doom-modeline-project-root-dir
    768   '((t (:inherit (doom-modeline-emphasis bold))))
    769   "Face used for the project part of the mode-line buffer path."
    770   :group 'doom-modeline-faces)
    771 
    772 (defface doom-modeline-panel
    773   '((t (:inherit doom-modeline-highlight)))
    774   "Face for \\='X out of Y\\=' segments.
    775 This applies to `anzu', `evil-substitute', `iedit' etc."
    776   :group 'doom-modeline-faces)
    777 
    778 (defface doom-modeline-host
    779   '((t (:inherit (doom-modeline italic))))
    780   "Face for remote hosts in the mode-line."
    781   :group 'doom-modeline-faces)
    782 
    783 (defface doom-modeline-input-method
    784   '((t (:inherit (doom-modeline-emphasis))))
    785   "Face for input method in the mode-line."
    786   :group 'doom-modeline-faces)
    787 
    788 (defface doom-modeline-input-method-alt
    789   '((t (:inherit (doom-modeline font-lock-doc-face) :slant normal)))
    790   "Alternative face for input method in the mode-line."
    791   :group 'doom-modeline-faces)
    792 
    793 (defface doom-modeline-debug
    794   '((t (:inherit (doom-modeline font-lock-doc-face) :slant normal)))
    795   "Face for debug-level messages in the mode-line. Used by vcs, check, etc."
    796   :group 'doom-modeline-faces)
    797 
    798 (defface doom-modeline-info
    799   '((t (:inherit (doom-modeline success))))
    800   "Face for info-level messages in the mode-line. Used by vcs, check, etc."
    801   :group 'doom-modeline-faces)
    802 
    803 (defface doom-modeline-warning
    804   '((t (:inherit (doom-modeline warning))))
    805   "Face for warnings in the mode-line. Used by vcs, check, etc."
    806   :group 'doom-modeline-faces)
    807 
    808 (defface doom-modeline-urgent
    809   '((t (:inherit (doom-modeline error))))
    810   "Face for errors in the mode-line. Used by vcs, check, etc."
    811   :group 'doom-modeline-faces)
    812 
    813 (defface doom-modeline-notification
    814   '((t (:inherit doom-modeline-warning)))
    815   "Face for notifications in the mode-line. Used by GitHub, mu4e, etc.
    816 Also see the face `doom-modeline-unread-number'."
    817   :group 'doom-modeline-faces)
    818 
    819 (defface doom-modeline-unread-number
    820   '((t (:inherit doom-modeline :slant italic)))
    821   "Face for unread number in the mode-line. Used by GitHub, mu4e, etc."
    822   :group 'doom-modeline-faces)
    823 
    824 (defface doom-modeline-bar
    825   '((t (:inherit doom-modeline-highlight)))
    826   "The face used for the left-most bar in the mode-line of an active window."
    827   :group 'doom-modeline-faces)
    828 
    829 (defface doom-modeline-bar-inactive
    830   `((t (:inherit doom-modeline)))
    831   "The face used for the left-most bar in the mode-line of an inactive window."
    832   :group 'doom-modeline-faces)
    833 
    834 (defface doom-modeline-debug-visual
    835   '((((background light)) :foreground "#D4843E" :inherit doom-modeline)
    836     (((background dark)) :foreground "#915B2D" :inherit doom-modeline))
    837   "Face to use for the mode-line while debugging."
    838   :group 'doom-modeline-faces)
    839 
    840 (defface doom-modeline-evil-emacs-state
    841   '((t (:inherit (doom-modeline font-lock-builtin-face))))
    842   "Face for the Emacs state tag in evil indicator."
    843   :group 'doom-modeline-faces)
    844 
    845 (defface doom-modeline-evil-insert-state
    846   '((t (:inherit (doom-modeline font-lock-keyword-face))))
    847   "Face for the insert state tag in evil indicator."
    848   :group 'doom-modeline-faces)
    849 
    850 (defface doom-modeline-evil-motion-state
    851   '((t (:inherit (doom-modeline font-lock-doc-face) :slant normal)))
    852   "Face for the motion state tag in evil indicator."
    853   :group 'doom-modeline-faces)
    854 
    855 (defface doom-modeline-evil-normal-state
    856   '((t (:inherit doom-modeline-info)))
    857   "Face for the normal state tag in evil indicator."
    858   :group 'doom-modeline-faces)
    859 
    860 (defface doom-modeline-evil-operator-state
    861   '((t (:inherit (doom-modeline mode-line))))
    862   "Face for the operator state tag in evil indicator."
    863   :group 'doom-modeline-faces)
    864 
    865 (defface doom-modeline-evil-visual-state
    866   '((t (:inherit doom-modeline-warning)))
    867   "Face for the visual state tag in evil indicator."
    868   :group 'doom-modeline-faces)
    869 
    870 (defface doom-modeline-evil-replace-state
    871   '((t (:inherit doom-modeline-urgent)))
    872   "Face for the replace state tag in evil indicator."
    873   :group 'doom-modeline-faces)
    874 
    875 (defface doom-modeline-evil-user-state
    876   '((t (:inherit doom-modeline-warning)))
    877   "Face for the replace state tag in evil indicator."
    878   :group 'doom-modeline-faces)
    879 
    880 (defface doom-modeline-overwrite
    881   '((t (:inherit doom-modeline-urgent)))
    882   "Face for overwrite indicator."
    883   :group 'doom-modeline-faces)
    884 
    885 (defface doom-modeline-god
    886   '((t (:inherit doom-modeline-info)))
    887   "Face for god-mode indicator."
    888   :group 'doom-modeline-faces)
    889 
    890 (defface doom-modeline-ryo
    891   '((t (:inherit doom-modeline-info)))
    892   "Face for RYO indicator."
    893   :group 'doom-modeline-faces)
    894 
    895 (defface doom-modeline-fly-insert-state
    896   '((t (:inherit (doom-modeline font-lock-keyword-face))))
    897   "Face for the insert state in xah-fly-keys indicator."
    898   :group 'doom-modeline-faces)
    899 
    900 (defface doom-modeline-fly-normal-state
    901   '((t (:inherit doom-modeline-info)))
    902   "Face for the normal state in xah-fly-keys indicator."
    903   :group 'doom-modeline-faces)
    904 
    905 (defface doom-modeline-boon-command-state
    906   '((t (:inherit doom-modeline-info)))
    907   "Face for the command state tag in boon indicator."
    908   :group 'doom-modeline-faces)
    909 
    910 (defface doom-modeline-boon-insert-state
    911   '((t (:inherit (doom-modeline font-lock-keyword-face))))
    912   "Face for the insert state tag in boon indicator."
    913   :group 'doom-modeline-faces)
    914 
    915 (defface doom-modeline-boon-special-state
    916   '((t (:inherit (doom-modeline font-lock-builtin-face))))
    917   "Face for the special state tag in boon indicator."
    918   :group 'doom-modeline-faces)
    919 
    920 (defface doom-modeline-boon-off-state
    921   '((t (:inherit (doom-modeline mode-line))))
    922   "Face for the off state tag in boon indicator."
    923   :group 'doom-modeline-faces)
    924 
    925 (defface doom-modeline-meow-normal-state
    926   '((t (:inherit doom-modeline-evil-normal-state)))
    927   "Face for the normal state in meow-edit indicator."
    928   :group 'doom-modeline-faces)
    929 
    930 (defface doom-modeline-meow-insert-state
    931   '((t (:inherit doom-modeline-evil-insert-state)))
    932   "Face for the insert state in meow-edit indicator."
    933   :group 'doom-modeline-faces)
    934 
    935 (defface doom-modeline-meow-beacon-state
    936   '((t (:inherit doom-modeline-evil-visual-state)))
    937   "Face for the beacon state in meow-edit indicator."
    938   :group 'doom-modeline-faces)
    939 
    940 (defface doom-modeline-meow-motion-state
    941   '((t (:inherit doom-modeline-evil-motion-state)))
    942   "Face for the motion state in meow-edit indicator."
    943   :group 'doom-modeline-faces)
    944 
    945 (defface doom-modeline-meow-keypad-state
    946   '((t (:inherit doom-modeline-evil-operator-state)))
    947   "Face for the keypad state in meow-edit indicator."
    948   :group 'doom-modeline-faces)
    949 
    950 (defface doom-modeline-persp-name
    951   '((t (:inherit (doom-modeline font-lock-comment-face italic))))
    952   "Face for the persp name."
    953   :group 'doom-modeline-faces)
    954 
    955 (defface doom-modeline-persp-buffer-not-in-persp
    956   '((t (:inherit (doom-modeline font-lock-doc-face italic))))
    957   "Face for the buffers which are not in the persp."
    958   :group 'doom-modeline-faces)
    959 
    960 (defface doom-modeline-repl-success
    961   '((t (:inherit doom-modeline-info)))
    962   "Face for REPL success state."
    963   :group 'doom-modeline-faces)
    964 
    965 (defface doom-modeline-repl-warning
    966   '((t (:inherit doom-modeline-warning)))
    967   "Face for REPL warning state."
    968   :group 'doom-modeline-faces)
    969 
    970 (defface doom-modeline-lsp-success
    971   '((t (:inherit doom-modeline-info)))
    972   "Face for LSP success state."
    973   :group 'doom-modeline-faces)
    974 
    975 (defface doom-modeline-lsp-warning
    976   '((t (:inherit doom-modeline-warning)))
    977   "Face for LSP warning state."
    978   :group 'doom-modeline-faces)
    979 
    980 (defface doom-modeline-lsp-error
    981   '((t (:inherit doom-modeline-urgent)))
    982   "Face for LSP error state."
    983   :group 'doom-modeline-faces)
    984 
    985 (defface doom-modeline-lsp-running
    986   '((t (:inherit (doom-modeline compilation-mode-line-run) :weight normal :slant normal)))
    987   "Face for LSP running state."
    988   :group 'doom-modeline-faces)
    989 
    990 (defface doom-modeline-battery-charging
    991   '((t (:inherit doom-modeline-info)))
    992   "Face for battery charging status."
    993   :group 'doom-modeline-faces)
    994 
    995 (defface doom-modeline-battery-full
    996   '((t (:inherit doom-modeline-info)))
    997   "Face for battery full status."
    998   :group 'doom-modeline-faces)
    999 
   1000 (defface doom-modeline-battery-normal
   1001   '((t (:inherit (doom-modeline mode-line))))
   1002   "Face for battery normal status."
   1003   :group 'doom-modeline-faces)
   1004 
   1005 (defface doom-modeline-battery-warning
   1006   '((t (:inherit doom-modeline-warning)))
   1007   "Face for battery warning status."
   1008   :group 'doom-modeline-faces)
   1009 
   1010 (defface doom-modeline-battery-critical
   1011   '((t (:inherit doom-modeline-urgent)))
   1012   "Face for battery critical status."
   1013   :group 'doom-modeline-faces)
   1014 
   1015 (defface doom-modeline-battery-error
   1016   '((t (:inherit doom-modeline-urgent)))
   1017   "Face for battery error status."
   1018   :group 'doom-modeline-faces)
   1019 
   1020 (defface doom-modeline-buffer-timemachine
   1021   '((t (:inherit doom-modeline-buffer-file :slant italic)))
   1022   "Face for timemachine status."
   1023   :group 'doom-modeline-faces)
   1024 
   1025 (defface doom-modeline-time
   1026   '((t (:inherit doom-modeline)))
   1027   "Face for display time."
   1028   :group 'doom-modeline-faces)
   1029 
   1030 (defface doom-modeline-compilation
   1031   '((t (:inherit doom-modeline-warning :slant italic :height 0.9)))
   1032   "Face for compilation progress."
   1033   :group 'doom-modeline-faces)
   1034 
   1035 ;;
   1036 ;; Externals
   1037 ;;
   1038 
   1039 (defvar mode-line-right-align-edge)
   1040 
   1041 (declare-function doom-modeline-shorten-irc "doom-modeline-segments")
   1042 (declare-function face-remap-remove-relative "face-remap")
   1043 (declare-function ffip-project-root "ext:find-file-in-project")
   1044 (declare-function project-root "project")
   1045 (declare-function projectile-project-root "ext:projectile")
   1046 
   1047 
   1048 ;;
   1049 ;; Utilities
   1050 ;;
   1051 
   1052 (defun doom-modeline-add-font-lock ()
   1053   "Fontify `doom-modeline-def-*' statements."
   1054   (font-lock-add-keywords
   1055    'emacs-lisp-mode
   1056    '(("(\\(doom-modeline-def-.+\\)\\_> +\\(.*?\\)\\_>"
   1057       (1 font-lock-keyword-face)
   1058       (2 font-lock-constant-face)))))
   1059 (doom-modeline-add-font-lock)
   1060 
   1061 (defun doom-modeline-add-imenu ()
   1062   "Add to `imenu' index."
   1063   (add-to-list
   1064    'imenu-generic-expression
   1065    '("Modelines"
   1066      "^\\s-*(\\(doom-modeline-def-modeline\\)\\s-+\\(\\(?:\\sw\\|\\s_\\|\\s'\\|\\\\.\\)+\\)"
   1067      2))
   1068   (add-to-list
   1069    'imenu-generic-expression
   1070    '("Segments"
   1071      "^\\s-*(\\(doom-modeline-def-segment\\)\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)"
   1072      2))
   1073   (add-to-list
   1074    'imenu-generic-expression
   1075    '("Envs"
   1076      "^\\s-*(\\(doom-modeline-def-env\\)\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)"
   1077      2)))
   1078 
   1079 
   1080 ;;
   1081 ;; Core helpers
   1082 ;;
   1083 
   1084 ;; FIXME #183: Force to calculate mode-line height
   1085 ;; @see https://github.com/seagle0128/doom-modeline/issues/183
   1086 ;; @see https://github.com/seagle0128/doom-modeline/issues/483
   1087 (unless (>= emacs-major-version 29)
   1088   (eval-and-compile
   1089     (defun doom-modeline-redisplay (&rest _)
   1090       "Call `redisplay' to trigger mode-line height calculations.
   1091 
   1092 Certain functions, including e.g. `fit-window-to-buffer', base
   1093 their size calculations on values which are incorrect if the
   1094 mode-line has a height different from that of the `default' face
   1095 and certain other calculations have not yet taken place for the
   1096 window in question.
   1097 
   1098 These calculations can be triggered by calling `redisplay'
   1099 explicitly at the appropriate time and this functions purpose
   1100 is to make it easier to do so.
   1101 
   1102 This function is like `redisplay' with non-nil FORCE argument,
   1103 but it will only trigger a redisplay when there is a non nil
   1104 `mode-line-format' and the height of the mode-line is different
   1105 from that of the `default' face. This function is intended to be
   1106 used as an advice to window creation functions."
   1107       (when (and (bound-and-true-p doom-modeline-mode)
   1108                  mode-line-format
   1109                  (/= (frame-char-height) (window-mode-line-height)))
   1110         (redisplay t))))
   1111   (advice-add #'fit-window-to-buffer :before #'doom-modeline-redisplay))
   1112 
   1113 ;; For `flycheck-color-mode-line'
   1114 (with-eval-after-load 'flycheck-color-mode-line
   1115   (defvar flycheck-color-mode-line-face-to-color)
   1116   (setq flycheck-color-mode-line-face-to-color 'doom-modeline))
   1117 
   1118 (defun doom-modeline-icon-displayable-p ()
   1119   "Return non-nil if icons are displayable."
   1120   (and doom-modeline-icon (featurep 'nerd-icons)))
   1121 
   1122 (defun doom-modeline-mwheel-available-p ()
   1123   "Whether mouse wheel is available."
   1124   (and (featurep 'mwheel) (bound-and-true-p mouse-wheel-mode)))
   1125 
   1126 ;; Keep `doom-modeline-current-window' up-to-date
   1127 (defun doom-modeline--selected-window ()
   1128   "Get the selected window."
   1129   (frame-selected-window))
   1130 
   1131 (defvar doom-modeline-current-window (doom-modeline--selected-window)
   1132   "Current window.")
   1133 
   1134 (defun doom-modeline--active ()
   1135   "Whether is an active window."
   1136   (unless (and (bound-and-true-p mini-frame-frame)
   1137                (and (frame-live-p mini-frame-frame)
   1138                     (frame-visible-p mini-frame-frame)))
   1139     (and doom-modeline-current-window
   1140          (eq (doom-modeline--selected-window) doom-modeline-current-window))))
   1141 
   1142 (defvar-local doom-modeline--limited-width-p nil)
   1143 
   1144 (defun doom-modeline--segment-visible (name)
   1145   "Whether the segment NAME should be displayed."
   1146   (and
   1147    (or (doom-modeline--active)
   1148        (member name doom-modeline-always-visible-segments))
   1149    (not doom-modeline--limited-width-p)))
   1150 
   1151 (defun doom-modeline-set-selected-window (&rest _)
   1152   "Set `doom-modeline-current-window' appropriately."
   1153   (let ((win (doom-modeline--selected-window)))
   1154     (setq doom-modeline-current-window
   1155           (if (minibuffer-window-active-p win)
   1156               (minibuffer-selected-window)
   1157             win))))
   1158 
   1159 (defun doom-modeline-unset-selected-window ()
   1160   "Unset `doom-modeline-current-window' appropriately."
   1161   (setq doom-modeline-current-window nil))
   1162 
   1163 (add-hook 'pre-redisplay-functions #'doom-modeline-set-selected-window)
   1164 
   1165 ;; Ensure modeline is inactive when Emacs is unfocused
   1166 (defvar doom-modeline--remap-faces '(mode-line
   1167                                      mode-line-active
   1168                                      mode-line-emphasis
   1169                                      mode-line-highlight
   1170                                      mode-line-buffer-id
   1171                                      doom-modeline
   1172                                      solaire-mode-line-face
   1173                                      solaire-mode-line-active-face
   1174                                      paradox-mode-line-face
   1175                                      flycheck-color-mode-line-error-face
   1176                                      flycheck-color-mode-line-warning-face
   1177                                      flycheck-color-mode-line-info-face
   1178                                      flycheck-color-mode-line-success-face))
   1179 
   1180 (defvar doom-modeline--remap-face-cookie-alist nil)
   1181 (defun doom-modeline-focus ()
   1182   "Focus mode-line."
   1183   (mapc #'face-remap-remove-relative doom-modeline--remap-face-cookie-alist))
   1184 
   1185 (defun doom-modeline-unfocus ()
   1186   "Unfocus mode-line."
   1187   (dolist (face doom-modeline--remap-faces)
   1188     (add-to-list 'doom-modeline--remap-face-cookie-alist
   1189                  (face-remap-add-relative face 'mode-line-inactive))))
   1190 
   1191 (with-no-warnings
   1192   (if (boundp 'after-focus-change-function)
   1193       (progn
   1194         (defun doom-modeline-focus-change (&rest _)
   1195           (if (frame-focus-state (frame-parent))
   1196               (progn
   1197                 (doom-modeline-focus)
   1198                 ;; HACK: pulse after focusing in the frame to refresh the buffer name.
   1199                 ;; @see https://github.com/seagle0128/doom-modeline/issues/591
   1200                 (when (fboundp 'pulse-momentary-highlight-region)
   1201                   (pulse-momentary-highlight-region 0 0)))
   1202             (doom-modeline-unfocus)))
   1203         (advice-add #'handle-switch-frame :after #'doom-modeline-focus-change)
   1204         (add-function :after after-focus-change-function #'doom-modeline-focus-change))
   1205     (progn
   1206       (add-hook 'focus-in-hook #'doom-modeline-focus)
   1207       (add-hook 'focus-out-hook #'doom-modeline-unfocus))))
   1208 
   1209 
   1210 ;;
   1211 ;; Core
   1212 ;;
   1213 
   1214 (defvar doom-modeline-fn-alist ())
   1215 (defvar doom-modeline-var-alist ())
   1216 
   1217 (defmacro doom-modeline-def-segment (name &rest body)
   1218   "Define a modeline segment NAME with BODY and byte compiles it."
   1219   (declare (indent defun) (doc-string 2))
   1220   (let ((sym (intern (format "doom-modeline-segment--%s" name)))
   1221         (docstring (if (stringp (car body))
   1222                        (pop body)
   1223                      (format "%s modeline segment" name))))
   1224     (cond ((and (symbolp (car body))
   1225                 (not (cdr body)))
   1226            `(add-to-list 'doom-modeline-var-alist (cons ',name ',(car body))))
   1227           (t
   1228            `(progn
   1229               (defun ,sym () ,docstring ,@body)
   1230               (add-to-list 'doom-modeline-fn-alist (cons ',name ',sym))
   1231               ,(unless (bound-and-true-p byte-compile-current-file)
   1232                  `(let (byte-compile-warnings)
   1233                     (unless (and (fboundp 'subr-native-elisp-p)
   1234                                  (subr-native-elisp-p (symbol-function #',sym)))
   1235                       (byte-compile #',sym)))))))))
   1236 
   1237 (defun doom-modeline--prepare-segments (segments)
   1238   "Prepare mode-line `SEGMENTS'."
   1239   (let (forms it)
   1240     (dolist (seg segments)
   1241       (cond ((stringp seg)
   1242              (push seg forms))
   1243             ((symbolp seg)
   1244              (cond ((setq it (alist-get seg doom-modeline-fn-alist))
   1245                     (push (list :eval (list it)) forms))
   1246                    ((setq it (alist-get seg doom-modeline-var-alist))
   1247                     (push it forms))
   1248                    ((error "%s is not a defined segment" seg))))
   1249             ((error "%s is not a valid segment" seg))))
   1250     (nreverse forms)))
   1251 
   1252 (defun doom-modeline-def-modeline (name lhs &optional rhs)
   1253   "Define a modeline format and byte-compiles it.
   1254 NAME is a symbol to identify it (used by `doom-modeline' for retrieval).
   1255 LHS and RHS are lists of symbols of modeline segments defined with
   1256 `doom-modeline-def-segment'.
   1257 
   1258 Example:
   1259   (doom-modeline-def-modeline \\='minimal
   1260     \\='(bar matches \" \" buffer-info)
   1261     \\='(media-info major-mode))
   1262   (doom-modeline-set-modeline \\='minimal t)"
   1263   (let ((sym (intern (format "doom-modeline-format--%s" name)))
   1264         (lhs-forms (doom-modeline--prepare-segments lhs))
   1265         (rhs-forms (doom-modeline--prepare-segments rhs)))
   1266     (defalias sym
   1267       (lambda ()
   1268         (list lhs-forms
   1269               (let* ((rhs-str (format-mode-line (cons "" rhs-forms)))
   1270                      (rhs-width (progn
   1271                                   (add-face-text-property
   1272                                    0 (length rhs-str) 'mode-line t rhs-str)
   1273                                   (doom-modeline-string-pixel-width rhs-str))))
   1274                 (propertize
   1275                  " "
   1276                  'face (doom-modeline-face)
   1277                  'display
   1278                  ;; Backport from `mode-line-right-align-edge' in 30
   1279                  (if (and (display-graphic-p)
   1280                            (not (eq mode-line-right-align-edge 'window)))
   1281 		              `(space :align-to (- ,mode-line-right-align-edge
   1282                                            (,rhs-width)))
   1283 		            `(space :align-to (,(- (window-pixel-width)
   1284                                            (window-scroll-bar-width)
   1285                                            (window-right-divider-width)
   1286                                            (* (or (cdr (window-margins)) 1)
   1287                                               (frame-char-width))
   1288                                            (pcase mode-line-right-align-edge
   1289                                              ('right-margin
   1290                                               (or (cdr (window-margins)) 0))
   1291                                              ('right-fringe
   1292                                               (or (cadr (window-fringes)) 0))
   1293                                              (_ 0))
   1294                                            rhs-width))))))
   1295               rhs-forms))
   1296       (concat "Modeline:\n"
   1297               (format "  %s\n  %s"
   1298                       (prin1-to-string lhs)
   1299                       (prin1-to-string rhs))))))
   1300 (put 'doom-modeline-def-modeline 'lisp-indent-function 'defun)
   1301 
   1302 (defun doom-modeline (key)
   1303   "Return a mode-line configuration associated with KEY (a symbol).
   1304 Throws an error if it doesn't exist."
   1305   (let ((fn (intern-soft (format "doom-modeline-format--%s" key))))
   1306     (when (functionp fn)
   1307       `(:eval (,fn)))))
   1308 
   1309 (defun doom-modeline-set-modeline (key &optional default)
   1310   "Set the modeline format. Does nothing if the modeline KEY doesn't exist.
   1311 If DEFAULT is non-nil, set the default mode-line for all buffers."
   1312   (when-let* ((modeline (doom-modeline key)))
   1313     (setf (if default
   1314               (default-value 'mode-line-format)
   1315             mode-line-format)
   1316           (list "%e" modeline))))
   1317 
   1318 ;;
   1319 ;; Helpers
   1320 ;;
   1321 
   1322 (defconst doom-modeline-ellipsis
   1323   (if (char-displayable-p ?…) "…" "...")
   1324   "Ellipsis.")
   1325 
   1326 (defsubst doom-modeline-spc ()
   1327   "Whitespace."
   1328   (propertize " " 'face (doom-modeline-face)))
   1329 
   1330 (defsubst doom-modeline-wspc ()
   1331   "Wide Whitespace."
   1332   (propertize "  " 'face (doom-modeline-face)))
   1333 
   1334 (defsubst doom-modeline-vspc ()
   1335   "Thin whitespace."
   1336   (propertize " "
   1337               'face (doom-modeline-face)
   1338               'display '((space :relative-width 0.5))))
   1339 
   1340 (defun doom-modeline-face (&optional face inactive-face)
   1341   "Display FACE in active window, and INACTIVE-FACE in inactive window.
   1342 IF FACE is nil, `mode-line' face will be used.
   1343 If INACTIVE-FACE is nil, `mode-line-inactive' face will be used."
   1344   (if (doom-modeline--active)
   1345       (or (and (facep face) `(:inherit (doom-modeline ,face)))
   1346           (and (facep 'mode-line-active) '(:inherit (doom-modeline mode-line-active)))
   1347           '(:inherit (doom-modeline mode-line)))
   1348     (or (and (facep inactive-face) `(:inherit (doom-modeline ,inactive-face)))
   1349         '(:inherit (doom-modeline mode-line-inactive)))))
   1350 
   1351 (defun doom-modeline-string-pixel-width (str)
   1352   "Return the width of STR in pixels."
   1353   (if (fboundp 'string-pixel-width)
   1354       (string-pixel-width str)
   1355     (* (string-width str) (window-font-width nil 'mode-line)
   1356        (if (display-graphic-p) 1.05 1.0))))
   1357 
   1358 (defun doom-modeline--font-height ()
   1359   "Calculate the actual char height of the mode-line."
   1360   (let ((height (face-attribute 'mode-line :height))
   1361         (char-height (window-font-height nil 'mode-line)))
   1362     (round
   1363      (* 1.0 (cond ((integerp height) (/ height 10))
   1364                   ((floatp height) (* height char-height))
   1365                   (t char-height))))))
   1366 
   1367 (defun doom-modeline--original-value (sym)
   1368   "Return the original value for SYM, if any.
   1369 
   1370 If SYM has an original value, return it in a list. Return nil
   1371 otherwise."
   1372   (let* ((orig-val-expr (get sym 'standard-value)))
   1373     (when (consp orig-val-expr)
   1374       (ignore-errors
   1375         (list
   1376          (eval (car orig-val-expr)))))))
   1377 
   1378 (defun doom-modeline-add-variable-watcher (symbol watch-function)
   1379   "Cause WATCH-FUNCTION to be called when SYMBOL is set if possible.
   1380 
   1381 See docs of `add-variable-watcher'."
   1382   (when (fboundp 'add-variable-watcher)
   1383     (add-variable-watcher symbol watch-function)))
   1384 
   1385 (defun doom-modeline-propertize-icon (icon &optional face)
   1386   "Propertize the ICON with the specified FACE.
   1387 
   1388 The face should be the first attribute, or the font family may be overridden.
   1389 So convert the face \":family XXX :height XXX :inherit XXX\" to
   1390 \":inherit XXX :family XXX :height XXX\".
   1391 See https://github.com/seagle0128/doom-modeline/issues/301."
   1392   (when icon
   1393     (if (doom-modeline-icon-displayable-p)
   1394         (when-let* ((props (get-text-property 0 'face icon)))
   1395           (when (listp props)
   1396             (cl-destructuring-bind (&key family height inherit &allow-other-keys) props
   1397               (propertize icon 'face `(:inherit (doom-modeline ,(or face inherit props))
   1398                                                 :family  ,(or family "")
   1399                                                 :height  ,(or height 1.0))))))
   1400       (propertize icon 'face `(:inherit (doom-modeline ,face))))))
   1401 
   1402 (defun doom-modeline-icon (icon-set icon-name unicode text &rest args)
   1403   "Display icon of ICON-NAME with ARGS in mode-line.
   1404 
   1405 ICON-SET includes `ipsicon', `octicon', `pomicon', `powerline', `faicon',
   1406 `wicon', `sucicon', `devicon', `codicon', `flicon' and `mdicon', etc.
   1407 UNICODE is the unicode char fallback. TEXT is the ASCII char fallback.
   1408 ARGS is same as `nerd-icons-octicon' and others."
   1409   (let ((face `(:inherit (doom-modeline
   1410                           ,(or (plist-get args :face) 'mode-line)))))
   1411     (cond
   1412      ;; Icon
   1413      ((and (doom-modeline-icon-displayable-p)
   1414            icon-name
   1415            (not (string-empty-p icon-name)))
   1416       (if-let* ((func (nerd-icons--function-name icon-set))
   1417                 (icon (and (fboundp func)
   1418                            (apply func icon-name args))))
   1419           (doom-modeline-propertize-icon icon face)
   1420         ""))
   1421      ;; Unicode fallback
   1422      ((and doom-modeline-unicode-fallback
   1423            unicode
   1424            (not (string-empty-p unicode))
   1425            (char-displayable-p (string-to-char unicode)))
   1426       (propertize unicode 'face face))
   1427      ;; ASCII text
   1428      (text
   1429       (propertize text 'face face))
   1430      ;; Fallback
   1431      (t ""))))
   1432 
   1433 (defun doom-modeline-icon-for-buffer ()
   1434   "Get the formatted icon for the current buffer."
   1435   (nerd-icons-icon-for-buffer))
   1436 
   1437 (defun doom-modeline-display-icon (icon)
   1438   "Display ICON in mode-line."
   1439   (if (doom-modeline--active)
   1440       icon
   1441     (doom-modeline-propertize-icon icon 'mode-line-inactive)))
   1442 
   1443 (defun doom-modeline-display-text (text)
   1444   "Display TEXT in mode-line."
   1445   (if (doom-modeline--active)
   1446       text
   1447     (propertize text 'face `(:inherit (mode-line-inactive
   1448                                        ,(get-text-property 0 'face text))))))
   1449 
   1450 (defun doom-modeline-vcs-name ()
   1451   "Display the vcs name."
   1452   (and vc-mode (cadr (split-string (string-trim vc-mode) "^[A-Z]+[-:]+"))))
   1453 
   1454 (defun doom-modeline--create-bar-image (face width height)
   1455   "Create the bar image.
   1456 
   1457 Use FACE for the bar, WIDTH and HEIGHT are the image size in pixels."
   1458   (when (and (image-type-available-p 'pbm)
   1459              (numberp width) (> width 0)
   1460              (numberp height) (> height 0))
   1461     (propertize
   1462      " " 'display
   1463      (let ((color (or (face-background face nil t) "None")))
   1464        (ignore-errors
   1465          (create-image
   1466           (concat (format "P1\n%i %i\n" width height)
   1467                   (make-string (* width height) ?1)
   1468                   "\n")
   1469           'pbm t :scale 1 :foreground color :ascent 'center))))))
   1470 
   1471 (defun doom-modeline--create-hud-image
   1472     (face1 face2 width height top-margin bottom-margin)
   1473   "Create the hud image.
   1474 
   1475 Use FACE1 for the bar, FACE2 for the background.
   1476 WIDTH and HEIGHT are the image size in pixels.
   1477 TOP-MARGIN and BOTTOM-MARGIN are the size of the margin above and below the bar,
   1478 respectively."
   1479   (when (and (display-graphic-p)
   1480              (image-type-available-p 'pbm)
   1481              (numberp width) (> width 0)
   1482              (numberp height) (> height 0))
   1483     (let ((min-height (min height doom-modeline-hud-min-height)))
   1484       (unless (> (- height top-margin bottom-margin) min-height)
   1485         (let ((margin (- height min-height)))
   1486           (setq top-margin (/ (* margin top-margin) (+ top-margin bottom-margin))
   1487                 bottom-margin (- margin top-margin)))))
   1488     (propertize
   1489      " " 'display
   1490      (let ((color1 (or (face-background face1 nil t) "None"))
   1491            (color2 (or (face-background face2 nil t) "None")))
   1492        (create-image
   1493         (concat
   1494          (format "P1\n%i %i\n" width height)
   1495          (make-string (* top-margin width) ?0)
   1496          (make-string (* (- height top-margin bottom-margin) width) ?1)
   1497          (make-string (* bottom-margin width) ?0)
   1498          "\n")
   1499         'pbm t :foreground color1 :background color2 :ascent 'center)))))
   1500 
   1501 ;; Check whether `window-total-width' is smaller than the limit
   1502 (defun doom-modeline-window-size-change-function (&rest _)
   1503   "Function for `window-size-change-functions'."
   1504   (setq doom-modeline--limited-width-p
   1505         (cond
   1506          ((integerp doom-modeline-window-width-limit)
   1507           (<= (window-total-width) doom-modeline-window-width-limit))
   1508          ((floatp doom-modeline-window-width-limit)
   1509           (<= (/ (window-total-width) (frame-width) 1.0)
   1510               doom-modeline-window-width-limit)))))
   1511 
   1512 (add-hook 'after-revert-hook #'doom-modeline-window-size-change-function)
   1513 (add-hook 'buffer-list-update-hook #'doom-modeline-window-size-change-function)
   1514 (add-hook 'window-size-change-functions #'doom-modeline-window-size-change-function)
   1515 
   1516 (defvar-local doom-modeline--project-root nil)
   1517 (defun doom-modeline--project-root ()
   1518   "Get the path to the project root.
   1519 Return nil if no project was found."
   1520   (or doom-modeline--project-root
   1521       (setq doom-modeline--project-root
   1522             (cond
   1523              ((and (memq doom-modeline-project-detection '(auto ffip))
   1524                    (fboundp 'ffip-project-root))
   1525               (let ((inhibit-message t))
   1526                 (ffip-project-root)))
   1527              ((and (memq doom-modeline-project-detection '(auto projectile))
   1528                    (bound-and-true-p projectile-mode))
   1529               (projectile-project-root))
   1530              ((and (memq doom-modeline-project-detection '(auto project))
   1531                    (fboundp 'project-current))
   1532               (when-let* ((project (project-current)))
   1533                 (expand-file-name
   1534                  (if (fboundp 'project-root)
   1535                      (project-root project)
   1536                    (car (with-no-warnings
   1537                           (project-roots project)))))))))))
   1538 
   1539 (doom-modeline-add-variable-watcher
   1540  'doom-modeline-project-detection
   1541  (lambda (_sym val op _where)
   1542    (when (eq op 'set)
   1543      (setq doom-modeline-project-detection val)
   1544      (dolist (buf (buffer-list))
   1545        (with-current-buffer buf
   1546          (setq doom-modeline--project-root nil)
   1547          (and buffer-file-name (revert-buffer t t)))))))
   1548 
   1549 (defun doom-modeline-project-p ()
   1550   "Check if the file is in a project."
   1551   (doom-modeline--project-root))
   1552 
   1553 (defun doom-modeline-project-root ()
   1554   "Get the path to the root of your project.
   1555 Return `default-directory' if no project was found."
   1556   (abbreviate-file-name
   1557    (or (doom-modeline--project-root) default-directory)))
   1558 
   1559 (defun doom-modeline--format-buffer-file-name ()
   1560   "Get and format the buffer file name."
   1561   (let ((buffer-file-name (file-local-name
   1562                            (or (buffer-file-name (buffer-base-buffer)) ""))))
   1563     (or (and doom-modeline-buffer-file-name-function
   1564              (funcall doom-modeline-buffer-file-name-function buffer-file-name))
   1565         buffer-file-name)))
   1566 
   1567 (defun doom-modeline--format-buffer-file-truename (b-f-n)
   1568   "Get and format buffer file truename via B-F-N."
   1569   (let ((buffer-file-truename (file-local-name
   1570                                (or (file-truename b-f-n) ""))))
   1571     (or (and doom-modeline-buffer-file-truename-function
   1572              (funcall doom-modeline-buffer-file-truename-function buffer-file-truename))
   1573         buffer-file-truename)))
   1574 
   1575 (defun doom-modeline-buffer-file-name ()
   1576   "Propertize file name based on `doom-modeline-buffer-file-name-style'."
   1577   (let* ((buffer-file-name (doom-modeline--format-buffer-file-name))
   1578          (buffer-file-truename (doom-modeline--format-buffer-file-truename buffer-file-name))
   1579          (file-name
   1580           (pcase doom-modeline-buffer-file-name-style
   1581             ('auto
   1582              (if (doom-modeline-project-p)
   1583                  (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename 'shrink 'shrink 'hide)
   1584                (propertize "%b" 'face 'doom-modeline-buffer-file)))
   1585             ('truncate-upto-project
   1586              (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename 'shrink))
   1587             ('truncate-from-project
   1588              (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename nil 'shrink))
   1589             ('truncate-with-project
   1590              (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename 'shrink 'shrink 'hide))
   1591             ('truncate-except-project
   1592              (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename 'shrink 'shrink))
   1593             ('truncate-upto-root
   1594              (doom-modeline--buffer-file-name-truncate buffer-file-name buffer-file-truename))
   1595             ('truncate-all
   1596              (doom-modeline--buffer-file-name-truncate buffer-file-name buffer-file-truename t))
   1597             ('truncate-nil
   1598              (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename))
   1599             ('relative-to-project
   1600              (doom-modeline--buffer-file-name-relative buffer-file-name buffer-file-truename))
   1601             ('relative-from-project
   1602              (doom-modeline--buffer-file-name buffer-file-name buffer-file-truename nil nil 'hide))
   1603             ('file-name
   1604              (propertize (file-name-nondirectory buffer-file-name)
   1605                          'face 'doom-modeline-buffer-file))
   1606             ('file-name-with-project
   1607              (format "%s|%s"
   1608                      (propertize (file-name-nondirectory
   1609                                   (directory-file-name (file-local-name (doom-modeline-project-root))))
   1610                                  'face 'doom-modeline-project-dir)
   1611                      (propertize (file-name-nondirectory buffer-file-name)
   1612                                  'face 'doom-modeline-buffer-file)))
   1613             ((or 'buffer-name _)
   1614              (propertize "%b" 'face 'doom-modeline-buffer-file)))))
   1615     (propertize (if (string-empty-p file-name)
   1616                     (propertize "%b" 'face 'doom-modeline-buffer-file)
   1617                   file-name)
   1618                 'mouse-face 'mode-line-highlight
   1619                 'help-echo (concat buffer-file-truename
   1620                                    (unless (string= (file-name-nondirectory buffer-file-truename)
   1621                                                     (buffer-name))
   1622                                      (concat "\n" (buffer-name)))
   1623                                    "\nmouse-1: Previous buffer\nmouse-3: Next buffer")
   1624                 'local-map mode-line-buffer-identification-keymap)))
   1625 
   1626 (defun doom-modeline--buffer-file-name-truncate (file-path true-file-path &optional truncate-tail)
   1627   "Propertize file name that truncates every dir along path.
   1628 
   1629 If TRUNCATE-TAIL is t also truncate the parent directory of the file."
   1630   (let ((dirs (shrink-path-prompt (file-name-directory true-file-path))))
   1631     (if (null dirs)
   1632         (propertize "%b" 'face 'doom-modeline-buffer-file)
   1633       (let ((dirname (car dirs))
   1634             (basename (cdr dirs)))
   1635         (concat (propertize (concat dirname
   1636                                     (if truncate-tail (substring basename 0 1) basename)
   1637                                     "/")
   1638                             'face 'doom-modeline-project-root-dir)
   1639                 (propertize (file-name-nondirectory file-path)
   1640                             'face 'doom-modeline-buffer-file))))))
   1641 
   1642 (defun doom-modeline--buffer-file-name-relative (_file-path true-file-path &optional include-project)
   1643   "Propertize file name showing directories relative to project's root only.
   1644 
   1645 If INCLUDE-PROJECT is non-nil, the project path will be included."
   1646   (let ((root (file-local-name (doom-modeline-project-root))))
   1647     (if (null root)
   1648         (propertize "%b" 'face 'doom-modeline-buffer-file)
   1649       (let ((relative-dirs (file-relative-name (file-name-directory true-file-path)
   1650                                                (if include-project (concat root "../") root))))
   1651         (and (equal "./" relative-dirs) (setq relative-dirs ""))
   1652         (concat (propertize relative-dirs 'face 'doom-modeline-buffer-path)
   1653                 (propertize (file-name-nondirectory true-file-path)
   1654                             'face 'doom-modeline-buffer-file))))))
   1655 
   1656 (defun doom-modeline--buffer-file-name (file-path
   1657                                         true-file-path
   1658                                         &optional
   1659                                         truncate-project-root-parent
   1660                                         truncate-project-relative-path
   1661                                         hide-project-root-parent)
   1662   "Propertize buffer name given by FILE-PATH or TRUE-FILE-PATH.
   1663 
   1664 If TRUNCATE-PROJECT-ROOT-PARENT is non-nil will be saved by truncating project
   1665 root parent down fish-shell style.
   1666 
   1667 Example:
   1668   ~/Projects/FOSS/emacs/lisp/comint.el => ~/P/F/emacs/lisp/comint.el
   1669 
   1670 If TRUNCATE-PROJECT-RELATIVE-PATH is non-nil will be saved by truncating project
   1671 relative path down fish-shell style.
   1672 
   1673 Example:
   1674   ~/Projects/FOSS/emacs/lisp/comint.el => ~/Projects/FOSS/emacs/l/comint.el
   1675 
   1676 If HIDE-PROJECT-ROOT-PARENT is non-nil will hide project root parent.
   1677 
   1678 Example:
   1679   ~/Projects/FOSS/emacs/lisp/comint.el => emacs/lisp/comint.el"
   1680   (let ((project-root (file-local-name (doom-modeline-project-root))))
   1681     (concat
   1682      ;; Project root parent
   1683      (unless hide-project-root-parent
   1684        (when-let* ((root-path-parent
   1685                     (file-name-directory (directory-file-name project-root))))
   1686          (propertize
   1687           (if (and truncate-project-root-parent
   1688                    (not (string-empty-p root-path-parent))
   1689                    (not (string= root-path-parent "/")))
   1690               (shrink-path--dirs-internal root-path-parent t)
   1691             (abbreviate-file-name root-path-parent))
   1692           'face 'doom-modeline-project-parent-dir)))
   1693      ;; Project directory
   1694      (propertize
   1695       (concat (file-name-nondirectory (directory-file-name project-root)) "/")
   1696       'face 'doom-modeline-project-dir)
   1697      ;; relative path
   1698      (propertize
   1699       (when-let* ((relative-path (file-relative-name
   1700                                   (or (file-name-directory
   1701                                        (if doom-modeline-buffer-file-true-name
   1702                                            true-file-path file-path))
   1703                                       "./")
   1704                                   project-root)))
   1705         (if (string= relative-path "./")
   1706             ""
   1707           (if truncate-project-relative-path
   1708               (substring (shrink-path--dirs-internal relative-path t) 1)
   1709             relative-path)))
   1710       'face 'doom-modeline-buffer-path)
   1711      ;; File name
   1712      (propertize (file-name-nondirectory file-path)
   1713                  'face 'doom-modeline-buffer-file))))
   1714 
   1715 (provide 'doom-modeline-core)
   1716 
   1717 ;;; doom-modeline-core.el ends here