From 27801ea209b5b7f5eb6aa422f7ab3711594f5735 Mon Sep 17 00:00:00 2001 From: Kiana Sheibani Date: Mon, 26 Aug 2024 19:39:06 -0400 Subject: [PATCH] feat!: use dirvish instead of treemacs for project tree --- config.org | 162 ++++++++++++++++++++++------------------------------- 1 file changed, 67 insertions(+), 95 deletions(-) diff --git a/config.org b/config.org index c260af1..0702a9a 100644 --- a/config.org +++ b/config.org @@ -811,7 +811,7 @@ The package allows you to define /patches/ which modify the definitions of funct #+call: confpkg("Support: Nix") -Some packages in this config such as =treemacs=, =org-roam=, etc. require certain tools to be in the environment. On a Nix-based system, there are a few different ways to handle this: +Some packages in this config such as =dirvish=, =org-roam=, etc. require certain tools to be in the environment. On a Nix-based system, there are a few different ways to handle this: 1. Put that tool in the actual environment, e.g. in a profile. This makes sense for simple things (=ripgrep=, =sqlite=, etc) but for more opinionated things like an instance of Python it becomes less desirable. 2. Build the tool and put a symlink to the output somewhere, e.g. in the HOME directory. This avoids polluting the environment, but you still have to deal with an unwieldy symlink that breaks Emacs if you accidentally delete it. @@ -973,7 +973,7 @@ modeline ophints (popup +defaults) ;;tabs -(treemacs +lsp) +;;(treemacs +lsp) unicode (vc-gutter +pretty) vi-tilde-fringe @@ -1029,7 +1029,7 @@ tree-sitter #+name: doom-emacs #+begin_src emacs-lisp :emacs -(dired +icons) +(dired +dirvish +icons) electric (ibuffer +icons) (undo +tree) @@ -2387,92 +2387,6 @@ Now that we have this word list, we can also plug it into ~cape-dict~ and get pr (add-hook! 'completion-at-point-functions :local :depth 40 #'cape-dict)) #+end_src -** Treemacs - -#+call: confpkg("Pkg: treemacs") - -Treemacs is a really useful package, but it also has a lot of defaults I don't like. Let's add a ~use-package!~ declaration to fix some of them: - -#+begin_src emacs-lisp -(use-package! treemacs - :defer t - :init - ; More accurate git status - (setq +treemacs-git-mode 'deferred - treemacs-python-executable - (if-let ((path (nix-build-out-path-gcroot - "treemacs-python" "nixpkgs#python3"))) - (concat path "/bin/python") - (error "Building python for treemacs failed"))) - :config - (setq ; Child-frame reading is broken (and sucks anyways) - treemacs-read-string-input 'from-minibuffer - ; Make "SPC 0" work like other window select commands - treemacs-select-when-already-in-treemacs 'stay) - - ; Better font styling - (custom-set-faces! - ; Variable pitch fonts - '((treemacs-root-face - treemacs-file-face) :inherit variable-pitch) - '(treemacs-tags-face :height 0.95 :inherit variable-pitch) - '(treemacs-directory-face :inherit treemacs-file-face) - '((treemacs-git-added-face - treemacs-git-modified-face - treemacs-git-renamed-face - treemacs-git-conflict-face) :inherit treemacs-file-face) - ; Better colors - `(treemacs-git-ignored-face - :foreground ,(doom-color 'base1) :slant italic :inherit treemacs-file-face) - `(treemacs-git-untracked-face - :foreground ,(doom-color 'base1) :inherit treemacs-file-face) - '(treemacs-async-loading-face - :height 0.8 :inherit (font-lock-comment-face treemacs-file-face))) - - (treemacs-hide-gitignored-files-mode) ; Hide git-ignored files by default - (treemacs-fringe-indicator-mode -1) ; No fringe indicator - (treemacs-resize-icons 12) ; Make icons smaller - ) -#+end_src - -*** Bindings - -A natural thing to do when browsing through the project tree is create a new file. The best way to do this is with the usual ~find-file~ command, bound to =SPC .=, but it would be nice to have a binding to save that leader key press. - -#+begin_src emacs-lisp -(map! :after treemacs - :mode treemacs-mode - "." #'find-file) -#+end_src - -*** Project Integration - -When I have a project open, Treemacs is flexible and allows me to open directories other than that project. This /would/ be great and convenient if it weren't for the fact that it doesn't do so very well, often completely messing up the existing project structure. This convenience function ensures that only the project directory is open. - -#+begin_src emacs-lisp -(defun ~/treemacs-fix-project () - "Modify the current `treemacs' workspace to only include the current project." - (interactive) - (require 'treemacs) - (let* ((name (concat "Perspective " (doom-project-name))) - (project (treemacs-project->create! - :name (doom-project-name) - :path (directory-file-name (doom-project-root)) - :path-status 'local-readable :is-disabled? nil)) - (workspace (treemacs-workspace->create! - :name name :projects (list project) :is-disabled? nil))) - ;; Only rebuild workspace if it doesn't have the structure we expect - (unless (equal (treemacs-current-workspace) workspace) - (setq treemacs--workspaces - (append (remove-if (lambda (w) - (string= (treemacs-workspace->name w) name) - treemacs--workspaces) - (list workspace)))) - (treemacs-do-switch-workspace workspace) - (treemacs--invalidate-buffer-project-cache) - (treemacs--rerender-after-workspace-change)))) -#+end_src - ** VTerm #+call: confpkg("Pkg: vterm") @@ -3998,17 +3912,75 @@ To make opening the journal more convenient, here's a command to open the latest * Languages and Modes -Despite Emacs being my editor of choice for programming, I don't actually have a lot of configuration for programming languages. I suppose that this is because language packages tend to not need much personal configuration, as the bounds of what a language mode needs to do are typically defined by the language itself. +This is the configuration for all the mode-related packages, including programming language packages. Most of this is configuring packages to work with my preferred Nix-based development environment. -** Dired +** Dirvish -#+call: confpkg("Mode: Dired") +#+call: confpkg("Mode: Dirvish") -Dired by default spawns a new buffer for every directory, which clutters up your buffer list very quickly. +~dirvish~ is a drop-in replacement to Emacs's native ~dired~ that adds a bunch of useful features and customization, inspired by vim's =ranger=. The package is provided by Doom Emacs's =:emacs dired= module, so we just need to configure it. + +*** Switching Projects + +The variable ~+workspaces-switch-project-function~ contains a function that is run whenever a project is opened. A file explorer seems like a natural place to open at this point. #+begin_src emacs-lisp -(after! dired - (setq dired-kill-when-opening-new-dired-buffer t)) +(after! doom-modules + (setq +workspaces-switch-project-function #'dirvish)) +#+end_src + +*** Appearance + +#+begin_src emacs-lisp +(after! dirvish + ;; Allocate more space to center window + (setq dirvish-default-layout '(1 0.15 0.45)) + + ;; Show nested directories + (pushnew! dirvish-attributes 'collapse) + + ;; Set dirvish line highlight to something less blinding + (set-face-attribute 'dirvish-hl-line nil :inherit 'hl-line)) +#+end_src + +*** Sidebar Project Tree + +I used to use =treemacs= as my dedicated project tree, but ~dirvish~ is much more polished and works better with the Emacs ecosystem. The provided ~dirvish-side~ extension adds support for using it in a sidebar. + +#+begin_src emacs-lisp +(defun ~/dirvish-side-open (&optional path) + "Select the Dirvish side session, creating one if it does not exist. + +If called with \\[universal-arguments], prompt for PATH, otherwise + it defaults to `project-current'." + (interactive (list (and current-prefix-arg + (read-directory-name "Open sidetree: ")))) + (require 'dirvish-side) + (let ((fullframep (when-let ((dv (dirvish-curr))) (car (dv-layout dv)))) + (visible (dirvish-side--session-visible-p)) + (path (or path (dirvish--get-project-root) default-directory))) + (cond (fullframep (user-error "Can not create side session here")) + (visible (select-window visible)) + (t (dirvish-side--new path))))) + +(map! :map evil-window-map + "0" #'~/dirvish-side-open) +(map! :leader + :desc "Select project tree window" + "0" #'~/dirvish-side-open + "o p" #'dirvish-side) +#+end_src + +**** Window Numbering + +If a side session is open, we'll configure =winum= to record it as having the index ~(popup . 0)~, i.e. the 0th popup window. It's not actually a popup, but this is the easiest way to separate it from the "main" windows. + +#+begin_src emacs-lisp +(after! (winum dirvish-side) + (defun ~/winum-dirvish-side () + (when (eq (selected-window) (dirvish-side--session-visible-p)) + '(popup . 0))) + (push #'~/winum-dirvish-side winum-assign-functions)) #+end_src ** Haskell