Skip to content

Latest commit

 

History

History
616 lines (469 loc) · 24.1 KB

CUSTOMIZING.org

File metadata and controls

616 lines (469 loc) · 24.1 KB

TL;DR: Grab the sample config. Read following docs in-depth if you want further customizations.


In relation to Dired

Here are some Dirvish exclusive features or aspects that Dired and Dirvish handled differently.

Cursor display and line highlighting

Dirvish by default hides the cursor in Dired buffers and highlights the current line. It uses the dirvish-hl-line face for the active window and dirvish-hl-line-inactive for inactive windows. To modify this behavior, customize the dirvish-hide-cursor variable.

File details display

dired-hide-details-mode is enabled in Dirvish by default. If you want the details at buffer initialization like in Dired, you can customize the dirvish-hide-details option.

Instead of dired-hide-details-mode, configuring dirvish-attributes is the recommended approach for finer-grained control and greater flexibility in displaying and ordering file details. See Dirvish “Attributes” below for detailed instructions.

Cache directory

Dirvish uses dirvish-cache-dir to store cached images and other persistent data.

Usage of GNU ls

It is recommended to use GNU ls (referred to as gls on macOS and FreeBSD) as your insert-directory-program. If you are using macOS, FreeBSD, or Windows, you will need to manually install GNU ls and possibly configure it as your insert-directory-program. On GNU/Linux systems, this program is typically pre-installed and utilized by Emacs without requiring additional setup.

# macOS
brew install coreutils

# FreeBSD
pkg install gnuls

# Windows - install via Scoop: https://scoop.sh/
scoop install coreutils

To ensure Dirvish correctly parses dired-listing-switches, adhere to specific formatting rules when setting this variable. These rules ensure compatibility with the dirvish-ls extension powered by transient, allowing for straightforward decomposition and composition of included switches.

  1. Make sure to use the long name of ls flags whenever possible.
    • use --almost-all instead of -A
    • use --sort=version instead of -v
  2. avoid duplicate flags which makes no sense.

    These 3 patterns give the same directory listing result, but the sort attribute would only get correct information with the last one.

    • --sort=version --sort=time (duplicate, the latter flag is ignored)
    • -v --sort-time (same as the above one, meanwhile this also violates rule NO.1)
    • --sort=time

These rules should also be followed when setting the dirvish-fd-switches option. For changing the sort criteria of a buffer, dirvish-quicksort is recommended over dired-sort-toggle-or-edit. If you choose to use dired-sort-toggle-or-edit, ensure the entered ls flags adhere to the specified rules.

Additionally, it’s best to avoid using options newly introduced in GNU ls. For instance, while the --time=mtime option might function correctly on your local machine with ls/gls version 9.6, a remote host running GNU ls version 8.3 can not recognize it. Consequently, if dired-listing-switches includes such an switch, Dirvish will display an empty buffer when you attempt to open any path on that remote host.

Buffer management

A Dirvish session maintains a collection of Dired and preview buffers that are reused throughout the session.

When you quit a Dirvish session, either by using dirvish-quit command (bound to q) or by opening a file (which automatically quits the session), all Dired buffers except the index buffer are killed.

Dirvish respects the dired-kill-when-opening-new-dired-buffer option, preventing the creation of multiple Dired buffers. Alternatively, you may manually remove unwanted Dired buffers using the dired-find-alternate-file command.

If you prefer Dirvish to kill all Dired buffers when quitting, instead of leaving the last index buffer open, set dirvish-reuse-session to nil.

See: the rationale behind buffer management in Dirvish

Hooks

Apart from the hooks provided by Dired, Dirvish got some additions.

dirvish-setup-hook

Functions called when directory data for the root buffer is ready.

dirvish-after-revert-hook:

Functions called after running revert-buffer command.

dirvish-find-entry-hook

Functions to be called before opening a directory or file.

Each function is called with the file’s FILENAME and FIND-FN until one returns a non-nil value. When a Dired buffer is created for the first time, FIND-FN is dired, and the function is called with that Dired buffer as current-buffer; Otherwise, it is one of find-file, find-alternate-file, or find-file-other-window. A non-nil return value from run-hook-with-args-until-succuss terminates dirvish--find-entry, allowing interception of file opening and customized handling of specific file types.

The code below configures dired-find-file* commands to automatically detect binary files based on their extensions and open them externally.

