Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add truncate style for path #279

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Dec 23, 2020
Merged
2 changes: 1 addition & 1 deletion Cask
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
(files "*.el" "*.org" "banners")

(development
(depends-on "page-break-lines"))
(depends-on "page-break-lines"))
198 changes: 191 additions & 7 deletions dashboard-widgets.el
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,25 @@ If nil it is disabled. Possible values for list-type are:
:type '(repeat (alist :key-type symbol :value-type string))
:group 'dashboard)

(defcustom dashboard-path-style nil
"Style to display path."
:type '(choice
(const :tag "No specify" nil)
(const :tag "Truncate the beginning part of the path" truncate-beginning)
(const :tag "Truncate the middle part of the path" truncate-middle)
(const :tag "Truncate the end part of the path" truncate-end))
:group 'dashboard)

(defcustom dashboard-path-max-length 70
"Maximum length for path to display."
:type 'integer
:group 'dashboard)

(defcustom dashboard-path-shorten-string "..."
"String the that displays in the center of the path."
:type 'string
:group 'dashboard)

(defvar recentf-list nil)

(defvar dashboard-buffer-name)
Expand Down Expand Up @@ -633,23 +652,153 @@ WIDGET-PARAMS are passed to the \"widget-create\" function."
(insert (propertize footer 'face 'dashboard-footer))
(insert "\n"))))

;;
;; Truncate
;;
(defun dashboard-f-filename (path)
"Return file name from PATH."
(file-name-nondirectory path))

(defun dashboard-f-base (path)
"Return directory name from PATH."
(file-name-nondirectory (directory-file-name (file-name-directory path))))

(defun dashboard-shorten-path-beginning (path)
"Shorten PATH from beginning if exceeding maximum length."
(let* ((len-path (length path)) (len-rep (length dashboard-path-shorten-string))
(len-total (- dashboard-path-max-length len-rep))
front)
(if (<= len-path dashboard-path-max-length) path
(setq front (substring path (- len-path len-total) len-path))
(concat dashboard-path-shorten-string front))))

(defun dashboard-shorten-path-middle (path)
"Shorten PATH from middle if exceeding maximum length."
(let* ((len-path (length path)) (len-rep (length dashboard-path-shorten-string))
(len-total (- dashboard-path-max-length len-rep))
(center (/ len-total 2))
(end-back center)
(start-front (- len-path center))
back front)
(if (<= len-path dashboard-path-max-length) path
(setq back (substring path 0 end-back)
front (substring path start-front len-path))
(concat back dashboard-path-shorten-string front))))

(defun dashboard-shorten-path-end (path)
"Shorten PATH from end if exceeding maximum length."
(let* ((len-path (length path)) (len-rep (length dashboard-path-shorten-string))
(len-total (- dashboard-path-max-length len-rep))
back)
(if (<= len-path dashboard-path-max-length) path
(setq back (substring path 0 len-total))
(concat back dashboard-path-shorten-string))))

(defun dashboard-shorten-path (path)
"Shorten the PATH."
(setq path (abbreviate-file-name path))
(cl-case dashboard-path-style
(truncate-beginning (dashboard-shorten-path-beginning path))
(truncate-middle (dashboard-shorten-path-middle path))
(truncate-end (dashboard-shorten-path-end path))
(t path)))

