diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 08df944b3..9567b875b 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -27,7 +27,7 @@ jobs:
with:
version: ${{ matrix.emacs_version }}
- - uses: actions/checkout@v1
+ - uses: actions/checkout@v2
- name: Doom version
run: "bin/doom version"
- name: Run tests
diff --git a/README.md b/README.md
index a86397f6b..25e1339fa 100644
--- a/README.md
+++ b/README.md
@@ -1,180 +1,250 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+# Doom Emacs
+
+[Website] • [Install](#install) • [Documentation] • [FAQ] • [Screenshots] • [Contribute](#contribute)
+
+
+
+
+
+[][Discord]

-
- Screenshots
- |
- Get started
- |
- Contribute
- |
- Documentation
- |
- FAQ
-
+
---
-**Quick start**
+### Table of Contents
+- [Introduction](#introduction)
+- [Features](#features)
+- [Prerequisites](#prerequisites)
+- [Install](#install)
+- [Roadmap](#roadmap)
+- [Getting help](#getting-help)
+- [Contributing](#contributing)
-```bash
-git clone https://github.com/hlissner/doom-emacs ~/.emacs.d
+
+# Introduction
+
+
+
+
+> It is a story as old as time. A stubborn, shell-dwelling, and melodramatic
+> vimmer -- envious of the features of modern text editors -- spirals into
+> despair before he succumbs to the [dark side][evil-mode]. This is his config.
+
+Doom is a configuration framework for [GNU Emacs] tailored for Emacs bankruptcy
+veterans who want less framework in their frameworks, a modicum of stability
+(and reproducibility) from their package manager, and the performance of a hand
+rolled config (or better). It can be a foundation for your own config or a
+resource for Emacs enthusiasts to learn more about our favorite operating
+system.
+
+Its design is guided by these mantras:
+
++ **Gotta go fast.** Startup and run-time performance are priorities. Doom goes
+ beyond by modifying packages to be snappier and load lazier.
++ **Close to metal.** There's less between you and vanilla Emacs by design.
+ That's less to grok and less to work around when you tinker. Internals ought
+ to be written as if reading them were part of Doom's UX, and it is!
++ **Opinionated, but not stubborn.** Doom is about reasonable defaults and
+ curated opinions, but use as little or as much of it as you like.
++ **Your system, your rules.** You know better. At least, Doom hopes so! It
+ won't *automatically* install system dependencies (and will force plugins not
+ to either). Rely on `doom doctor` to tell you what's missing.
++ **Nix/Guix was a great idea!** The Emacs ecosystem is temperamental. Things
+ break and they break often. Disaster recovery should be a priority! Doom's
+ package management should be declarative and your private config reproducible,
+ and comes with a means to roll back releases and updates (still a WIP).
+
+Check out [the FAQ][FAQ] for answers to common questions about the project.
+
+
+# Features
+- Minimalistic good looks inspired by modern editors.
+- Curated and sane defaults for many packages, (major) OSes, and Emacs itself.
+- A modular organizational structure for separating concerns in your config.
+- A standard library designed to simplify your elisp bike shedding.
+- A declarative [package management system][package-management] (powered by
+ [straight.el]) with a command line interface. Install packages from anywhere,
+ not just (M)ELPA, and pin them to any commit.
+- Optional vim emulation powered by [evil-mode], including ports of popular vim
+ plugins like [vim-sneak], [vim-easymotion], [vim-unimpaired] and
+ [more][ported-vim-plugins]!
+- Opt-in LSP integration for many languages, using [lsp-mode].
+- Support for *many* programming languages. Includes syntax highlighting,
+ linters/checker integration, inline code evaluation, code completion (where
+ possible), REPLs, documentation lookups, snippets, and more!
+- Support for *many* tools, like docker, pass, ansible, terraform, and more.
+- A Spacemacs-esque [keybinding scheme][bindings], centered around leader
+ and localleader prefix keys (SPC and SPCm for
+ evil users, C-c and C-c l for vanilla users).
+- A rule-based [popup manager][popup-system] to control how temporary buffers
+ are displayed (and disposed of).
+- Per-file indentation style detection and [editorconfig] integration. Let
+ someone else can argue about tabs vs **_spaces_**.
+- Project-management tools and framework-specific minor modes with their own
+ snippets libraries.
+- Project search (and replace) utilities, powered by [ripgrep] and [ivy] or
+ [helm].
+- Isolated and persistent workspaces (also substitutes for vim tabs).
+- Support for Chinese and Japanese input systems.
+- Save a snapshot of your shell environment to a file for Emacs to load at
+ startup. No more struggling to get Emacs to inherit your `PATH`, among other
+ things.
+
+
+# Prerequisites
++ Git 2.23+
++ Emacs 26.1+ *(27 is recommended)* with GNUTLS support
++ [ripgrep] 11.0+
++ GNU `find`
++ *OPTIONAL:* [fd] 7.3.0+ (improves file indexing performance for some commands)
+
+Doom is comprised of [~150 optional modules][Modules], some of which may have
+additional dependencies. [Visit their documentation][Modules] or run `bin/doom
+doctor` to check for any that you may have missed.
+
+
+# Install
+``` sh
+git clone --depth 1 https://github.com/hlissner/doom-emacs ~/.emacs.d
~/.emacs.d/bin/doom install
```
-More details, including dependencies and how to install Emacs, can be found [in
-the documentation](docs/getting_started.org#install).
+Then [read our Getting Started guide][documentation] to be walked through
+setting up, configuring and maintaining Doom Emacs.
-**Table of Contents**
+It's a good idea to add `~/.emacs.d/bin` to your `PATH`! Other `bin/doom`
+commands you should know about:
-- [What is Doom Emacs](#what-is-doom-emacs)
- - [Doom's mantras](#dooms-mantras)
- - [Features](#features)
-- [Getting Help](#getting-help)
- - [Community](#community)
- - [Troubleshooting](#troubleshooting)
- - [Contributing](#contributing)
++ `doom sync` to synchronize your private config with Doom. Installs new
+ packages, removes orphaned packages and regenerates caches. Run this whenever
+ you modify your private `init.el` or `packages.el`, or install/remove an Emacs
+ package through your OS package manager (e.g. mu4e or agda).
++ `doom upgrade` to update Doom to the latest release & all installed packages.
++ `doom doctor` to diagnose common issues with your system and config.
++ `doom env` to dump a snapshot of your shell environment to a file that Doom
+ will load at startup. This allows Emacs to inherit your `PATH`, among other
+ things.
++ `doom build` to recompile all installed packages (use this if you up/downgrade
+ Emacs).
-# What is Doom Emacs
-
-
-
+# Roadmap
+Doom is an active and ongoing project. To make that development more
+transparent, its roadmap (and other concerns) are published across three github
+project boards and a newsletter:
-It is a story as old as time. A stubborn, shell-dwelling, and melodramatic as
-vimmer -- envious of the features of modern text editors -- spirals into despair
-before succumbing to the [dark side][url:evil-mode]. This is his config.
++ [Development Roadmap](/projects/3): roughly outlines our goals between release
+ milestones and their progress.
++ [Plugins under review](/projects/2): lists plugins we are watching and
+ considering for inclusion, and what their status for inclusion is. Please
+ consult this list before requesting new packages/features.
++ [Upstream bugs](/projects/5): lists issues that originate from elsewhere, and
+ whether or not we have local workarounds or temporary fixes for them.
++ ~~Doom's newsletter~~ (not finished) will contain changelogs in between
+ releases.
+
-Doom is a configuration framework for [GNU
-Emacs](https://www.gnu.org/software/emacs/) tailored for Emacs bankruptcy
-veterans who want less framework in their frameworks and the performance of a
-hand rolled config (or better). It can be a foundation for your own config or a
-resource for Emacs enthusiasts to learn more about our favorite OS.
+# Getting help
+Emacs is no journey of a mere thousand miles. You _will_ run into problems and
+mysterious errors. When you do, here are some places you can look for help:
-## Doom's mantras
++ [Our documentation][documentation] covers many use cases.
+ + [The Configuration section][configuration] covers how to configure Doom and
+ its packages.
+ + [The Package Management section][package-management] covers how to install
+ and disable packages.
+ + [This section][bin/doom] explains the `bin/doom` script's most important
+ commands.
+ + [This section][common-mistakes] lists some common configuration mistakes new
+ users make, when migrating a config from another distro or their own.
+ + [This answer][change-theme] shows you how to add your own themes to your
+ private config.
+ + [This answer][change-font] shows you how to change the default font.
+ + Your issue may be documented in the [FAQ].
++ With Emacs built-in help system documentation is a keystroke away:
+ + For functions: `SPC h f` or `C-h f`
+ + For variables: `SPC h v` or `C-h v`
+ + For a keybind: `SPC h k` or `C-h k`
+ + To search available keybinds: `SPC h b b` or `C-h b b`
++ Run `bin/doom doctor` to detect common issues with your development
+ environment and private config.
++ Check out the [FAQ], in case your question has already been answered.
++ Search [Doom's issue tracker](/issues) in case your issue was already
+ reported.
++ Hop on [our Discord server][discord]; it's active and friendly! Keep an eye on
+ the #announcements channel, where I announce breaking updates and releases.
-- **Gotta go fast.** Startup and run-time performance are priorities. Doom goes
- beyond lazy loading packages by modifying them to be snappier and load lazier!
-- **Close to metal.** There's less between you and vanilla Emacs by design.
- There's less to grok, on top of Emacs.
-- **Readability counts.** Internals ought to be written as if reading them were
- part of the user experience, and it is! Modules should be syntactically sweet.
- Backend logic should be functional (as much as elisp permits), abstraction
- light and (hopefully) documented.
-- **Opinionated, but not stubborn.** Doom is a bundle of reasonable defaults and
- curated opinions, but all of it should be optional. Use as little or as much
- of it as you like.
-- **Your system, your rules.** There are more ways to set up your development
- environment than there are dislikes on Youtube Rewind '18, so Doom leaves it
- to you. Doom will not *automatically* install system dependencies (and will
- coerce its plugins not to do so either). Use `doom doctor` to figure out
- what's missing.
-## Features
+# Contribute
+[](http://makeapullrequest.com)
+[](https://github.com/bbatsov/emacs-lisp-style-guide)
+[][liberapay]
+[][paypal]
-- Minimalistic good looks inspired by modern editors.
-- A modular architecture for a more organized Emacs configuration.
-- A custom elisp library to help simplify your config.
-- (Optional) Vim-emulation powered by [evil-mode][url:evil-mode], including
- ports of popular vim plugins and functionality.
-- A declarative [package management system][doom:packages] (powered by
- [straight.el][url:straight]) with a command line interface. Install packages
- from anywhere, not just (M)ELPA.
-- A curated set of sane defaults for all packages, all (major) OSes, and Emacs
- itself.
-- Support for *many* programming languages. Too many to list. Includes syntax
- highlighting, linters/checker integration, inline code evaluation, code
- completion (where possible), REPLs, documentation lookups, snippets, and more!
-- Support for *many* tools, like docker, pass, ansible, terraform, and more.
-- A Spacemacs-esque [keybinding scheme][doom:bindings], centered around leader
- and localleader prefix keys (SPC and SPCm, by
- default).
-- A rule-based [popup management system][doom:popups] that dictates how
- temporary or disposable buffers are displayed (and disposed of).
-- Automatic indentation detection and [editorconfig][url:editorconfig]
- integration. Let someone else argue about tabs vs **\_\***spaces**\*\_**.
-- Project-management tools and framework-specific minor modes with their own
- snippets libraries.
-- Project search (and replace) utilities, powered by [ripgrep][url:ripgrep].
-- Isolated and persistent workspaces (also substitutes for vim tabs).
-- An envvar file generator that captures a snapshot of your shell environment
- for Doom to load at startup. No more struggling to get Emacs to inherit your
- `PATH`, among other things.
+Doom is a labor of love and incurable madness, but I'm only one guy. Doom
+wouldn't be where it is today without your help. I welcome contributions of any
+kind!
-# Getting Help
++ I :heart: pull requests and bug reports (see the [Contributing
+ Guidelines][contribute])!
++ Don't hesitate to [tell me my Elisp-fu sucks](/issues/new), but please tell me
+ why.
++ Hop on [our Discord server][Discord] and say hi! Help others, hang out or talk
+ to me about Emacs, gamedev, programming, physics, pixel art, anime, gaming --
+ anything you like. Nourish this lonely soul.
++ If you'd like to support my work financially, buy me a drink through
+ [liberapay] or [paypal]. My work contends with studies, adventures in indie
+ gamedev and freelance work. Donations help me allocate more time to my Emacs
+ and OSS capers.
+
+[](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/links/0)
+[](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/links/1)
+[](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/links/2)
+[](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/links/3)
+[](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/links/4)
+[](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/links/5)
+[](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/links/6)
+[](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/links/7)
-## Community
-We have [a Discord server][url:discord]! Hop on and say hi!
+[contribute]: docs/contributing.org
+[discord]: https://discord.gg/qvGgnVx
+[documentation]: docs/index.org
+[faq]: docs/faq.org
+[install]: docs/getting_started.org#install
+[backtrace]: docs/getting_started.org#how-to-extract-a-backtrace-from-an-error
+[configuration]: docs/getting_started.org#configuring-doom
+[package-management]: docs/getting_started.org#package-management
+[bin/doom]: docs/getting_started.org#the-bindoom-utility
+[common-mistakes]: docs/getting_started.org#common-mistakes-when-configuring-doom-emacs
+[change-theme]: docs/faq.org#how-do-i-change-the-theme
+[change-font]: docs/faq.org#how-do-i-change-the-fonts
+[modules]: docs/modules.org
+[popup-system]: modules/ui/popup/README.org
+[screenshots]: #screenshots
+[website]: https://doomemacs.org
-## Troubleshooting
+[bindings]: modules/config/default/+evil-bindings.el
+[editorconfig]: http://editorconfig.org/
+[evil-mode]: https://github.com/emacs-evil/evil
+[fd]: https://github.com/sharkdp/fd
+[gnu emacs]: https://www.gnu.org/software/emacs/
+[helm]: https://github.com/emacs-helm/helm
+[ivy]: https://github.com/abo-abo/swiper
+[lsp-mode]: https://github.com/emacs-lsp/lsp-mode
+[nix]: https://nixos.org
+[ported-vim-plugins]: modules/editor/evil/README.org#ported-vim-plugins
+[ripgrep]: https://github.com/BurntSushi/ripgrep
+[straight.el]: https://github.com/raxod502/straight.el
+[vim-easymotion]: https://github.com/easymotion/vim-easymotion
+[vim-lion]: https://github.com/tommcdo/vim-lion
+[vim-sneak]: https://github.com/justinmk/vim-sneak
+[vim-unimpaired]: https://github.com/tpope/vim-unimpaired
-Encountered strange behavior or an error? Here are some things to try before you
-shoot off that bug report:
-
-- Run `bin/doom sync`. This ensures Doom is properly set up and its autoloads
- files are up-to-date.
-- If you have byte-compiled your config (with `bin/doom compile`), see if
- `bin/doom clean` makes the issue go away. Never debug issues with a
- byte-compiled config, it will make your job harder.
-- Run `bin/doom doctor` to detect common issues in your development environment.
-- Search Doom's issue tracker for mention of any error messages you've received.
-- [Visit our FAQ][docs:faq] to see if your issue is listed.
-
-If all else fails, [file that bug report][github:new-issue]! Please include the
-behavior you've observed, the behavior you expected, and any error messages or
-warnings logged to the \*Messages\* buffer (can be opened with SPC h
-e or `M-x view-echo-area-messages`).
-
-It's a great help if you included a backtrace with errors, i.e. `M-x
-toggle-debug-on-error` then recreating the error(s).
-
-## Contributing
-
-Doom (and my Emacs work in general) is a labor of love and incurable madness,
-done on my spare time. If you'd like to support my work, there are many things
-you can do to help; I welcome any contribution!
-
-- I love pull requests and bug reports. Check out the [Contributing
- Guidelines][docs:contributing] to find out how you can help out.
-- I welcome Elisp pointers! Don't hesitate to [tell me my Elisp-fu
- sucks][github:new-issue] (but please tell me why).
-- Hop on [our Discord server][url:discord] and say hi! Help others out, hang out
- or talk to me about Emacs, or gamedev, or programming, machine learning,
- physics, pixel art, anime, gaming -- anything you like. Nourish this lonely
- soul!
-- If you'd like to support my work financially, consider buying me a drink
- through [liberapay][url:liberapay] or [paypal][url:paypal]. Donations are a
- great help. My work here contends with studies, ventures in indie gamedev, and
- my freelance work.
-
-[docs:wiki]: docs/index.org
-[docs:wiki-quickstart]: docs/getting_started.org
-[docs:wiki-modules]: docs/index.org#Module%20List
-[docs:wiki-customization]: docs/getting_started.org#Customize
-[docs:contributing]: docs/contributing.org
-[docs:faq]: docs/faq.org
-[github:new-issue]: https://github.com/hlissner/doom-emacs/issues/new
-[doom:bindings]: modules/config/default/+evil-bindings.el
-[doom:packages]: core/autoload/packages.el
-[doom:popups]: modules/ui/popup/README.org
-[url:discord]: https://discord.gg/qvGgnVx
-[url:liberapay]: https://liberapay.com/hlissner/donate
-[url:paypal]: https://paypal.me/henriklissner/10
-[url:editorconfig]: http://editorconfig.org/
-[url:evil-mode]: https://github.com/emacs-evil/evil
-[url:ripgrep]: https://github.com/BurntSushi/ripgrep
-[url:straight]: https://github.com/raxod502/straight.el
+[liberapay]: https://liberapay.com/hlissner/donate
+[paypal]: https://paypal.me/henriklissner/10
diff --git a/core/autoload/config.el b/core/autoload/config.el
index d465d66f4..cacd0d32d 100644
--- a/core/autoload/config.el
+++ b/core/autoload/config.el
@@ -53,8 +53,8 @@ And jumps to your `doom!' block."
;;
;;; Managements
-(cl-defmacro doom--compile (command &key on-success on-failure)
- (declare (indent defun))
+(defmacro doom--if-compile (command on-success &optional on-failure)
+ (declare (indent 2))
`(with-current-buffer (compile ,command)
(add-hook
'compilation-finish-functions
@@ -76,19 +76,20 @@ Runs `doom-reload-hook' afterwards."
(interactive)
(require 'core-cli)
(when (and IS-WINDOWS (file-exists-p doom-env-file))
- (warn "Can't regenerate envvar file from within Emacs. Run 'doom env' from the console"))
- (doom--compile (format "%s sync -e" doom-bin)
- :on-success
- (let ((doom-reloading-p t))
- (doom-initialize 'force)
- (with-demoted-errors "PRIVATE CONFIG ERROR: %s"
- (general-auto-unbind-keys)
- (unwind-protect
- (doom-initialize-modules 'force)
- (general-auto-unbind-keys t)))
- (run-hook-wrapped 'doom-reload-hook #'doom-try-run-hook)
- (print! (success "Config successfully reloaded!")))
- :on-failure
+ (message "Can't regenerate envvar file from within Emacs. Run 'doom env' from the console"))
+ ;; In case doom/reload is run before incrementally loaded packages are loaded,
+ ;; which could cause odd load order issues.
+ (mapc #'require (cdr doom-incremental-packages))
+ (doom--if-compile (format "%s sync -e" doom-bin)
+ (let ((doom-reloading-p t))
+ (doom-initialize 'force)
+ (with-demoted-errors "PRIVATE CONFIG ERROR: %s"
+ (general-auto-unbind-keys)
+ (unwind-protect
+ (doom-initialize-modules 'force)
+ (general-auto-unbind-keys t)))
+ (run-hook-wrapped 'doom-reload-hook #'doom-try-run-hook)
+ (print! (success "Config successfully reloaded!")))
(user-error "Failed to reload your config")))
;;;###autoload
@@ -119,25 +120,22 @@ imported into Emacs."
(interactive "P")
(when IS-WINDOWS
(user-error "Cannot reload envvar file from within Emacs on Windows, run it from cmd.exe"))
- (doom--compile
- (format "%s -ic '%s env%s'"
- (string-trim
- (shell-command-to-string
- (format "getent passwd %S | cut -d: -f7"
- (user-login-name))))
- doom-bin (if arg " -c" ""))
- :on-success
- (let ((doom-reloading-p t))
- (unless arg
- (doom-load-envvars-file doom-env-file)))
- :on-failure
+ (doom--if-compile
+ (format "%s -ic '%s env%s'"
+ (string-trim
+ (shell-command-to-string
+ (format "getent passwd %S | cut -d: -f7"
+ (user-login-name))))
+ doom-bin (if arg " -c" ""))
+ (let ((doom-reloading-p t))
+ (unless arg
+ (doom-load-envvars-file doom-env-file)))
(error "Failed to generate env file")))
;;;###autoload
(defun doom/upgrade ()
"Run 'doom upgrade' then prompt to restart Emacs."
(interactive)
- (doom--compile (format "%s upgrade" doom-bin)
- :on-success
- (when (y-or-n-p "You must restart Emacs for the upgrade to take effect.\n\nRestart Emacs?")
- (doom/restart-and-restore))))
+ (doom--if-compile (format "%s -y upgrade" doom-bin)
+ (when (y-or-n-p "You must restart Emacs for the upgrade to take effect.\n\nRestart Emacs?")
+ (doom/restart-and-restore))))
diff --git a/core/autoload/debug.el b/core/autoload/debug.el
index bd2f241d6..7b3f5ddcd 100644
--- a/core/autoload/debug.el
+++ b/core/autoload/debug.el
@@ -184,15 +184,45 @@ markdown and copies it to your clipboard, ready to be pasted into bug reports!"
;;;###autoload
(defun doom/am-i-secure ()
- "Test to see if your root certificates are securely configured in emacs."
+ "Test to see if your root certificates are securely configured in emacs.
+Some items are not supported by the `nsm.el' module."
(declare (interactive-only t))
(interactive)
(unless (string-match-p "\\_" system-configuration-features)
(warn "gnutls support isn't built into Emacs, there may be problems"))
(if-let* ((bad-hosts
(cl-loop for bad
- in '("https://wrong.host.badssl.com/"
- "https://self-signed.badssl.com/")
+ in '("https://expired.badssl.com/"
+ "https://wrong.host.badssl.com/"
+ "https://self-signed.badssl.com/"
+ "https://untrusted-root.badssl.com/"
+ ;; "https://revoked.badssl.com/"
+ ;; "https://pinning-test.badssl.com/"
+ "https://sha1-intermediate.badssl.com/"
+ "https://rc4-md5.badssl.com/"
+ "https://rc4.badssl.com/"
+ "https://3des.badssl.com/"
+ "https://null.badssl.com/"
+ "https://sha1-intermediate.badssl.com/"
+ ;; "https://client-cert-missing.badssl.com/"
+ "https://dh480.badssl.com/"
+ "https://dh512.badssl.com/"
+ "https://dh-small-subgroup.badssl.com/"
+ "https://dh-composite.badssl.com/"
+ "https://invalid-expected-sct.badssl.com/"
+ ;; "https://no-sct.badssl.com/"
+ ;; "https://mixed-script.badssl.com/"
+ ;; "https://very.badssl.com/"
+ "https://subdomain.preloaded-hsts.badssl.com/"
+ "https://superfish.badssl.com/"
+ "https://edellroot.badssl.com/"
+ "https://dsdtestprovider.badssl.com/"
+ "https://preact-cli.badssl.com/"
+ "https://webpack-dev-server.badssl.com/"
+ "https://captive-portal.badssl.com/"
+ "https://mitm-software.badssl.com/"
+ "https://sha1-2016.badssl.com/"
+ "https://sha1-2017.badssl.com/")
if (condition-case _e
(url-retrieve-synchronously bad)
(error nil))
diff --git a/core/autoload/files.el b/core/autoload/files.el
index 3e22607e7..65d0a6639 100644
--- a/core/autoload/files.el
+++ b/core/autoload/files.el
@@ -324,7 +324,7 @@ file if it exists, without confirmation."
(`aborted (message "Aborted"))
(_ t)))
-(defun doom--sudo-file (file)
+(defun doom--sudo-file-path (file)
(let ((host (or (file-remote-p file 'host) "localhost")))
(concat "/" (when (file-remote-p file)
(concat (file-remote-p file 'method) ":"
@@ -340,27 +340,32 @@ file if it exists, without confirmation."
(defun doom/sudo-find-file (file)
"Open FILE as root."
(interactive "FOpen file as root: ")
- (find-file (doom--sudo-file file)))
+ (find-file (doom--sudo-file-path file)))
;;;###autoload
(defun doom/sudo-this-file ()
"Open the current file as root."
(interactive)
- (find-alternate-file (doom--sudo-file (or buffer-file-name
- (when (or (derived-mode-p 'dired-mode)
- (derived-mode-p 'wdired-mode))
- default-directory)))))
+ (find-file
+ (doom--sudo-file-path
+ (or buffer-file-name
+ (when (or (derived-mode-p 'dired-mode)
+ (derived-mode-p 'wdired-mode))
+ default-directory)))))
;;;###autoload
(defun doom/sudo-save-buffer ()
"Save this file as root."
(interactive)
- (let ((file (doom--sudo-file buffer-file-name)))
+ (let ((file (doom--sudo-file-path buffer-file-name)))
(if-let (buffer (find-file-noselect file))
(let ((origin (current-buffer)))
+ (copy-to-buffer buffer (point-min) (point-max))
(unwind-protect
(with-current-buffer buffer
(save-buffer))
(unless (eq origin buffer)
- (kill-buffer buffer))))
+ (kill-buffer buffer))
+ (with-current-buffer origin
+ (revert-buffer t t))))
(user-error "Unable to open %S" file))))
diff --git a/core/autoload/fonts.el b/core/autoload/fonts.el
index 8df22d185..546e7cc0f 100644
--- a/core/autoload/fonts.el
+++ b/core/autoload/fonts.el
@@ -12,7 +12,7 @@ scaled up by `doom-big-font-increment'. See `doom-font' for details on
acceptable values for this variable.")
;;;###autoload
-(defvar doom-big-font-increment 8
+(defvar doom-big-font-increment 4
"How many steps to increase the font size (with `doom-font' as the base) when
`doom-big-font-mode' is enabled and `doom-big-font' is nil.")
diff --git a/core/autoload/help.el b/core/autoload/help.el
index 3c5954d7d..7cd190969 100644
--- a/core/autoload/help.el
+++ b/core/autoload/help.el
@@ -3,9 +3,6 @@
(defvar doom--help-major-mode-module-alist
'((dockerfile-mode :tools docker)
(agda2-mode :lang agda)
- (haxor-mode :lang assembly)
- (mips-mode :lang assembly)
- (nasm-mode :lang assembly)
(c-mode :lang cc)
(c++-mode :lang cc)
(objc++-mode :lang cc)
diff --git a/core/autoload/packages.el b/core/autoload/packages.el
index 9d6d7eed0..349f34805 100644
--- a/core/autoload/packages.el
+++ b/core/autoload/packages.el
@@ -128,7 +128,8 @@ installed."
'builtin)
((assq package package-alist)
'elpa)
- ('other)))
+ ((locate-library (symbol-name package))
+ 'other)))
;;;###autoload
(defun doom-package-different-recipe-p (name)
diff --git a/core/autoload/text.el b/core/autoload/text.el
index ae91e71e7..b56917d76 100644
--- a/core/autoload/text.el
+++ b/core/autoload/text.el
@@ -117,7 +117,7 @@ in some cases."
;;; Commands
(defun doom--bol-bot-eot-eol (&optional pos)
- (save-excursion
+ (save-mark-and-excursion
(when pos
(goto-char pos))
(let* ((bol (if visual-line-mode
@@ -155,7 +155,7 @@ in some cases."
"Jump between the indentation column (first non-whitespace character) and the
beginning of the line. The opposite of
`doom/forward-to-last-non-comment-or-eol'."
- (interactive "d")
+ (interactive "^d")
(let ((pt (or point (point))))
(cl-destructuring-bind (bol bot _eot _eol)
(doom--bol-bot-eot-eol pt)
@@ -177,7 +177,7 @@ beginning of the line. The opposite of
(defun doom/forward-to-last-non-comment-or-eol (&optional point)
"Jumps between the last non-blank, non-comment character in the line and the
true end of the line. The opposite of `doom/backward-to-bol-or-indent'."
- (interactive "d")
+ (interactive "^d")
(let ((pt (or point (point))))
(cl-destructuring-bind (_bol _bot eot eol)
(doom--bol-bot-eot-eol pt)
@@ -260,15 +260,9 @@ opposite indentation style."
Respects `require-final-newline'."
(interactive)
- (goto-char (point-max))
- (skip-chars-backward " \t\n\v")
- (when (looking-at "\n\\(\n\\|\\'\\)")
- (forward-char 1))
- (when require-final-newline
- (unless (bolp)
- (insert "\n")))
- (when (looking-at "\n+")
- (replace-match "")))
+ (save-excursion
+ (goto-char (point-max))
+ (delete-blank-lines)))
;;;###autoload
(defun doom/dos2unix ()
diff --git a/core/autoload/themes.el b/core/autoload/themes.el
index 2fb84ef3f..a78336cdf 100644
--- a/core/autoload/themes.el
+++ b/core/autoload/themes.el
@@ -34,8 +34,9 @@ all themes. It will apply to all themes once they are loaded."
(defmacro custom-set-faces! (&rest specs)
"Apply a list of face SPECS as user customizations.
-This is a drop-in replacement for `custom-set-face' that allows for a simplified
-face format."
+This is a convenience macro alternative to `custom-set-face' which allows for a
+simplified face format, and takes care of load order issues, so you can use
+doom-themes' API without worry."
(declare (indent defun))
`(custom-theme-set-faces! 'user ,@specs))
diff --git a/core/autoload/ui.el b/core/autoload/ui.el
index 3f142e5eb..56905444d 100644
--- a/core/autoload/ui.el
+++ b/core/autoload/ui.el
@@ -105,7 +105,7 @@ See `display-line-numbers' for what these values mean."
(_ (symbol-name next))))))
;;;###autoload
-(defun doom/delete-frame ()
+(defun doom/delete-frame-with-prompt ()
"Delete the current frame, but ask for confirmation if it isn't empty."
(interactive)
(if (cdr (frame-list))
diff --git a/core/cli/autoloads.el b/core/cli/autoloads.el
index 4cd2e5fd0..cfc03ba57 100644
--- a/core/cli/autoloads.el
+++ b/core/cli/autoloads.el
@@ -90,7 +90,6 @@ one wants that.")
(defun doom-cli--byte-compile-file (file)
(condition-case-unless-debug e
(let ((byte-compile-warnings (if doom-debug-mode byte-compile-warnings))
- (byte-compile-dynamic t)
(byte-compile-dynamic-docstrings t))
(when (byte-compile-file file)
(unless doom-interactive-mode
diff --git a/core/cli/doctor.el b/core/cli/doctor.el
index 5f790ccfa..22e690e2e 100644
--- a/core/cli/doctor.el
+++ b/core/cli/doctor.el
@@ -123,11 +123,8 @@ in."
"both is rarely intentional; you should one or the other."))
;; Check for fonts
- (if (not (fboundp 'find-font))
- (progn
- (warn! "Warning: unable to detect font")
- (explain! "The `find-font' function is missing. This could indicate the incorrect "
- "version of Emacs is being used!"))
+ (if (not (executable-find "fc-list"))
+ (warn! "Warning: unable to detect fonts because fontconfig isn't installed")
;; all-the-icons fonts
(when (and (pcase system-type
(`gnu/linux (concat (or (getenv "XDG_DATA_HOME")
diff --git a/core/cli/env.el b/core/cli/env.el
index de66a3e32..bb546ede1 100644
--- a/core/cli/env.el
+++ b/core/cli/env.el
@@ -9,10 +9,10 @@ them manually from your private config with the `doom-load-envvars-file'
function."))
"Creates or regenerates your envvars file.
-The envvars file is created by scraping your (interactive) shell environment
-into newline-delimited KEY=VALUE pairs. Typically by running '$SHELL -ic env'
-(or '$SHELL -c set' on windows). Doom loads this file at startup (if it exists)
-to ensure Emacs mirrors your shell environment (particularly to ensure PATH and
+The envvars file is created by scraping the current shell environment into
+newline-delimited KEY=VALUE pairs. Typically by running '$SHELL -ic env' (or
+'$SHELL -c set' on windows). Doom loads this file at startup (if it exists) to
+ensure Emacs mirrors your shell environment (particularly to ensure PATH and
SHELL are correctly set).
This is useful in cases where you cannot guarantee that Emacs (or the daemon)
@@ -59,7 +59,7 @@ Why this over exec-path-from-shell?
(defvar doom-env-ignored-vars
'("^DBUS_SESSION_BUS_ADDRESS$"
"^GPG_AGENT_INFO$"
- "^GPG_TTY$"
+ "^\\(SSH\\|GPG\\)_TTY$"
"^HOME$"
"^PS1$"
"^PWD$"
@@ -103,7 +103,6 @@ default, on Linux, this is '$SHELL -ic /usr/bin/env'. Variables in
(insert
(concat
"# -*- mode: sh -*-\n"
- (format "# Generated from a %s shell environent\n" shell-file-name)
"# ---------------------------------------------------------------------------\n"
"# This file was auto-generated by `doom env'. It contains a list of environment\n"
"# variables scraped from your default shell (excluding variables blacklisted\n"
diff --git a/core/core-editor.el b/core/core-editor.el
index c4178aa3d..1702c4d8e 100644
--- a/core/core-editor.el
+++ b/core/core-editor.el
@@ -85,8 +85,13 @@ possible."
create-lockfiles nil
make-backup-files nil
;; But have a place to store them in case we do use them...
- auto-save-list-file-name (concat doom-cache-dir "autosave")
- backup-directory-alist `(("." . ,(concat doom-cache-dir "backup/"))))
+ ;; auto-save-list-file-name (concat doom-cache-dir "autosave")
+ auto-save-list-file-prefix (concat doom-cache-dir "autosave/")
+ auto-save-file-name-transforms `((".*" ,auto-save-list-file-prefix t))
+ backup-directory-alist `((".*" . ,(concat doom-cache-dir "backup/"))))
+
+(after! tramp
+ (add-to-list 'backup-directory-alist (cons tramp-file-name-regexp nil)))
(add-hook! 'after-save-hook
(defun doom-guess-mode-h ()
@@ -101,45 +106,67 @@ possible."
;;
;;; Formatting
-;; Indentation
-(setq-default tab-width 4
- tab-always-indent t
- indent-tabs-mode nil
- fill-column 80)
+;; Favor spaces over tabs. Pls dun h8, but I think spaces (and 4 of them) is a
+;; more consistent default than 8-space tabs. It can be changed on a per-mode
+;; basis anyway (and is, where tabs are the canonical style, like go-mode).
+(setq-default indent-tabs-mode nil
+ tab-width 4)
-;; Word wrapping
-(setq-default word-wrap t
- truncate-lines t
- truncate-partial-width-windows nil)
+;; Make `tabify' and `untabify' only affect indentation. Not tabs/spaces in the
+;; middle of a line.
+(setq tabify-regexp "^\t* [ \t]+")
-(setq sentence-end-double-space nil
- delete-trailing-lines nil
- require-final-newline t
- tabify-regexp "^\t* [ \t]+") ; for :retab
+;; An archaic default in the age of widescreen 4k displays? I disagree. We still
+;; frequently split our terminals and editor frames, or have them side-by-side,
+;; using up more of that newly available horizontal real-estate.
+(setq-default fill-column 80)
-;; Favor hard-wrapping in text modes
-(add-hook 'text-mode-hook #'auto-fill-mode)
+;; Continue wrapped words at whitespace, rather than in the middle of a word.
+(setq-default word-wrap t)
+;; ...but don't do any wrapping by default. It's expensive. Enable
+;; `visual-line-mode' if you want soft line-wrapping. `auto-fill-mode' for hard
+;; line-wrapping.
+(setq-default truncate-lines t)
+;; If enabled (and `truncate-lines' was disabled), soft wrapping no longer
+;; occurs when that window is less than `truncate-partial-width-windows'
+;; characters wide. We don't need this, and it's extra work for Emacs otherwise,
+;; so off it goes.
+(setq truncate-partial-width-windows nil)
+
+;; This was a widespread practice in the days of typewriters. I actually prefer
+;; it when writing prose with monospace fonts, but it is obsolete otherwise.
+(setq sentence-end-double-space nil)
+
+;; The POSIX standard defines a line is "a sequence of zero or more non-newline
+;; characters followed by a terminating newline", so files should end in a
+;; newline. Windows doesn't respect this (because it's Windows), but we should,
+;; since programmers' tools tend to be POSIX compliant.
+(setq require-final-newline t)
+
+;; Default to soft line-wrapping in text modes. It is more sensibile for text
+;; modes, even if hard wrapping is more performant.
+(add-hook 'text-mode-hook #'visual-line-mode)
;;
;;; Clipboard / kill-ring
-;; Eliminate duplicates in the kill ring. That is, if you kill the same thing
-;; twice, you won't have to use M-y twice to get past it to older entries in the
-;; kill ring.
+;; Cull duplicates in the kill ring to reduce bloat and make the kill ring
+;; easier to peruse (with `counsel-yank-pop' or `helm-show-kill-ring'.
(setq kill-do-not-save-duplicates t)
-;;
+;; Allow UTF or composed text from the clipboard, even in the terminal or on
+;; non-X systems (like Windows or macOS), where only `STRING' is used.
(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))
;; Fixes the clipboard in tty Emacs by piping clipboard I/O through xclip, xsel,
-;; pb{copy,paste}, wl-copy, termux-clipboard-get, or getclip (cygwin).
+;; pb{copy,paste}, wl-copy, termux-clipboard-get, or getclip (cygwin); depending
+;; on what is available.
(unless IS-WINDOWS
(add-hook! 'tty-setup-hook
(defun doom-init-clipboard-in-tty-emacs-h ()
- (and (not (getenv "SSH_CONNECTION"))
- (require 'xclip nil t)
- (xclip-mode +1)))))
+ (and (require 'clipetty nil t)
+ (global-clipetty-mode +1)))))
;;
@@ -147,7 +174,8 @@ possible."
(push '("/LICENSE\\'" . text-mode) auto-mode-alist)
(push '("\\.log\\'" . text-mode) auto-mode-alist)
-(push '("\\.env\\'" . sh-mode) auto-mode-alist)
+(push '("rc\\'" . conf-mode) auto-mode-alist)
+(push '("\\.\\(?:hex\\|nes\\)\\'" . hexl-mode) auto-mode-alist)
;;
@@ -166,13 +194,13 @@ possible."
;; Only prompts for confirmation when buffer is unsaved.
revert-without-query (list "."))
- ;; Instead of using `auto-revert-mode' or `global-auto-revert-mode', we employ
- ;; lazy auto reverting on `focus-in-hook' and `doom-switch-buffer-hook'.
+ ;; Instead of `auto-revert-mode' or `global-auto-revert-mode', we lazily auto
+ ;; revert; when we save a file or switch buffers/windows (or focus on Emacs).
;;
- ;; This is because autorevert abuses the heck out of inotify handles which can
- ;; grind Emacs to a halt if you do expensive IO (outside of Emacs) on the
- ;; files you have open (like compression). We only really need to revert
- ;; changes when we switch to a buffer or when we focus the Emacs frame.
+ ;; Autorevert normally abuses the heck out of inotify handles which can grind
+ ;; Emacs to a halt if you do expensive IO (outside of Emacs) on the files you
+ ;; have open (like compression). The only alternative is aggressive polling,
+ ;; which is unreliable and expensive with a lot of buffers open.
(defun doom-auto-revert-buffer-h ()
"Auto revert current buffer, if necessary."
(unless (or auto-revert-mode (active-minibuffer-window))
@@ -197,9 +225,9 @@ possible."
(file-truename file)
file))
(setq recentf-filename-handlers
- '(substring-no-properties
- doom--recent-file-truename
- abbreviate-file-name)
+ '(substring-no-properties ; strip out lingering text properties
+ doom--recent-file-truename ; resolve symlinks of local files
+ abbreviate-file-name) ; replace $HOME with ~
recentf-save-file (concat doom-cache-dir "recentf")
recentf-auto-cleanup 'never
recentf-max-menu-items 0
@@ -265,8 +293,7 @@ possible."
`pp' can be expensive for longer lists, and there's no reason to prettify cache
files, so we replace calls to `pp' with the much faster `prin1'."
:around #'save-place-alist-to-file
- (cl-letf (((symbol-function #'pp)
- (symbol-function #'prin1)))
+ (cl-letf (((symbol-function #'pp) #'prin1))
(funcall orig-fn)))
(save-place-mode +1))
@@ -340,19 +367,18 @@ files, so we replace calls to `pp' with the much faster `prin1'."
(use-package! dtrt-indent
;; Automatic detection of indent settings
:when doom-interactive-mode
- :defer t
- :init
- (add-hook! '(change-major-mode-after-body-hook read-only-mode-hook)
- (defun doom-detect-indentation-h ()
- (unless (or (not after-init-time)
- doom-inhibit-indent-detection
- doom-large-file-p
- (memq major-mode doom-detect-indentation-excluded-modes)
- (member (substring (buffer-name) 0 1) '(" " "*")))
- ;; Don't display messages in the echo area, but still log them
- (let ((inhibit-message (not doom-debug-mode)))
- (dtrt-indent-mode +1)))))
+ :hook ((change-major-mode-after-body read-only-mode) . doom-detect-indentation-h)
:config
+ (defun doom-detect-indentation-h ()
+ (unless (or (not after-init-time)
+ doom-inhibit-indent-detection
+ doom-large-file-p
+ (memq major-mode doom-detect-indentation-excluded-modes)
+ (member (substring (buffer-name) 0 1) '(" " "*")))
+ ;; Don't display messages in the echo area, but still log them
+ (let ((inhibit-message (not doom-debug-mode)))
+ (dtrt-indent-mode +1))))
+
;; Enable dtrt-indent even in smie modes so that it can update `tab-width',
;; `standard-indent' and `evil-shift-width' there as well.
(setq dtrt-indent-run-after-smie t)
@@ -536,51 +562,6 @@ files, so we replace calls to `pp' with the much faster `prin1'."
(setq so-long-predicate #'doom-buffer-has-long-lines-p))
-(use-package! undo-tree
- ;; Branching & persistent undo
- :after-call doom-switch-buffer-hook after-find-file
- :config
- (setq undo-tree-visualizer-diff t
- undo-tree-auto-save-history t
- undo-tree-enable-undo-in-region t
- ;; Increase undo-limits by a factor of ten to avoid emacs prematurely
- ;; truncating the undo history and corrupting the tree. See
- ;; https://github.com/syl20bnr/spacemacs/issues/12110
- undo-limit 800000
- undo-strong-limit 12000000
- undo-outer-limit 120000000
- undo-tree-history-directory-alist
- `(("." . ,(concat doom-cache-dir "undo-tree-hist/"))))
-
- ;; Compress undo-tree history files with zstd, if available. File size isn't
- ;; the (only) concern here: the file IO barrier is slow for Emacs to cross;
- ;; reading a tiny file and piping it in-memory through zstd is *slightly*
- ;; faster than Emacs reading the entire undo-tree file from the get go (on
- ;; SSDs). Whether or not that's true in practice, we still enjoy zstd's ~80%
- ;; file savings (these files add up over time and zstd is so incredibly fast).
- (when (executable-find "zstd")
- (defadvice! doom--undo-tree-make-history-save-file-name-a (file)
- :filter-return #'undo-tree-make-history-save-file-name
- (concat file ".zst")))
-
- ;; Strip text properties from undo-tree data to stave off bloat. File size
- ;; isn't the concern here; undo cache files bloat easily, which can cause
- ;; freezing, crashes, GC-induced stuttering or delays when opening files.
- (defadvice! doom--undo-tree-strip-text-properties-a (&rest _)
- :before #'undo-list-transfer-to-tree
- (dolist (item buffer-undo-list)
- (and (consp item)
- (stringp (car item))
- (setcar item (substring-no-properties (car item))))))
-
- ;; Undo-tree is too chatty about saving its history files. This doesn't
- ;; totally suppress it logging to *Messages*, it only stops it from appearing
- ;; in the echo-area.
- (advice-add #'undo-tree-save-history :around #'doom-shut-up-a)
-
- (global-undo-tree-mode +1))
-
-
(use-package! ws-butler
;; a less intrusive `delete-trailing-whitespaces' on save
:after-call after-find-file
diff --git a/core/core-keybinds.el b/core/core-keybinds.el
index a79258aee..19b0517c4 100644
--- a/core/core-keybinds.el
+++ b/core/core-keybinds.el
@@ -77,7 +77,8 @@ all hooks after it are ignored.")
:init
;; Convenience aliases
(defalias 'define-key! #'general-def)
- (defalias 'unmap! #'general-unbind))
+ (defalias 'undefine-key! #'general-unbind))
+
;; HACK `map!' uses this instead of `define-leader-key!' because it consumes
;; 20-30% more startup time, so we reimplement it ourselves.
@@ -108,8 +109,8 @@ all hooks after it are ignored.")
(general--concat t doom-leader-key ,key)
,desc))))))))
(macroexp-progn
- (cons `(after! which-key ,@(nreverse wkforms))
- (nreverse forms)))))
+ (append (and wkforms `((after! which-key ,@(nreverse wkforms))))
+ (nreverse forms)))))
(defmacro define-leader-key! (&rest args)
"Define keys.
diff --git a/core/core-lib.el b/core/core-lib.el
index 0354c2d06..1bf435167 100644
--- a/core/core-lib.el
+++ b/core/core-lib.el
@@ -93,7 +93,7 @@ Accepts the same arguments as `message'."
ARGS is a list of the last N arguments to pass to FUN. The result is a new
function which does the same as FUN, except that the last N arguments are fixed
at the values with which this function was called."
- (declare (pure t) (side-effect-free t))
+ (declare (side-effect-free t))
(lambda (&rest pre-args)
(apply fn (append pre-args args))))
diff --git a/core/core-modules.el b/core/core-modules.el
index b4ff99504..f3c22fb71 100644
--- a/core/core-modules.el
+++ b/core/core-modules.el
@@ -142,10 +142,8 @@ following properties:
:path [STRING] path to category root directory
Example:
- (doom-module-set :lang 'haskell :flags '(+intero))"
- (puthash (cons category module)
- plist
- doom-modules))
+ (doom-module-set :lang 'haskell :flags '(+dante))"
+ (puthash (cons category module) plist doom-modules))
(defun doom-module-path (category module &optional file)
"Like `expand-file-name', but expands FILE relative to CATEGORY (keywordp) and
@@ -483,39 +481,6 @@ WARNINGS:
(lambda () ,@body)
'append)))
-(defmacro require! (category module &rest flags)
- "Loads the CATEGORY MODULE module with FLAGS.
-
-CATEGORY is a keyword, MODULE is a symbol and FLAGS are symbols.
-
- (require! :lang php +lsp)
-
-This is for testing and internal use. This is not the correct way to enable a
-module."
- `(let ((doom-modules (or ,doom-modules (doom-modules)))
- (module-path (doom-module-locate-path ,category ',module)))
- (doom-module-set
- ,category ',module
- (let ((plist (doom-module-get ,category ',module)))
- ,(when flags
- `(plist-put plist :flags `,flags))
- (unless (plist-member plist :path)
- (plist-put plist :path ,(doom-module-locate-path category module)))
- plist))
- (if (directory-name-p module-path)
- (condition-case-unless-debug ex
- (let ((doom--current-module ',(cons category module))
- (doom--current-flags ',flags))
- (load! "init" module-path :noerror)
- (load! "config" module-path :noerror))
- ('error
- (lwarn 'doom-modules :error
- "%s in '%s %s' -> %s"
- (car ex) ,category ',module
- (error-message-string ex))))
- (warn 'doom-modules :warning "Couldn't find module '%s %s'"
- ,category ',module))))
-
(defmacro featurep! (category &optional module flag)
"Returns t if CATEGORY MODULE is enabled.
@@ -540,16 +505,5 @@ CATEGORY and MODULE can be omitted When this macro is used from inside a module
(memq category (doom-module-get (car module) (cdr module) :flags)))))
t))
-;; DEPRECATED
-(defmacro def-package! (&rest args)
- (message "`def-package!' was renamed to `use-package!'; use that instead.")
- `(use-package! ,@args))
-(make-obsolete 'def-package! 'use-package! "2.0.9")
-
-(defmacro def-package-hook! (&rest args)
- (message "`def-package-hook!' was renamed to `use-package-hook!'; use that instead.")
- `(use-package-hook! ,@args))
-(make-obsolete 'def-package-hook! 'use-package-hook! "2.0.9")
-
(provide 'core-modules)
;;; core-modules.el ends here
diff --git a/core/core-packages.el b/core/core-packages.el
index ea21d41e7..416e0f2d0 100644
--- a/core/core-packages.el
+++ b/core/core-packages.el
@@ -1,23 +1,21 @@
;;; core/core-packages.el -*- lexical-binding: t; -*-
;; Emacs package management is opinionated, and so is Doom. Doom uses `straight'
-;; to create a declarative, lazy-loaded and optionally rolling-release package
+;; to create a declarative, lazy-loaded and (nominally) reproducible package
;; management system. We use `straight' over `package' because the latter is
-;; tempermental. ELPA sources suffer downtime occasionally, and often fail at
-;; building some packages when GNU Tar is unavailable (e.g. MacOS users start
-;; with BSD tar). There are also known gnutls errors in the current stable
-;; release of Emacs (26.x) which bork TLS handshakes with ELPA repos (mainly
-;; gnu.elpa.org). See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3434.
+;; tempermental. ELPA sources suffer downtime occasionally and often fail to
+;; build packages when GNU Tar is unavailable (e.g. MacOS users start with BSD
+;; tar). Known gnutls errors plague the current stable release of Emacs (26.x)
+;; which bork TLS handshakes with ELPA repos (mainly gnu.elpa.org). See
+;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3434.
;;
;; What's worse, you can only get the latest version of packages through ELPA.
;; In an ecosystem that is constantly changing, this is more frustrating than
-;; convenient. Straight (and Doom) can do rolling release, but it is optional
-;; (and will eventually be opt-in).
+;; convenient. Straight (and Doom) can do rolling release, but it is opt-in.
;;
-;; ANyhow, interacting with this package management system is done through the
-;; bin/doom script included with Doom Emacs. You'll find more about it by
-;; running 'doom help' (I highly recommend you add it to your PATH), but here
-;; are the highlights:
+;; Interacting with this package management system is done through Doom's
+;; bin/doom script. Find out more about it by running 'doom help' (I highly
+;; recommend you add the script to your PATH). Here are some highlights:
;;
;; + `bin/doom install`: a wizard that guides you through setting up Doom and
;; your private config for the first time.
@@ -83,35 +81,36 @@ missing) and shouldn't be deleted.")
("melpa" . ,(concat proto "://melpa.org/packages/"))
("org" . ,(concat proto "://orgmode.org/elpa/")))))
+;; package.el has no business modifying the user's init.el
(advice-add #'package--ensure-init-file :override #'ignore)
-;; Don't save `package-selected-packages' to `custom-file'
-(defadvice! doom--package-inhibit-custom-file-a (&optional value)
- :override #'package--save-selected-packages
- (if value (setq package-selected-packages value)))
-
-;; Refresh package.el the first time you call `package-install'
+;; Refresh package.el the first time you call `package-install', so it can still
+;; be used (e.g. to temporarily test packages). Remember to run 'doom sync' to
+;; purge them; they can conflict with packages installed via straight!
(add-transient-hook! 'package-install (package-refresh-contents))
-;;; straight
+
+;;
+;;; Straight
+
(setq straight-base-dir doom-local-dir
- straight-repository-branch "develop"
+ straight-repository-branch "master"
straight-cache-autoloads nil ; we already do this, and better.
;; Doom doesn't encourage you to modify packages in place. Disabling this
- ;; makes 'doom refresh' instant (once everything set up), which is much
- ;; nicer UX than the several seconds modification checks.
+ ;; makes 'doom sync' instant (once everything set up), which is much nicer
+ ;; UX than the several seconds modification checks.
straight-check-for-modifications nil
;; We handle package.el ourselves (and a little more comprehensively)
straight-enable-package-integration nil
;; Before switching to straight, `doom-local-dir' would average out at
;; around 100mb with half Doom's modules at ~230 packages. Afterwards, at
- ;; around 1gb. With shallow cloning, that is reduced to ~400mb. This
- ;; imposes an issue with packages that require their git history for
- ;; certain things to work (like magit and org), but we can deal with that
- ;; when we cross that bridge.
+ ;; around 1gb. With shallow cloning, that is reduced to ~400mb. This has
+ ;; no affect on packages that are pinned, however (run 'doom purge' to
+ ;; compact those after-the-fact). Some packages break when shallow cloned
+ ;; (like magit and org), but we'll deal with that elsewhere.
straight-vc-git-default-clone-depth 1
;; Prefix declarations are unneeded bulk added to our autoloads file. Best
- ;; we just don't have to deal with them at all.
+ ;; we don't have to deal with them at all.
autoload-compute-prefixes nil
;; We handle it ourselves
straight-fix-org nil)
@@ -119,7 +118,7 @@ missing) and shouldn't be deleted.")
(defadvice! doom--read-pinned-packages-a (orig-fn &rest args)
"Read from `doom-pinned-packages' on top of straight's lockfiles."
:around #'straight--lockfile-read-all
- (append (apply orig-fn args)
+ (append (apply orig-fn args) ; lockfiles still take priority
(doom-package-pinned-list)))
@@ -260,7 +259,7 @@ elsewhere."
(doplist! ((prop val) (list ,@plist) plist)
(unless (null val)
(plist-put! plist prop val)))
- ;; Some basic key validation; error if you're not using a valid key
+ ;; Some basic key validation; throws an error on invalid properties
(condition-case e
(when-let (recipe (plist-get plist :recipe))
(cl-destructuring-bind
@@ -286,8 +285,8 @@ elsewhere."
"A convenience macro for disabling packages in bulk.
Only use this macro in a module's (or your private) packages.el file."
(macroexp-progn
- (cl-loop for p in packages
- collect `(package! ,p :disable t))))
+ (mapcar (lambda (p) `(package! ,p :disable t))
+ packages)))
(defmacro unpin! (&rest targets)
"Unpin packages in TARGETS.
diff --git a/core/core-projects.el b/core/core-projects.el
index 05c6a0ba7..daca64c3a 100644
--- a/core/core-projects.el
+++ b/core/core-projects.el
@@ -15,9 +15,6 @@ Emacs.")
"fd")
"name of `fd-find' executable binary")
-(defvar doom-projectile-cache-timer-file (concat doom-cache-dir "projectile.timers")
- "Where to save project file cache timers.")
-
;;
;;; Packages
@@ -45,18 +42,18 @@ Emacs.")
;; Projectile runs four functions to determine the root (in this order):
;;
- ;; + `projectile-root-local' -> consults the `projectile-project-root'
- ;; variable for an explicit path.
- ;; + `projectile-root-bottom-up' -> consults
- ;; `projectile-project-root-files-bottom-up'; searches from / to your
- ;; current directory for certain files (including .project and .git)
- ;; + `projectile-root-top-down' -> consults `projectile-project-root-files';
- ;; searches from the current directory down to / for certain project
- ;; markers, like package.json, setup.py, or Cargo.toml
- ;; + `projectile-root-top-down-recurring' -> consults
- ;; `projectile-project-root-files-top-down-recurring'; e.g. searches from
- ;; the current directory down to / for a directory that has Makefile but
- ;; doesn't have a parent with one of those files.
+ ;; + `projectile-root-local' -> checks the `projectile-project-root' variable
+ ;; for an explicit path.
+ ;; + `projectile-root-bottom-up' -> searches from / to your current directory
+ ;; for the paths listed in `projectile-project-root-files-bottom-up'. This
+ ;; includes .git and .project
+ ;; + `projectile-root-top-down' -> searches from the current directory down to
+ ;; / the paths listed in `projectile-root-files', like package.json,
+ ;; setup.py, or Cargo.toml
+ ;; + `projectile-root-top-down-recurring' -> searches from the current
+ ;; directory down to / for a directory that has one of
+ ;; `projectile-project-root-files-top-down-recurring' but doesn't have a
+ ;; parent directory with the same file.
;;
;; In the interest of performance, we reduce the number of project root marker
;; files/directories projectile searches for when resolving the project root.
@@ -75,6 +72,14 @@ Emacs.")
(push (abbreviate-file-name doom-local-dir) projectile-globally-ignored-directories)
+ ;; Override projectile's dirconfig file '.projectile' with doom's project marker '.project'.
+ (defadvice! doom--projectile-dirconfig-file-a ()
+ :override #'projectile-dirconfig-file
+ (cond
+ ;; Prefers '.projectile' to maintain compatibility with existing projects.
+ ((file-exists-p! (or ".projectile" ".project") (projectile-project-root)))
+ ((expand-file-name ".project" (projectile-project-root)))))
+
;; Disable commands that won't work, as is, and that Doom already provides a
;; better alternative for.
(put 'projectile-ag 'disabled "Use +{ivy,helm}/project-search instead")
diff --git a/core/core-ui.el b/core/core-ui.el
index faf5309f9..6ff9e85ba 100644
--- a/core/core-ui.el
+++ b/core/core-ui.el
@@ -138,10 +138,11 @@ size.")
e.g. If you indent with spaces by default, tabs will be highlighted. If you
indent with tabs, spaces at BOL are highlighted.
-Does nothing if `whitespace-mode' is already active or the current buffer is
-read-only or not file-visiting."
+Does nothing if `whitespace-mode' or 'global-whitespace-mode' is already
+active or if the current buffer is read-only or not file-visiting."
(unless (or (eq major-mode 'fundamental-mode)
buffer-read-only
+ (bound-and-true-p global-whitespace-mode)
(null buffer-file-name))
(require 'whitespace)
(set (make-local-variable 'whitespace-style)
@@ -159,6 +160,10 @@ read-only or not file-visiting."
;; Simpler confirmation prompt when killing Emacs
(setq confirm-kill-emacs #'doom-quit-p)
+;; Don't prompt for confirmation when we create a new file or buffer (assume the
+;; user knows what they're doing).
+(setq confirm-nonexistent-file-or-buffer nil)
+
(setq uniquify-buffer-name-style 'forward
;; no beeping or blinking please
ring-bell-function #'ignore
@@ -203,12 +208,18 @@ read-only or not file-visiting."
;;
;;; Cursor
-;; Don't blink the cursor, it's too distracting.
+;; The blinking cursor is distracting, but also interferes with cursor settings
+;; in some minor modes that try to change it buffer-locally (like treemacs) and
+;; can cause freezing for folks (esp on macOS) with customized & color cursors.
(blink-cursor-mode -1)
;; Don't blink the paren matching the one at point, it's too distracting.
(setq blink-matching-paren nil)
+;; Some terminals offer two different cursors: a “visible” static cursor and a
+;; “very visible” blinking one. By default, Emacs uses the very visible cursor
+;; and switches to it when you start or resume Emacs. If `visible-cursor' is nil
+;; when Emacs starts or resumes, it uses the normal cursor.
(setq visible-cursor nil)
;; Don't stretch the cursor to fit wide characters, it is disorienting,
@@ -222,8 +233,6 @@ read-only or not file-visiting."
;; Make `next-buffer', `other-buffer', etc. ignore unreal buffers.
(push '(buffer-predicate . doom-buffer-frame-predicate) default-frame-alist)
-(setq confirm-nonexistent-file-or-buffer t)
-
(defadvice! doom--switch-to-fallback-buffer-maybe-a (&rest _)
"Switch to `doom-fallback-buffer' if on last real buffer.
@@ -269,9 +278,6 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
(setq indicate-buffer-boundaries nil
indicate-empty-lines nil)
-;; remove continuation arrow on right fringe
-(delq! 'continuation fringe-indicator-alist 'assq)
-
;;
;;; Windows/frames
@@ -328,8 +334,9 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
window-divider-default-right-width 1)
(add-hook 'doom-init-ui-hook #'window-divider-mode)
-;; Prompt the user for confirmation when deleting a non-empty frame
-(global-set-key [remap delete-frame] #'doom/delete-frame)
+;; Prompt for confirmation when deleting a non-empty frame; a last line of
+;; defense against accidental loss of work.
+(global-set-key [remap delete-frame] #'doom/delete-frame-with-prompt)
;; always avoid GUI
(setq use-dialog-box nil)
@@ -353,8 +360,8 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
;; while we're in the minibuffer.
(setq enable-recursive-minibuffers t)
-;; Show current key-sequence in minibuffer, like vim does. Any feedback after
-;; typing is better UX than no feedback at all.
+;; Show current key-sequence in minibuffer ala 'set showcmd' in vim. Any
+;; feedback after typing is better UX than no feedback at all.
(setq echo-keystrokes 0.02)
;; Expand the minibuffer to fit multi-line text displayed in the echo-area. This
@@ -364,7 +371,7 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
max-mini-window-height 0.15)
;; Typing yes/no is obnoxious when y/n will do
-(fset #'yes-or-no-p #'y-or-n-p)
+(advice-add #'yes-or-no-p :override #'y-or-n-p)
;; Try really hard to keep the cursor from getting stuck in the read-only prompt
;; portion of the minibuffer.
@@ -412,7 +419,7 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
(use-package! hl-line
;; Highlights the current line
- :hook ((prog-mode text-mode conf-mode) . hl-line-mode)
+ :hook ((prog-mode text-mode conf-mode special-mode) . hl-line-mode)
:config
;; Not having to render the hl-line overlay in multiple buffers offers a tiny
;; performance boost. I also don't need to see it in other buffers.
@@ -421,17 +428,17 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
;; Temporarily disable `hl-line' when selection is active, since it doesn't
;; serve much purpose when the selection is so much more visible.
- (defvar doom-buffer-hl-line-mode nil)
+ (defvar doom--hl-line-mode nil)
(add-hook! '(evil-visual-state-entry-hook activate-mark-hook)
(defun doom-disable-hl-line-h ()
(when hl-line-mode
- (setq-local doom-buffer-hl-line-mode t)
+ (setq-local doom--hl-line-mode t)
(hl-line-mode -1))))
(add-hook! '(evil-visual-state-exit-hook deactivate-mark-hook)
(defun doom-enable-hl-line-maybe-h ()
- (when doom-buffer-hl-line-mode
+ (when doom--hl-line-mode
(hl-line-mode +1)))))
@@ -513,10 +520,6 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
;; languages like Lisp.
(setq rainbow-delimiters-max-face-count 3)
-;;;###package pos-tip
-(setq pos-tip-internal-border-width 6
- pos-tip-border-width 1)
-
;;
;;; Line numbers
@@ -541,6 +544,7 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
;; Underline looks a bit better when drawn lower
(setq x-underline-at-descent-line t)
+;; DEPRECATED In Emacs 27
(defvar doom--prefer-theme-elc nil
"If non-nil, `load-theme' will prefer the compiled theme (unlike its default
behavior). Do not set this directly, this is let-bound in `doom-init-theme-h'.")
@@ -588,29 +592,44 @@ behavior). Do not set this directly, this is let-bound in `doom-init-theme-h'.")
"Load the theme specified by `doom-theme' in FRAME."
(when (and doom-theme (not (memq doom-theme custom-enabled-themes)))
(with-selected-frame (or frame (selected-frame))
- (let ((doom--prefer-theme-elc t))
+ (let ((doom--prefer-theme-elc t)) ; DEPRECATED in Emacs 27
(load-theme doom-theme t)))))
-(defadvice! doom--run-load-theme-hooks-a (theme &optional _no-confirm no-enable)
- "Set up `doom-load-theme-hook' to run after `load-theme' is called."
- :after-while #'load-theme
- (unless no-enable
- (setq doom-theme theme
- doom-init-theme-p t)
- (run-hooks 'doom-load-theme-hook)))
+(defadvice! doom--load-theme-a (orig-fn theme &optional no-confirm no-enable)
+ "Run `doom-load-theme-hook' on `load-theme' and fix its issues.
-(defadvice! doom--prefer-compiled-theme-a (orig-fn &rest args)
- "Make `load-theme' prioritize the byte-compiled theme for a moderate boost in
-startup (or theme switch) time, so long as `doom--prefer-theme-elc' is non-nil."
+1. Disable previously enabled themes.
+2. Don't let face-remapping screw up loading the new theme
+ (*cough*`mixed-pitch-mode').
+3. Record the current theme in `doom-theme'."
:around #'load-theme
- (if (or (null after-init-time)
- doom--prefer-theme-elc)
- (cl-letf* ((old-locate-file (symbol-function 'locate-file))
- ((symbol-function 'locate-file)
- (lambda (filename path &optional _suffixes predicate)
- (funcall old-locate-file filename path '("c" "") predicate))))
- (apply orig-fn args))
- (apply orig-fn args)))
+ ;; HACK Run `load-theme' from an estranged buffer, where we can be assured
+ ;; that buffer-local face remaps (by `mixed-pitch-mode', for instance)
+ ;; won't interfere with changing themes.
+ (with-temp-buffer
+ (when-let (result (funcall orig-fn theme no-confirm no-enable))
+ (unless no-enable
+ (setq doom-theme theme
+ doom-init-theme-p t)
+ (mapc #'disable-theme (remq theme custom-enabled-themes))
+ (run-hooks 'doom-load-theme-hook))
+ result)))
+
+(unless EMACS27+
+ ;; DEPRECATED Not needed in Emacs 27
+ (defadvice! doom--prefer-compiled-theme-a (orig-fn &rest args)
+ "Have `load-theme' prioritize the byte-compiled theme.
+This offers a moderate boost in startup (or theme switch) time, so long as
+`doom--prefer-theme-elc' is non-nil."
+ :around #'load-theme
+ (if (or (null after-init-time)
+ doom--prefer-theme-elc)
+ (cl-letf* ((old-locate-file (symbol-function 'locate-file))
+ ((symbol-function 'locate-file)
+ (lambda (filename path &optional _suffixes predicate)
+ (funcall old-locate-file filename path '("c" "") predicate))))
+ (apply orig-fn args))
+ (apply orig-fn args))))
;;
@@ -624,9 +643,13 @@ startup (or theme switch) time, so long as `doom--prefer-theme-elc' is non-nil."
(add-hook 'after-change-major-mode-hook #'doom-highlight-non-default-indentation-h 'append)
;; Initialize custom switch-{buffer,window,frame} hooks:
+ ;;
;; + `doom-switch-buffer-hook'
;; + `doom-switch-window-hook'
;; + `doom-switch-frame-hook'
+ ;;
+ ;; These should be done as late as possible, as not to prematurely trigger
+ ;; hooks during startup.
(add-hook 'buffer-list-update-hook #'doom-run-switch-window-hooks-h)
(add-hook 'focus-in-hook #'doom-run-switch-frame-hooks-h)
(dolist (fn '(switch-to-next-buffer switch-to-prev-buffer))
@@ -664,14 +687,14 @@ startup (or theme switch) time, so long as `doom--prefer-theme-elc' is non-nil."
(put 'customize-themes 'disabled "Set `doom-theme' or use `load-theme' in $DOOMDIR/config.el instead")
;; Doesn't exist in terminal Emacs, so we define it to prevent void-function
-;; errors emitted from packages use it without checking for it first.
+;; errors emitted from packages that blindly try to use it.
(unless (fboundp 'define-fringe-bitmap)
(fset 'define-fringe-bitmap #'ignore))
(after! whitespace
(defun doom-disable-whitespace-mode-in-childframes-a (orig-fn)
- "`whitespace-mode' inundates child frames with whitspace markers, so disable
-it to fix all that visual noise."
+ "`whitespace-mode' inundates child frames with whitespace markers, so
+disable it to fix all that visual noise."
(unless (frame-parameter nil 'parent-frame)
(funcall orig-fn)))
(add-function :around whitespace-enable-predicate #'doom-disable-whitespace-mode-in-childframes-a))
diff --git a/core/core.el b/core/core.el
index 30c666ae2..f25296992 100644
--- a/core/core.el
+++ b/core/core.el
@@ -19,20 +19,26 @@
(defvar doom--initial-load-path load-path)
(defvar doom--initial-process-environment process-environment)
(defvar doom--initial-exec-path exec-path)
-(defvar doom--initial-file-name-handler-alist file-name-handler-alist)
-;; This is consulted on every `require', `load' and various path/io functions.
-;; You get a minor speed up by nooping this.
+;; `file-name-handler-alist' is consulted on every `require', `load' and various
+;; path/io functions. You get a minor speed up by nooping this. However, this
+;; may cause problems on builds of Emacs where its site lisp files aren't
+;; byte-compiled and we're forced to load the *.el.gz files (e.g. on Alpine)
(unless noninteractive
- (setq file-name-handler-alist nil))
+ (defvar doom--initial-file-name-handler-alist file-name-handler-alist)
-;; Restore `file-name-handler-alist', because it is needed for handling
-;; encrypted or compressed files, among other things.
-(defun doom-reset-file-handler-alist-h ()
- (setq file-name-handler-alist doom--initial-file-name-handler-alist))
-(add-hook 'emacs-startup-hook #'doom-reset-file-handler-alist-h)
+ (setq file-name-handler-alist nil)
+ ;; Restore `file-name-handler-alist', because it is needed for handling
+ ;; encrypted or compressed files, among other things.
+ (defun doom-reset-file-handler-alist-h ()
+ ;; Re-add rather than `setq', because file-name-handler-alist may have
+ ;; changed since startup, and we want to preserve those.
+ (dolist (handler file-name-handler-alist)
+ (add-to-list 'doom--initial-file-name-handler-alist handler))
+ (setq file-name-handler-alist doom--initial-file-name-handler-alist))
+ (add-hook 'emacs-startup-hook #'doom-reset-file-handler-alist-h))
-;; Load the bare necessities
+;; Just the bare necessities
(require 'core-lib)
@@ -135,65 +141,88 @@ users).")
;;
;;; Emacs core configuration
-;; lo', longer logs ahoy, so we may reliably locate lapses in doom's logic
+;; lo', longer logs ahoy, so to reliably locate lapses in doom's logic later
(setq message-log-max 8192)
;; Reduce debug output, well, unless we've asked for it.
(setq debug-on-error doom-debug-mode
jka-compr-verbose doom-debug-mode)
-;; UTF-8 as the default coding system
+;; Contrary to what many Emacs users have in their configs, you really don't
+;; need more than this to make UTF-8 the default coding system:
(when (fboundp 'set-charset-priority)
(set-charset-priority 'unicode)) ; pretty
(prefer-coding-system 'utf-8) ; pretty
(setq locale-coding-system 'utf-8) ; please
-;; Except for the clipboard on Windows, where its contents could be in an
-;; encoding that's wider than utf-8, so we let Emacs/the OS decide what encoding
-;; to use.
+;; The clipboard's on Windows could be in an encoding that's wider (or thinner)
+;; than utf-8, so let Emacs/the OS decide what encoding to use there.
(unless IS-WINDOWS
(setq selection-coding-system 'utf-8)) ; with sugar on top
-;; Disable warnings from legacy advice system. They aren't useful, and we can't
-;; often do anything about them besides changing packages upstream
+;; Disable warnings from legacy advice system. They aren't useful, and what can
+;; we do about them, besides changing packages upstream?
(setq ad-redefinition-action 'accept)
;; Make apropos omnipotent. It's more useful this way.
(setq apropos-do-all t)
-;; Don't make a second case-insensitive pass over `auto-mode-alist'. If it has
-;; to, it's our (the user's) failure. One case for all!
+;; A second, case-insensitive pass over `auto-mode-alist' is time wasted, and
+;; indicates misconfiguration (or that the user needs to stop relying on case
+;; insensitivity).
(setq auto-mode-case-fold nil)
-;; Display the bare minimum at startup. We don't need all that noise. The
-;; dashboard/empty scratch buffer is good enough.
+;; Less noise at startup. The dashboard/empty scratch buffer is good enough.
(setq inhibit-startup-message t
inhibit-startup-echo-area-message user-login-name
inhibit-default-init t
+ ;; Avoid pulling in many packages by starting the scratch buffer in
+ ;; `fundamental-mode', rather than, say, `org-mode' or `text-mode'.
initial-major-mode 'fundamental-mode
initial-scratch-message nil)
-(fset #'display-startup-echo-area-message #'ignore)
+
+;; Get rid of "For information about GNU Emacs..." message at startup, unless
+;; we're in a daemon session, where it'll say "Starting Emacs daemon." instead,
+;; which isn't so bad.
+(unless (daemonp)
+ (advice-add #'display-startup-echo-area-message :override #'ignore))
;; Emacs "updates" its ui more often than it needs to, so we slow it down
-;; slightly, from 0.5s:
+;; slightly from 0.5s:
(setq idle-update-delay 1)
-;; Emacs is a huge security vulnerability, what with all the dependencies it
-;; pulls in from all corners of the globe. Let's at least try to be more
-;; discerning.
-(setq gnutls-verify-error (getenv "INSECURE")
+;; Emacs is essentially one huge security vulnerability, what with all the
+;; dependencies it pulls in from all corners of the globe. Let's try to be at
+;; least a little more discerning.
+(setq gnutls-verify-error (not (getenv "INSECURE"))
+ gnutls-algorithm-priority
+ (when (boundp 'libgnutls-version)
+ (concat "SECURE128:+SECURE192:-VERS-ALL"
+ (if (and (not IS-WINDOWS)
+ (not (version< emacs-version "26.3"))
+ (>= libgnutls-version 30605))
+ ":+VERS-TLS1.3")
+ ":+VERS-TLS1.2"))
+ ;; `gnutls-min-prime-bits' is set based on recommendations from
+ ;; https://www.keylength.com/en/4/
+ gnutls-min-prime-bits 3072
tls-checktrust gnutls-verify-error
- tls-program '("gnutls-cli --x509cafile %t -p %p %h"
+ ;; Emacs is built with `gnutls' by default, so `tls-program' would not
+ ;; be used in that case. Otherwiese, people have reasons to not go with
+ ;; `gnutls', we use `openssl' instead.
+ ;; For more details, see https://redd.it/8sykl1
+ tls-program '("openssl s_client -connect %h:%p -CAfile %t -nbio -no_ssl3 -no_tls1 -no_tls1_1 -ign_eof"
+ "gnutls-cli -p %p --dh-bits=3072 --ocsp --x509cafile=%t \
+--strict-tofu --priority='SECURE192:+SECURE128:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3' %h"
;; compatibility fallbacks
- "gnutls-cli -p %p %h"
- "openssl s_client -connect %h:%p -no_ssl2 -no_ssl3 -ign_eof"))
+ "gnutls-cli -p %p %h"))
-;; Emacs stores authinfo in HOME and in plaintext. Let's not do that, mkay? This
-;; file usually stores usernames, passwords, and other such treasures for the
+;; Emacs stores authinfo in $HOME and in plaintext. Let's not do that, mkay?
+;; This file stores usernames, passwords, and other such treasures for the
;; aspiring malicious third party.
(setq auth-sources (list (expand-file-name "authinfo.gpg" doom-etc-dir)
"~/.authinfo.gpg"))
-;; Emacs on Windows frequently confuses HOME (C:\Users\) and APPDATA,
+;; Emacs on Windows frequently confuses HOME (C:\Users\) and %APPDATA%,
;; causing `abbreviate-home-dir' to produce incorrect paths.
(when IS-WINDOWS
(setq abbreviated-home-dir "\\`'"))
@@ -228,9 +257,9 @@ users).")
;;
;;; Optimizations
-;; Disable bidirectional text rendering for a modest performance boost. Of
-;; course, this renders Emacs unable to detect/display right-to-left languages
-;; (sorry!), but for us left-to-right language speakers/writers, it's a boon.
+;; Disable bidirectional text rendering for a modest performance boost. I've set
+;; this to `nil' in the past, but the `bidi-display-reordering's docs say that
+;; is an undefined state and suggest this to be just as good:
(setq-default bidi-display-reordering 'left-to-right
bidi-paragraph-direction 'left-to-right)
@@ -240,9 +269,15 @@ users).")
(setq highlight-nonselected-windows nil)
;; More performant rapid scrolling over unfontified regions. May cause brief
-;; spells of inaccurate fontification immediately after scrolling.
+;; spells of inaccurate syntax highlighting right after scrolling, which should
+;; quickly self-correct.
(setq fast-but-imprecise-scrolling t)
+;; Font locking is the source of much slowness in Emacs. jit-lock-mode tries to
+;; defer fontification until the user is idle. This should help... in theory.
+(setq jit-lock-defer-time 0 ; only defer while processing input
+ jit-lock-stealth-time 2) ; fontify the rest of the buffer after a delay
+
;; Resizing the Emacs frame can be a terribly expensive part of changing the
;; font. By inhibiting this, we halve startup times, particularly when we use
;; fonts that are larger than the system default (which would resize the frame).
@@ -251,16 +286,15 @@ users).")
;; Don't ping things that look like domain names.
(setq ffap-machine-p-known 'reject)
+;; Font compacting can be terribly expensive, especially for rendering icon
+;; fonts on Windows. Whether it has a noteable affect on Linux and Mac hasn't
+;; been determined, but we inhibit it there anyway.
+(setq inhibit-compacting-font-caches t)
+
;; Performance on Windows is considerably worse than elsewhere, especially if
;; WSL is involved. We'll need everything we can get.
(when IS-WINDOWS
- ;; Reduce the workload when doing file IO
- (setq w32-get-true-file-attributes nil)
-
- ;; Font compacting can be terribly expensive, especially for rendering icon
- ;; fonts on Windows. Whether it has a noteable affect on Linux and Mac hasn't
- ;; been determined.
- (setq inhibit-compacting-font-caches t))
+ (setq w32-get-true-file-attributes nil)) ; slightly faster IO
;; Remove command line options that aren't relevant to our current OS; means
;; slightly less to process at startup.
@@ -274,17 +308,19 @@ users).")
;; Adopt a sneaky garbage collection strategy of waiting until idle time to
;; collect; staving off the collector while the user is working.
(when doom-interactive-mode
+ (setq gc-cons-percentage 0.6)
(add-transient-hook! 'pre-command-hook (gcmh-mode +1))
(with-eval-after-load 'gcmh
(setq gcmh-idle-delay 10
- gcmh-verbose doom-debug-mode
- gcmh-high-cons-threshold 16777216) ; 16mb
+ gcmh-high-cons-threshold 16777216
+ gcmh-verbose doom-debug-mode ; 16mb
+ gc-cons-percentage 0.1)
(add-hook 'focus-out-hook #'gcmh-idle-garbage-collect)))
;; HACK `tty-run-terminal-initialization' is *tremendously* slow for some
;; reason. Disabling it completely could have many side-effects, so we
-;; defer it until later.
-(unless (display-graphic-p)
+;; defer it until later, at which time it (somehow) runs very quickly.
+(unless (daemonp)
(advice-add #'tty-run-terminal-initialization :override #'ignore)
(add-hook! 'window-setup-hook
(defun doom-init-tty-h ()
@@ -338,12 +374,12 @@ If you want to disable incremental loading altogether, either remove
`doom-incremental-first-idle-timer' to nil. Incremental loading does not occur
in daemon sessions (they are loaded immediately at startup).")
-(defvar doom-incremental-first-idle-timer 2
+(defvar doom-incremental-first-idle-timer 2.0
"How long (in idle seconds) until incremental loading starts.
Set this to nil to disable incremental loading.")
-(defvar doom-incremental-idle-timer 1.5
+(defvar doom-incremental-idle-timer 0.75
"How long (in idle seconds) in between incrementally loading packages.")
(defun doom-load-packages-incrementally (packages &optional now)
@@ -384,7 +420,7 @@ intervals."
If this is a daemon session, load them all immediately instead."
(if (daemonp)
(mapc #'require (cdr doom-incremental-packages))
- (when (integerp doom-incremental-first-idle-timer)
+ (when (numberp doom-incremental-first-idle-timer)
(run-with-idle-timer doom-incremental-first-idle-timer
nil #'doom-load-packages-incrementally
(cdr doom-incremental-packages) t))))
@@ -407,8 +443,7 @@ Meant to be used with `run-hook-wrapped'."
nil)
(defun doom-display-benchmark-h (&optional return-p)
- "Display a benchmark, showing number of packages and modules, and how quickly
-they were loaded at startup.
+ "Display a benchmark including number of packages and modules loaded.
If RETURN-P, return the message as a string instead of displaying it."
(funcall (if return-p #'format #'message)
@@ -481,7 +516,7 @@ The overall load order of Doom is as follows:
Module config.el files
~/.doom.d/config.el
`doom-init-modules-hook'
- `after-init-hook'
+ `doom-after-init-hook' (`after-init-hook')
`emacs-startup-hook'
`doom-init-ui-hook'
`window-setup-hook'
@@ -493,7 +528,7 @@ to least)."
(setq doom-init-p t)
;; Reset as much state as possible, so `doom-initialize' can be treated like
- ;; a reset function. Particularly useful for reloading the config.
+ ;; a reset function. e.g. when reloading the config.
(setq-default exec-path doom--initial-exec-path
load-path doom--initial-load-path
process-environment doom--initial-process-environment)
diff --git a/core/packages.el b/core/packages.el
index e1a3e9612..6e22d9c1e 100644
--- a/core/packages.el
+++ b/core/packages.el
@@ -3,10 +3,10 @@
;; core.el
(package! auto-minor-mode :pin "17cfa1b548")
-(package! gcmh :pin "8867533a73")
+(package! gcmh :pin "b1bde50891")
;; core-ui.el
-(package! all-the-icons :pin "1416f37984")
+(package! all-the-icons :pin "0b74fc3618")
(package! hide-mode-line :pin "88888825b5")
(package! highlight-numbers :pin "8b4744c7f4")
(package! rainbow-delimiters :pin "5125f4e476")
@@ -14,12 +14,12 @@
;; core-editor.el
(package! better-jumper :pin "6d240032ca")
-(package! dtrt-indent :pin "48221c928b")
+(package! dtrt-indent :pin "9163cd990f")
(package! helpful :pin "c54e9ddbd6")
(when IS-MAC
(package! ns-auto-titlebar :pin "1efc30d385"))
(package! pcre2el :pin "0b5b2a2c17")
-(package! smartparens :pin "1f8857c5fe")
+(package! smartparens :pin "555626a43f")
(package! so-long
:built-in 'prefer ; included in Emacs 27+
;; REVIEW so-long is slated to be published to ELPA eventually, but until then
@@ -27,21 +27,22 @@
;; on a potato.
:recipe (:host github :repo "hlissner/emacs-so-long")
:pin "ed666b0716")
-(package! undo-tree :pin "5b6df03781")
(package! ws-butler
;; Use my fork of ws-butler, which has a few choice improvements and
;; optimizations (the original has been abandoned).
:recipe (:host github :repo "hlissner/ws-butler")
- :pin "e4430d3778")
+ :pin "2bb49d3ee7")
(unless IS-WINDOWS
- (package! xclip :pin "d022cf947d"))
+ (package! clipetty
+ :recipe (:host github :repo "spudlyo/clipetty")
+ :pin "7ee3f9c52f"))
;; core-projects.el
-(package! projectile :pin "341150c0e7")
+(package! projectile :pin "eec569dc32")
;; core-keybinds.el
-(package! general :pin "f6e928622d")
-(package! which-key :pin "7b068f3e95")
+(package! general :pin "14ad4c888b")
+(package! which-key :pin "8b49ae978c")
;; autoload/cache.el
(package! persistent-soft :pin "a1e0ddf2a1")
diff --git a/core/templates/packages.example.el b/core/templates/packages.example.el
index 2afbc7e28..4c7ece798 100644
--- a/core/templates/packages.example.el
+++ b/core/templates/packages.example.el
@@ -4,19 +4,15 @@
;; To install a package with Doom you must declare them here, run 'doom sync' on
;; the command line, then restart Emacs for the changes to take effect.
;; Alternatively, use M-x doom/reload.
-;;
-;; WARNING: Disabling core packages listed in ~/.emacs.d/core/packages.el may
-;; have nasty side-effects and is not recommended.
-;; All of Doom's packages are pinned to a specific commit, and updated from
-;; release to release. To un-pin all packages and live on the edge, do:
-;(unpin! t)
-
-;; ...but to unpin a single package:
+;; Doom's packages are pinned to a specific commit and updated from release to
+;; release. The `unpin!' macro allows you to unpin single packages...
;(unpin! pinned-package)
-;; Use it to unpin multiple packages
+;; ...or multiple packages
;(unpin! pinned-package another-pinned-package)
+;; ...Or *all* packages (NOT RECOMMENDED; will likely break things)
+;(unpin! t)
;; To install SOME-PACKAGE from MELPA, ELPA or emacsmirror:
diff --git a/docs/faq.org b/docs/faq.org
index 731984508..fa438bc40 100644
--- a/docs/faq.org
+++ b/docs/faq.org
@@ -13,11 +13,11 @@
- [[#why-is-startup-time-important-why-not-use-the-daemon][Why is startup time important? Why not use the daemon?]]
- [[#how-do-i-use-doom-alongside-other-emacs-configs][How do I use Doom alongside other Emacs configs?]]
- [[#why-should-i-use-doom-instead-of-rolling-my-own-config][Why should I use Doom instead of rolling my own config?]]
- - [[#what-is-the-meaning-behind-dooms-naming-conventions][What is the meaning behind Doom's naming conventions?]]
- - [[#how-can-i-contribute-tosupport-doom][How can I contribute to/support Doom?]]
+ - [[#what-is-the-meaning-behind-dooms-naming-convention-in-its-source-code][What is the meaning behind Doom's naming convention in its source code?]]
- [[#what-version-of-doom-am-i-running][What version of Doom am I running?]]
+ - [[#is-discord-the-only-option-for-interacting-with-your-community][Is Discord the only option for interacting with your community?]]
- [[#configuration][Configuration]]
- - [[#should-i-fork-doom-to-customize-it][Should I fork Doom to customize it?]]
+ - [[#does-doom-respect-xdg-conventions][Does Doom respect XDG conventions]]
- [[#how-do-i-configure-doom-emacs][How do I configure Doom Emacs?]]
- [[#how-do-i-enable-or-disable-a-doom-module][How do I enable or disable a Doom module?]]
- [[#how-do-i-change-the-theme][How do I change the theme?]]
@@ -27,13 +27,14 @@
- [[#how-do-i-change-the-leaderlocalleader-keys][How do I change the leader/localleader keys?]]
- [[#how-do-i-change-the-style-of-line-numbers-or-disable-them-altogether][How do I change the style of line-numbers (or disable them altogether)?]]
- [[#how-do-i-change-the-behavior-and-appearance-of-popup-windows][How do I change the behavior and appearance of popup windows?]]
- - [[#how-do-i-change-the-appearance-a-face-or-faces][How do I change the appearance a face (or faces)?]]
+ - [[#how-do-i-customize-a-theme-or-faces][How do I customize a theme or face(s)?]]
- [[#can-doom-be-customized-without-restarting-emacs][Can Doom be customized without restarting Emacs?]]
- [[#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-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]]
+ - [[#which-terminal-should-i-use][Which terminal should I use?]]
+ - [[#how-do-i-enable-lsp-support-for-insert-language-here][How do I enable LSP support for ?]]
- [[#package-management][Package Management]]
- [[#how-do-i-install-a-package-from-elpa][How do I install a package from ELPA?]]
- [[#how-do-i-install-a-package-from-githubanother-source][How do I install a package from github/another source?]]
@@ -62,6 +63,7 @@
- [[#tramp-connections-hang-forever-when-connecting][TRAMP connections hang forever when connecting]]
- [[#an-upstream-package-was-broken-and-i-cant-update-it][An upstream package was broken and I can't update it]]
- [[#why-do-i-see-ugly-indentation-highlights-for-tabs][Why do I see ugly indentation highlights for tabs?]]
+ - [[#clipetty--emit-opening-output-file-permission-denied-devpts29-error]["clipetty--emit: Opening output file: Permission denied, /dev/pts/29" error]]
- [[#contributing][Contributing]]
* General
@@ -81,9 +83,9 @@ in the [[file:getting_started.org::On Windows][Getting Starting guide]].
If you're a Windows user, help us improve our documentation!
** Is Doom only for vimmers?
-No, but it is Doom's primary audience. Its maintainer is a dyed-in-the-wool
-vimmer with almost two decades of vim muscle memory, and he came to Emacs to
-find a better vim.
+No, but it is Doom's primary audience, because its maintainer is a
+dyed-in-the-wool vimmer with almost two decades of vim muscle memory, and he
+adopted Emacs in search of a better vim.
Although Doom is less polished without evil, its growing non-evil user base is
slowly improving the situation. We welcome suggestions and PRs to help
@@ -93,12 +95,16 @@ If you'd still like a go at it, see the [[file:../modules/editor/evil/README.org
[[file:../modules/editor/evil/README.org][:editor evil]] module's documentation.
** I am a beginner. Can I use Doom?
-If you're new to the terminal, to programming, or Emacs and/or vim, Doom (or
-Emacs, for that matter) is a rough place to start. Neither Doom nor Emacs are
-particularly beginner friendly. That's not to say it's impossible, or that we
-won't help you if you ask, but expect a hefty commitment and a bumpy journey.
+This isn't a choice I can make for you. Generally, if you're new to the
+terminal, to programming, or Emacs and/or vim, then Doom (and Emacs, for that
+matter) will be a rough place to start. Neither Doom nor Emacs are particularly
+beginner friendly. Emacs' main draw is its unparalleled extensibility, but
+anything so extensible has a learning curve.
-Remember to check out the [[file:index.org][Documentation]] for a guide to getting started.
+That's not to say it's impossible, or that we won't help you if you ask, but
+expect a hefty commitment and a bumpy journey. And don't pass up on the
+[[file:index.org][Documentation]], which will walk you through setting up Doom, and includes links
+to external resources created by our community.
** How does Doom compare to Spacemacs?
To paraphrase (and expand upon) a [[https://www.reddit.com/r/emacs/comments/6pa0oq/quickstart_tutorial_for_emacs_newbies_with_doom/dkp1bhd/][reddit answer]] to this question by [[https://github.com/gilbertw1][@gilbertw1]]:
@@ -113,18 +119,19 @@ To paraphrase (and expand upon) a [[https://www.reddit.com/r/emacs/comments/6pa0
consensus. It is [mostly] the work of one developer and caters to his
vim-slanted tastes. Doom's defaults enforce very particular (albeit optional)
workflows.
-+ *Doom lacks manpower.* Bugs stick around longer, documentation is light and
- development is at the mercy of it's single maintainer's schedule, health and
- whims.
-+ *Doom is not beginner friendly.* Spacemacs works out of the box. Your mileage
- may vary with Doom; assembly is required! Familiarity with Emacs Lisp (or
- programming in general), git and the command line will go a long way to ease
- you into Doom.
-+ *Doom manages its packages outside of Emacs.* Spacemacs installs (and checks
- for packages) on startup or on demand. Doom leaves package management to be
- done externally, through the ~bin/doom~ script. This allows for package
- management to be scripted on the command line and enables a number of startup
- optimizations we wouldn't have otherwise.
++ *Doom lacks manpower.* Bugs stick around longer, documentation is lighter and
+ development is at the mercy of it's maintainer's schedule, health and whims.
++ *Doom is not beginner friendly.* Doom lacks a large community to constantly
+ improve and produce tutorials/guides for it. Spacemacs is more likely to work
+ right out of the box. Doom also holds your hand less. A little elisp, shell
+ and git-fu will go a long way to ease you into Doom.
++ *Doom is managed through it's command line interface.* The ~bin/doom~ script
+ allows you to script package management, manage your config, or utilize elisp
+ functionality externally, like org tangling or batch processing.
++ *Doom's package manager is declarative and rolling release is opt-in.* Doom
+ takes a little after nix, striving for as much config reproducibility as Emacs
+ (and git) will permit. Spacemacs uses package.el, which is rolling release
+ only.
** Why such a complicated package management system?
Doom had +four+ *five* goals for its package management system:
@@ -293,34 +300,65 @@ 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
-some of them, ordinary lazy loading techniques don't work. To name a few:
+step further. There are some massive plugins out there for which 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 or read. You no longer need ~org-babel-do-load-languages~ in your
config -- in fact, you shouldn't use it at all!
++ =org-protocol= needs to be loaded to intercept requests for org-protocol://
+ URLs. Since org-protocol depends on org, this can be expensive to load
+ yourself, so Doom loads as soon as a org-protocol:// request is received, just
+ before it is processed.
+ 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 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=:
+In addition, 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.
- #+BEGIN_SRC elisp
- (calendar find-func format-spec org-macs org-compat org-faces org-entities
- org-list org-pcomplete org-src org-footnote org-macro ob org org-agenda
- org-capture)
- #+END_SRC
+For example, instead of loading =org= (a giant package), it will load these
+dependencies, one at a time, before finally loading =org=:
- This ensures packages load as quickly as possible when you first load an org
- file.
+#+BEGIN_SRC elisp
+(calendar find-func format-spec org-macs org-compat org-faces
+ org-entities org-list org-pcomplete org-src org-footnote
+ org-macro ob org org-agenda org-capture)
+#+END_SRC
+
+This ensures packages load as quickly as possible when you first load an org
+file.
+
+*** 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~).
+
+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)
+(setq file-name-handler-alist nil)
+
+;; ... your whole emacs config here ...
+
+;; Then restore it later:
+(setq file-name-handler-alist doom--file-name-handler-alist)
+
+;; Alternatively, restore it even later:
+(add-hook 'emacs-startup-hook
+ (lambda ()
+ (setq file-name-handler-alist doom--file-name-handler-alist)))
+#+END_SRC
+
+Don't forget to restore ~file-name-handler-alist~, otherwise TRAMP won't work
+and compressed/encrypted files won't open.
*** 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
@@ -382,44 +420,61 @@ permanent entry point.
#+end_quote
** Why should I use Doom instead of rolling my own config?
-If you care about personalizing the software you use on a daily basis, even half
-as much as I do, then you probably need professional help, but you also know it
-is time consuming. Emacs out-of-the-box is a barren wasteland with archaic
-defaults. Building anything out here and getting a feel for it will take /a lot/
-of time. Time that I've already wasted and can never get back.
+Time. If you care about personalizing the software you use on a daily basis,
+even half as much as I do, then you probably need professional help, but you
+also know it is time consuming. Emacs out-of-the-box is a barren wasteland with
+archaic defaults. Building anything out here and getting a feel for it will take
+/a lot/ of time. Time that I've already wasted and can never get back.
Time you could otherwise spend attending your daughter's dance recitals, that
baseball game your son's team almost won last Thursday, or answering the court
summons to fight for custody of your kids.
++ Doom has solved many problems big and small you'll likely run into at some
+ point in your Emacs career. And the problems don't end there! Let someone else
+ worry about the menial things.
++ Doom will be faster than most hand-rolled configs. Startup is one thing, but
+ Doom invests a lot of effort to improve runtime performance as well.
++ Doom's package manager (powered by straight.el) is declarative, non-rolling
+ release and (nominally) reproducible; which is unique on the Emacs distro
+ scene. Upstream issues won't surprise you as much, and you can roll back when
+ you don't have the time to deal with them.
++ It facilitates integration with the command line, which makes it easy to
+ integrate external tools with Emacs via the =bin/doom= script.
+
Also, Doom's fast yo.
-** What is the meaning behind Doom's naming conventions?
+** What is the meaning behind Doom's naming convention in its source code?
You'll find [[file:contributing.org::*Conventions][an overview of Doom's code conventions]] in the [[file:contributing.org][contributing guide]].
-** How can I contribute to/support Doom?
-Take a look at the [[file:contributing.org][Contributing guide]].
-
** What version of Doom am I running?
You'll find the current version displayed in the modeline on the dashboard. It
-can also be retrieved using ~M-x doom/version~ (bound to =SPC h d v= by default)
-or ~doom info~ on the command line.
+can also be retrieved using ~M-x doom/version~ (bound to =SPC h d v= or =C-h d
+v= by default) or ~bin/doom version~ on the command line.
+
+** Is Discord the only option for interacting with your community?
+Yes. I selected it for my personal convenience and have no plans to extend our
+community to any other platform (like Matrix, IRC or Slack), or add bridges for
+them. I already have my hands full managing the one.
+
+My being so active on our Discord is owed to that fact that my friends, family
+and other communities were on Discord to begin with. My availability was the
+most important factor in choosing a platform, even if there are other platforms
+better suited to the task.
+
+Email is a possible alternative, but it is constantly swamped; expect a long
+turn-around time.
* Configuration
-** Should I fork Doom to customize it?
-No. Not unless you have a good reason for doing so (and you're comfortable with
-the git-rebase workflow). Your customization can be relegated to =~/.doom.d/=
-(or =~/.config/doom/=) entirely.
+** Does Doom respect XDG conventions
+Yes. Your private config (normally in =~/.doom.d=) can be moved to
+=~/.config/doom=.
-If you /must/ modify Doom proper to get something done, it's a code smell.
-
-Visit the [[file:getting_started.org::*Customize][Customize section]] of [[file:getting_started.org][the Getting Started guide]] for details on how to
-do this.
+And as of Emacs 27, Emacs will recognize =~/.config/emacs=.
** How do I configure Doom Emacs?
-Canonically, your private config is kept in =~/.doom.d/= or =~/.config/doom/=.
-Doom will prioritize =~/.config/doom=, if it exists. This directory is referred
-to as your ~$DOOMDIR~.
+Canonically, your private config is kept in =~/.doom.d/= (or =~/.config/doom/=).
+This directory is referred to as your ~$DOOMDIR~.
Your private config is typically comprised of an =init.el=, =config.el= and
=packages.el= file. Put all your config in =config.el=, install packages by
@@ -427,11 +482,14 @@ adding ~package!~ declarations to =packages.el=, and enable/disable modules in
you ~doom!~ block, which should have been created in your =init.el= when you
first ran ~doom install~.
+You shouldn't need to fork Doom or modify =~/.emacs.d=. If you have to do this
+to achieve something, it can be considered a bug.
+
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?
Comment or uncomment the module in your ~doom!~ block, found in
-=$DOOMDIR/init.el=.
+=~/.doom.d/init.el=.
Remember to run ~bin/doom sync~ afterwards, on the command line, to sync your
module list with Doom.
@@ -613,18 +671,18 @@ 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)?
+** How do I customize a theme or face(s)?
Doom provides the ~custom-set-faces!~ and ~custom-theme-set-faces!~ macros as a
convenience.
-#+begin_quote
-*Do not use ~M-x customize~ or any of the built-in Emacs customize-* API.* Doom
-does not support it and never will; those settings could break at any time.
-#+end_quote
+See =SPC h f custom-set-faces\!= (or =C-h f custom-set-faces\!=) for
+documentation on and examples of its use.
-See = f custom-set-faces\!= (or =M-x helpful-function custom-set-faces\!=)
-for documentation and examples on how to use it. == is =SPC h= for evil
-users and =C-h= for non-evil users.
+#+begin_quote
+Other sources may recommend ~M-x customize~, ~M-x customize-themes~ or ~M-x
+customize-face~. *Do not use these commands.* Doom does not support them and
+their settings could break any time.
+#+end_quote
** Can Doom be customized without restarting Emacs?
Short answer: You can, but you shouldn't.
@@ -643,20 +701,13 @@ tools for experienced Emacs users to skirt around it (most of the time):
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.
+ complications arising from your private config.
- You can quickly restart Emacs and restore the last session with
~doom/restart-and-restore~ (bound to =SPC q r=).
** Can Vim/Evil be removed for a more vanilla Emacs experience?
Yes! See the [[file:../modules/editor/evil/README.org::Removing evil-mode][Removing evil-mode]] section in [[file:../modules/editor/evil/README.org][:editor evil]]'s documentation.
-** Should I use ~make~ or ~bin/doom~?
-~bin/doom~ is recommended. Doom's Makefile (to manage your config, at least) is
-deprecated. It forwards to ~bin/doom~ anyway.
-
** When should and shouldn't I use ~bin/doom~?
~bin/doom~ is your best friend. It'll keep all your secrets (mostly because it's
a shell script incapable of sentience and thus incapable of retaining, much less
@@ -710,6 +761,54 @@ doom --yes update
YES=1 doom update
#+END_SRC
+** Which terminal should I use?
+Looking for a terminal in Emacs? Doom offers four modules:
+
++ =:term eshell=
++ =:term shell=,
++ =:term term=
++ =:term vterm=.
+
+But which do you choose?
+
++ =eshell= is the Emacs Lisp shell. It's stable, works anywhere Emacs runs (on
+ any OS) and has no external dependencies, /but/ lacks features you'll expect
+ from mature shells and tends to be slower than them.
++ =shell= is a shell /for/ your shell. Think of it like a REPL for bash/zsh,
+ rather than terminal emulation. Due to its simplicity, you're less likely to
+ encounter edge cases (e.g. against your shell config), but it has the smallest
+ feature set. It also won't work with TUI programs like htop or vim.
++ =term= is Emacs' built-in terminal emulator. It's alright when it works, awful
+ when it doesn't. =vterm= is almost always a better option.
++ =vterm= is as good as terminal emulation gets in Emacs atm, but has a few
+ extra steps to get going. a) Emacs must be built with dynamic modules support
+ and b) you'll need to compile vterm-module.so, which has external dependencies
+ (libvterm). It is automatically built when you first open =vterm=, but this
+ will fail on Windows, NixOS and Guix out of the box -- you're on your own
+ there!
+
+For a terminal in Emacs, =eshell= and =vterm= are generally the best options.
+
+** How do I enable LSP support for ?
+Doom supports LSP, but it is not enabled by default. To enable it, you must:
+
+1. Enable the =:tools lsp= module,
+2. Enable the =+lsp= flag for the appropriate modules you want LSP support for
+ (e.g. =:lang (python +lsp)= or =:lang (rust +lsp)=),
+3. Install the prerequisite LSP servers through your package manager or other
+ means. You can find a list of supported servers on [[https://github.com/emacs-lsp/lsp-mode#supported-languages][the lsp-mode project page]].
+4. Run ~doom sync~ on the command line and restart Emacs.
+
+Some language modules may lack LSP support (either because it hasn't been
+implemented yet or I'm not aware of it yet -- let us know!). To enable LSP for
+these languages, add this to =$DOOMDIR/config.el=:
+
+#+BEGIN_SRC elisp
+(add-hook 'MAJOR-MODE-local-vars-hook #'lsp!)
+;; Where =MAJOR-MODE= is the major mode you're targeting. e.g.
+;; lisp-mode-local-vars-hook
+#+END_SRC
+
* Package Management
** How do I install a package from ELPA?
See the "[[file:getting_started.org::*Installing packages][Installing packages]]" section of the [[file:getting_started.org][Getting Started]] guide.
@@ -968,9 +1067,6 @@ known fix for this. To work around it, you must either:
** Doom crashes when...
Here are a few common causes for random crashes:
-+ You have enabled ~undo-tree-auto-save-history~. A bloated cache for a
- particular file can cause a stack overflow. These caches are stored in
- =~/.emacs.d/.local/cache/undo-tree-hist/=. Delete this folder to clear it.
+ On some systems (particularly MacOS), manipulating the fringes or window
margins can cause Emacs to crash. This is most prominent in the Doom Dashboard
(which tries to center its contents), in org-mode buffers (which uses
@@ -1064,5 +1160,8 @@ There are a couple ways to address this:
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.
+** "clipetty--emit: Opening output file: Permission denied, /dev/pts/29" error
+This applies to tmux users, in particular. See
+https://github.com/spudlyo/clipetty/issues/15 for a solution.
* TODO Contributing
diff --git a/docs/getting_started.org b/docs/getting_started.org
index 2ab8da320..5e04916a9 100644
--- a/docs/getting_started.org
+++ b/docs/getting_started.org
@@ -564,7 +564,7 @@ disabled by adding or removing them from your ~doom!~ block (found in
=$DOOMDIR/init.el=).
#+begin_quote
-If =$DOOMDIR/init.el= doesn't exist, you haven't installed Doom yet. See [[*Install][the
+If =$DOOMDIR/init.el= doesn't exist, you haven't installed Doom yet. See [[#install][the
"Install" section]] above.
#+end_quote
@@ -717,14 +717,29 @@ To unpin a package, use the ~unpin!~ macro:
;; Or to unpin an entire category of modules
(unpin! :completion :lang :tools)
+
+;; This will work too, if you prefer the syntax, but it provides no concise
+;; syntax for unpinning multiple packages:
+(package! helm :pin nil)
#+END_SRC
-To unpin all packages and make Doom Emacs rolling release, use
+Though it is *highly* discouraged, you may unpin all packages and make Doom
+Emacs rolling release:
#+BEGIN_SRC elisp
(unpin! t)
#+END_SRC
+#+begin_quote
+Unpinning all packages is discouraged because Doom's modules are designed
+against the pinned versions of its packages. More volatile packages (like
+lsp-mode, ein and org) change rapidly, and are likely to cause breakages if
+unpinned.
+
+Instead, it's a better idea to selectively unpin packages, or repin them to the
+exact commit you want.
+#+end_quote
+
*** Disabling packages
The ~package!~ macro possesses a ~:disable~ property:
@@ -895,7 +910,7 @@ also be helpful for debugging.
+ define-key
+ global-set-key
+ map!
-+ unmap!
++ undefine-key!
+ define-key!
** Writing your own modules
diff --git a/docs/index.org b/docs/index.org
index e122f664e..cb0e4fd1a 100644
--- a/docs/index.org
+++ b/docs/index.org
@@ -29,7 +29,7 @@ d s= (or =C-h d s=).
- [[#asking-for-help][Asking for help]]
- [[#project-roadmap][Project roadmap]]
- [[#tutorials--guides][Tutorials & guides]]
- - [[#projects-that-supportcompliment-doom][Projects that support/compliment Doom]]
+ - [[#projects-that-supportcomplement-doom][Projects that support/complement Doom]]
- [[#similar-projects][Similar projects]]
* TODO Release Notes
@@ -96,7 +96,7 @@ d s= (or =C-h d s=).
+ *Vim & Evil*
- [[https://gist.github.com/dmsul/8bb08c686b70d5a68da0e2cb81cd857f][A crash course on modal editing and Ex commands]]
-** Projects that support/compliment Doom
+** Projects that support/complement Doom
+ [[https://github.com/plexus/chemacs][plexus/chemacs]]
+ [[https://github.com/r-darwish/topgrade][r-darwish/topgrade]]
diff --git a/docs/modules.org b/docs/modules.org
index e062d5113..5bb2516d3 100644
--- a/docs/modules.org
+++ b/docs/modules.org
@@ -42,7 +42,7 @@ completion.
+ [[file:../modules/completion/company/README.org][company]] =+childframe +tng= - The ultimate code completion backend
+ helm =+fuzzy +childframe= - *Another* search engine for love and life
+ ido - The /other/ *other* search engine for love and life
-+ [[file:../modules/completion/ivy/README.org][ivy]] =+fuzzy +prescient +childframe= - /The/ search engine for love and life
++ [[file:../modules/completion/ivy/README.org][ivy]] =+fuzzy +prescient +childframe +icons= - /The/ search engine for love and life
* :config
Modules that configure Emacs one way or another, or focus on making it easier
@@ -61,6 +61,7 @@ Modules that affect and augment your ability to manipulate or insert text.
+ [[file:../modules/editor/file-templates/README.org][file-templates]] - Auto-inserted templates in blank new files
+ [[file:../modules/editor/fold/README.org][fold]] - universal code folding
+ format =+onsave= - TODO
++ god - TODO
+ [[file:../modules/editor/lispy/README.org][lispy]] - TODO
+ multiple-cursors - TODO
+ [[file:../modules/editor/objed/README.org][objed]] - TODO
@@ -75,6 +76,7 @@ Modules that reconfigure or augment packages or features built into Emacs.
+ [[file:../modules/emacs/dired/README.org][dired]] =+ranger +icons= - TODO
+ electric - TODO
+ [[file:../modules/emacs/ibuffer/README.org][ibuffer]] =+icons= - TODO
++ [[file:../modules/emacs/undo/README.org][undo]] =+tree= - A smarter, more intuitive & persistent undo history
+ vc - TODO
* :email
@@ -90,7 +92,6 @@ Modules that reconfigure or augment packages or features built into Emacs.
Modules that bring support for a language or group of languages to Emacs.
+ [[file:../modules/lang/agda/README.org][agda]] - TODO
-+ assembly - TODO
+ [[file:../modules/lang/cc/README.org][cc]] =+lsp= - TODO
+ [[file:../modules/lang/clojure/README.org][clojure]] =+lsp= - TODO
+ common-lisp - TODO
@@ -107,14 +108,16 @@ Modules that bring support for a language or group of languages to Emacs.
+ [[file:../modules/lang/fsharp/README.org][fsharp]] - TODO
+ [[file:../modules/lang/fstar/README.org][fstar]] - F* support
+ [[file:../modules/lang/go/README.org][go]] =+lsp= - TODO
-+ [[file:../modules/lang/haskell/README.org][haskell]] =+dante +intero +lsp= - TODO
++ [[file:../modules/lang/haskell/README.org][haskell]] =+dante +ghcide +lsp= - TODO
+ hy - TODO
+ [[file:../modules/lang/idris/README.org][idris]] - TODO
++ [[file:../modules/lang/json/README.org][json]] =+lsp= - TODO
+ java =+meghanada +lsp= - TODO
+ [[file:../modules/lang/javascript/README.org][javascript]] =+lsp= - JavaScript, TypeScript, and CoffeeScript support
-+ julia - TODO
++ julia =+lsp= - TODO
+ kotlin =+lsp+= - TODO
+ [[file:../modules/lang/latex/README.org][latex]] =+latexmk +cdlatex +lsp= - TODO
++ [[file:../modules/lang/latex/README.org][latex]] =+latexmk +cdlatex +fold= - TODO
+ lean - TODO
+ [[file:../modules/lang/ledger/README.org][ledger]] - TODO
+ lua =+moonscript= - TODO
@@ -122,7 +125,7 @@ Modules that bring support for a language or group of languages to Emacs.
+ [[file:../modules/lang/nim/README.org][nim]] - TODO
+ nix - TODO
+ [[file:../modules/lang/ocaml/README.org][ocaml]] =+lsp= - TODO
-+ [[file:../modules/lang/org/README.org][org]] =+brain +dragndrop +gnuplot +hugo +ipython +journal +jupyter +pandoc +pomodoro +present= - TODO
++ [[file:../modules/lang/org/README.org][org]] =+brain +dragndrop +gnuplot +hugo +ipython +journal +jupyter +pandoc +pomodoro +present +roam= - TODO
+ [[file:../modules/lang/perl/README.org][perl]] - TODO
+ [[file:../modules/lang/php/README.org][php]] =+lsp= - TODO
+ plantuml - TODO
@@ -136,10 +139,12 @@ Modules that bring support for a language or group of languages to Emacs.
+ scala =+lsp= - TODO
+ [[file:../modules/lang/scheme/README.org][scheme]] - TODO
+ [[file:../modules/lang/sh/README.org][sh]] =+fish +lsp= - TODO
++ [[file:../modules/lang/sml/README.org][sml]] - TODO
+ [[file:../modules/lang/solidity/README.org][solidity]] - TODO
+ swift =+lsp= - TODO
+ terra - TODO
+ web =+lsp= - HTML and CSS (SCSS/SASS/LESS/Stylus) support.
++ [[file:../modules/lang/yaml/README.org][yaml]] =+lsp= - TODO
* :term
Modules that offer terminal emulation.
@@ -153,7 +158,7 @@ Modules that offer terminal emulation.
Small modules that give Emacs access to external tools & services.
+ ansible - TODO
-+ debugger - A (nigh-)universal debugger in Emacs
++ debugger =+lsp= - A (nigh-)universal debugger in Emacs
+ [[file:../modules/tools/direnv/README.org][direnv]] - TODO
+ [[file:../modules/tools/docker/README.org][docker]] =+lsp= - TODO
+ [[file:../modules/tools/editorconfig/README.org][editorconfig]] - TODO
@@ -164,7 +169,7 @@ Small modules that give Emacs access to external tools & services.
backend
+ [[file:../modules/tools/lsp/README.org][lsp]] =+peek= - TODO
+ macos - TODO
-+ magit - TODO
++ [[file:../modules/tools/magit/README.org][magit]] =+forge= - TODO
+ make - TODO
+ pass - TODO
+ pdf - TODO
@@ -190,7 +195,7 @@ Aesthetic modules that affect the Emacs interface or user experience.
+ [[file:../modules/ui/neotree/README.org][neotree]] - TODO
+ [[file:../modules/ui/ophints/README.org][ophints]] - TODO
+ [[file:../modules/ui/popup/README.org][popup]] =+all +defaults= - Makes temporary/disposable windows less intrusive
-+ pretty-code - TODO
++ [[file:../modules//ui/pretty-code/README.org][pretty-code]] =+fira +hasklig +iosevka +pragmata-pro= - TODO
+ [[file:../modules/ui/tabs/README.org][tabs]] - TODO
+ treemacs - TODO
+ [[file:../modules/ui/unicode/README.org][unicode]] - TODO
diff --git a/init.example.el b/init.example.el
index 1e15228b5..370dd77d4 100644
--- a/init.example.el
+++ b/init.example.el
@@ -1,11 +1,11 @@
;;; init.el -*- lexical-binding: t; -*-
-;; This file controls what Doom modules are enabled and what order they load in.
-;; Remember to run 'doom sync' after modifying it!
+;; This file controls what Doom modules are enabled and what order they load
+;; in. Remember to run 'doom sync' after modifying it!
;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's
-;; documentation. There you'll find information about all of Doom's modules
-;; and what flags they support.
+;; documentation. There you'll find information about all of Doom's
+;; modules and what flags they support.
;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or
;; 'C-c g k' for non-vim users) to view its documentation. This works on
@@ -34,17 +34,17 @@
;;hydra
;;indent-guides ; highlighted indent columns
modeline ; snazzy, Atom-inspired modeline, plus API
- nav-flash ; blink the current line after jumping
+ ;;nav-flash ; blink cursor line after big motions
;;neotree ; a project drawer, like NERDTree for vim
ophints ; highlight the region an operation acts on
(popup +defaults) ; tame sudden yet inevitable temporary windows
- ;;pretty-code ; replace bits of code with pretty symbols
+ ;;pretty-code ; ligatures or substitute text with pretty symbols
;;tabs ; an tab bar for Emacs
;;treemacs ; a project drawer, like neotree but cooler
;;unicode ; extended unicode support for various languages
vc-gutter ; vcs diff in the fringe
vi-tilde-fringe ; fringe tildes to mark beyond EOB
- window-select ; visually switch windows
+ ;;window-select ; visually switch windows
workspaces ; tab emulation, persistence & separate workspaces
;;zen ; distraction-free coding or writing
@@ -66,13 +66,14 @@
dired ; making dired pretty [functional]
electric ; smarter, keyword-based electric-indent
;;ibuffer ; interactive buffer management
+ undo ; persistent, smarter undo for your inevitable mistakes
vc ; version-control and Emacs, sitting in a tree
:term
- ;;eshell ; a consistent, cross-platform shell (WIP)
- ;;shell ; a terminal REPL for Emacs
- ;;term ; terminals in Emacs
- ;;vterm ; another terminals in Emacs
+ ;;eshell ; the elisp shell that works everywhere
+ ;;shell ; simple shell REPL for Emacs
+ ;;term ; basic terminal emulator for Emacs
+ ;;vterm ; the best terminal emulation in Emacs
:checkers
syntax ; tasing you for every semicolon you forget
@@ -103,14 +104,14 @@
:lang
;;agda ; types of types of types of types...
- ;;assembly ; assembly for fun or debugging
;;cc ; C/C++/Obj-C madness
;;clojure ; java with a lisp
;;common-lisp ; if you've seen one lisp, you've seen them all
;;coq ; proofs-as-programs
;;crystal ; ruby at the speed of c
;;csharp ; unity, .NET, and mono shenanigans
- data ; config/data formats
+ ;;data ; config/data formats
+ ;;(dart +flutter) ; paint ui and not much else
;;elixir ; erlang done right
;;elm ; care for a cup of TEA?
emacs-lisp ; drown in parentheses
@@ -119,10 +120,11 @@
;;faust ; dsp, but you get to keep your soul
;;fsharp ; ML stands for Microsoft's Language
;;fstar ; (dependent) types and (monadic) effects and Z3
- ;;go ; the hipster dialect
+ ;;(go +lsp) ; the hipster dialect
;;(haskell +dante) ; a language that's lazier than I am
;;hy ; readability of scheme w/ speed of python
;;idris ;
+ ;;json ; At least it ain't XML
;;(java +meghanada) ; the poster child for carpal tunnel syndrome
;;javascript ; all(hope(abandon(ye(who(enter(here))))))
;;julia ; a better, faster MATLAB
@@ -136,13 +138,7 @@
;;nim ; python + lisp at the speed of c
;;nix ; I hereby declare "nix geht mehr!"
;;ocaml ; an objective camel
- (org ; organize your plain life in plain text
- +dragndrop ; drag & drop files/images into org buffers
- ;;+hugo ; use Emacs for hugo blogging
- ;;+jupyter ; ipython/jupyter support for babel
- ;;+pandoc ; export-with-pandoc support
- ;;+pomodoro ; be fruitful with the tomato technique
- +present) ; using org-mode for presentations
+ org ; organize your plain life in plain text
;;perl ; write code no one else can comprehend
;;php ; perl's insecure younger brother
;;plantuml ; diagrams for confusing people more
@@ -157,10 +153,12 @@
;;scala ; java, but good
;;scheme ; a fully conniving family of lisps
sh ; she sells {ba,z,fi}sh shells on the C xor
+ ;;sml
;;solidity ; do you need a blockchain? No.
;;swift ; who asked for emoji variables?
;;terra ; Earth and Moon in alignment for performance.
;;web ; the tubes
+ ;;yaml ; JSON, but readable
:email
;;(mu4e +gmail)
diff --git a/modules/app/irc/autoload/irc.el b/modules/app/irc/autoload/irc.el
index b560563fe..2f6434af6 100644
--- a/modules/app/irc/autoload/irc.el
+++ b/modules/app/irc/autoload/irc.el
@@ -7,12 +7,14 @@
(not inhibit-workspace))
(+workspace-switch +irc--workspace-name 'auto-create))
(let ((buffers (doom-buffers-in-mode 'circe-mode nil t)))
- (if buffers
- (ignore (switch-to-buffer (car buffers)))
- (require 'circe)
- (delete-other-windows)
- (switch-to-buffer (doom-fallback-buffer))
- t)))
+ (if (not (member (window-buffer) buffers))
+ (if buffers
+ (ignore (switch-to-buffer (car buffers)))
+ (require 'circe)
+ (delete-other-windows)
+ (switch-to-buffer (doom-fallback-buffer))
+ t)
+ (user-error "IRC buffer is already active and selected"))))
;;;###autoload
(defun =irc (&optional inhibit-workspace)
diff --git a/modules/app/irc/config.el b/modules/app/irc/config.el
index 38f910a0c..30b5c1e5e 100644
--- a/modules/app/irc/config.el
+++ b/modules/app/irc/config.el
@@ -48,7 +48,6 @@ playback.")
(use-package! circe
:commands circe circe-server-buffers
- :init (setq circe-network-defaults nil)
:config
(setq circe-default-quit-message nil
circe-default-part-message nil
@@ -95,6 +94,25 @@ playback.")
(add-hook 'circe-mode-hook #'+irc--add-circe-buffer-to-persp-h)
(add-hook 'circe-mode-hook #'turn-off-smartparens-mode)
+ ;; HACK Fix #1862: circe hangs on TLS connections when using OpenSSL versions
+ ;; > 1.1.0, where tls.el does not correctly determine the end of the info
+ ;; block. This fixes proposed in jorgenschaefer/circe#340
+ (setq-hook! 'circe-mode-hook
+ tls-end-of-info
+ (concat "\\("
+ ;; `openssl s_client' regexp. See ssl/ssl_txt.c lines 219-220.
+ ;; According to apps/s_client.c line 1515 `---' is always the last
+ ;; line that is printed by s_client before the real data.
+ "^ Verify return code: .+\n\\(\\|^ Extended master secret: .+\n\\)\\(\\|^ Max Early Data: .+\n\\)---\n\\|"
+ ;; `gnutls' regexp. See src/cli.c lines 721-.
+ "^- Simple Client Mode:\n"
+ "\\(\n\\|" ; ignore blank lines
+ ;; According to GnuTLS v2.1.5 src/cli.c lines 640-650 and 705-715 in
+ ;; `main' the handshake will start after this message. If the
+ ;; handshake fails, the programs will abort.
+ "^\\*\\*\\* Starting TLS handshake\n\\)*"
+ "\\)"))
+
(defadvice! +irc--circe-run-disconnect-hook-a (&rest _)
"Runs `+irc-disconnect-hook' after circe disconnects."
:after #'circe--irc-conn-disconnected
diff --git a/modules/app/irc/packages.el b/modules/app/irc/packages.el
index fe52975f8..d4609d107 100644
--- a/modules/app/irc/packages.el
+++ b/modules/app/irc/packages.el
@@ -1,5 +1,5 @@
;; -*- no-byte-compile: t; -*-
;;; app/irc/packages.el
-(package! circe :pin "0c79138fb2")
+(package! circe :pin "e5bf5f8974")
(package! circe-notifications :pin "291149ac12")
diff --git a/modules/app/regex/autoload/export.el b/modules/app/regex/autoload/export.el
deleted file mode 100644
index 90fbff748..000000000
--- a/modules/app/regex/autoload/export.el
+++ /dev/null
@@ -1,14 +0,0 @@
-;;; app/regex/autoload/export.el
-
-;;;###autoload
-(defun +regex/export () (interactive)) ; TODO +regex/export
-
-
-;;
-(defun +regex-export-python ()) ; import (re|regex)
-
-(defun +regex-export-php ()) ; preg_(match(_all)?|replace)
-
-(defun +regex-export-ruby ()) ; %r[.+]
-
-(defun +regex-export-js ()) ; /.+/
diff --git a/modules/app/regex/autoload/regex.el b/modules/app/regex/autoload/regex.el
deleted file mode 100644
index 0df6b7994..000000000
--- a/modules/app/regex/autoload/regex.el
+++ /dev/null
@@ -1,272 +0,0 @@
-;;; app/regex/autoload/regex.el
-
-(defvar +regex--text-buffer nil)
-(defvar +regex--text-replace-buffer nil)
-(defvar +regex--expr-buffer nil)
-(defvar +regex--expr-replace-buffer nil)
-(defvar +regex--groups-buffer nil)
-(defvar +regex--replace-buffer nil)
-
-;;
-(defface +regex-match-0-face
- `((t (:foreground "Black" :background ,(doom-color 'magenta) :bold t)))
- "TODO"
- :group 'faces)
-
-(defface +regex-match-1-face
- `((t (:foreground "Black" :background ,(doom-color 'blue) :bold t)))
- "TODO"
- :group 'faces)
-
-(defface +regex-match-2-face
- `((t (:foreground "Black" :background ,(doom-color 'green) :bold t)))
- "TODO"
- :group 'faces)
-
-(defvar +regex-faces
- '(+regex-match-0-face +regex-match-1-face +regex-match-2-face)
- "TODO")
-
-;;
-(defvar +regex-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\C-c\C-c" #'+regex-update-buffers)
- (define-key map "\C-c\C-r" #'=regex/replace)
- (define-key map "\C-c\C-k" #'+regex/quit)
- (define-key map [remap kill-current-buffer] #'+regex/quit)
- (define-key map [remap kill-buffer] #'+regex/quit)
- map)
- "TODO")
-
-;;;###autoload
-(define-minor-mode +regex-mode
- "TODO"
- :init-value nil
- :global nil
- :lighter ""
- :keymap +regex-mode-map
- (if +regex-mode
- (add-hook 'after-change-functions #'+regex-update-buffers nil t)
- (remove-hook 'after-change-functions #'+regex-update-buffers t)))
-
-;;;###autoload
-(defun =regex (&optional dummy-text)
- "Start the Regex IDE."
- (interactive "P")
- (unless (buffer-live-p +regex--expr-buffer)
- (condition-case ex
- (progn
- (setq +regex--expr-buffer (get-buffer-create "*doom-regex*")
- +regex--text-buffer (if dummy-text (get-buffer-create "*doom-regex-text*") (current-buffer))
- +regex--groups-buffer (get-buffer-create "*doom-regex-groups*"))
- (when dummy-text
- (+workspace-switch +regex-workspace-name t)
- (switch-to-buffer +regex--text-buffer)
- (with-current-buffer +regex--text-buffer
- (insert +regex-dummy-text)))
- (pop-to-buffer +regex--groups-buffer)
- (pop-to-buffer +regex--expr-buffer)
- (with-current-buffer +regex--expr-buffer
- (conf-mode)
- (rainbow-delimiters-mode +1)
- (doom/toggle-line-numbers +1)
- (setq-local require-final-newline nil)
- (+regex-mode +1)
- (text-scale-set 3)))
- ('error
- (+regex/quit)
- (error "Failed to open the Regexp IDE: %s" ex)))))
-
-;;;###autoload
-(defun =regex/replace ()
- (interactive)
- (unless (buffer-live-p +regex--replace-buffer)
- (let (text)
- (=regex t)
- (with-selected-window (get-buffer-window +regex--text-buffer)
- (setq text (buffer-string))
- (select-window (split-window-right))
- (switch-to-buffer (get-buffer-create "*doom-regex-text-repl*"))
- (erase-buffer)
- (insert text)
- (read-only-mode +1)
- (setq +regex--text-replace-buffer (current-buffer)))
- (with-current-buffer +regex--expr-buffer
- (select-window (split-window-right))
- (switch-to-buffer (get-buffer-create "*doom-regex-repl*"))
- (conf-mode)
- (rainbow-delimiters-mode +1)
- (doom/toggle-line-numbers -1)
- (setq-local require-final-newline nil)
- (setq mode-line-format nil
- +regex--expr-replace-buffer (current-buffer))
- (+regex-mode +1)
- (text-scale-set 3)))))
-
-;;;###autoload
-(defun +regex/quit ()
- "TODO"
- (interactive)
- (when (and +regex--text-buffer (buffer-live-p +regex--text-buffer))
- (with-current-buffer +regex--text-buffer
- (+regex-mode -1)
- (remove-overlays nil nil 'category '+regex))
- (when (equal (buffer-name +regex--text-buffer) "*doom-regex-text*")
- (kill-buffer +regex--text-buffer)))
- (when (equal (+workspace-current-name) +regex-workspace-name)
- (+workspace/delete +regex-workspace-name))
- (mapc (lambda (bufname)
- (let ((buf (symbol-value bufname)))
- (when (and buf (buffer-live-p buf))
- (kill-buffer buf)
- (set bufname nil))))
- (list '+regex--text-replace-buffer
- '+regex--expr-replace-buffer
- '+regex--expr-buffer
- '+regex--groups-buffer
- '+regex--replace-buffer)))
-
-(defun +regex--expr ()
- (when (buffer-live-p +regex--expr-buffer)
- (with-current-buffer +regex--expr-buffer
- (string-trim (buffer-string)))))
-
-(defun +regex--expr-replace ()
- (when (buffer-live-p +regex--expr-replace-buffer)
- (with-current-buffer +regex--expr-replace-buffer
- (string-trim (buffer-string)))))
-
-;;;###autoload
-(defun +regex-update-buffers (&optional beg end len)
- (interactive)
- (let* ((inhibit-read-only t)
- (regex (or (+regex--expr) ""))
- (replace (or (+regex--expr-replace) ""))
- (str (or (with-current-buffer +regex--text-buffer (buffer-string)) "")))
- (with-current-buffer +regex--groups-buffer
- (erase-buffer))
- (with-current-buffer +regex--text-buffer
- (remove-overlays nil nil 'category '+regex)
- (when (> (length regex) 0)
- (save-excursion
- (goto-char (point-min))
- (pcase +regex-default-backend
- ('emacs (+regex-backend-emacs regex replace str))
- ('perl (+regex-backend-perl regex replace str))))))
- (with-current-buffer +regex--groups-buffer
- (goto-char (point-min)))))
-
-
-;; --- backends ---------------------------
-
-(defun +regex--render-perl (regex text)
- "From "
- (with-temp-buffer
- (insert (format "@lines = ;
-$line = join(\"\", @lines);
-print \"(\";
-while ($line =~ m/%s/gm) {
- print \"(\", length($`), \" \", length($&), \" \";
- for $i (1 .. 20) {
- if ($$i) {
- my $group = $$i;
- $group =~ s/([\\\\\"])/\\\\\\1/g;
- print \"(\", $i, \" . \\\"\", $group, \"\\\") \";
- }
- }
- print \")\";
-}
-print \")\";
-__DATA__
-%s" (replace-regexp-in-string "/" "\\/" regex nil t) text))
- (call-process-region (point-min) (point-max) "perl" t t)
- (goto-char (point-min))
- (read (current-buffer))))
-
-(defun +regex--replace-perl (regex replace text)
- (unless (or (string-empty-p regex)
- (string-empty-p replace)
- (string-empty-p text))
- (with-temp-buffer
- (insert (format "@lines = ;
-$line = join(\"\", @lines);
-$line =~ s/%s/%s/gm;
-print $line;
-__DATA__
-%s" (replace-regexp-in-string "/" "\\/" regex nil t) (replace-regexp-in-string "/" "\\/" replace nil t) text))
- (call-process-region (point-min) (point-max) "perl" t t)
- (buffer-string))))
-
-;;;###autoload
-(defun +regex-backend-perl (regex replace str)
- "TODO"
- (cl-assert (stringp regex))
- (cl-assert (stringp replace))
- (cl-assert (stringp str))
- (let ((i 0)
- (results (+regex--render-perl regex str)))
- (when (buffer-live-p +regex--text-replace-buffer)
- (let ((replace (+regex--replace-perl regex replace str)))
- (with-current-buffer +regex--text-replace-buffer
- (erase-buffer)
- (insert
- (if (and (listp results)
- replace
- (not (string-empty-p replace)))
- replace
- str)))))
- (dolist (result (if (listp results) results))
- (let* ((offset (nth 0 result))
- (length (nth 1 result))
- (matches (nthcdr 2 result))
- (ov (make-overlay (1+ offset) (+ offset length 1))))
- (overlay-put ov 'face (nth (mod i 3) +regex-faces))
- (overlay-put ov 'category '+regex)
- (cl-incf i)
- (let* ((match-zero (buffer-substring (1+ offset) (+ offset length 1)))
- (line (format "Match: %s\n" (propertize match-zero 'face 'font-lock-string-face))))
- (with-current-buffer +regex--groups-buffer
- (insert line)))
- (dolist (match matches)
- (with-current-buffer +regex--groups-buffer
- (goto-char (point-max))
- (insert (format "Group %d: %s\n"
- (propertize (car match) 'face 'font-lock-constant-face)
- (propertize (cdr match) 'face 'font-lock-string-face)))))
- (with-current-buffer +regex--groups-buffer
- (insert ?\n))))))
-
-;;;###autoload
-(defun +regex-backend-emacs (regex replace str)
- "TODO"
- (cl-assert (stringp regex))
- (cl-assert (stringp replace))
- (cl-assert (stringp str))
- (let ((i 0)
- pos)
- (when (buffer-live-p +regex--text-replace-buffer)
- (with-current-buffer +regex--text-replace-buffer
- (erase-buffer)
- (insert str)
- (when (and (listp results) (string-empty-p replace))
- (replace-regexp regex replace))))
- (while (and (setq pos (point))
- (re-search-forward regex nil t))
- (if (= (point) pos)
- (forward-char 1)
- (let ((ov (make-overlay (match-beginning 0) (match-end 0))))
- (overlay-put ov 'face (nth (mod i 3) +regex-faces))
- (overlay-put ov 'category '+regex))
- (cl-incf i)
- (dotimes (i 10)
- (when-let (text (match-string i))
- (save-match-data
- (with-current-buffer +regex--groups-buffer
- (goto-char (point-max))
- (insert
- (format "Group %d: %s\n"
- (propertize i 'face 'font-lock-constant-face)
- (propertize text 'face 'font-lock-string-face)))))))
- (with-current-buffer +regex--groups-buffer
- (insert ?\n))))))
-
diff --git a/modules/app/regex/config.el b/modules/app/regex/config.el
deleted file mode 100644
index 595d619e4..000000000
--- a/modules/app/regex/config.el
+++ /dev/null
@@ -1,51 +0,0 @@
-;;; app/regex/config.el
-
-;; Often, I find myself writing regular expressions that could terrify seasoned
-;; programmers (or little children). To hone my regex fu, I need a regex
-;; playground. Sure, there's regexr.com, but don't be silly, that's not Emacs.
-;;
-;; Sadly, the Emacs' regex syntax is niche and lacks support for a few
-;; questionably useful features, like lookaround assertions, conditionals, case
-;; modifiers or backreferences, among others. No, I want PCRE. I am going to
-;; have my cake and eat it too, damn it!
-;;
-;; Workflow:
-;; + Invoke `=regex' (if opened with C-u, opens in separate workspace with a
-;; dummy text buffer).
-;; + A regex window will popup up. Any matches will be highlighted in the
-;; original buffer.
-;; + C-c C-k to close it
-;; + TODO C-c C-e to export to various langauges
-;;
-;; WARNING: THIS IS A WORK IN PROGRESS
-
-(defvar +regex-workspace-name "*regex*"
- "TODO")
-
-(defvar +regex-default-backend 'perl
- "The backend used to process regular expressions.
-The `emacs' backend handles regular expressions directly.
-The `perl' backend talks to a perl subprocess to do the handling.")
-
-(defvar +regex-dummy-text
- "Welcome to DOOM Emacs, proudly hosted by the demons of hell!
-
-Edit the Expression & Text to see matches. Roll over matches or the expression
-for details. Undo mistakes with ctrl-z. Save Favorites & Share expressions with
-friends or the Community. Explore your results with Tools. A full Reference &
-Help is available in the Library, or watch the video Tutorial.
-
-Sample text for testing:
-abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
-0123456789 _+-.,!@#$%^&*();\/|<>\"'
-12345 -98.7 3.141 .6180 9,000 +42
-555.123.4567 +1-(800)-555-2468
-foo@demo.net bar.ba@test.co.uk
-www.demo.com http://foo.co.uk/
-http://regexr.com/foo.html?q=bar
-https://mediatemple.net"
- "TODO")
-
-(set-popup-rules!
- '(("^\\*doom-regex\\*$" :size 4 :quit nil)
- ("^\\*doom-regex-groups" :side 'left :size 28 :select nil :quit nil)))
diff --git a/modules/app/rss/packages.el b/modules/app/rss/packages.el
index 1d33be22a..076686e55 100644
--- a/modules/app/rss/packages.el
+++ b/modules/app/rss/packages.el
@@ -1,5 +1,5 @@
;; -*- no-byte-compile: t; -*-
;;; app/rss/packages.el
-(package! elfeed :pin "3f0edb1737")
+(package! elfeed :pin "d0405e6386")
(package! elfeed-org :pin "77b6bbf222")
diff --git a/modules/app/twitter/packages.el b/modules/app/twitter/packages.el
index d5ef4732c..927619ae8 100644
--- a/modules/app/twitter/packages.el
+++ b/modules/app/twitter/packages.el
@@ -2,4 +2,4 @@
;;; app/twitter/packages.el
(package! twittering-mode :pin "114891e8fd")
-(package! avy :pin "cf95ba9582")
+(package! avy :pin "3bf83140fa")
diff --git a/modules/checkers/grammar/config.el b/modules/checkers/grammar/config.el
index 581f207c0..58a505fb5 100644
--- a/modules/checkers/grammar/config.el
+++ b/modules/checkers/grammar/config.el
@@ -7,7 +7,8 @@
langtool-correct-buffer)
:init (setq langtool-default-language "en-US")
:config
- (unless langtool-language-tool-jar
+ (unless (or langtool-bin
+ langtool-language-tool-jar)
(setq langtool-language-tool-jar
(cond (IS-MAC
(locate-file "libexec/languagetool-commandline.jar"
diff --git a/modules/checkers/spell/config.el b/modules/checkers/spell/config.el
index 760c3f1ef..7936b24cd 100644
--- a/modules/checkers/spell/config.el
+++ b/modules/checkers/spell/config.el
@@ -65,10 +65,10 @@
(defun +spell-inhibit-duplicate-detection-maybe-h ()
"Don't mark duplicates when style/grammar linters are present.
e.g. proselint and langtool."
- (when (or (and (bound-and-true-p flycheck-mode)
- (executable-find "proselint"))
- (featurep 'langtool))
- (setq-local flyspell-mark-duplications-flag nil))))
+ (and (or (and (bound-and-true-p flycheck-mode)
+ (executable-find "proselint"))
+ (featurep 'langtool))
+ (setq-local flyspell-mark-duplications-flag nil))))
;; Ensure mode-local predicates declared with `set-flyspell-predicate!' are
;; used in their respective major modes.
diff --git a/modules/checkers/syntax/config.el b/modules/checkers/syntax/config.el
index 268fe2bc9..f6c52c0a1 100644
--- a/modules/checkers/syntax/config.el
+++ b/modules/checkers/syntax/config.el
@@ -10,9 +10,14 @@
(setq flycheck-emacs-lisp-load-path 'inherit)
;; Check only when saving or opening files. Newline & idle checks are a mote
- ;; excessive, especially when that can easily catch code in an incomplete
- ;; state, so we removed them.
- (setq flycheck-check-syntax-automatically '(save mode-enabled))
+ ;; excessive and can catch code in an incomplete state, producing false
+ ;; positives, so we removed them.
+ (setq flycheck-check-syntax-automatically '(save mode-enabled idle-buffer-switch))
+
+ ;; For the above functionality, check syntax in a buffer that you switched to
+ ;; only briefly. This allows "refreshing" the syntax check state for several
+ ;; buffers quickly after e.g. changing a config file.
+ (setq flycheck-buffer-switch-check-intermediate-buffers t)
;; Display errors a little quicker (default is 0.9s)
(setq flycheck-display-errors-delay 0.25)
@@ -41,7 +46,7 @@
(use-package! flycheck-popup-tip
:commands flycheck-popup-tip-show-popup flycheck-popup-tip-delete-popup
- :init (add-hook 'flycheck-mode-hook #'+syntax-init-popups-h)
+ :hook (flycheck-mode . +syntax-init-popups-h)
:config
(setq flycheck-popup-tip-error-prefix "✕ ")
(after! evil
@@ -58,8 +63,7 @@
(use-package! flycheck-posframe
:when (featurep! +childframe)
- :defer t
- :init (add-hook 'flycheck-mode-hook #'+syntax-init-popups-h)
+ :hook (flycheck-mode . +syntax-init-popups-h)
:config
(setq flycheck-posframe-warning-prefix "⚠ "
flycheck-posframe-info-prefix "··· "
diff --git a/modules/checkers/syntax/packages.el b/modules/checkers/syntax/packages.el
index e25b891d7..d4cf34bbc 100644
--- a/modules/checkers/syntax/packages.el
+++ b/modules/checkers/syntax/packages.el
@@ -1,7 +1,7 @@
;; -*- no-byte-compile: t; -*-
;;; checkers/syntax/packages.el
-(package! flycheck :pin "08345d38e2")
+(package! flycheck :pin "f19a51c0f1")
(package! flycheck-popup-tip :pin "ef86aad907")
(when (featurep! +childframe)
(package! flycheck-posframe :pin "2b3e94c2e4"))
diff --git a/modules/completion/company/config.el b/modules/completion/company/config.el
index dddf2309b..62a1a4f52 100644
--- a/modules/completion/company/config.el
+++ b/modules/completion/company/config.el
@@ -4,24 +4,23 @@
:commands company-complete-common company-manual-begin company-grab-line
:after-call pre-command-hook after-find-file
:init
- (setq company-minimum-prefix-length 2
+ (setq company-idle-delay 0.25
+ company-minimum-prefix-length 2
company-tooltip-limit 14
- company-dabbrev-downcase nil
- company-dabbrev-ignore-case nil
- company-dabbrev-code-other-buffers t
company-tooltip-align-annotations t
company-require-match 'never
company-global-modes
'(not erc-mode message-mode help-mode gud-mode eshell-mode)
- company-backends '(company-capf)
- company-frontends
- '(company-pseudo-tooltip-frontend
- company-echo-metadata-frontend))
+ company-backends '(company-capf)
+ company-frontends '(company-pseudo-tooltip-frontend
+ company-echo-metadata-frontend))
:config
(when (featurep! :editor evil)
(add-hook 'company-mode-hook #'evil-normalize-keymaps)
- ;; Don't persist company popups when switching back to normal mode.
- (add-hook 'evil-normal-state-entry-hook #'company-abort)
+ (unless (featurep! +childframe)
+ ;; Don't persist company popups when switching back to normal mode.
+ ;; `company-box' aborts on mode switch so it doesn't need this.
+ (add-hook 'evil-normal-state-entry-hook #'company-abort))
;; Allow users to switch between backends on the fly. E.g. C-x C-s followed
;; by C-x C-n, will switch from `company-yasnippet' to
;; `company-dabbrev-code'.
@@ -50,8 +49,7 @@
;; Packages
(after! company-files
- (pushnew! company-files--regexps
- "file:\\(\\(?:\\.\\{1,2\\}/\\|~/\\|/\\)[^\]\n]*\\)"))
+ (add-to-list 'company-files--regexps "file:\\(\\(?:\\.\\{1,2\\}/\\|~/\\|/\\)[^\]\n]*\\)"))
(use-package! company-prescient
diff --git a/modules/completion/company/packages.el b/modules/completion/company/packages.el
index 87a5be858..2006fe791 100644
--- a/modules/completion/company/packages.el
+++ b/modules/completion/company/packages.el
@@ -1,8 +1,8 @@
;; -*- no-byte-compile: t; -*-
;;; completion/company/packages.el
-(package! company :pin "9de9905ed2")
+(package! company :pin "61ddd9afb5")
(package! company-dict :pin "cd7b8394f6")
-(package! company-prescient :pin "7fd8c3b802")
+(package! company-prescient :pin "53307731f3")
(when (featurep! +childframe)
(package! company-box :pin "8fc6168f2d"))
diff --git a/modules/completion/helm/config.el b/modules/completion/helm/config.el
index 5f1666850..66e8d7b9a 100644
--- a/modules/completion/helm/config.el
+++ b/modules/completion/helm/config.el
@@ -77,35 +77,31 @@ be negative.")
(setq helm-display-function #'+helm-posframe-display-fn))
(let ((fuzzy (featurep! +fuzzy)))
- (setq helm-M-x-fuzzy-match fuzzy
- helm-apropos-fuzzy-match fuzzy
- helm-apropos-fuzzy-match fuzzy
+ (setq helm-apropos-fuzzy-match fuzzy
helm-bookmark-show-location fuzzy
helm-buffers-fuzzy-matching fuzzy
- helm-completion-in-region-fuzzy-match fuzzy
- helm-completion-in-region-fuzzy-match fuzzy
helm-ff-fuzzy-matching fuzzy
helm-file-cache-fuzzy-match fuzzy
helm-flx-for-helm-locate fuzzy
helm-imenu-fuzzy-match fuzzy
helm-lisp-fuzzy-completion fuzzy
helm-locate-fuzzy-match fuzzy
- helm-mode-fuzzy-match fuzzy
helm-projectile-fuzzy-match fuzzy
helm-recentf-fuzzy-match fuzzy
- helm-semantic-fuzzy-match fuzzy))
+ helm-semantic-fuzzy-match fuzzy)
+ ;; Make sure that we have helm-multi-matching or fuzzy matching,
+ ;; (as prescribed by the fuzzy flag) also in the following cases:
+ ;; - helmized commands that use `completion-at-point' and similar functions
+ ;; - native commands that fall back to `completion-styles' like `helm-M-x'
+ (push (if EMACS27+
+ (if fuzzy 'flex 'helm)
+ (if fuzzy 'helm-flex 'helm))
+ completion-styles))
:config
(set-popup-rule! "^\\*helm" :vslot -100 :size 0.22 :ttl nil)
- ;; HACK Doom doesn't support these commands, which invite the user to install
- ;; the package via ELPA. Force them to use +helm/* instead, because they work
- ;; out of the box.
- (advice-add #'helm-projectile-rg :override #'+helm/project-search)
- (advice-add #'helm-projectile-ag :override #'+helm/project-search)
- (advice-add #'helm-projectile-grep :override #'+helm/project-search)
-
- ;; Hide the modeline
+ ;; Hide the modeline in helm windows as it serves little purpose.
(defun +helm--hide-mode-line (&rest _)
(with-current-buffer (helm-buffer-get)
(unless helm-mode-line-string
@@ -121,7 +117,6 @@ be negative.")
(dolist (fn '(helm-describe-variable helm-describe-function))
(advice-add fn :around #'doom-use-helpful-a)))
-
(use-package! helm-flx
:when (featurep! +fuzzy)
:hook (helm-mode . helm-flx-mode)
@@ -187,3 +182,7 @@ be negative.")
(lambda (buf &optional _resume) (pop-to-buffer buf)))
(global-set-key [remap swiper] #'swiper-helm)
(add-to-list 'swiper-font-lock-exclude #'+doom-dashboard-mode nil #'eq))
+
+
+(use-package! helm-descbinds
+ :hook (helm-mode . helm-descbinds-mode))
diff --git a/modules/completion/helm/packages.el b/modules/completion/helm/packages.el
index 9513afaa3..e16931e25 100644
--- a/modules/completion/helm/packages.el
+++ b/modules/completion/helm/packages.el
@@ -1,7 +1,7 @@
;; -*- no-byte-compile: t; -*-
;;; completion/helm/packages.el
-(package! helm :pin "21e778bc88")
+(package! helm :pin "d978f20f4c")
(package! helm-rg :pin "785a80fe5c")
(package! helm-c-yasnippet :pin "65ca732b51")
(package! helm-company :pin "6eb5c2d730")
@@ -13,6 +13,7 @@
(when (featurep! +fuzzy)
(package! helm-flx :pin "6640fac5cb"))
(when (featurep! +childframe)
- (package! posframe :pin "8a9af547e6"))
+ (package! posframe :pin "e62e584268"))
(when (featurep! :lang org)
- (package! helm-org :pin "8457e1e462"))
+ (package! helm-org :pin "b7a18dfc17"))
+(package! helm-descbinds :pin "b725159823")
diff --git a/modules/completion/ido/config.el b/modules/completion/ido/config.el
index 39e53d998..e1221dd1d 100644
--- a/modules/completion/ido/config.el
+++ b/modules/completion/ido/config.el
@@ -1,59 +1,64 @@
;;; completion/ido/config.el -*- lexical-binding: t; -*-
-(defun +ido-init-h ()
- (setq ido-ignore-buffers
- '("\\` " "^\\*ESS\\*" "^\\*Messages\\*" "^\\*Help\\*" "^\\*Buffer"
- "^\\*.*Completions\\*$" "^\\*Ediff" "^\\*tramp" "^\\*cvs-"
- "_region_" " output\\*$" "^TAGS$" "^\*Ido")
- ido-use-faces nil
- ido-confirm-unique-completion t
- ido-case-fold t
- ido-enable-tramp-completion nil
- ido-enable-flex-matching t
- ido-create-new-buffer 'always
- ido-enable-tramp-completion t
- ido-enable-last-directory-history t
- ido-save-directory-list-file (concat doom-cache-dir "ido.last"))
+(defvar ido-mode-hook nil
+ "List of hooks to run when `ido-mode' is activated.")
- (unless (member "\\`.DS_Store$" ido-ignore-files)
- (push "\\`.DS_Store$" ido-ignore-files)
- (push "Icon\\?$" ido-ignore-files))
-
- (define-key! (ido-common-completion-map ido-completion-map ido-file-completion-map)
- "\C-n" #'ido-next-match
- "\C-p" #'ido-prev-match
- "\C-w" #'ido-delete-backward-word-updir
- ;; Go to $HOME with ~
- "~" (λ! (if (looking-back "/" (point-min))
- (insert "~/")
- (call-interactively #'self-insert-command))))
-
- (defadvice! +ido--sort-mtime-a ()
- "Sort ido filelist by mtime instead of alphabetically."
- :override #'ido-sort-mtime
- (setq ido-temp-list
- (sort ido-temp-list
- (lambda (a b)
- (time-less-p
- (sixth (file-attributes (concat ido-current-directory b)))
- (sixth (file-attributes (concat ido-current-directory a)))))))
- (ido-to-end ;; move . files to end (again)
- (cl-loop for x in ido-temp-list
- if (char-equal (string-to-char x) ?.)
- collect x)))
- (add-hook! '(ido-make-file-list-hook ido-make-dir-list-hook)
- #'ido-sort-mtime)
-
- ;;
- (ido-mode 1)
- (ido-everywhere 1)
- (ido-ubiquitous-mode 1)
- (ido-vertical-mode 1)
- (flx-ido-mode +1)
- (crm-custom-mode +1)
-
- ;;
- (remove-hook 'ido-setup-hook #'+ido-init-h))
;;
-(add-hook 'ido-setup-hook #'+ido-init-h)
+;;; Packages
+
+(use-package! ido
+ :after-call pre-command-hook
+ :hook (ido-mode . ido-everywhere)
+ :hook (ido-mode . ido-ubiquitous-mode)
+ :preface
+ ;; HACK `ido' is a really old package. It defines `ido-mode' manually and
+ ;; doesn't define a hook, so we define one for it.")
+ (defadvice! +ido-run-hooks-a (&rest _)
+ :after #'ido-mode
+ (run-hooks 'ido-mode-hook))
+ :init
+ (setq ido-save-directory-list-file (concat doom-cache-dir "ido.last"))
+ :config
+ (pushnew! ido-ignore-files "\\`.DS_Store$" "Icon\\?$")
+ (setq ido-ignore-buffers
+ '("\\` " "^\\*ESS\\*" "^\\*Messages\\*" "^\\*[Hh]elp" "^\\*Buffer"
+ "^\\*.*Completions\\*$" "^\\*Ediff" "^\\*tramp" "^\\*cvs-" "_region_"
+ " output\\*$" "^TAGS$" "^\*Ido")
+ ido-auto-merge-work-directories-length -1
+ ido-confirm-unique-completion t
+ ido-case-fold t
+ ido-create-new-buffer 'always
+ ido-enable-flex-matching t)
+
+ (map! :map (ido-common-completion-map ido-file-completion-map)
+ "C-w" #'ido-delete-backward-word-updir
+ :map ido-common-completion-map
+ "C-n" #'ido-next-match
+ "C-p" #'ido-prev-match
+ [down] #'ido-next-match
+ [up] #'ido-prev-match
+ :map ido-file-completion-map
+ ;; Go to $HOME with ~
+ "~" (λ! (if (looking-back "/" (point-min))
+ (insert "~/")
+ (call-interactively #'self-insert-command))))
+
+ (ido-mode +1))
+
+
+(use-package! ido-vertical-mode
+ :hook (ido-mode . ido-vertical-mode)
+ :config (setq ido-vertical-show-count t))
+
+
+(use-package! ido-sort-mtime
+ :hook (ido-mode . ido-sort-mtime-mode))
+
+
+(use-package! crm-custom
+ :hook (ido-mode . crm-custom-mode))
+
+
+(use-package! flx-ido
+ :hook (ido-mode . flx-ido-mode))
diff --git a/modules/completion/ido/packages.el b/modules/completion/ido/packages.el
index e90c485bd..fc694fbfc 100644
--- a/modules/completion/ido/packages.el
+++ b/modules/completion/ido/packages.el
@@ -2,6 +2,7 @@
;;; completion/ido/packages.el
(package! flx-ido :pin "17f5c9cb2a")
-(package! ido-completing-read+ :pin "74861eabd0")
+(package! ido-completing-read+ :pin "98d3a6e56b")
+(package! ido-sort-mtime :pin "f638ff0c92")
(package! ido-vertical-mode :pin "16c4c1a112")
(package! crm-custom :pin "f1aaccf643")
diff --git a/modules/completion/ivy/README.org b/modules/completion/ivy/README.org
index b21b92c61..ea1599519 100644
--- a/modules/completion/ivy/README.org
+++ b/modules/completion/ivy/README.org
@@ -136,7 +136,7 @@ These keybindings are available while a search is active:
| =C-c C-o= | Open a buffer with your search results |
| =C-c C-e= | Open a writable buffer of your search results |
| =C-SPC= | Preview the current candidate |
-| =M-RET= | Open the selected candidate in other-window |
+| =C-RET= | Open the selected candidate in other-window |
Changes to the resulting wgrep buffer (opened by =C-c C-e=) can be committed
with =C-c C-c= and aborted with =C-c C-k= (alternatively =ZZ= and =ZQ=, for evil
diff --git a/modules/completion/ivy/autoload/ivy.el b/modules/completion/ivy/autoload/ivy.el
index 3c34ae2c8..f646469af 100644
--- a/modules/completion/ivy/autoload/ivy.el
+++ b/modules/completion/ivy/autoload/ivy.el
@@ -207,8 +207,8 @@ If ARG (universal argument), open selection in other-window."
;;;###autoload
(defun +ivy/projectile-find-file ()
"A more sensible `counsel-projectile-find-file', which will revert to
-`counsel-find-file' if invoked from $HOME, `counsel-file-jump' if invoked from a
-non-project, `projectile-find-file' if in a big project (more than
+`counsel-find-file' if invoked from $HOME or /, `counsel-file-jump' if invoked
+from a non-project, `projectile-find-file' if in a big project (more than
`ivy-sort-max-size' files), or `counsel-projectile-find-file' otherwise.
The point of this is to avoid Emacs locking up indexing massive file trees."
@@ -219,6 +219,7 @@ The point of this is to avoid Emacs locking up indexing massive file trees."
(let ((this-command 'counsel-find-file))
(call-interactively
(cond ((or (file-equal-p default-directory "~")
+ (file-equal-p default-directory "/")
(when-let (proot (doom-project-root))
(file-equal-p proot "~")))
#'counsel-find-file)
diff --git a/modules/completion/ivy/config.el b/modules/completion/ivy/config.el
index fd262e1d0..db5baab53 100644
--- a/modules/completion/ivy/config.el
+++ b/modules/completion/ivy/config.el
@@ -122,7 +122,14 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
'(:columns
((counsel-describe-variable-transformer (:width 40)) ; the original transformer
(+ivy-rich-describe-variable-transformer (:width 50))
- (ivy-rich-counsel-variable-docstring (:face font-lock-doc-face)))))
+ (ivy-rich-counsel-variable-docstring (:face font-lock-doc-face))))
+ 'counsel-M-x
+ '(:columns
+ ((counsel-M-x-transformer (:width 60))
+ (ivy-rich-counsel-function-docstring (:face font-lock-doc-face))))
+ ;; Apply switch buffer transformers to `counsel-projectile-switch-to-buffer' as well
+ 'counsel-projectile-switch-to-buffer
+ (plist-get ivy-rich-display-transformers-list 'ivy-switch-buffer))
;; Remove built-in coloring of buffer list; we do our own
(setq ivy-switch-buffer-faces-alist nil)
@@ -135,11 +142,6 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
(when switch-buffer-alist
(setcar switch-buffer-alist '+ivy-rich-buffer-name)))
- ;; Apply switch buffer transformers to `counsel-projectile-switch-to-buffer' as well
- (plist-put! ivy-rich-display-transformers-list
- 'counsel-projectile-switch-to-buffer
- (plist-get ivy-rich-display-transformers-list 'ivy-switch-buffer))
-
(ivy-rich-mode +1))
@@ -153,9 +155,10 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
(all-the-icons-ivy-setup)
(after! counsel-projectile
- (let ((all-the-icons-ivy-file-commands '(counsel-projectile
- counsel-projectile-find-file
- counsel-projectile-find-dir)))
+ (let ((all-the-icons-ivy-file-commands
+ '(counsel-projectile
+ counsel-projectile-find-file
+ counsel-projectile-find-dir)))
(all-the-icons-ivy-setup))))
@@ -259,7 +262,10 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
(cond ((executable-find doom-projectile-fd-binary)
(cons doom-projectile-fd-binary (list "-t" "f" "-E" ".git")))
((executable-find "rg")
- (split-string (format counsel-rg-base-command "--files --no-messages") " " t))
+ (append (list "rg" "--files" "--color=never" "--hidden" "--no-messages")
+ (cl-loop for dir in projectile-globally-ignored-directories
+ collect "--glob" and collect (concat "!" dir))
+ (if IS-WINDOWS (list "--path-separator /"))))
((cons find-program args)))
(unless (listp args)
(user-error "`counsel-file-jump-args' is a list now, please customize accordingly."))
@@ -297,8 +303,8 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
;; no highlighting visited files; slows down the filtering
(ivy-set-display-transformer #'counsel-projectile-find-file nil)
- (if (featurep! +prescient)
- (setq counsel-projectile-sort-files t)))
+ (when (featurep! +prescient)
+ (setq counsel-projectile-sort-files t)))
(use-package! wgrep
@@ -325,7 +331,9 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
;; posframe.
(dolist (fn '(swiper counsel-rg counsel-grep counsel-git-grep))
(setf (alist-get fn ivy-posframe-display-functions-alist)
- #'ivy-display-function-fallback)))
+ #'ivy-display-function-fallback))
+
+ (add-hook 'doom-reload-hook #'posframe-delete-all))
(use-package! flx
@@ -336,8 +344,9 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
(use-package! ivy-prescient
- :hook (ivy-mode . ivy-prescient-mode)
:when (featurep! +prescient)
+ :hook (ivy-mode . ivy-prescient-mode)
+ :hook (ivy-prescient-mode . prescient-persist-mode)
:init
(setq prescient-filter-method
(if (featurep! +fuzzy)
@@ -354,8 +363,7 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
(ivy-prescient-re-builder str)))
;; NOTE prescient config duplicated with `company'
- (setq prescient-save-file (concat doom-cache-dir "prescient-save.el"))
- (prescient-persist-mode +1))
+ (setq prescient-save-file (concat doom-cache-dir "prescient-save.el")))
;;;###package swiper
diff --git a/modules/completion/ivy/packages.el b/modules/completion/ivy/packages.el
index 40b28ce3d..3f1b3ad4a 100644
--- a/modules/completion/ivy/packages.el
+++ b/modules/completion/ivy/packages.el
@@ -1,23 +1,23 @@
;; -*- no-byte-compile: t; -*-
;;; completion/ivy/packages.el
-(package! swiper :pin "5f1d9ce045")
+(package! swiper :pin "64f05f4735")
(package! ivy)
(package! ivy-hydra)
(package! counsel)
(package! amx :pin "e512e74e83")
(package! counsel-projectile :pin "b556ed8995")
-(package! ivy-rich :pin "0f22aff4c7")
+(package! ivy-rich :pin "596874d146")
(package! wgrep :pin "5977b8e000")
(if (featurep! +prescient)
- (package! ivy-prescient :pin "7fd8c3b802")
+ (package! ivy-prescient :pin "53307731f3")
(when (featurep! +fuzzy)
(package! flx :pin "17f5c9cb2a")))
(when (featurep! +childframe)
- (package! ivy-posframe :pin "6d697ff00a"))
+ (package! ivy-posframe :pin "ae9bafe94f"))
(when (featurep! +icons)
(package! all-the-icons-ivy :pin "a70cbfa1ef"))
diff --git a/modules/config/default/+emacs-bindings.el b/modules/config/default/+emacs-bindings.el
index 1bd78b052..25391b39c 100644
--- a/modules/config/default/+emacs-bindings.el
+++ b/modules/config/default/+emacs-bindings.el
@@ -86,6 +86,7 @@
;;; s --- search
(:prefix-map ("s" . "search")
+ :desc "Search project for symbol" "." #'+default/search-project-for-symbol-at-point
:desc "Search buffer" "b" #'swiper
:desc "Search current directory" "d" #'+default/search-cwd
:desc "Search other directory" "D" #'+default/search-other-cwd
@@ -123,6 +124,17 @@
(:prefix-map ("n" . "notes")
:desc "Search notes for symbol" "." #'+default/search-notes-for-symbol-at-point
:desc "Org agenda" "a" #'org-agenda
+ (:when (featurep! :tools biblio)
+ :desc "Bibliographic entries" "b"
+ (cond ((featurep! :completion ivy) #'ivy-bibtex)
+ ((featurep! :completion helm) #'helm-bibtex)))
+
+ :desc "Toggle org-clock" "c" #'+org/toggle-clock
+ :desc "Cancel org-clock" "C" #'org-clock-cancel
+ :desc "Open deft" "d" #'deft
+ (:when (featurep! :lang org +noter)
+ :desc "Org noter" "e" #'org-noter)
+
:desc "Find file in notes" "f" #'+default/find-in-notes
:desc "Browse notes" "F" #'+default/browse-notes
:desc "Org store link" "l" #'org-store-link
@@ -139,7 +151,20 @@
(:when (featurep! :lang org +journal)
(:prefix ("j" . "journal")
:desc "New Entry" "j" #'org-journal-new-entry
- :desc "Search Forever" "s" #'org-journal-search-forever)))
+ :desc "Search Forever" "s" #'org-journal-search-forever))
+ (:when (featurep! :lang org +roam)
+ (:prefix ("r" . "roam")
+ :desc "Switch to buffer" "b" #'org-roam-switch-to-buffer
+ :desc "Org Roam Capture" "c" #'org-roam-capture
+ :desc "Find file" "f" #'org-roam-find-file
+ :desc "Show graph" "g" #'org-roam-graph-show
+ :desc "Insert" "i" #'org-roam-insert
+ :desc "Org Roam" "r" #'org-roam
+ (:prefix ("d" . "by date")
+ :desc "Arbitrary date" "d" #'org-roam-dailies-date
+ :desc "Today" "t" #'org-roam-dailies-today
+ :desc "Tomorrow" "m" #'org-roam-dailies-tomorrow
+ :desc "Yesterday" "y" #'org-roam-dailies-yesterday))))
;;; o --- open
"o" nil ; we need to unbind it first as Org claims this prefix
@@ -180,6 +205,7 @@
;;; p --- project
(:prefix ("p" . "project")
+ :desc "Search project for symbol" "." #'+default/search-project-for-symbol-at-point
:desc "Find file in other project" "F" #'doom/find-file-in-other-project
:desc "Search project" "s" #'+default/search-project
:desc "List project tasks" "t" #'magit-todos-list
diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el
index 9b5a06525..468e0dcc5 100644
--- a/modules/config/default/+evil-bindings.el
+++ b/modules/config/default/+evil-bindings.el
@@ -7,9 +7,9 @@
(define-key! evil-ex-completion-map
"C-a" #'evil-beginning-of-line
"C-b" #'evil-backward-char
- "C-s" (if (featurep! :completion ivy)
- #'counsel-minibuffer-history
- #'helm-minibuffer-history))
+ "C-f" #'evil-forward-char
+ "C-j" #'previous-complete-history-element
+ "C-k" #'next-complete-history-element)
(define-key! :keymaps +default-minibuffer-maps
[escape] #'abort-recursive-edit
@@ -18,16 +18,21 @@
"C-u" #'evil-delete-back-to-indentation
"C-v" #'yank
"C-w" #'doom/delete-backward-word
- "C-z" (λ! (ignore-errors (call-interactively #'undo)))
- ;; Scrolling lines
- "C-j" #'next-line
- "C-k" #'previous-line
- "C-S-j" #'scroll-up-command
- "C-S-k" #'scroll-down-command)
+ "C-z" (λ! (ignore-errors (call-interactively #'undo))))
- (define-key! read-expression-map
- "C-j" #'next-line-or-history-element
- "C-k" #'previous-line-or-history-element))
+ (when (featurep! :editor evil +everywhere)
+ (define-key! :keymaps +default-minibuffer-maps
+ "C-f" #'forward-word
+ "C-b" #'backward-word
+ "M-f" #'foward-char
+ "M-b" #'backward-char
+ "C-j" #'next-line
+ "C-k" #'previous-line
+ "C-S-j" #'scroll-up-command
+ "C-S-k" #'scroll-down-command)
+ (define-key! read-expression-map
+ "C-j" #'next-line-or-history-element
+ "C-k" #'previous-line-or-history-element)))
;;
@@ -42,19 +47,11 @@
(and (featurep! :completion company +tng)
(+company-has-completion-p))
#'+company/complete)
- :n [tab] (general-predicate-dispatch nil
- (and (featurep! :editor fold)
- (save-excursion (end-of-line) (invisible-p (point))))
- #'+fold/toggle
- (fboundp 'evil-jump-item)
- #'evil-jump-item)
:v [tab] (general-predicate-dispatch nil
(and (bound-and-true-p yas-minor-mode)
(or (eq evil-visual-selection 'line)
(not (memq (char-after) (list ?\( ?\[ ?\{ ?\} ?\] ?\))))))
- #'yas-insert-snippet
- (fboundp 'evil-jump-item)
- #'evil-jump-item)
+ #'yas-insert-snippet)
;; Smarter newlines
:i [remap newline] #'newline-and-indent ; auto-indent on newline
@@ -76,7 +73,6 @@
(:after man :map Man-mode-map
:n "q" #'kill-current-buffer)
- :m "gs" #'+evil/easymotion ; lazy-load `evil-easymotion'
(:after (evil-org evil-easymotion)
:map evil-org-mode-map
:m "gsh" #'+org/goto-visible)
@@ -161,15 +157,18 @@
(:when (featurep! :completion helm)
(:after helm :map helm-map
+ [remap next-line] #'helm-next-line
+ [remap previous-line] #'helm-previous-line
[left] #'left-char
[right] #'right-char
"C-S-f" #'helm-previous-page
"C-S-n" #'helm-next-source
"C-S-p" #'helm-previous-source
- "C-S-j" #'helm-next-source
- "C-S-k" #'helm-previous-source
- "C-j" #'helm-next-line
- "C-k" #'helm-previous-line
+ (:when (featurep! :editor evil +everywhere)
+ "C-j" #'helm-next-line
+ "C-k" #'helm-previous-line
+ "C-S-j" #'helm-next-source
+ "C-S-k" #'helm-previous-source)
"C-u" #'helm-delete-minibuffer-contents
"C-s" #'helm-minibuffer-history
;; Swap TAB and C-z
@@ -266,7 +265,6 @@
:desc "M-x" ":" #'execute-extended-command
:desc "Pop up scratch buffer" "x" #'doom/open-scratch-buffer
:desc "Org Capture" "X" #'org-capture
-
;; C-u is used by evil
:desc "Universal argument" "u" #'universal-argument
:desc "window" "w" evil-window-map
@@ -275,12 +273,10 @@
(:when (featurep! :ui popup)
:desc "Toggle last popup" "~" #'+popup/toggle)
:desc "Find file" "." #'find-file
-
:desc "Switch buffer" "," #'switch-to-buffer
(:when (featurep! :ui workspaces)
:desc "Switch workspace buffer" "," #'persp-switch-to-buffer
:desc "Switch buffer" "<" #'switch-to-buffer)
-
:desc "Switch to last buffer" "`" #'evil-switch-to-windows-last-buffer
:desc "Resume last search" "'"
(cond ((featurep! :completion ivy) #'ivy-resume)
@@ -468,14 +464,23 @@
(:prefix-map ("n" . "notes")
:desc "Search notes for symbol" "*" #'+default/search-notes-for-symbol-at-point
:desc "Org agenda" "a" #'org-agenda
+ (:when (featurep! :tools biblio)
+ :desc "Bibliographic entries" "b"
+ (cond ((featurep! :completion ivy) #'ivy-bibtex)
+ ((featurep! :completion helm) #'helm-bibtex)))
+
:desc "Toggle org-clock" "c" #'+org/toggle-clock
:desc "Cancel org-clock" "C" #'org-clock-cancel
:desc "Open deft" "d" #'deft
+ (:when (featurep! :lang org +noter)
+ :desc "Org noter" "e" #'org-noter)
+
:desc "Find file in notes" "f" #'+default/find-in-notes
:desc "Browse notes" "F" #'+default/browse-notes
:desc "Org store link" "l" #'org-store-link
:desc "Tags search" "m" #'org-tags-view
:desc "Org capture" "n" #'org-capture
+ :desc "Goto capture" "N" #'org-capture-goto-target
:desc "Active org-clock" "o" #'org-clock-goto
:desc "Todo list" "t" #'org-todo-list
:desc "Search notes" "s" #'+default/org-notes-search
@@ -484,6 +489,20 @@
:desc "Org export to clipboard" "y" #'+org/export-to-clipboard
:desc "Org export to clipboard as RTF" "Y" #'+org/export-to-clipboard-as-rich-text
+ (:when (featurep! :lang org +roam)
+ (:prefix ("r" . "roam")
+ :desc "Switch to buffer" "b" #'org-roam-switch-to-buffer
+ :desc "Org Roam Capture" "c" #'org-roam-capture
+ :desc "Find file" "f" #'org-roam-find-file
+ :desc "Show graph" "g" #'org-roam-graph-show
+ :desc "Insert" "i" #'org-roam-insert
+ :desc "Org Roam" "r" #'org-roam
+ (:prefix ("d" . "by date")
+ :desc "Arbitrary date" "d" #'org-roam-dailies-date
+ :desc "Today" "t" #'org-roam-dailies-today
+ :desc "Tomorrow" "m" #'org-roam-dailies-tomorrow
+ :desc "Yesterday" "y" #'org-roam-dailies-yesterday)))
+
(:when (featurep! :lang org +journal)
(:prefix ("j" . "journal")
:desc "New Entry" "j" #'org-journal-new-entry
@@ -553,10 +572,10 @@
:desc "Find recent project files" "r" #'projectile-recentf
:desc "Run project" "R" #'projectile-run-project
:desc "Save project files" "s" #'projectile-save-project-buffers
- :desc "Pop up scratch buffer" "x" #'doom/open-project-scratch-buffer
- :desc "Switch to scratch buffer" "X" #'doom/switch-to-project-scratch-buffer
:desc "List project tasks" "t" #'magit-todos-list
- :desc "Test project" "T" #'projectile-test-project)
+ :desc "Test project" "T" #'projectile-test-project
+ :desc "Pop up scratch buffer" "x" #'doom/open-project-scratch-buffer
+ :desc "Switch to scratch buffer" "X" #'doom/switch-to-project-scratch-buffer)
;;; q --- quit/session
(:prefix-map ("q" . "quit/session")
@@ -626,7 +645,7 @@
(:when (featurep! :lang org +pomodoro)
:desc "Pomodoro timer" "t" #'org-pomodoro)
:desc "Soft line wrapping" "w" #'visual-line-mode
- (:when (featurep! :ui word-wrap)
+ (:when (featurep! :editor word-wrap)
:desc "Soft line wrapping" "w" #'+word-wrap-mode)
:desc "Zen mode" "z" #'writeroom-mode))
diff --git a/modules/config/default/autoload/files.el b/modules/config/default/autoload/files.el
index 3c90f6d23..e49e8255f 100644
--- a/modules/config/default/autoload/files.el
+++ b/modules/config/default/autoload/files.el
@@ -27,11 +27,15 @@
;;;###autoload
(defun +default/browse-notes ()
"Browse files from `org-directory'."
- (interactive) (doom-project-browse org-directory))
+ (interactive)
+ (require 'org)
+ (doom-project-browse org-directory))
;;;###autoload
(defun +default/find-in-notes ()
"Find a file under `org-directory', recursively."
- (interactive) (doom-project-find-file org-directory))
+ (interactive)
+ (require 'org)
+ (doom-project-find-file org-directory))
;;;###autoload
(defun +default/find-file-under-here ()
diff --git a/modules/config/default/autoload/text.el b/modules/config/default/autoload/text.el
index d8f8c0293..7c523817e 100644
--- a/modules/config/default/autoload/text.el
+++ b/modules/config/default/autoload/text.el
@@ -35,7 +35,7 @@
(defun +default/yank-buffer-filename ()
"Copy the current buffer's path to the kill ring."
(interactive)
- (if-let* ((filename (or buffer-file-name (bound-and-true-p list-buffers-directory))))
+ (if-let (filename (or buffer-file-name (bound-and-true-p list-buffers-directory)))
(message (kill-new (abbreviate-file-name filename)))
(error "Couldn't find filename in current buffer")))
diff --git a/modules/config/default/config.el b/modules/config/default/config.el
index 91af1f621..8ed0cf535 100644
--- a/modules/config/default/config.el
+++ b/modules/config/default/config.el
@@ -1,19 +1,19 @@
;;; config/default/config.el -*- lexical-binding: t; -*-
(defvar +default-minibuffer-maps
- `(minibuffer-local-map
- minibuffer-local-ns-map
- minibuffer-local-completion-map
- minibuffer-local-must-match-map
- minibuffer-local-isearch-map
- read-expression-map
- ,@(cond ((featurep! :completion ivy)
- '(ivy-minibuffer-map
- ivy-switch-buffer-map))
- ((featurep! :completion helm)
- '(helm-map
- helm-ag-map
- helm-read-file-map))))
+ (append '(minibuffer-local-map
+ minibuffer-local-ns-map
+ minibuffer-local-completion-map
+ minibuffer-local-must-match-map
+ minibuffer-local-isearch-map
+ read-expression-map)
+ (cond ((featurep! :completion ivy)
+ '(ivy-minibuffer-map
+ ivy-switch-buffer-map))
+ ((featurep! :completion helm)
+ '(helm-map
+ helm-ag-map
+ helm-read-file-map))))
"A list of all the keymaps used for the minibuffer.")
@@ -31,8 +31,11 @@
(after! epa
;; With GPG 2.1+, this forces gpg-agent to use the Emacs minibuffer to prompt
;; for the key passphrase.
- (setq epa-pinentry-mode 'loopback)
- ;; Default to the first secret key available in your keyring.
+ (set (if EMACS27+
+ 'epg-pinentry-mode
+ 'epa-pinentry-mode) ; DEPRECATED `epa-pinentry-mode'
+ 'loopback)
+ ;; Default to the first secret key available in your keyring.
(setq-default
epa-file-encrypt-to
(or (default-value 'epa-file-encrypt-to)
@@ -254,6 +257,7 @@
"s-c" (if (featurep 'evil) #'evil-yank #'copy-region-as-kill)
"s-v" #'yank
"s-s" #'save-buffer
+ "s-x" #'execute-extended-command
:v "s-x" #'kill-region
;; Buffer-local font scaling
"s-+" #'doom/reset-font-size
@@ -377,10 +381,15 @@
;; A Doom convention where C-s on popups and interactive searches will invoke
;; ivy/helm for their superior filtering.
- (define-key! :keymaps +default-minibuffer-maps
- "C-s" (if (featurep! :completion ivy)
- #'counsel-minibuffer-history
- #'helm-minibuffer-history))
+ (when-let (command (cond ((featurep! :completion ivy)
+ #'counsel-minibuffer-history)
+ ((featurep! :completion helm)
+ #'helm-minibuffer-history)))
+ (define-key!
+ :keymaps (append +default-minibuffer-maps
+ (when (featurep! :editor evil +everywhere)
+ '(evil-ex-completion-map)))
+ "C-s" command))
;; Smarter C-a/C-e for both Emacs and Evil. C-a will jump to indentation.
;; Pressing it again will send you to the true bol. Same goes for C-e, except
diff --git a/modules/config/default/packages.el b/modules/config/default/packages.el
index ad818e198..8178f8758 100644
--- a/modules/config/default/packages.el
+++ b/modules/config/default/packages.el
@@ -1,9 +1,9 @@
;; -*- no-byte-compile: t; -*-
;;; config/default/packages.el
-(package! avy :pin "cf95ba9582")
+(package! avy :pin "3bf83140fa")
(package! drag-stuff :pin "6d06d846cd")
(package! link-hint :pin "0d9cabcdb7")
(unless (featurep! :editor evil)
- (package! expand-region :pin "1603d01fbf"))
+ (package! expand-region :pin "ea6b4cbb99"))
diff --git a/modules/editor/evil/+commands.el b/modules/editor/evil/+commands.el
index 69b9082ba..3bf6cf5e5 100644
--- a/modules/editor/evil/+commands.el
+++ b/modules/editor/evil/+commands.el
@@ -28,8 +28,6 @@
;; TODO (evil-ex-define-cmd "rx" 'doom:regex) ; open re-builder
(evil-ex-define-cmd "sh[ell]" #'+eshell:run)
-(evil-ex-define-cmd "t[mux]" #'+tmux:run) ; send to tmux
-(evil-ex-define-cmd "tcd" #'+tmux:cd-here) ; cd to default-directory in tmux
(evil-ex-define-cmd "pad" #'+evil:open-scratch-buffer)
;;; GIT
@@ -49,9 +47,9 @@
(evil-ex-define-cmd "k[ill]m" #'+evil:kill-matching-buffers)
(evil-ex-define-cmd "k[ill]o" #'doom/kill-other-buffers)
(evil-ex-define-cmd "k[ill]b" #'doom/kill-buried-buffers)
-(evil-ex-define-cmd "l[ast]" #'doom/popup-restore)
+(evil-ex-define-cmd "l[ast]" #'+popup/restore)
(evil-ex-define-cmd "messages" #'view-echo-area-messages)
-(evil-ex-define-cmd "pop[up]" #'doom/popup-this-buffer)
+(evil-ex-define-cmd "pop[up]" #'+popup/buffer)
;;; Project navigation
(evil-ex-define-cmd "a" #'projectile-find-other-file)
@@ -100,4 +98,8 @@
(evil-ex-define-cmd "tabsave" #'+workspace:save)
;;; Org-mode
-(evil-ex-define-cmd "cap" #'org-capture)
+(evil-ex-define-cmd "cap[ture]" #'org-capture)
+
+;;; ibuffer
+(when (featurep! :emacs ibuffer)
+ (evil-ex-define-cmd "buffers" #'ibuffer))
diff --git a/modules/editor/evil/+everywhere.el b/modules/editor/evil/+everywhere.el
deleted file mode 100644
index fcc34b980..000000000
--- a/modules/editor/evil/+everywhere.el
+++ /dev/null
@@ -1,250 +0,0 @@
-;;; editor/evil/+everywhere.el -*- lexical-binding: t; -*-
-
-;; We load evil-collection ourselves for these reasons:
-;;
-;; 1. To truly lazy load it. Some of its modules, like
-;; evil-collection-{elisp-mode,buff-menu} are loaded immediately, because
-;; Emacs loads their packages immediately, which pulls in all of
-;; evil-collection (and other packages with it, sometimes).
-;; 2. This ensures a predictable load order, versus lazy loading using :defer or
-;; :after-call. This means users can use (after! org ...) and be sure that
-;; their changes will override evil-collection's.
-;; 3. Ideally, we'd do away with evil-collection entirely. It changes too often,
-;; introduces breaking bugs too frequently, and I don't agree with all their
-;; design choices. Regardless, it does more good than trouble, so it may be
-;; here to stay.
-;; 4. Adds `+evil-collection-disabled-list', to make it easier for users to
-;; disable modules, and to reduce the effort required to maintain our copy of
-;; `evil-collection-list' (now I can just copy it from time to time).
-
-(defvar +evil-collection-disabled-list
- '(anaconda-mode
- buff-menu
- comint
- company
- custom
- eldoc
- elisp-mode
- ert
- free-keys
- help
- helm
- image
- kotlin-mode
- occur
- package-menu
- ruby-mode
- simple
- slime
- lispy)
- "A list of `evil-collection' modules to ignore. See the definition of this
-variable for an explanation of the defaults (in comments). See
-`evil-collection-mode-list' for a list of available options.")
-
-(defvar evil-collection-setup-minibuffer nil)
-
-;; We do this ourselves, and better.
-(defvar evil-collection-want-unimpaired-p nil)
-
-;; We handle loading evil-collection ourselves
-(defvar evil-collection--supported-modes nil)
-
-;; This has to be defined here since evil-collection doesn't autoload its own.
-;; It must be updated whenever evil-collection updates theirs. Here's an easy
-;; way to update it:
-;;
-;; (with-current-buffer
-;; (url-retrieve-synchronously "https://raw.githubusercontent.com/emacs-evil/evil-collection/master/evil-collection.el" t t)
-;; (goto-char (point-min))
-;; (when (re-search-forward "^(defvar evil-collection--supported-modes\n[^(]+")
-;; (let ((list (sexp-at-point)))
-;; ;; Fixes
-;; (when (assq 'pdf list)
-;; (setf (alist-get 'pdf list) '(pdf-tools)))
-;; (kill-new (prin1-to-string list)))))
-
-(defvar evil-collection-mode-list
- `(2048-game
- ag
- alchemist
- anaconda-mode
- apropos
- arc-mode
- bookmark
- (buff-menu "buff-menu")
- calc
- calendar
- cider
- cmake-mode
- comint
- company
- compile
- (custom cus-edit)
- cus-theme
- daemons
- dashboard
- deadgrep
- debbugs
- debug
- diff-mode
- dired
- dired-sidebar
- disk-usage
- doc-view
- docker
- ebib
- edbi
- edebug
- ediff
- eglot
- elfeed
- elisp-mode
- elisp-refs
- elisp-slime-nav
- emms
- epa
- ert
- eshell
- eval-sexp-fu
- evil-mc
- eww
- flycheck
- flymake
- free-keys
- geiser
- ggtags
- git-timemachine
- gnus
- go-mode
- grep
- guix
- hackernews
- helm
- help
- helpful
- hg-histedit
- hungry-delete
- ibuffer
- image
- image-dired
- image+
- imenu-list
- indium
- info
- ivy
- js2-mode
- leetcode
- lispy
- log-edit
- log-view
- lsp-ui-imenu
- lua-mode
- kotlin-mode
- macrostep
- man
- magit
- magit-todos
- ,@(if evil-collection-setup-minibuffer '(minibuffer))
- monky
- mu4e
- mu4e-conversation
- neotree
- notmuch
- nov
- (occur replace)
- omnisharp
- outline
- p4
- (package-menu package)
- pass
- (pdf pdf-tools)
- popup
- proced
- process-menu
- prodigy
- profiler
- python
- quickrun
- racer
- realgud
- reftex
- restclient
- rjsx-mode
- robe
- rtags
- ruby-mode
- simple
- slime
- sly
- tablist
- tar-mode
- (term term ansi-term multi-term)
- tetris
- tide
- transmission
- typescript-mode
- vc-annotate
- vc-dir
- vc-git
- vdiff
- view
- vlf
- vterm
- w3m
- wdired
- wgrep
- which-key
- woman
- xref
- youtube-dl
- (ztree ztree-diff)))
-
-(defun +evil-collection-init (module &optional disabled-list)
- "Initialize evil-collection-MODULE.
-
-Unlike `evil-collection-init', this respects `+evil-collection-disabled-list',
-and complains if a module is loaded too early (during startup)."
- (unless (memq (or (car-safe module) module) disabled-list)
- (doom-log "Initialized evil-collection-%s %s"
- (or (car-safe module) module)
- (if doom-init-time "" "(too early!)"))
- (with-demoted-errors "evil-collection error: %s"
- (evil-collection-init (list module)))))
-
-
-;;
-;;; Bootstrap
-
-;; These modes belong to packages that Emacs always loads at startup, causing
-;; evil-collection to load immediately. We avoid this by loading them after
-;; evil-collection has first loaded...
-(with-eval-after-load 'evil-collection
- (mapc #'+evil-collection-init '(comint custom help)))
-
-;; ...or on first invokation of their associated major/minor modes.
-(add-transient-hook! 'Buffer-menu-mode
- (+evil-collection-init '(buff-menu "buff-menu")))
-(add-transient-hook! 'image-mode
- (+evil-collection-init 'image))
-(add-transient-hook! 'emacs-lisp-mode
- (+evil-collection-init 'elisp-mode))
-(add-transient-hook! 'occur-mode
- (+evil-collection-init 'occur))
-
-(evil-define-key* 'normal process-menu-mode-map
- "q" #'kill-current-buffer
- "d" #'process-menu-delete-process)
-
-;; Don't overwrite the leader keys
-(setq evil-collection-key-blacklist
- (list doom-leader-key doom-localleader-key
- doom-leader-alt-key doom-localleader-alt-key))
-
-;; HACK Do this ourselves because evil-collection break's `eval-after-load' load
-;; order by loading their target plugin before applying keys. It'd be too
-;; much work to accommodate this eveywhere we want to bind our own evil
-;; keybinds.
-(dolist (mode evil-collection-mode-list)
- (dolist (req (or (cdr-safe mode) (list mode)))
- (with-eval-after-load req
- (+evil-collection-init mode +evil-collection-disabled-list))))
diff --git a/modules/editor/evil/README.org b/modules/editor/evil/README.org
index d83e57182..bbb2bd803 100644
--- a/modules/editor/evil/README.org
+++ b/modules/editor/evil/README.org
@@ -36,7 +36,6 @@ This holy module brings the vim experience to Emacs.
+ [[https://github.com/TheBB/evil-indent-plus][evil-indent-plus]]
+ [[https://github.com/edkolev/evil-lion][evil-lion]]
+ [[https://github.com/redguardtoo/evil-nerd-commenter][evil-nerd-commentary]]
-+ [[https://github.com/redguardtoo/evil-matchit][evil-matchit]]
+ [[https://github.com/cofi/evil-numbers][evil-numbers]]
+ [[https://github.com/noctuid/evil-textobj-anyblock][evil-textobj-anyblock]]
+ [[https://github.com/hlissner/evil-snipe][evil-snipe]]
@@ -72,6 +71,7 @@ The following vim plugins have been ported to evil:
| vim-lion | evil-lion | omap =gl= / =gL= |
| vim-seek or vim-sneak | evil-snipe | mmap =s= / =S=, omap =z= / =Z= & =x= / =X= |
| vim-surround | evil-embrace and evil-surround | vmap =S=, omap =ys= |
+| vim-unimpaired | (provided by Doom) | [[https://github.com/hlissner/doom-emacs/blob/develop/modules/editor/evil/config.el#L413-L460][see the list]] |
This module has also ported vim-unimpaired keybinds to Emacs.
diff --git a/modules/editor/evil/autoload/evil.el b/modules/editor/evil/autoload/evil.el
index 575f97077..aece9766a 100644
--- a/modules/editor/evil/autoload/evil.el
+++ b/modules/editor/evil/autoload/evil.el
@@ -92,22 +92,6 @@ the only window, use evil-window-move-* (e.g. `evil-window-move-far-left')."
"Swap windows downward."
(interactive) (+evil--window-swap 'down))
-;;;###autoload
-(defun +evil/easymotion (&optional state keymap)
- "Invoke `evil-easymotion' lazily without compromising which-key integration."
- (interactive (list 'motion 'global))
- (let ((prefix (this-command-keys)))
- (require 'evil-easymotion)
- (evil-define-key* state keymap prefix evilem-map)
- (setq prefix-arg current-prefix-arg
- unread-command-events
- (mapcar (lambda (e) (cons t e))
- (vconcat (when evil-this-operator
- (where-is-internal evil-this-operator
- nil
- t))
- prefix)))))
-
;;;###autoload (autoload '+evil:apply-macro "editor/evil/autoload/evil" nil t)
(evil-define-operator +evil:apply-macro (beg end)
"Apply macro to each line."
diff --git a/modules/editor/evil/autoload/textobjects.el b/modules/editor/evil/autoload/textobjects.el
index a1c53b03f..ec40a417a 100644
--- a/modules/editor/evil/autoload/textobjects.el
+++ b/modules/editor/evil/autoload/textobjects.el
@@ -7,7 +7,8 @@
;;;###autoload (autoload '+evil:defun-txtobj "editor/evil/autoload/textobjects" nil nil)
(evil-define-text-object +evil:defun-txtobj (count &optional _beg _end type)
- "Text object to select the whole buffer."
+ "Text object to select the top-level Lisp form or function definition at
+point."
(cl-destructuring-bind (beg . end)
(bounds-of-thing-at-point 'defun)
(evil-range beg end type)))
diff --git a/modules/editor/evil/config.el b/modules/editor/evil/config.el
index 98c39ebf0..3dfb39fd3 100644
--- a/modules/editor/evil/config.el
+++ b/modules/editor/evil/config.el
@@ -45,8 +45,6 @@ directives. By default, this only recognizes C directives.")
evil-emacs-state-cursor '(box +evil-emacs-cursor-fn)
evil-insert-state-cursor 'bar
evil-visual-state-cursor 'hollow
- ;; must be set before evil/evil-collection is loaded
- evil-want-keybinding (not (featurep! +everywhere))
;; Only do highlighting in selected window so that Emacs has less work
;; to do highlighting them all.
evil-ex-interactive-search-highlight 'selected-window)
@@ -146,6 +144,15 @@ directives. By default, this only recognizes C directives.")
(when (eq major-mode 'fundamental-mode)
(hack-local-variables)))
+ ;; HACK Invoking helpful from evil-ex throws a "No recursive edit is in
+ ;; progress" error because, between evil-ex and helpful,
+ ;; `abort-recursive-edit' gets called one time too many.
+ (defadvice! +evil--fix-helpful-key-in-evil-ex-a (key-sequence)
+ :before #'helpful-key
+ (when (evil-ex-p)
+ (run-at-time 0.1 nil #'helpful-key key-sequence)
+ (abort-recursive-edit)))
+
;; Make ESC (from normal mode) the universal escaper. See `doom-escape-hook'.
(advice-add #'evil-force-normal-state :after #'+evil-escape-a)
@@ -165,17 +172,6 @@ directives. By default, this only recognizes C directives.")
(advice-add #'evil-open-above :around #'+evil--insert-newline-above-and-respect-comments-a)
(advice-add #'evil-open-below :around #'+evil--insert-newline-below-and-respect-comments-a)
- ;; Recenter screen after most searches
- (dolist (fn '(evil-visualstar/begin-search-forward
- evil-visualstar/begin-search-backward
- evil-ex-search-word-forward
- evil-ex-search-word-backward
- evil-ex-search-next
- evil-ex-search-previous
- evil-ex-search-forward
- evil-ex-search-backward))
- (advice-add fn :around #'doom-preserve-window-position-a))
-
;; --- custom interactive codes -----------
;; These arg types will highlight matches in the current buffer
(evil-ex-define-argument-type regexp-match
@@ -214,6 +210,7 @@ directives. By default, this only recognizes C directives.")
;;; Packages
(use-package! evil-easymotion
+ :after-call pre-command-hook
:commands evilem-create evilem-default-keybindings
:config
;; Use evil-search backend, instead of isearch
@@ -221,7 +218,6 @@ directives. By default, this only recognizes C directives.")
:bind ((evil-ex-search-highlight-all nil)))
(evilem-make-motion evilem-motion-search-previous #'evil-ex-search-previous
:bind ((evil-ex-search-highlight-all nil)))
-
(evilem-make-motion evilem-motion-search-word-forward #'evil-ex-search-word-forward
:bind ((evil-ex-search-highlight-all nil)))
(evilem-make-motion evilem-motion-search-word-backward #'evil-ex-search-word-backward
@@ -403,26 +399,6 @@ To change these keys see `+evil-repeat-keys'."
evil-ex-search-previous evil-ex-search-next)
-;; `evil-collection'
-(when (featurep! +everywhere)
- (setq evil-collection-company-use-tng (featurep! :completion company +tng))
-
- (unless doom-reloading-p
- (load! "+everywhere"))
-
- ;; Don't let evil-collection interfere with certain keys
- (appendq! evil-collection-key-blacklist
- (append (when (featurep! :tools lookup)
- '("gd" "gf" "K"))
- (when (featurep! :tools eval)
- '("gr" "gR"))
- '("[" "]" "gz" "")))
-
- (defadvice! +evil-collection-disable-blacklist-a (orig-fn)
- :around #'evil-collection-vterm-toggle-send-escape ; allow binding to ESC
- (let (evil-collection-key-blacklist)
- (funcall-interactively orig-fn))))
-
;; Keybinds that have no Emacs+evil analogues (i.e. don't exist):
;; zq - mark word at point as good word
;; zw - mark word at point as bad
@@ -567,6 +543,7 @@ To change these keys see `+evil-repeat-keys'."
;; evil-easymotion (see `+evil/easymotion')
(:after evil-easymotion
+ :m "gs" evilem-map
(:map evilem-map
"a" (evilem-create #'evil-forward-arg)
"A" (evilem-create #'evil-backward-arg)
diff --git a/modules/editor/evil/init.el b/modules/editor/evil/init.el
new file mode 100644
index 000000000..1674bceb4
--- /dev/null
+++ b/modules/editor/evil/init.el
@@ -0,0 +1,269 @@
+;;; editor/evil/init.el -*- lexical-binding: t; -*-
+
+;; We load evil-collection ourselves for these reasons:
+;;
+;; 1. To truly lazy load it. Some of its modules, like
+;; evil-collection-{elisp-mode,buff-menu} are loaded immediately, because
+;; Emacs loads their packages immediately, which pulls in all of
+;; evil-collection (and other packages with it, sometimes).
+;; 2. This ensures a predictable load order, versus lazy loading using :defer or
+;; :after-call. This means users can use (after! org ...) and be sure that
+;; their changes will override evil-collection's.
+;; 3. Ideally, we'd do away with evil-collection entirely. It changes too often,
+;; introduces breaking bugs too frequently, and I don't agree with all their
+;; design choices. Regardless, it does more good than trouble, so it may be
+;; here to stay.
+;; 4. Adds `+evil-collection-disabled-list', to make it easier for users to
+;; disable modules, and to reduce the effort required to maintain our copy of
+;; `evil-collection-list' (now I can just copy it from time to time).
+
+(when (and doom-interactive-mode
+ (not doom-reloading-p)
+ (featurep! +everywhere))
+
+ (setq evil-collection-company-use-tng (featurep! :completion company +tng)
+ ;; must be set before evil/evil-collection is loaded
+ evil-want-keybinding nil)
+
+ (defvar +evil-collection-disabled-list
+ '(anaconda-mode
+ buff-menu
+ comint
+ company
+ custom
+ eldoc
+ elisp-mode
+ ert
+ free-keys
+ help
+ helm
+ image
+ kotlin-mode
+ occur
+ package-menu
+ ruby-mode
+ simple
+ slime
+ lispy)
+ "A list of `evil-collection' modules to ignore. See the definition of this
+variable for an explanation of the defaults (in comments). See
+`evil-collection-mode-list' for a list of available options.")
+
+ (defvar evil-collection-setup-minibuffer nil)
+
+ ;; We do this ourselves, and better.
+ (defvar evil-collection-want-unimpaired-p nil)
+
+ ;; We handle loading evil-collection ourselves
+ (defvar evil-collection--supported-modes nil)
+
+ ;; This has to be defined here since evil-collection doesn't autoload its own.
+ ;; It must be updated whenever evil-collection updates theirs. Here's an easy
+ ;; way to update it:
+ ;;
+ ;; (with-current-buffer
+ ;; (url-retrieve-synchronously "https://raw.githubusercontent.com/emacs-evil/evil-collection/master/evil-collection.el" t t)
+ ;; (goto-char (point-min))
+ ;; (when (re-search-forward "^(defvar evil-collection--supported-modes\n[^(]+")
+ ;; (let ((list (sexp-at-point)))
+ ;; ;; Fixes
+ ;; (when (assq 'pdf list)
+ ;; (setf (alist-get 'pdf list) '(pdf-tools)))
+ ;; (let ((diff (cl-set-difference evil-collection-mode-list list :test #'equal)))
+ ;; (list (- (length list) (length evil-collection-mode-list))
+ ;; diff)
+ ;; (message "diff: %s" diff)
+ ;; (kill-new (prin1-to-string list))))))
+
+ (defvar evil-collection-mode-list
+ `(2048-game
+ ag
+ alchemist
+ anaconda-mode
+ apropos
+ arc-mode
+ bookmark
+ (buff-menu "buff-menu")
+ calc
+ calendar
+ cider
+ cmake-mode
+ comint
+ company
+ compile
+ (custom cus-edit)
+ cus-theme
+ daemons
+ dashboard
+ deadgrep
+ debbugs
+ debug
+ diff-mode
+ dired
+ dired-sidebar
+ disk-usage
+ doc-view
+ docker
+ ebib
+ edbi
+ edebug
+ ediff
+ eglot
+ elfeed
+ elisp-mode
+ elisp-refs
+ elisp-slime-nav
+ emms
+ epa
+ ert
+ eshell
+ eval-sexp-fu
+ evil-mc
+ eww
+ flycheck
+ flymake
+ free-keys
+ geiser
+ ggtags
+ git-timemachine
+ gnus
+ go-mode
+ grep
+ guix
+ hackernews
+ helm
+ help
+ helpful
+ hg-histedit
+ hungry-delete
+ ibuffer
+ image
+ image-dired
+ image+
+ imenu-list
+ indium
+ info
+ ivy
+ js2-mode
+ leetcode
+ lispy
+ log-edit
+ log-view
+ lsp-ui-imenu
+ lua-mode
+ kotlin-mode
+ macrostep
+ man
+ magit
+ magit-todos
+ ,@(if evil-collection-setup-minibuffer '(minibuffer))
+ monky
+ mu4e
+ mu4e-conversation
+ neotree
+ notmuch
+ nov
+ (occur replace)
+ omnisharp
+ outline
+ p4
+ (package-menu package)
+ pass
+ (pdf pdf-tools)
+ popup
+ proced
+ process-menu
+ prodigy
+ profiler
+ python
+ quickrun
+ racer
+ realgud
+ reftex
+ restclient
+ rjsx-mode
+ robe
+ rtags
+ ruby-mode
+ simple
+ slime
+ sly
+ tablist
+ tar-mode
+ (term term ansi-term multi-term)
+ tetris
+ tide
+ transmission
+ typescript-mode
+ vc-annotate
+ vc-dir
+ vc-git
+ vdiff
+ view
+ vlf
+ vterm
+ w3m
+ wdired
+ wgrep
+ which-key
+ woman
+ xref
+ xwidget
+ youtube-dl
+ (ztree ztree-diff)))
+
+ (defun +evil-collection-init (module &optional disabled-list)
+ "Initialize evil-collection-MODULE.
+
+Unlike `evil-collection-init', this respects `+evil-collection-disabled-list',
+and complains if a module is loaded too early (during startup)."
+ (unless (memq (or (car-safe module) module) disabled-list)
+ (doom-log "Initialized evil-collection-%s %s"
+ (or (car-safe module) module)
+ (if doom-init-time "" "(too early!)"))
+ (with-demoted-errors "evil-collection error: %s"
+ (evil-collection-init (list module)))))
+
+ ;; These modes belong to packages that Emacs always loads at startup, causing
+ ;; evil-collection to load immediately. We avoid this by loading them after
+ ;; evil-collection has first loaded...
+ (with-eval-after-load 'evil-collection
+ ;; Don't let evil-collection interfere with certain keys
+ (setq evil-collection-key-blacklist
+ (append (list doom-leader-key doom-localleader-key
+ doom-leader-alt-key)
+ (when (featurep! :tools lookup)
+ '("gd" "gf" "K"))
+ (when (featurep! :tools eval)
+ '("gr" "gR"))
+ '("[" "]" "gz" "")))
+
+ (evil-define-key* 'normal process-menu-mode-map
+ "q" #'kill-current-buffer
+ "d" #'process-menu-delete-process)
+
+ (mapc #'+evil-collection-init '(comint custom help)))
+
+ (defadvice! +evil-collection-disable-blacklist-a (orig-fn)
+ :around #'evil-collection-vterm-toggle-send-escape ; allow binding to ESC
+ (let (evil-collection-key-blacklist)
+ (funcall-interactively orig-fn)))
+
+ ;; ...or on first invokation of their associated major/minor modes.
+ (add-transient-hook! 'Buffer-menu-mode
+ (+evil-collection-init '(buff-menu "buff-menu")))
+ (add-transient-hook! 'image-mode
+ (+evil-collection-init 'image))
+ (add-transient-hook! 'emacs-lisp-mode
+ (+evil-collection-init 'elisp-mode))
+ (add-transient-hook! 'occur-mode
+ (+evil-collection-init '(occur replace)))
+
+ ;; HACK Do this ourselves because evil-collection break's `eval-after-load'
+ ;; load order by loading their target plugin before applying keys. This
+ ;; makes it hard for end-users to overwrite these keybinds with a
+ ;; simple `after!' or `with-eval-after-load'.
+ (dolist (mode evil-collection-mode-list)
+ (dolist (req (or (cdr-safe mode) (list mode)))
+ (with-eval-after-load req
+ (+evil-collection-init mode +evil-collection-disabled-list)))))
diff --git a/modules/editor/evil/packages.el b/modules/editor/evil/packages.el
index 9e116ce96..2a427f444 100644
--- a/modules/editor/evil/packages.el
+++ b/modules/editor/evil/packages.el
@@ -1,7 +1,7 @@
;; -*- no-byte-compile: t; -*-
;;; editor/evil/packages.el
-(package! evil :pin "7c42ba4de0")
+(package! evil :pin "8aa6337fa8")
(package! evil-args :pin "758ad5ae54")
(package! evil-easymotion :pin "79c13ed3bc")
(package! evil-embrace :pin "4379adea03")
@@ -9,16 +9,16 @@
(package! evil-exchange :pin "3030e21ee1")
(package! evil-indent-plus :pin "0c7501e6ef")
(package! evil-lion :pin "6b03593f5d")
-(package! evil-nerd-commenter :pin "fa40dab8d2")
+(package! evil-nerd-commenter :pin "747e346f11")
(package! evil-numbers
:recipe (:host github :repo "janpath/evil-numbers")
- :pin "d988041c1f")
+ :pin "c2cfdd1eb1")
(package! evil-snipe :pin "3ec8adfd49")
(package! evil-surround :pin "9b0b17f06c")
(package! evil-textobj-anyblock :pin "ff00980f06")
(package! evil-traces :pin "bc25cae9fa")
(package! evil-visualstar :pin "06c053d8f7")
-(package! exato :pin "88266fa7fc")
+(package! exato :pin "d5daea3017")
(package! evil-quick-diff
:recipe (:host github :repo "rgrinberg/evil-quick-diff")
:pin "69c883720b")
@@ -31,4 +31,4 @@
(package! neotree)
(autoload 'neotree-make-executor "neotree" nil nil 'macro))
- (package! evil-collection :pin "e6a4ba695e"))
+ (package! evil-collection :pin "493d523c9b"))
diff --git a/modules/editor/file-templates/packages.el b/modules/editor/file-templates/packages.el
index 67d4ada0e..42c98b815 100644
--- a/modules/editor/file-templates/packages.el
+++ b/modules/editor/file-templates/packages.el
@@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; editor/file-templates/packages.el
-(package! yasnippet :pin "3bf9a3b1af")
+(package! yasnippet :pin "ac03c2f192")
diff --git a/modules/editor/file-templates/templates/sh-mode/__ b/modules/editor/file-templates/templates/sh-mode/__
index 3bb86a69c..397669fa0 100644
--- a/modules/editor/file-templates/templates/sh-mode/__
+++ b/modules/editor/file-templates/templates/sh-mode/__
@@ -1,3 +1,4 @@
#!/usr/bin/env `(if (equal (file-name-extension buffer-file-name) "zsh") "zsh" "bash")`
+set -euo pipefail
$0
diff --git a/modules/editor/fold/config.el b/modules/editor/fold/config.el
index 8e5a445ed..fd478b236 100644
--- a/modules/editor/fold/config.el
+++ b/modules/editor/fold/config.el
@@ -53,7 +53,19 @@
nil (lambda (_arg) (matlab-forward-sexp)))
(nxml-mode "\\|[^/>]*[^/]>"
- "