From 6cdc06043288834a213f80e9145712ef8c8ef71b Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 26 Jan 2020 04:19:39 -0500 Subject: [PATCH] Update & revise docs/faq.org --- docs/faq.org | 373 +++++++++++++++++++-------------------------------- 1 file changed, 139 insertions(+), 234 deletions(-) diff --git a/docs/faq.org b/docs/faq.org index 7b8abd0fa..4bc5defe1 100644 --- a/docs/faq.org +++ b/docs/faq.org @@ -37,7 +37,7 @@ - [[#can-vimevil-be-removed-for-a-more-vanilla-emacs-experience][Can Vim/Evil be removed for a more vanilla Emacs experience?]] - [[#should-i-use-make-or-bindoom][Should I use ~make~ or ~bin/doom~?]] - [[#when-should-and-shouldnt-i-use-bindoom][When should and shouldn't I use ~bin/doom~?]] - - [[#when-to-run-doom-refresh][When to run ~doom refresh~]] + - [[#when-to-run-doom-sync][When to run ~doom sync~]] - [[#how-to-suppress-confirmation-prompts-while-bindoom-is-running][How to suppress confirmation prompts while ~bin/doom~ is running]] - [[#defaults][Defaults]] - [[#why-ivy-over-helm][Why Ivy over Helm?]] @@ -134,15 +134,15 @@ Doom had +four+ *five* goals for its package management system: are out-of-date through official channels, have changed hands, have a superior fork, or aren't available in ELPA repos. 3. *Performance:* lazy-loading the package management system is a tremendous - boon to start up speed. Initializing package.el and quelpa (and/or checking - that your packages are installed) every time you start up is expensive. + boon to start up speed. Initializing package.el and straight (and/or checking + that your packages are installed) each time you start up is expensive. 4. *Organization:* an Emacs configuration grows so quickly, in complexity and size. A clear separation of concerns (configuration of packages from their installation) is more organized. 5. *Reproducibility:* /This goal hasn't been implemented yet/, but all our work up until now is aimed at this goal. Emacs is a tumultuous ecosystem; packages break left and right, and we rely on hundreds of them. Eventually, we want - package versions to be locked to versions of Doom so that Doom installs are + package versions to be locked to Doom's releases so that Doom installs are reproducible. ** How does Doom start up so quickly? @@ -160,10 +160,10 @@ up ~gc-cons-threshold~ (and perhaps ~gc-cons-percentage~) temporarily: ;; ... your emacs config here ... #+END_SRC -However, it is important to reset it eventually (as late as possible). Not doing -so will cause garbage collection freezes during long-term interactive use. -Conversely, a ~gc-cons-threshold~ that is too small will cause stuttering. We -use 16mb as our default. +However, it is important to reset it eventually. Not doing so will cause garbage +collection freezes during long-term interactive use. Conversely, a +~gc-cons-threshold~ that is too small will cause stuttering. We use 16mb as our +default. #+BEGIN_SRC emacs-lisp (add-hook 'emacs-startup-hook @@ -190,14 +190,16 @@ helm and ivy). Here is how Doom does it: (add-hook 'minibuffer-exit-hook #'doom-restore-garbage-collection-h) #+END_SRC +Another alternative (which is [[https://github.com/hlissner/doom-emacs/blob/develop/core/core.el#L269-L274][what Doom uses]]) is to use the [[https://gitlab.com/koral/gcmh/][gcmh]] package to +stave off the GC until you are idle or unfocus the Emacs frame. + *** Unset ~file-name-handler-alist~ temporarily Emacs consults this variable every time a file is read or library loaded, or when certain functions in the file API are used (like ~expand-file-name~ or ~file-truename~). -They do so to check if a special handler is needed to read it, but none of these -handlers are necessary for the initialization work we do at startup, so it is -generally safe to disable it (temporarily!): +Emacs does to check if a special handler is needed to read that file, but none +of them are (typically) necessary at startup, so we disable them (temporarily!): #+BEGIN_SRC emacs-lisp (defvar doom--file-name-handler-alist file-name-handler-alist) @@ -214,60 +216,38 @@ generally safe to disable it (temporarily!): (setq file-name-handler-alist doom--file-name-handler-alist))) #+END_SRC -It is important to restore this variable, otherwise you won't be able to use -TRAMP and Emacs will be unable to read compressed/encrypted files. - -*** Cut down on ~load-path~ lookups -Each ~load~ and ~require~ call (without an second argument) costs an O(n) lookup -on ~load-path~. The average Doom config has approximately 260 packages including -dependencies, and around 40 built-in packages. That means a minimum of 300 -entries in ~load-path~ with a worst case of =n=300= for /each/ package load (but -realistically, =n= will be somewhere between =2= and =20=). - -The cost isn't great, but it does add up. There isn't much to do about this, -except be mindful of it where we can: - -+ Paths in Doom's autoloads file are replaced with absolute ones, thus incurring - no lookup cost to lazy load them. -+ The ~load!~ macro is used instead of ~require~ where possible. This builds - paths with string concatenation (which is baked in at compile time, removing - most of the associated cost). -+ ~load-path~ is let-bound to a subset of itself where possible (the - ~doom--initial-load-path~ variable contains the value of ~load-path~ before it - was touched by Doom). +Don't forget to restore ~file-name-handler-alist~, otherwise TRAMP won't work +and compressed/encrypted files won't open. *** Concatenate package autoloads When you install a package, a PACKAGE-autoloads.el file is generated. This file -contains a map of autoloaded functions and snippets declared by the package -(that's what those ~;;;###autoload~ comments are for in packages). They tell -Emacs where to find them, when they are eventually called. In your conventional -Emacs config, every single one of these autoloads files are loaded immediately -at startup. +contains a map of autoloaded functions and snippets declared by the package. +They tell Emacs where to find them when they are eventually called. In your +conventional Emacs config, every one of these autoloads files are loaded +immediately at startup (when ~package-initialize~ is called). Since you'll commonly have hundreds of packages, loading hundreds of autoloads -file can hurt startup times. We get around this by concatenating these autoloads -files into one giant one (in =~/.emacs.d/.local/autoloads.pkg.el=) when you run -~doom refresh~. +file can hurt startup times, especially without an SSD. We get around this by +concatenating these files into one giant one when you run ~doom sync~. -Emacs 27+ will introduce a ~package-quickstart~ feature that will do this for -you -- the =straight= package manager does this for you too -- but Doom Emacs -has its own specialized mechanism for doing this, and has tacked a number of -Doom-specific optimizations on top of it. +Emacs 27+ introduces a ~package-quickstart~ command does this for you, and +=straight=, our package manager, does this for you too, but [[https://github.com/hlissner/doom-emacs/tree/develop/core/cli/autoloads.el][Doom Emacs has its +own specialized mechanism]] for this, topped off with a few Doom-specific +optimizations. *** Lazy load package management system(s) Initializing package.el or straight.el at startup is expensive. We can save some time by delaying that initialization until we actually need these libraries (and -only eagerly load them when we're doing package management, e.g. when we run -~doom refresh~). +load them only when we're doing package management, e.g. when we run ~doom +sync~). -Among other things, ~doom refresh~ does a lot for us. It generates concatenated +Among other things, ~doom sync~ does a lot for us. It generates concatenated autoloads files; caches expensive variables like caches ~load-path~, ~Info-directory-list~ and ~auto-mode-alist~; and preforms all your package management activities there -- far away from your interactive sessions. -How exactly Doom accomplishes all this is a little complex, so instead, here is -a boiled-down version you can use in your own configs (for package.el, not -straight.el): +How exactly Doom accomplishes all this is a long story, so here is a boiled-down +version you can use in your own configs (for package.el, not straight.el): #+BEGIN_SRC emacs-lisp (defvar cache-file "~/.emacs.d/cache/autoloads") @@ -278,26 +258,12 @@ straight.el): (package-initialize) (with-temp-buffer (cl-pushnew doom-core-dir load-path :test #'string=) - (dolist (spec package-alist) - (when-let (desc (cdr spec)) - (let ((file (concat (package--autoloads-file-name desc) ".el"))) - (when (file-readable-p file) - ;; Ensure that the contents of this autoloads file believes they - ;; haven't been moved: - (insert "(let ((load-file-name " (prin1-to-string (abbreviate-file-name file)) "))\n") - (insert-file-contents file) - (save-excursion - ;; Delete forms that modify `load-path' and `auto-mode-alist', we - ;; will set them once, later. - (while (re-search-forward "^\\s-*\\((\\(?:add-to-list\\|\\(?:when\\|if\\) (boundp\\)\\s-+'\\(?:load-path\\|auto-mode-alist\\)\\)" nil t) - (goto-char (match-beginning 1)) - (kill-sexp))) - ;; Remove unnecessary comment lines and (provide ...) forms - (while (re-search-forward "^\\(?:;;\\(.*\n\\)\\|\n\\|(provide '[^\n]+\\)" nil t) - (unless (nth 8 (syntax-ppss)) - (replace-match "" t t))) - (unless (bolp) (insert "\n")) - (insert ")\n"))))) + (dolist (desc (delq nil (mapcar #'cdr package-alist))) + (let ((load-file-name (concat (package--autoloads-file-name desc) ".el"))) + (when (file-readable-p load-file-name) + (condition-case _ + (while t (insert (read (current-buffer)))) + (end-of-file))))) (prin1 `(setq load-path ',load-path auto-mode-alist ',auto-mode-alist Info-directory-list ',Info-directory-list) @@ -309,10 +275,9 @@ straight.el): #+END_SRC You'll need to delete ~cache-files~ any time you install, remove, or update a -new package, however. In that case you could advise ~package-install~ and -~package-delete~ to call ~initialize~ when they succeed. Or, you could make -~initialize~ interactive and call it manually when you determine it's necessary. -Up to you! +new package. You could advise ~package-install~ and ~package-delete~ to call +~initialize~ when they succeed, or make ~initialize~ interactive and call it +manually when necessary. Up to you! Note: package.el is sneaky, and will initialize itself if you're not careful. *Not on my watch, criminal scum!* @@ -327,20 +292,21 @@ Note: package.el is sneaky, and will initialize itself if you're not careful. *** Lazy load more than everything ~use-package~ can defer your packages. Using it is a no-brainer, but Doom goes a little further with lazy loading. There are some massive plugins out there. For -many of them, ordinary lazy loading techniques simply don't work. To name a few: +some of them, ordinary lazy loading techniques don't work. To name a few: + The =lang/org= module defers loading babel packages until their src blocks are - executed. You no longer need ~org-babel-do-load-languages~ in your config. + executed or read. You no longer need ~org-babel-do-load-languages~ in your + config -- in fact, you shouldn't use it at all! + Company and yasnippet are loaded as late as possible (waiting until the user opens a non-read-only, file-visiting buffer (that isn't in fundamental-mode)). -+ The =evil-easymotion= package has many keybinds. You'd need to load the - package for them to all take effect, so instead, =gs= is bound to a command - that loads the package and then invisibly populates =gs=, then simulates the - =gs= keypress as though those new keys had always been there. -+ A number of packages are "incrementally" loaded. This is a Doom feature where, - after a few seconds of idle time post-startup, Doom will load packages - piecemeal while Emacs. It will quickly abort if it detects input, as to make - the process as subtle as possible. ++ The =evil-easymotion= package binds many keys, none of which are available + until you load the package. Instead of loading it at startup, =gs= is bound to + a command that loads the package, populates =gs=, then simulates the =gs= key + press as though those new keys had always been there. ++ Doom loads some packages "incrementally". i.e. after a few seconds of idle + time post-startup, Doom loads packages piecemeal (one dependency at a time) + while Emacs. It aborts if it detects input, as to make the process as subtle + as possible. For example, instead of loading =org= (a giant package), it will load these dependencies, one at a time, before finally loading =org=: @@ -354,21 +320,6 @@ many of them, ordinary lazy loading techniques simply don't work. To name a few: This ensures packages load as quickly as possible when you first load an org file. -*** +Exploit byte-compilation!+ -It used to be that byte-compilation bought a 40-60% improvement in startup -times, because expensive operations (like ~package-initialize~ or -~exec-path-from-shell~) were evaluated at compile time, but Doom has changed. - -I've since adopted a pre-cache approach (when running ~doom refresh~), which -brings these startup benefits to uncompiled Emacs. This renders byte-compilation -significantly less beneficial for startup time. - -That said, compilation will still benefit Doom's snappiness in general. - -Run ~doom compile :core~ to only compile Doom's core files, or ~doom compile~ to -compile the /entire/ config (=~/.emacs.d= and =~/.doom.d=) -- which may take a -while. - *** Use [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html][lexical-binding]] everywhere Add ~;; -*- lexical-binding: t; -*-~ to the top of your elisp files. This can break code if you've written it to depend on undeclared dynamic variables, but @@ -381,32 +332,30 @@ find more about it in: + [[http://nullprogram.com/blog/2016/12/22/]["Some Performance Advantages of Lexical Scope."]] ** Why is startup time important? Why not use the daemon? -One of my motivations for a config that starts up fast (aside from the learning -experience) was to shape Emacs into a viable alternative to vim for one-shot -editing in the terminal (without ~-Q~). This also facilitates: +The central motivation for a config that starts up fast (aside from the learning +experience) was to have a viable alternative to vim for quick, one-shot editing +in the terminal (without ~-Q~). -- Running multiple, independent instances of Emacs (e.g. on a per-project basis, or - for nix-shell users, or to isolate one instance for IRC from an instance for - writing code, etc). +Besides that, it happens to facilitate: + +- Running multiple, independent instances of Emacs (e.g. on a per-project basis, + or for nix-shell users, or to isolate one instance for IRC from an instance + for writing code, etc). - Quicker restarting of Emacs, to reload package settings or recover from disastrous errors which can leave Emacs in a broken state. - Faster integration with "edit in Emacs" solutions (like [[https://github.com/alpha22jp/atomic-chrome][atomic-chrome]]), and - the potential to use them without a running daemon. + without a daemon. -What's more, I don't like using more tools than I need. We should not need a -second program just to make the first run comfortably. +What's more, I believe a daemon shouldn't be necessary to get a sane startup +time out of Emacs. ** How do I use Doom alongside other Emacs configs? I recommend [[https://github.com/plexus/chemacs][Chemacs]]. You can think of it as a bootloader for Emacs. You'll [[file:getting_started.org::*Alongside other Emacs configs (with Chemacs)][find instructions on how to use it with Doom in the user manual]]. -If you only want to try it out without affecting your current config, it is safe -to install Doom anywhere you like. The ~bin/doom~ utility will only address the -config the script is located under. - You'll still need a separate folder for personal configuration (=~/.doom.d= or -=~/.config/doom= by default), but the =-p PATH= flag (or ~DOOMDIR~ environment -variable) will allow you to use a different location: +=~/.config/doom= by default), but the =--doomdir PATH= switch (or ~DOOMDIR~ +environment variable) will allow you to use a different location: #+BEGIN_SRC bash # First install Doom somewhere @@ -479,80 +428,28 @@ first ran ~doom install~. Check out the [[file:getting_started.org::Customize][Customize section]] in the [[file:getting_started.org][Getting Started]] guide for details. ** How do I enable or disable a Doom module? -You'll find your ~doom!~ block in =~/.doom.d/init.el=. This block contains a -list of modules you want enabled and what order to load them in. Disable modules -by commenting them out with semicolons. To enable them, remove those leading -semicolons: +Comment or uncomment the module in your ~doom!~ block, found in +=$DOOMDIR/init.el=. -#+BEGIN_SRC emacs-lisp -(doom! :lang - python ; this is enabled - ;;ruby ; this is disabled - rust) -#+END_SRC - -Remember to run ~bin/doom refresh~ afterwards, on the command line, to sync your +Remember to run ~bin/doom sync~ afterwards, on the command line, to sync your module list with Doom. -You can find a comprehensive list of modules in the [[file:index.org::*Module list][Module Index]]. +See the "[[file:getting_started.org::*Configuration modules][Configuration modules]]" section of the [[file:getting_started.org][Getting Started]] guide for more +information. ** How do I install a package from ELPA? -Add a ~package!~ declaration to =~/.doom.d/packages.el= for each package you -want installed. - -#+BEGIN_SRC elisp -(package! winum) -#+END_SRC - -Remember to run ~doom refresh~ afterwards to ensure the package is installed. - -You'll find more information in the "[[file:getting_started.org::*Installing%20packages][Installing packages]]" section of the [[file:getting_started.org][Getting -Started]] guide. +See the "[[file:getting_started.org::*Installing%20packages][Installing packages]]" section of the [[file:getting_started.org][Getting Started]] guide. ** How do I install a package from github/another source? -The ~package!~ macro can be passed a MELPA style recipe, allowing you to install -packages from just about anywhere: - -#+BEGIN_SRC elisp -(package! evil :recipe (:host github :repo "hlissner/my-evil-fork")) -#+END_SRC - -Remember to run ~doom refresh~ every time you modify you package list, to ensure -your packages are set up and installed. - -You can find more information about the recipe format [[https://github.com/raxod502/straight.el#the-recipe-format][in the straight.el package -readme]]. - -#+begin_quote -If a MELPA recipe exists for the package you are writing a ~package!~ -declaration for, you may omit keywords and Doom's package manager will fill them -in with values from its original recipe. -#+end_quote - -You'll find more information in the "[[file:getting_started.org::*Installing%20packages%20from%20external%20sources][Installing packages from external sources]]" -section of the [[file:getting_started.org][Getting Started]] guide. +See the "[[file:getting_started.org::*Installing%20packages%20from%20external%20sources][Installing packages from external sources]]" section of the [[file:getting_started.org][Getting +Started]] guide. ** How do I change where an existing package is installed from? -~package!~ declarations in your private =packages.el= file have precedence over -modules (even your own). Simply add a new one for that package with the new -recipe. - -You'll find more information in the "[[file:getting_started.org::*Changing%20a%20built-in%20recipe%20for%20a%20package][Changing a built-in recipe for a package]]" -section of the [[file:getting_started.org][Getting Started]] guide. +See the "[[file:getting_started.org::*Changing%20a%20built-in%20recipe%20for%20a%20package][Changing a built-in recipe for a package]]" section of the [[file:getting_started.org][Getting +Started]] guide. ** How do I disable a package completely? -With the ~package!~ macro's ~:disable~ property: - -#+BEGIN_SRC elisp -;;; add to DOOMDIR/packages.el -(package! irony :disable t) -#+END_SRC - -Remember to run ~doom refresh~ afterwards to ensure that the package is -uninstalled and disabled. - -You'll find more information in the "[[file:getting_started.org::*Disabling%20packages][Disabling packages]]" section of the [[file:getting_started.org][Getting -Started]] guide. +See the "[[file:getting_started.org::*Disabling%20packages][disabling packages]]" section of the [[file:getting_started.org][Getting Started]] guide. ** How do I reconfigure a package included in Doom? ~use-package!~ and ~after!~ (wrappers around ~use-package~ and @@ -620,8 +517,8 @@ install it, then load it: (setq doom-theme 'solarized-dark) #+END_SRC -Don't forget to run ~doom refresh~ after adding that ~package!~ statement to -ensure the package is installed. +Don't forget to run ~doom sync~ after adding that ~package!~ statement to ensure +the package is installed. ** How do I change the fonts? Doom exposes five (optional) variables for controlling fonts in Doom, they are: @@ -632,8 +529,8 @@ Doom exposes five (optional) variables for controlling fonts in Doom, they are: + ~doom-unicode-font~ + ~doom-big-font~ (used for ~doom-big-font-mode~) -Each of these will accept either a =font-spec=, font string (="Input Mono-12"=), -or [[https://wiki.archlinux.org/index.php/X_Logical_Font_Description][xlfd font string]]. +They all accept either a =font-spec=, font string (="Input Mono-12"=), or [[https://wiki.archlinux.org/index.php/X_Logical_Font_Description][xlfd +font string]]. e.g. #+BEGIN_SRC emacs-lisp @@ -760,6 +657,7 @@ rules. You'll find more comprehensive documentation on ~set-popup-rule!~ in its docstring (available through =SPC h f= -- or =C-h f= for non-evil users). + ** How do I change the appearance a face (or faces)? Doom provides the ~custom-set-faces!~ and ~custom-theme-set-faces!~ macros as a convenience. @@ -785,15 +683,14 @@ tools for experienced Emacs users to skirt around it (most of the time): - On-the-fly evaluation won't work for all changes. e.g. Changing your ~doom!~ block (i.e. the list of modules for Doom to enable). - But rather than running ~doom refresh~ and restarting Emacs, Doom provides - ~M-x doom/reload~ for your convenience (bound to =SPC h r r= and =C-h r r=). - This runs ~doom refresh~, restarts the Doom initialization process and - re-evaluates your personal config. However, this won't clear pre-existing - state; Doom won't unload modules/packages that have already been loaded and it - can't anticipate complications arising from a private config that isn't - idempotent. -- Many ~bin/doom~ commands are available as elisp commands with the ~doom//*~ - prefix. e.g. ~doom//refresh~, ~doom//update~, etc. Feel free to use them, but + But rather than running ~doom sync~ and restarting Emacs, Doom provides ~M-x + doom/reload~ for your convenience (bound to =SPC h r r= and =C-h r r=). This + runs ~doom sync~, restarts the Doom initialization process and re-evaluates + your personal config. However, this won't clear pre-existing state; Doom won't + unload modules/packages that have already been loaded and it can't anticipate + complications arising from a private config that isn't idempotent. +- Some ~bin/doom~ commands are available as elisp commands. e.g. ~doom/reload~ + for ~doom sync~, ~doom/upgrade~ for ~doom upgrade~ ~doom//s~, ~doom//update~, etc. Feel free to use them, but consider them highly experimental and subject to change without notice. - You can quickly restart Emacs and restore the last session with ~doom/restart-and-restore~ (bound to =SPC q r=). @@ -815,7 +712,7 @@ commands that you may find particularly useful: + ~doom doctor~ :: Diagnose common issues in your environment and list missing external dependencies for your enabled modules. -+ ~doom refresh~ :: Ensures that all missing packages are installed, orphaned ++ ~doom sync~ :: Ensures that all missing packages are installed, orphaned packages are removed, and metadata properly generated. + ~doom install~ :: Install any missing packages. + ~doom update~ :: Update all packages that Doom's (enabled) modules use. @@ -829,12 +726,12 @@ commands that you may find particularly useful: #+BEGIN_SRC bash git pull - doom refresh + doom sync doom update #+END_SRC -** When to run ~doom refresh~ -As a rule of thumb you should run ~doom refresh~ whenever you: +** When to run ~doom sync~ +As a rule of thumb you should run ~doom sync~ whenever you: + Update Doom with ~git pull~ instead of ~doom upgrade~, + Change your ~doom!~ block in =$DOOMDIR/init.el=, @@ -843,8 +740,8 @@ As a rule of thumb you should run ~doom refresh~ whenever you: + Install an Emacs package or dependency outside of Emacs (i.e. through your OS package manager). -If anything is misbehaving, it's a good idea to run ~doom refresh~ first. ~doom -refresh~ is responsible for regenerating your autoloads file (which tells Doom +If anything is misbehaving, it's a good idea to run ~doom sync~ first. ~doom +sync~ is responsible for regenerating your autoloads file (which tells Doom where to find lazy-loaded functions and libraries), installing missing packages, and uninstall orphaned (unneeded) packages. @@ -860,7 +757,7 @@ YES=1 doom update * Defaults ** Why Ivy over Helm? -Short answer: I chose ivy because it is the simpler of the two. +Short answer: ivy is simpler to maintain. Long answer: Features and performance appear to be the main talking points when comparing the two, but as far as I'm concerned they are equal in both respects @@ -930,21 +827,20 @@ Otherwise, it is trivial to install expand-region and binds keys to it yourself: #+END_SRC ** Why not use exec-path-from-shell instead of ~doom env~? -In a nutshell, the ~doom env~ approach is a faster and more robust solution. +The ~doom env~ approach is a faster and more reliable solution. 1. ~exec-path-from-shell~ must spawn (at least) one process at startup to scrape - your shell environment. This can be arbitrarily slow depending on the user's - shell configuration. A single program (like pyenv or nvm) or config framework - (like oh-my-zsh) could undo all of Doom's startup optimizations in one fell - swoop. + your shell environment. This can be slow depending on the user's shell + configuration. A single program (like pyenv or nvm) or config framework (like + oh-my-zsh) could undo Doom's startup optimizations in one fell swoop. -2. ~exec-path-from-shell~ only scrapes /some/ state from your shell. You have to - be proactive in order to get it to capture all the envvars relevant to your - development environment. +2. ~exec-path-from-shell~ takes a whitelist approach and captures only ~PATH~ + and ~MANPATH~ by default. You must be proactive in order to capture all the + envvars relevant to your development environment and tools. - I'd rather it inherit your shell environment /correctly/ (and /completely/) - or not at all. It frontloads the debugging process rather than hiding it - until it you least want to deal with it. +~doom env~ takes the blacklist approach and captures all of your shell +environment. This front loads the debugging process, which is nicer than dealing +with it later, while you're getting work done. That said, if you still want ~exec-path-from-shell~, it is trivial to install yourself: @@ -964,16 +860,16 @@ TL;DR: =ws-butler= is less imposing. Don't be that guy who PRs 99 whitespace adjustments around his one-line contribution. Don't automate this aggressive behavior by attaching ~delete-trailing-whitespace~ (or ~whitespace-cleanup~) to ~before-save-hook~. If -you have rambunctious colleagues peppering trailing whitespace into your project, -you need to have a talk (with wiffle bats, preferably) rather than play this -passive-aggressive game of whack-a-mole. +you have rambunctious colleagues peppering trailing whitespace into your +project, you need to have a talk (with wiffle bats, preferably) rather than play +a passive-aggressive game of whack-a-mole. -Here at Doom Inc we believe that operations that mutate entire files should -never be automated. Rather, they should be invoked deliberately -- by someone -that is aware of the potential consequences. This is where =ws-butler= comes in. -It only cleans up whitespace /on the lines you've touched/ *and* it leaves -behind virtual whitespace (which is never written to the file, but remains there -so your cursor doesn't get thrown around in all that cleanup work). +Here at Doom Inc we believe that operations that mutate entire files should not +be automated. Rather, they should be invoked deliberately, when and where it is +needed, by someone that is aware of the potential consequences. This is where +=ws-butler= comes in. It only cleans up whitespace /on the lines you've touched/ +*and* it leaves behind virtual whitespace (which is never written to the file) +so your cursor doesn't get thrown around in all that cleanup work. In any case, if you had used =ws-butler= from the beginning, trailing whitespace and newlines would never be a problem! @@ -1010,14 +906,14 @@ manually (e.g. by double-clicking each file in explorer). ** ~void-variable~ and ~void-function~ errors on startup The most common culprit for these types of errors are: -1. An out-of-date autoloads file. To regenerate it, run ~doom refresh~. +1. An out-of-date autoloads file. Run ~doom sync~ to regenerate them. - To avoid this issue, remember to run ~doom refresh~ whenever you modify your + To avoid this issue, remember to run ~doom sync~ whenever you modify your ~doom!~ block in =~/.doom.d/init.el=, or add ~package!~ declarations to =~/.doom.d/packages.el=. Or if you modify =~/.emacs.d/.local= by hand, for whatever reason. - See ~doom help refresh~ for details on what this command does and when you + See ~doom help sync~ for details on what this command does and when you should use it. 2. Emacs byte-code isn't forward compatible. If you've recently switched to a @@ -1075,8 +971,8 @@ If you still want to restore the old behavior, simply disable evil-snipe-mode: 1. Make sure you don't have both =~/.doom.d= and =~/.config/doom= directories. Doom will ignore the former if the latter exists. -2. Remember to run ~doom refresh~ when it is necessary. To get to know when, - exactly, you should run this command, run ~doom help refresh~. +2. Remember to run ~doom sync~ when it is necessary. To get to know when, + exactly, you should run this command, run ~doom help sync~. If neither of these solve your issue, try ~bin/doom doctor~. It will detect a variety of common issues, and may give you some clues as to what is wrong. @@ -1138,7 +1034,7 @@ Emacs will search for this file in ~custom-theme-load-path~ and ~doom-theme~ to ~'third-party-theme~, it will search for ~third-party-theme-theme.el~. This is rarely intentional. Omit the ~-theme~ suffix. -3. Did you run ~doom refresh~ after adding your third party theme plugin's +3. Did you run ~doom sync~ after adding your third party theme plugin's ~package!~ declaration to =~/.doom.d/packages.el=? ** TRAMP connections hang forever when connecting You'll find solutions [[https://www.emacswiki.org/emacs/TrampMode#toc7][on the emacswiki]]. @@ -1148,21 +1044,30 @@ upstream, you can't run ~doom update~ to get the latest fixes due to evaluation errors. In those cases, you need to delete the broken local copy before you can install -the new one, which is achieved thus: +the new one, which is achieved by either deleting it from +=~/.emacs.d/.local/straight/repos=, or by cycling the module that installs it: 1. Comment out the broken module/package. -2. Run ~doom refresh -p~. +2. Run ~doom sync~. 3. Uncomment the module/package. -4. Run ~doom refresh~. +4. Run ~doom sync~. ** Why do I see ugly indentation highlights for tabs? [[https://github.com/hlissner/doom-emacs/blob/develop/core/core-ui.el#L132-L150][Doom highlights non-standard indentation]]. i.e. Indentation that doesn't match -the indent style you've set for that file. Doom uses space indentation for most -languages by default (excluding languages where tabs are the norm, like Go). +the indent style you've set for that file. Spaces are Doom's default style for +most languages (excluding languages where tabs are the norm, like Go). There are a couple ways to address this: -1. Change ~indent-tabs-mode~ (nil = spaces, t = tabs). +1. Fix your indentation! If it's highlighted, you have tabs when you should have + spaces (or spaces when you should be using tabs). + + Two easy commands for that: + + - =M-x tabify= + - =M-x untabify= + +2. Change ~indent-tabs-mode~ (nil = spaces, t = tabs) in =~/.doom.d/config.el=: #+BEGIN_SRC elisp ;; use tab indentation everywhere @@ -1173,13 +1078,13 @@ There are a couple ways to address this: (setq-hook! '(c-mode-hook c++-mode-hook) indent-tabs-mode t) ; C/C++ #+END_SRC -2. Use [[https://editorconfig.org/][editorconfig]] to configure code style on a per-project basis. If you +3. Use [[https://editorconfig.org/][editorconfig]] to configure code style on a per-project basis. If you enable Doom's =:tools editorconfig= module, Doom will recognize =.editorconfigrc= files. -3. Or trust in dtrt-indent; a plugin Doom uses to analyze and detect - indentation when you open a file (that isn't in a project with an - editorconfig file). This isn't foolproof, and won't work for files that have - no content in them, but it can help in one-off scenarios. +4. Or trust in dtrt-indent; a plugin Doom uses to analyze and detect indentation + when you open a file (that isn't in a project with an editorconfig file). + This isn't foolproof, and won't work for files that have no content in them, + but it can help in one-off scenarios. * TODO Contributing