(defun dashboard-shorten-paths (paths alist)
"Shorten all path from PATHS and store it to ALIST."
(let (lst-display abbrev (index 0))
(setf (symbol-value alist) nil) ; reset
(dolist (item paths)
(setq abbrev (dashboard-shorten-path item)
;; Add salt here, and use for extraction.
;; See function `dashboard-extract-key-path-alist'.
abbrev (format "%s|%s" index abbrev))
;; store `abbrev' as id; and `item' with value
(push (cons abbrev item) (symbol-value alist))
(push abbrev lst-display)
(cl-incf index))
(reverse lst-display)))

(defun dashboard-extract-key-path-alist (key alist)
"Remove salt from KEY, and return true shorten path from ALIST."
(let* ((key (car (assoc key alist))) (split (split-string key "|")))
(nth 1 split)))

(defun dashboard-expand-path-alist (key alist)
"Get the full path (un-shorten) using KEY from ALIST."
(cdr (assoc key alist)))

(defun dashboard--generate-align-format (fmt len)
"Return FMT after inserting align LEN."
(let ((pos (1+ (string-match-p "%s" fmt))))
(concat (substring fmt 0 pos)
(concat "-" (number-to-string len))
(substring fmt pos (length fmt)))))

(defun dashboard--get-align-length (alist &optional dir)
"Return maximum align length from ALIST.

If optional argument DIR is non-nil; align with directory name instead."
(let ((align-length -1) path len-path)
(dolist (item alist)
(setq path (cdr item)
path (if dir (dashboard-f-base path) (dashboard-f-filename path))
len-path (length path)
align-length (max len-path align-length)))
align-length))

;;
;; Recentf
;;
(defcustom dashboard-recentf-show-base nil
"Show the base file name infront of it's path."
:type '(choice
(const :tag "Don't show the base infront" nil)
(const :tag "Respect format" t)
(const :tag "Align the from base" align))
:group 'dashboard)

(defcustom dashboard-recentf-item-format "%s %s"
"Format to use when showing the base of the file name."
:type 'string
:group 'dashboard)

(defvar dashboard-recentf-alist nil
"Alist records shorten's recent files and it's full paths.")

(defvar dashboard--recentf-cache-item-format nil
"Cache to record the new generated align format.")

(defun dashboard-insert-recents (list-size)
"Add the list of LIST-SIZE items from recently edited files."
(setq dashboard--recentf-cache-item-format nil)
(recentf-mode)
(dashboard-insert-section
"Recent Files:"
recentf-list
(dashboard-shorten-paths recentf-list 'dashboard-recentf-alist)
list-size
(dashboard-get-shortcut 'recents)
`(lambda (&rest ignore) (find-file-existing ,el))
(abbreviate-file-name el)))
`(lambda (&rest ignore)
(find-file-existing (dashboard-expand-path-alist ,el dashboard-recentf-alist)))
(let* ((file (dashboard-expand-path-alist el dashboard-recentf-alist))
(filename (dashboard-f-filename file))
(path (dashboard-extract-key-path-alist el dashboard-recentf-alist)))
(cl-case dashboard-recentf-show-base
(align
(unless dashboard--recentf-cache-item-format
(let* ((len-align (dashboard--get-align-length dashboard-recentf-alist))
(new-fmt (dashboard--generate-align-format
dashboard-recentf-item-format len-align)))
(setq dashboard--recentf-cache-item-format new-fmt)))
(format dashboard--recentf-cache-item-format filename path))
(nil (format dashboard-recentf-item-format filename path))
(t path)))))

;;
;; Bookmarks
;;
(defvar dashboard-bookmark-alist nil
"Alist records shorten's recent files and it's full paths.")

(defun dashboard-insert-bookmarks (list-size)
"Add the list of LIST-SIZE items of bookmarks."
(require 'bookmark)
Expand All @@ -661,7 +810,7 @@ WIDGET-PARAMS are passed to the \"widget-create\" function."
`(lambda (&rest ignore) (bookmark-jump ,el))
(let ((file (bookmark-get-filename el)))
(if file
(format "%s - %s" el (abbreviate-file-name file))
(format "%s - %s" el (dashboard-shorten-path file))
el))))

;;
Expand All @@ -676,16 +825,51 @@ switch to."
:type '(choice (const :tag "Default" nil) function)
:group 'dashboard)

(defcustom dashboard-projects-show-base nil
"Show the project name infront of it's path."
:type '(choice
(const :tag "Don't show the base infront" nil)
(const :tag "Respect format" t)
(const :tag "Align the from base" align))
:group 'dashboard)

(defcustom dashboard-projects-item-format "%s %s"
"Format to use when showing the base of the project name."
:type 'string
:group 'dashboard)

(defvar dashboard-projects-alist nil
"Alist records the shorten's project paths and it's full paths.")

(defvar dashboard--projects-cache-item-format nil
"Cache to record the new generated align format.")

(defun dashboard-insert-projects (list-size)
"Add the list of LIST-SIZE items of projects."
(setq dashboard--projects-cache-item-format nil)
(dashboard-insert-section
"Projects:"
(dashboard-subseq (dashboard-projects-backend-load-projects) 0 list-size)
(dashboard-shorten-paths
(dashboard-subseq (dashboard-projects-backend-load-projects) 0 list-size)
'dashboard-projects-alist)
list-size
(dashboard-get-shortcut 'projects)
`(lambda (&rest ignore)
(funcall (dashboard-projects-backend-switch-function) ,el))
(abbreviate-file-name el)))
(funcall (dashboard-projects-backend-switch-function)
(dashboard-expand-path-alist ,el dashboard-projects-alist)))
(let* ((file (dashboard-expand-path-alist el dashboard-projects-alist))
(filename (dashboard-f-base file))
(path (dashboard-extract-key-path-alist el dashboard-projects-alist)))
(cl-case dashboard-projects-show-base
(align
(unless dashboard--projects-cache-item-format
(let* ((len-align (dashboard--get-align-length dashboard-projects-alist t))
(new-fmt (dashboard--generate-align-format
dashboard-projects-item-format len-align)))
(setq dashboard--projects-cache-item-format new-fmt)))
(format dashboard--projects-cache-item-format filename path))
(nil (format dashboard-projects-item-format filename path))
(t path)))))

(defun dashboard-projects-backend-load-projects ()
"Depending on `dashboard-projects-backend' load corresponding backend.
Expand Down