(defun dirvish-open-binaries-externally (file fn)
  "When FN is not `dired', open binary FILE externally."
  (when-let* (((not (eq fn 'dired)))
              ((file-exists-p file))
              ((not (file-directory-p file)))
              ((member (downcase (or (file-name-extension file) ""))
                       dirvish-binary-exts)))
    ;; return t to terminate `dirvish--find-entry'.
    (prog1 t (dired-do-open))))

(add-hook 'dirvish-find-entry-hook #'dirvish-open-binaries-externally)

In practical applications, you might register multiple functions to handle different file types, assigning specific handlers for each.

dirvish-preview-setup-hook

Functions called in the regular preview buffer.

find-dired integration

find-dired should work seamlessly with Dirvish. However, there are currently no plans to integrate Dirvish further into its output buffer, as dirvish-fd offers a superior alternative. See Extensions:dirvish-fd.el for more information.

Dirvish “Attributes”

A Dirvish attribute is a visual indicator displayed inline within dired buffers, providing additional information about each file.

Available attributes

For now Dirvish offers these attributes:

  • subtree-state: a indicator for directory expanding state.
  • nerd-icon | all-the-icons | vscode-icon: file icons provided by various backends.
  • collapse: append unique nested paths to the end of filename.
  • git-msg: short git commit log.
  • vc-state: version control state at left fringe.
  • file-size: file size or directories file counts.
  • file-time: file modification time
  • file-modes: file modes (-rw-r–rwx)

Here is an overview of how does these attributes look like:

https://user-images.githubusercontent.com/16313743/178137697-3ff4ca5a-aaf3-44d4-b644-9e9a2e7f911a.svg

To achieve this, the only thing you need to do is put these symbols into dirvish-attributes, notice that the order matters for some attributes.

(setq dirvish-attributes
      (append
       ;; The order of these attributes is insignificant, they are always
       ;; displayed in the same position.
       '(vc-state subtree-state nerd-icons collapse)
       ;; Other attributes are displayed in the order they appear in this list.
       '(git-msg file-modes file-time file-size)))

After modifying this variable, you should call revert-buffer (bound to g by default) to apply the latest configuration.

Setup menu

Alternatively, you can dynamically toggle or adjust the order of these attributes by M-x dirvish-setup-menu.

A quick demo:

setup-menu.mp4

Multile layout recipies

In Dirvish, a Dirvish window with an associated layout includes a preview window and, optionally, one or more parent windows. You can toggle the visibility of the session layout (preview and parent windows) using dirvish-layout-toggle.

You can define multiple layouts in dirvish-layout-recipes and cycle through them with dirvish-layout-switch. This allows you to have different pane ratios for various tasks. For example, use a 1:3 ratio for image previews or a 1:3:5 ratio for general file previews.

Mode line | Header line

Dirvish displays information about the current directory or session in the mode line and header line. These features are enabled by default and include sensible default configurations.

Changing its placement, height and format

The mode line only span the directory panes by default, to make them span all panes, just set dirvish-use-mode-line to global. Setting the same option to nil hides the mode line in dirvish buffers.

To hide the leading bar image in mode-line and header-line, set dirvish-mode-line-bar-image-width to 0.

To configure the content in the mode line, put the segments you wanted into dirvish-mode-line-format. There is also dirvish-mode-line-height for you to set the height of the mode line.

The header line can be customized in the same way with dirvish-use-header-line, dirvish-header-line-format and dirvish-header-line-height.

The dired-switches-in-mode-line option is ignored in Dirvish.

;; Placement
;; (setq dirvish-use-header-line nil)      ; hide header line (show the classic dired header)
;; (setq dirvish-use-mode-line nil)        ; hide mode line
(setq dirvish-use-header-line 'global)     ; make header line span all panes
(setq dirvish-mode-line-bar-image-width 0) ; hide the leading bar image

;; Height
;;; '(25 . 35) means
;;;   - height in single window sessions is 25
;;;   - height in full-frame sessions is 35
(setq dirvish-header-line-height '(25 . 35))
(setq dirvish-mode-line-height 25) ; shorthand for '(25 . 25)

;; Segments
;;; 1. the order of segments *matters* here
;;; 2. it's ok to place raw strings in it as separators
(setq dirvish-header-line-format
      '(:left (path) :right (free-space))
      dirvish-mode-line-format
      '(:left (sort file-time " " file-size symlink) :right (omit yank index)))

Special buffers for displaying mode-line and header-line

When Dirvish uses a layout that occupies the entire frame, the mode-line and header-line are displayed in separate buffers and their corresponding windows. These buffers are initialized with dirvish-misc-mode. To customize the settings of these buffers, append your configuration to dirvish-misc-mode-hook.

File preview

Dirvish offers out-of-the-box file previews for text files and directories. Furthermore, it provides interfaces and extensive user options to customize and expand its preview capabilities.

Install dependencies for an enhanced preview experience

Dirvish offers file preview presets that depend on specific binaries. If you don’t require these extra preview features, you can remove the corresponding entries from dirvish-preview-dispatchers (documented below). Dirvish will then no longer prompt you to install the associated programs.

Toggle install instructions

macOS

brew install poppler ffmpegthumbnailer mediainfo vips 7zip imagemagick

Debian-based

apt install poppler-utils ffmpegthumbnailer mediainfo libvips-tools imagemagick

Arch-based

pacman -S poppler ffmpegthumbnailer mediainfo libvips 7zip imagemagick

FreeBSD

pkg install poppler ffmpegthumbnailer vips 7-zip ImageMagick7

Windows

# install via Scoop: https://scoop.sh/
scoop install poppler mtn mediainfo libvips 7zip imagemagick

Preview methods for various filetypes

Dirvish uses different preview strategies towards various filetypes. You may want to turn off preview for certain file extensions, dirvish-preview-disabled-exts allows you to do that.

A preview dispatcher represents a strategy for file preview on certain conditions. The variable dirvish-preview-dispatchers, which holds all the active dispatchers, has the default value looks like:

(image gif video audio epub pdf archive)
  • image: preview image files, requires vipsthumbnail
  • gif: preview GIF image files with animation
  • video: preview videos files with thumbnail, requires ffmpegthumbnailer on Linux/macOS requires mtn on Windows (special thanks to @samb233!)
  • audio: preview audio files with metadata, requires mediainfo
  • epub: preview epub documents, requires epub-thumbnail
  • pdf: preview pdf documents via pdf-tools
  • archive: preview archive files such as .tar, .zip, requires 7z

Each dispatcher in this list handles the validation and preview content generation for the corresponding filetype. To enable/disable certain preview methods, just modify this list to your preferences.

For example, if for some reason you are not able to install epub-thumbnail or want to display preview for epub files via packages like nov, just remove the epub dispatcher like this:

(setq dirvish-preview-dispatchers (remove 'epub dirvish-preview-dispatchers))

Two dispatchers, dired and fallback, are enabled by default as fallback handlers. These dispatchers are used to preview text files and directories respectively, but can be overridden by custom dispatchers. For example, you can use eza to preview directories instead of dired (see Preview directory using ~eza~ command section below).

The dirvish-preview-dired-sync-omit option allows dired preview buffers to sync your dired-omit-mode and its settings from the root window, it is turned off by default.

Dirvish also offers these user options to customize its preview behavior. Refer to the docstrings of these options for detailed information.

  • dirvish-preview-buffers-max-count
  • dirvish-preview-environment
  • dirvish-preview-large-file-threshold

Customizations for preview buffers

There are several types of buffer can be placed in the preview window in Dirvish.

Directory files listing

The dired preview dispatcher creates buffers in dirvish-directory-view-mode. This mode is also used for the parent directory listing buffers. Consequently, a single hook can configure both the parent buffer and the dired preview buffer.

(add-hook 'dirvish-directory-view-mode-hook #'diredfl-mode)

Regular files with certain major mode

When a regular file with certain major mode is being previewed, you can change its settings by the dirvish-preview-setup-hook.

Special preview buffer

A dirvish-special-preview-mode buffer is displayed in the preview window for all the rest filetypes. This includes cases for shell command output, error/warning info display, image and metadata and etc.

Other use cases

Here are several examples on how to extend the preview capabilities of Dirvish.

Preview PDF files with generated thumbnail

The default pdf preview method uses pdf-tools to open the document, which works fine for most of the pdf documents, but it feels sluggish for some documents especially those big ones.

Dirvish provided an alternative PDF preview dispatcher pdf-preface which generates preface image for pdf files and use those preface images as the preview. This allows the user to preview big pdf files in a non-blocking fashion.

Note: this dispatcher requires the pdftoppm executable.

(setq dirvish-preview-dispatchers
      (cl-substitute 'pdf-preface 'pdf dirvish-preview-dispatchers))

Preview directory using eza command

If you find Dired’s default directory previews unsatisfactory, you can create a custom previewer using the eza command.

(dirvish-define-preview eza (file)
  "Use `eza' to generate directory preview."
  :require ("eza") ; tell Dirvish to check if we have the executable
  (when (file-directory-p file) ; we only interest in directories here
    `(shell . ("eza" "-al" "--color=always" "--icons=always"
               "--group-directories-first" ,file))))

(push 'eza dirvish-preview-dispatchers)

This makes Dirvish use the output from exa shell command as your preview content for a directory entry. On a side note, you can customize the corresponding ansi-color faces to change the coloring in the preview window if your theme doesn’t have good integration with the ansi-color package.

(set-face-attribute 'ansi-color-blue nil :foreground "#FFFFFF")

https://user-images.githubusercontent.com/16313743/158852998-ebf4f1f7-7e12-450d-bb34-ce04ac22309c.png

Contrib preview dispatchers

Here are some user-contributed preview dispatchers. Explore these if the built-in preview handlers don’t meet your needs for certain file types. Contributions to this list are welcome!

https://github.com/alexluigit/dirvish/wiki/Contrib-preview-dispatchers

Sample config

Dirvish

The extra commands in this sample config are documented at Extensions. All of these extensions are inactive by default and will be loaded on demand (usually you don’t have to require them explicitly if you installed dirvish from MELPA or /path/to/dirvish/extensions/ is in your load-path).

(use-package dired
  :config
  (setq dired-listing-switches
        "-l --almost-all --human-readable --group-directories-first --no-group")
  ;; this command is useful when you want to close the window of `dirvish-side'
  ;; automatically when opening a file
  (put 'dired-find-alternate-file 'disabled nil))

(use-package dirvish
  :ensure t
  :init
  (dirvish-override-dired-mode)
  :custom
  (dirvish-quick-access-entries ; It's a custom option, `setq' won't work
   '(("h" "~/"                          "Home")
     ("d" "~/Downloads/"                "Downloads")
     ("m" "/mnt/"                       "Drives")
     ("s" "/ssh:my-remote-server")      "SSH server"
     ("e" "/sudo:root@localhost:/etc")  "Modify program settings"
     ("t" "~/.local/share/Trash/files/" "TrashCan")))
  :config
  ;; (dirvish-peek-mode)             ; Preview files in minibuffer
  ;; (dirvish-side-follow-mode)      ; similar to `treemacs-follow-mode'
  (setq dirvish-mode-line-format
        '(:left (sort symlink) :right (omit yank index)))
  (setq dirvish-attributes           ; The order *MATTERS* for some attributes
        '(vc-state subtree-state nerd-icons collapse git-msg file-time file-size)
        dirvish-side-attributes
        '(vc-state nerd-icons collapse file-size))
  :bind ; Bind `dirvish-fd|dirvish-side|dirvish-dwim' as you see fit
  (("C-c f" . dirvish)
   :map dirvish-mode-map          ; Dirvish inherits `dired-mode-map'
   ;; (";" . dired-up-directory)  ; So you can adjust dired bindings here
   ("?"   . dirvish-dispatch)     ; contains most of sub-menus in dirvish extensions
   ("f"   . dirvish-history-go-forward)
   ("b"   . dirvish-history-go-backward)
   ("y"   . dirvish-yank-menu)
   ("N"   . dirvish-narrow)
   ("^"   . dirvish-history-last)
   ("s"   . dirvish-setup-menu)   ; `st' toggles mtime, `ss' toggles file size, etc.
   ("h"   . dirvish-history-jump) ; remapped `describe-mode'
   ("r"   . dirvish-quicksort)    ; remapped `dired-sort-toggle-or-edit'
   ("v"   . dirvish-vc-menu)      ; remapped `dired-view-file'
   ("TAB" . dirvish-subtree-toggle)
   ("M-a" . dirvish-quick-access)
   ("M-f" . dirvish-file-info-menu)
   ("M-l" . dirvish-ls-switches-menu)
   ("M-m" . dirvish-mark-menu)
   ("M-t" . dirvish-layout-toggle)
   ("M-e" . dirvish-emerge-menu)
   ("M-j" . dirvish-fd-jump)))

Mouse settings

Disclaimer: you can skip this section if you don’t care about mouse support.

Emacs 29 added mouse drag-and-drop support for Dired, the following settings will enable it:

(setq dired-mouse-drag-files t)                   ; added in Emacs 29
(setq mouse-drag-and-drop-region-cross-program t) ; added in Emacs 29

Some keybindings for mouse:

  • left click: expanding/collapsing a directory or opening a file
  • right click: opening a file/directory
  • middle click: opening a file/directory in new window
(setq mouse-1-click-follows-link nil)
(define-key dirvish-mode-map (kbd "<mouse-1>") 'dirvish-subtree-toggle-or-open)
(define-key dirvish-mode-map (kbd "<mouse-2>") 'dired-mouse-find-file-other-window)
(define-key dirvish-mode-map (kbd "<mouse-3>") 'dired-mouse-find-file)

TRAMP integration

Dirvish integrates TRAMP at its core. Some features such as file preview are disabled over synchronous TRAMP connections (see below on how to bypass this limitation). For certain commands such as dirvish-yank you should configure your ssh authentication properly to avoid being stuck with a prompt you will not be able to answer to in the child emacs.

(use-package tramp
  :config
  ;; Enable full-featured Dirvish over TRAMP on ssh connections
  ;; https://www.gnu.org/software/tramp/#Improving-performance-of-asynchronous-remote-processes
  (connection-local-set-profile-variables
   'remote-direct-async-process
   '((tramp-direct-async-process . t)))
  (connection-local-set-profiles
   '(:application tramp :protocol "ssh")
   'remote-direct-async-process)
  ;; Tips to speed up connections
  (setq tramp-verbose 0)
  (setq tramp-chunksize 2000)
  (setq tramp-ssh-controlmaster-options nil))

Complementary packages

These packages are only listed here for discoverability.

(use-package dired-x
  :config
  ;; If you're using Emacs 30+, you likely don't need this. Emacs 30 introduces
  ;; the `dired-do-open` command and `shell-command-guess-open` option,
  ;; providing a more straightforward way to open files externally with your
  ;; operating system's default application (e.g., "open" on macOS, "xdg-open"
  ;; on Linux).
  ;; (when-let* ((cmd (cond ((eq 'darwin system-type) "open")
  ;;                        ((memq system-type '(ms-dos cygwin windows-nt)) "start")
  ;;                        (t "xdg-open"))))
  ;;   (setq dired-guess-shell-alist-user  ; let OS decide how to open certain files
  ;;         `(("\\.\\(?:docx\\|pdf\\|djvu\\|eps\\)\\'" ,cmd)
  ;;           ("\\.\\(?:jpe?g\\|png\\|gif\\|xpm\\)\\'" ,cmd)
  ;;           ("\\.\\(?:xcf\\)\\'" ,cmd)
  ;;           ("\\.csv\\'" ,cmd)
  ;;           ("\\.tex\\'" ,cmd)
  ;;           ("\\.\\(?:mp4\\|mkv\\|avi\\|flv\\|rm\\|rmvb\\|ogv\\)\\(?:\\.part\\)?\\'" ,cmd)
  ;;           ("\\.\\(?:mp3\\|flac\\)\\'" ,cmd)
  ;;           ("\\.html?\\'" ,cmd)
  ;;           ("\\.md\\'" ,cmd))))
  ;; Make dired-omit-mode hide all "dotfiles"
  (setq dired-omit-files
        (concat dired-omit-files "\\|^\\..*$")))

;; Additional syntax highlighting for dired
(use-package diredfl
  :hook
  ((dired-mode . diredfl-mode)
   ;; highlight parent and directory preview as well
   (dirvish-directory-view-mode . diredfl-mode))
  :config
  (set-face-attribute 'diredfl-dir-name nil :bold t))

;; Use `nerd-icons' as Dirvish's icon backend
(use-package nerd-icons)

;; Or, use `vscode-icon' instead
;; (use-package vscode-icon
;;   :config
;;   (push '("jpg" . "image") vscode-icon-file-alist))

;; miscs
(setq delete-by-moving-to-trash t)