ui/modeline: refactor path builder & add other styles

This brings +doom-modeline-buffer-file-name styles to the new modeline
module, controlled by the +modeline-buffer-path-function variable.

The available functions are:

* +modeline-file-path-with-project: project/src/lib/file.c
* +modeline-file-path-from-project: src/lib/file.c
* +modeline-file-path-truncated-with-project: project/s/l/file.c
* +modeline-file-path-truncated-upto-project: ~/w/project/src/lib/file.c
* +modeline-file-path-truncated-upto-project-root: ~/w/p/s/lib/file.c
* +modeline-file-path-truncated: ~/w/p/s/l/file.c
* +modeline-file-name: file.c

The default is file-path-with-project.
This commit is contained in:
Henrik Lissner 2018-08-22 22:36:44 +02:00
parent 6282526743
commit dc9841b192
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395

View file

@ -27,9 +27,22 @@ modeline.")
"If non-nil, the bar is transparent, and only used to police the height of the "If non-nil, the bar is transparent, and only used to police the height of the
mode-line.") mode-line.")
(defvar +modeline-buffer-path-function #'+modeline-file-path (defvar +modeline-buffer-path-function #'+modeline-file-path-with-project
"The function that returns the buffer name display for file-visiting "A function that returns, in list form, components of the buffer file name
buffers.") display in the mode-line.
Each item should either be a string or a a cons cell whose CAR is the path
component and CDR is the name of a face.
Currently available functions:
+ `+modeline-file-path-with-project': project/src/lib/file.c
+ `+modeline-file-path-from-project': src/lib/file.c
+ `+modeline-file-path-truncated-with-project': project/s/l/file.c
+ `+modeline-file-path-truncated-upto-project': ~/w/project/src/lib/file.c
+ `+modeline-file-path-truncated-upto-project-root': ~/w/p/s/lib/file.c
+ `+modeline-file-path-truncated': ~/w/p/s/l/file.c
+ `+modeline-file-name': file.c")
;; Convenience aliases ;; Convenience aliases
(defvaralias 'mode-line-format-left '+modeline-format-left) (defvaralias 'mode-line-format-left '+modeline-format-left)
@ -236,27 +249,109 @@ buffers.")
concat (if (eq idx len) "\"};" "\",\n"))) concat (if (eq idx len) "\"};" "\",\n")))
'xpm t :ascent 'center))))) 'xpm t :ascent 'center)))))
(defun +modeline-file-path (&optional path) (defun +modeline-build-path (&optional path)
(let ((buffer-file-name (or path buffer-file-name)) "Construct the file path for the `+modeline-buffer-id' segment using
(root (doom-project-root))) `+mdoeline-buffer-path-function'. If the buffer has no `buffer-file-name', just
(cond ((null root) use `buffer-name'."
(propertize "%b" 'face 'doom-modeline-buffer-file)) (let ((buffer-file-name (or path buffer-file-name)))
((or (null buffer-file-name) (if (or (eq major-mode 'dired-mode)
(directory-name-p buffer-file-name)) (null buffer-file-name))
(propertize (abbreviate-file-name (or buffer-file-name default-directory)) (propertize "%s" 'face 'doom-modeline-buffer-path)
'face 'doom-modeline-buffer-path)) (cl-loop for spec in (funcall +modeline-buffer-path-function)
((let* ((true-filename (file-truename buffer-file-name)) if (stringp spec) concat spec
(relative-dirs (file-relative-name (file-name-directory true-filename) else concat (propertize (car spec) 'face (cdr spec))))))
root)))
(if (equal "./" relative-dirs) (setq relative-dirs ""))
(concat (propertize (concat (doom-project-name) "/")
'face 'doom-modeline-buffer-project-root)
(propertize relative-dirs
'face 'doom-modeline-buffer-path)
(propertize (file-name-nondirectory true-filename)
'face 'doom-modeline-buffer-file)))))))
;; TODO Add shrink-path alternatives
;;
;; Buffer file path styles
;;
(defun +modeline-file-path-with-project ()
"Returns the unaltered buffer file path relative to the project root's
parent.
e.g. project/src/lib/file.c"
(let* ((project-root (doom-project-root))
(true-filename (file-truename buffer-file-name))
(relative-dirs (file-relative-name (file-name-directory true-filename)
project-root)))
(list (cons (concat (doom-project-name) "/")
'doom-modeline-buffer-project-root)
(cons (if (equal "./" relative-dirs) "" relative-dirs)
'doom-modeline-buffer-path)
(cons (file-name-nondirectory true-filename)
'doom-modeline-buffer-file))))
(defun +modeline-file-path-from-project ()
"Returns file path relative to the project root.
e.g. src/lib/file.c
Meant for `+modeline-buffer-path-function'."
(cdr (+modeline-file-path-with-project)))
(defun +modeline-file-path-truncated-with-project ()
"Returns file path relative to (and including) project root, with descendent
folders truncated.
e.g. project/s/l/file.c
Meant for `+modeline-buffer-path-function'."
(let* ((parts (+modeline-file-path-with-project))
(dirs (car (nth 1 parts))))
(setcar (nth 1 parts)
(shrink-path--dirs-internal dirs t))
parts))
(defun +modeline-file-path-truncated-upto-project ()
"Returns file path, truncating segments prior to the project.
e.g. ~/w/project/src/lib/file.c
Meant for `+modeline-buffer-path-function'."
(pcase-let
((`(,root-parent ,root ,dir, file)
(shrink-path-file-mixed (doom-project-root)
(file-name-directory buffer-file-name)
buffer-file-name)))
(list (cons root-parent 'font-lock-comment-face)
(cons root 'doom-modeline-buffer-project-root)
(cons (concat "/" dir) 'doom-modeline-buffer-path)
(cons file 'doom-modeline-buffer-file))))
(defun +modeline-file-path-truncated-upto-project-root ()
"Return file path, truncating segemnts prior to (and including) the project
root.
e.g. ~/w/p/src/lib/file.c
Meant for `+modeline-buffer-path-function'."
(let* ((parts (+modeline-file-path-truncated-upto-project))
(root (car (nth 1 parts))))
(setcar (nth 1 parts)
(let ((first (substring root 0 1)))
(if (equal first ".")
(substring root 0 2)
first)))
parts))
(defun +modeline-file-path-truncated ()
"Return absolute file path with all directories truncated.
e.g. ~/w/p/s/l/file.c
Meant for `+modeline-buffer-path-function'."
(pcase-let ((`(,dir . ,file) (shrink-path-prompt buffer-file-name)))
(list (cons dir 'doom-modeline-buffer-path)
(cons file 'doom-modeline-buffer-file))))
(defun +modeline-file-name ()
"Return buffer name.
e.g. file.c
Meant for `+modeline-buffer-path-function'."
(list (cons "%b" 'doom-modeline-buffer-path)))
;; ;;
@ -339,7 +434,7 @@ buffers.")
:init "%b" :init "%b"
:faces t :faces t
(if buffer-file-name (if buffer-file-name
(funcall +modeline-buffer-path-function buffer-file-name) (+modeline-build-path buffer-file-name)
"%b")) "%b"))
(def-modeline-segment! +modeline-buffer-directory (def-modeline-segment! +modeline-buffer-directory