Files
emacs/config/files.org
2025-10-30 14:35:55 -05:00

5.3 KiB

Files

I've been increasingly using dired, and dirvish to handle files for a while now. At times it can be a bit cumbersome, but with time it could easily be all I need.

Dired

I mostly just modify the dired list command switches, and have dired open new directories in the same buffer. This comes with some benefits, and drawbacks but for now it seems to work best this way.

(use-feature dired
  :commands (dired)
  :custom
  (dired-listing-switches
   "-l --almost-all --human-readable --group-directories-first --no-group")
  :config
  (put 'dired-find-alternate-file 'disabled nil))

Dirvish

Dirvish is a very exceptional dired enhancement. With this package one can have similar functionality to vifm, yazi, and so on all within the comfort of emacs. I have most of the comforts enabled here; however they come with certain dependencies. It will function without them however.

(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")
     ("s" "/ssh:192.168.88.1"          "SSH server")))
  :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))
  ;; open large directory (over 20000 files) asynchronously with `fd' command
  (setq dirvish-large-directory-threshold 20000)

  (setq insert-directory-program
        (if (eq system-type 'gnu/linux)
            "ls"
          "gls"))
  
  :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)          ; [?] a helpful cheatsheet
   ("a"   . dirvish-setup-menu)        ; [a]ttributes settings:`t' toggles mtime, `f' toggles fullframe, etc.
   ("f"   . dirvish-file-info-menu)    ; [f]ile info
   ("o"   . dirvish-quick-access)      ; [o]pen `dirvish-quick-access-entries'
   ("s"   . dirvish-quicksort)         ; [s]ort flie list
   ("r"   . dirvish-history-jump)      ; [r]ecent visited
   ("l"   . dirvish-ls-switches-menu)  ; [l]s command flags
   ("v"   . dirvish-vc-menu)           ; [v]ersion control commands
   ("*"   . dirvish-mark-menu)
   ("y"   . dirvish-yank-menu)
   ("N"   . dirvish-narrow)
   ("^"   . dirvish-history-last)
   ("TAB" . dirvish-subtree-toggle)
   ("M-f" . dirvish-history-go-forward)
   ("M-b" . dirvish-history-go-backward)
   ("M-e" . dirvish-emerge-menu)))

Diredfl

This package just adds a bit of color to dired output. Looks good, but nothing too fancy.

(use-package diredfl
  :after (dired dirvish)
  :ensure t
  :hook
  (dired-mode-hook . diredfl-mode)
  (dirvish-directory-view-mode . diredfl-mode)
  :config
  (set-face-attribute 'diredfl-dir-name nil :bold t))

Projects

I use Projectile for project management. It provides everything I need in a fairly small, logical key map.

(use-package projectile
  :ensure t
  :init
  (setq projectile-project-search-path '(("~/Project" . 3)))
  :config
  (define-key projectile-mode-map (kbd "C-c C-p") 'projectile-command-map)
  (global-set-key (kbd "C-c p") 'projectile-command-map)
  (projectile-mode +1))

Helpful Settings

I have some settings for tidying up files on save, and keeping backup files together.

(use-feature files
  ;;:hook
  ;;(before-save . delete-trailing-whitespace)
  :config
  ;; source: http://steve.yegge.googlepages.com/my-dot-emacs-file
  (defun rename-file-and-buffer (new-name)
    "Renames both current buffer and file it's visiting to NEW-NAME."
    (interactive "sNew name: ")
    (let ((name (buffer-name))
          (filename (buffer-file-name)))
      (if (not filename)
          (message "Buffer '%s' is not visiting a file." name)
        (if (get-buffer new-name)
            (message "A buffer named '%s' already exists." new-name)
          (progn
            (rename-file filename new-name 1)
            (rename-buffer new-name)
            (set-visited-file-name new-name)
            (set-buffer-modified-p nil))))))
  :custom
  (require-final-newline t "Automatically add newline at end of file")
  (backup-by-copying t)
  (delete-old-versions t)
  (kept-new-versions 10)
  (kept-old-versions 5)
  (version-control t)
  (safe-local-variable-values
   '((eval load-file "./init-dev.el")
     (org-clean-refile-inherit-tags))
   "Store safe local variables here instead of in emacs-custom.el"))