Files
emacs/lisp/dirvish/dirvish-icons.el

139 lines
5.9 KiB
EmacsLisp

;;; dirvish-icons.el --- Icon support for Dirvish -*- lexical-binding: t -*-
;; Copyright (C) 2021-2025 Alex Lu
;; Author : Alex Lu <https://github.com/alexluigit>
;; Keywords: files, convenience
;; Homepage: https://github.com/alexluigit/dirvish
;; SPDX-License-Identifier: GPL-3.0-or-later
;;; Commentary:
;; Integrate `all-the-icons', `nerd-icons', and `vscode-icon' with Dirvish.
;;; Code:
(declare-function all-the-icons-icon-for-file "all-the-icons")
(declare-function all-the-icons-icon-for-dir "all-the-icons")
(declare-function nerd-icons-icon-for-file "nerd-icons")
(declare-function nerd-icons-icon-for-dir "nerd-icons")
(declare-function vscode-icon-can-scale-image-p "vscode-icon")
(declare-function vscode-icon-file "vscode-icon")
(declare-function vscode-icon-dir-exists-p "vscode-icon")
(declare-function vscode-icon-create-image "vscode-icon")
(defvar vscode-icon-size)
(defvar vscode-icon-dir-alist)
(defvar vscode-icon-dir)
(require 'all-the-icons nil t)
(require 'vscode-icon nil t)
(require 'dirvish)
(defvar dirvish--vscode-icon-directory
(concat (and (boundp 'vscode-icon-dir) vscode-icon-dir)
(if (and (fboundp 'vscode-icon-can-scale-image-p) (vscode-icon-can-scale-image-p)) "128/" "23/")))
(defcustom dirvish-icon-delimiter " "
"A string attached to the icon (for both backends)."
:group 'dirvish :type 'string)
(defcustom dirvish-all-the-icons-offset 0.01
"Icon's vertical offset used for `all-the-icons' backend.
Set it to nil to use the default offset from `all-the-icons'."
:group 'dirvish :type '(choice (float nil)))
(defcustom dirvish-all-the-icons-height nil
"Icon height used for `all-the-icons' backend.
The height of the icon is scaled to this value (try 0.8).
Set it to nil to use the default height from `all-the-icons'."
:group 'dirvish :type '(choice (float nil)))
(defcustom dirvish-all-the-icons-palette 'all-the-icons
"Coloring style used for file `all-the-icons' backend.
Values are interpreted as follows:
- all-the-icons, meaning let `all-the-icons.el' to do the coloring.
- A face that is used for all the icons.
- nil, inherit face at point."
:group 'dirvish :type '(choice face symbol (const nil)))
(defcustom dirvish-nerd-icons-offset 0.00
"Icon's vertical offset used for `nerd-icons' backend.
Set it to nil to use the default offset from `nerd-icons'."
:group 'dirvish :type '(choice float (const nil)))
(defcustom dirvish-nerd-icons-height nil
"Icon height used for `nerd-icons' backend.
The height of the icon is scaled to this value (try 0.8).
Set it to nil to use the default height from `nerd-icons'."
:group 'dirvish :type '(choice float (const nil)))
(defcustom dirvish-nerd-icons-palette 'nerd-icons
"Coloring style used for file `nerd-icons' backend.
Values are interpreted as follows:
- nerd-icons, meaning let `nerd-icons.el' to do the coloring.
- A face that is used for all the icons.
- nil, inherit face at point."
:group 'dirvish :type '(choice face symbol (const nil)))
(defcustom dirvish-vscode-icon-size 32
"Icon (image pixel) size used for `vscode-icon' backend.
The value should be a integer between 23 to 128."
:group 'dirvish :type 'integer)
(dirvish-define-attribute all-the-icons
"File icons provided by `all-the-icons.el'."
:width (+ (length dirvish-icon-delimiter) 2)
(let* ((offset `(:v-adjust ,dirvish-all-the-icons-offset))
(height `(:height ,dirvish-all-the-icons-height))
(face (cond (hl-face `(:face ,hl-face))
((eq dirvish-all-the-icons-palette 'all-the-icons) nil)
(t `(:face ,dirvish-all-the-icons-palette))))
(icon-attrs (append face offset height))
(icon (if (eq (car f-type) 'dir)
(apply #'all-the-icons-icon-for-dir f-name icon-attrs)
(apply #'all-the-icons-icon-for-file f-str icon-attrs)))
(icon-str (concat icon (propertize dirvish-icon-delimiter 'face hl-face)))
(ov (make-overlay (1- f-beg) f-beg)))
(overlay-put ov 'after-string icon-str)
`(ov . ,ov)))
(dirvish-define-attribute nerd-icons
"File icons provided by `nerd-icons.el'."
:width (+ (length dirvish-icon-delimiter) 2)
(let* ((offset `(:v-adjust ,dirvish-nerd-icons-offset))
(height `(:height ,dirvish-nerd-icons-height))
(face (cond (hl-face `(:face ,hl-face))
((eq dirvish-nerd-icons-palette 'nerd-icons) nil)
(t `(:face ,dirvish-nerd-icons-palette))))
(icon-attrs (append face offset height))
(icon (if (eq (car f-type) 'dir)
(apply #'nerd-icons-icon-for-dir f-name icon-attrs)
(apply #'nerd-icons-icon-for-file f-str icon-attrs)))
(icon-str (concat icon (propertize dirvish-icon-delimiter 'face hl-face)))
(ov (make-overlay (1- f-beg) f-beg)))
(overlay-put ov 'after-string icon-str)
`(ov . ,ov)))
(dirvish-define-attribute vscode-icon
"File icons provided by `vscode-icon.el'."
:width (1+ (length dirvish-icon-delimiter))
(let* ((vscode-icon-size dirvish-vscode-icon-size)
(icon
(dirvish-attribute-cache f-name :vscode-icon
(let ((default-directory dirvish--vscode-icon-directory))
(if (eq (car f-type) 'dir)
(let* ((base (file-name-sans-extension f-str))
(i-base (or (cdr (assoc base vscode-icon-dir-alist))
base))
(i-path (vscode-icon-dir-exists-p i-base)))
(vscode-icon-create-image
(or i-path (expand-file-name "default_folder.png"))))
(vscode-icon-file f-name)))))
(ov (make-overlay (1- f-beg) f-beg)))
(overlay-put ov 'display icon)
(overlay-put ov 'before-string (propertize " " 'face hl-face))
(overlay-put ov 'after-string
(propertize dirvish-icon-delimiter 'face hl-face))
`(ov . ,ov)))
(provide 'dirvish-icons)
;;; dirvish-icons.el ends here