Merge remote-tracking branch 'origin/develop' into download-iosevka
This commit is contained in:
commit
3a257cfc56
428 changed files with 9639 additions and 6497 deletions
42
.github/ISSUE_TEMPLATE/bug_report.md
vendored
42
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -1,43 +1,41 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Something went wrong, please fix it!
|
||||
about: Doom might be misbehaving
|
||||
labels: is:bug
|
||||
title: "[BUG] "
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Describe the issue**
|
||||
Start with a brief 1 or 2 sentence summary of issue.
|
||||
**What did you expect to happen?**
|
||||
...
|
||||
|
||||
Then follow with a longer explanation, if necessary. Here are some suggestions
|
||||
on what to include:
|
||||
- What you expected vs what actually happened
|
||||
- Screenshots/casts of your issue
|
||||
- A link to your private config
|
||||
- Labels for any keys you reference (use `SPC h k` to inspect a key)
|
||||
- Any warnings or errors logged to \*Messages\* (`SPC h e` or `M-x
|
||||
view-echo-area-messages`).
|
||||
|
||||
**What actually happened?**
|
||||
...
|
||||
|
||||
|
||||
**Additional details:**
|
||||
- Include a link to your private config
|
||||
- Include screenshots/casts of your issue
|
||||
- If you mention key sequences, include what commands they're bound to (use `SPC
|
||||
h k KEY` or `C-h h k KEY` to inspect keys).
|
||||
- Include any warnings or errors logged to \*Messages\* (use `M-x
|
||||
view-echo-area-messages` to see it).
|
||||
|
||||
<details><pre>
|
||||
If available, please a backtrace of the error here.
|
||||
If an error message is involved include a backtrace of it.
|
||||
|
||||
To acquire a backtrace, enable `debug-on-error` then recreate the error. Here
|
||||
are ways to enable `debug-on-error`:
|
||||
- `M-x toggle-debug-on-error`,
|
||||
- Start Emacs with `emacs --debug-init`
|
||||
- If the error occurred while using `bin/doom`, use the `-d`/`--debug`
|
||||
- switches or the `DEBUG` environment variable.
|
||||
How to acquire a backtrace:
|
||||
https://github.com/hlissner/doom-emacs/blob/develop/docs/getting_started.org#how-to-extract-a-backtrace-from-an-error
|
||||
</pre></details>
|
||||
|
||||
|
||||
**Steps to reproduce**
|
||||
**Steps to reproduce:**
|
||||
1. Select these example steps,
|
||||
2. Delete them,
|
||||
3. And replace them with precise steps to reproduce your issue.
|
||||
4. Fill in "system information" below.
|
||||
|
||||
|
||||
**System information**
|
||||
**System information:**
|
||||
<details><pre>
|
||||
Place the output of `M-x doom/info` or `~/.emacs.d/bin/doom info` here.
|
||||
</pre></details>
|
||||
|
|
26
.github/ISSUE_TEMPLATE/feature_request.md
vendored
26
.github/ISSUE_TEMPLATE/feature_request.md
vendored
|
@ -1,28 +1,20 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Make suggestions for improving Doom Emacs
|
||||
labels: is:request
|
||||
title: "[REQUEST] "
|
||||
assignees: ''
|
||||
about: It'd be cool if Doom did/had/would...
|
||||
labels: is:new
|
||||
---
|
||||
|
||||
**Describe the feature**
|
||||
Start with a brief 1 or 2 sentence summary of feature.
|
||||
|
||||
Then follow up with an extended explanation, if necessary. Here are some
|
||||
suggestions on what to include:
|
||||
- How is it helpful?
|
||||
- How is the feature used?
|
||||
- If the feature involves new plugins, include links to them
|
||||
- iF the feature involves replacement of current functionality, describe how the
|
||||
new functionality is better.
|
||||
- If the feature is implemented in another editor Emacs distro:
|
||||
- Include screenshots or screencasts of it
|
||||
- Include links to its implementation
|
||||
- Include names of commands (and not just the keybinds to invoke them)
|
||||
- If the feature involves replacement of current functionality, how the new
|
||||
functionality is better?
|
||||
- If the feature is implemented in another editor or Emacs distro, include:
|
||||
- Screenshots or screencasts of it
|
||||
- Links to its implementation
|
||||
- Names of relevant commands (and not only the keybinds to invoke them)
|
||||
|
||||
|
||||
**System information**
|
||||
<details><pre>
|
||||
Include the output of `M-x doom/info` or `~/.emacs.d/bin/doom info` here.
|
||||
Place the output of `M-x doom/info` or `~/.emacs.d/bin/doom info` here.
|
||||
</pre></details>
|
||||
|
|
31
.github/ISSUE_TEMPLATE/how_to.md
vendored
31
.github/ISSUE_TEMPLATE/how_to.md
vendored
|
@ -1,23 +1,26 @@
|
|||
---
|
||||
name: How do I...
|
||||
about: How to get Doom/Emacs to behave a certain way
|
||||
labels: is:howto, status:pending-review
|
||||
title: "[HOWTO] "
|
||||
assignees: ''
|
||||
labels: is:question
|
||||
---
|
||||
|
||||
**What I want to achieve**
|
||||
Start with a brief 1 or 2 sentence summary of what you're trying to achieve.
|
||||
> Please visit our Discord server to ask how-to and workflow questions:
|
||||
> https://discord.gg/qvGgnVx -- post on Doom's issue tracker as a last resort.
|
||||
|
||||
Follow up with an expanded explanation, if necessary. A few suggestions of what
|
||||
you could include are:
|
||||
- Code or steps you've tried that did not yield the results you wanted.
|
||||
- Screenshots/casts of a proposed workflow in another editor or Emacs distro,
|
||||
- Additional material or links to resources that could help clarify what you are
|
||||
trying to do.
|
||||
- A link to your private config, if available.
|
||||
- The names of commands available in other Emacs distros (rather than just the
|
||||
keybinds that invoke them).
|
||||
**What are you trying to achieve?**
|
||||
...
|
||||
|
||||
|
||||
**What have you tried?**
|
||||
...
|
||||
|
||||
|
||||
**Additional information**
|
||||
- Do you have screenshots/casts of this workflow in another editor or Emacs
|
||||
distro? (If possible, include names of specific commands or functions from
|
||||
other editors/emacs distros)
|
||||
- Do you have additional material or links to resources that could help clarify
|
||||
what you are trying to do?
|
||||
|
||||
|
||||
**System information**
|
||||
|
|
9
.github/ISSUE_TEMPLATE/question.md
vendored
9
.github/ISSUE_TEMPLATE/question.md
vendored
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
name: Question
|
||||
about: A question about the project or maintainer
|
||||
labels: is:question, status:pending-review
|
||||
title: "[QUESTION] "
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
What would you like to know?
|
30
.github/PULL_REQUEST/bump.md
vendored
Normal file
30
.github/PULL_REQUEST/bump.md
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
name: Bump a package
|
||||
about: Update a pinned package to a new commit
|
||||
labels: is:update re:packages
|
||||
---
|
||||
> You're about to request a package be bumped to a newer commit.
|
||||
>
|
||||
> 1. Please make sure this PR targets the `develop` branch and not `master`.
|
||||
> 2. Describe why these bumps are necessary below
|
||||
> 3. Please conform your commit messages to one of the following formats:
|
||||
>
|
||||
> Bump to username/repo@a1b2c3d
|
||||
>
|
||||
> From username/repo@z9y8x7w
|
||||
>
|
||||
> OR, if multiple packages are bumped in one commit:
|
||||
>
|
||||
> Bump package1, package2 & package 3
|
||||
>
|
||||
> emacs-lsp/lsp-mode@91e37a6 -> emacs-lsp/lsp-mode@c8188ef
|
||||
> emacs-lsp/lsp-ui@cf6906c -> emacs-lsp/lsp-ui@582e153
|
||||
>
|
||||
> (Commit hashes should be limited to 7 characters)
|
||||
>
|
||||
> 4. You've included links to relevant issues, if any
|
||||
> 5. You've deleted this template
|
||||
>
|
||||
> Thank you for contributing to Doom Emacs! <3
|
||||
|
||||
Explain why this bump is necessary here...
|
|
@ -1,6 +1,10 @@
|
|||
> To ensure that this PR is processed as quickly as possible, please ensure the
|
||||
> following steps have been taken:
|
||||
> - [ ] This PR targets the develop branch and not master
|
||||
---
|
||||
name: General Contribution
|
||||
about: A general code or documentation PR
|
||||
---
|
||||
> Please follow these steps before submitting your PR:
|
||||
>
|
||||
> - [ ] This PR targets the `develop` branch and not `master`
|
||||
> - [ ] If your PR is a work in progress, include [WIP] in its title
|
||||
> - [ ] Its commits' summaries are reasonably descriptive
|
||||
> - [ ] You've described what this PR addresses below
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -7,12 +7,15 @@ modules/private
|
|||
.cask/
|
||||
cask/
|
||||
elpa/
|
||||
test/.local*/
|
||||
|
||||
# emacs tempfiles that shouldn't be there
|
||||
.mc-lists.el
|
||||
.org-id-locations
|
||||
.tern-port
|
||||
auto-save-list
|
||||
.extension/
|
||||
.dap-breakpoints
|
||||
auto-save-list/
|
||||
semanticdb
|
||||
ede-projects.el
|
||||
tramp
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016-2019 Henrik Lissner.
|
||||
Copyright (c) 2016-2020 Henrik Lissner.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
|
85
Makefile
85
Makefile
|
@ -1,85 +0,0 @@
|
|||
DOOM = "bin/doom"
|
||||
MODULES = $(patsubst modules/%/, %, $(sort $(dir $(wildcard modules/*/ modules/*/*/))))
|
||||
|
||||
all: deprecated
|
||||
@$(DOOM) refresh
|
||||
|
||||
deprecated:
|
||||
@echo "Using make to manage your Doom config is deprecated"
|
||||
@echo
|
||||
@echo "Use the 'bin/doom' script instead. The equivalent of 'make' is 'doom refresh'."
|
||||
@echo
|
||||
@echo "See 'doom help' for a list of commands"
|
||||
@echo
|
||||
@read -p "Press enter to continue"
|
||||
|
||||
## Shortcuts
|
||||
a: autoloads
|
||||
i: install
|
||||
u: update
|
||||
U: upgrade
|
||||
r: autoremove
|
||||
c: compile
|
||||
cc: compile-core
|
||||
cp: compile-plugins
|
||||
re: recompile
|
||||
d: doctor
|
||||
|
||||
quickstart: install
|
||||
|
||||
|
||||
## Package management
|
||||
install: deprecated
|
||||
@$(DOOM) install
|
||||
update: deprecated
|
||||
@$(DOOM) update
|
||||
autoremove: deprecated
|
||||
@$(DOOM) autoremove
|
||||
autoloads: deprecated
|
||||
@$(DOOM) autoloads
|
||||
upgrade: deprecated
|
||||
@$(DOOM) upgrade
|
||||
|
||||
## Byte compilation
|
||||
compile: deprecated
|
||||
@$(DOOM) compile
|
||||
compile-core: deprecated
|
||||
@$(DOOM) compile :core
|
||||
compile-private: deprecated
|
||||
@$(DOOM) compile :private
|
||||
compile-plugins: deprecated
|
||||
@$(DOOM) build
|
||||
recompile: deprecated
|
||||
@$(DOOM) recompile
|
||||
clean: deprecated
|
||||
@$(DOOM) clean
|
||||
# compile-module
|
||||
# compile-module/submodule
|
||||
$(patsubst %, compile-%, $(MODULES)): | .local/autoloads.el
|
||||
@$(DOOM) $@ $(subst compile-, , $@)
|
||||
|
||||
|
||||
## Unit tests
|
||||
test:
|
||||
@$(DOOM) test
|
||||
test-core:
|
||||
@$(DOOM) test :core
|
||||
# test-module
|
||||
# test-module/submodule
|
||||
$(patsubst %, test-%, $(MODULES)):
|
||||
@$(DOOM) test $(subst test-, , $@)
|
||||
|
||||
|
||||
## Utility tasks
|
||||
# Runs Emacs from a different folder than ~/.emacs.d; only use this for testing!
|
||||
run:
|
||||
@$(DOOM) run $(ARGS)
|
||||
# Prints debug info about your current setup
|
||||
info:
|
||||
@$(DOOM) info
|
||||
|
||||
# Diagnoses potential OS/environment issues
|
||||
doctor:
|
||||
@$(DOOM) doctor
|
||||
|
||||
.PHONY: all compile test testi clean
|
76
README.md
76
README.md
|
@ -7,7 +7,7 @@
|
|||
<a href="https://github.com/hlissner/doom-emacs/actions">
|
||||
<img src="https://github.com/hlissner/doom-emacs/workflows/CI/badge.svg" alt="Build status: develop">
|
||||
</a>
|
||||
<a href="https://discord.gg/bcZ6P3y">
|
||||
<a href="https://discord.gg/qvGgnVx">
|
||||
<img src="https://img.shields.io/badge/Discord-blue.svg?logo=discord&label=join" alt="Join our discord server" align="right">
|
||||
</a>
|
||||
<br><br>
|
||||
|
@ -35,6 +35,9 @@ git clone 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).
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
- [What is Doom Emacs](#what-is-doom-emacs)
|
||||
|
@ -55,46 +58,47 @@ 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 succumbing to the [dark side][url:evil-mode]. This is his config.
|
||||
|
||||
Doom is a configuration for [GNU Emacs](https://www.gnu.org/software/emacs/)
|
||||
designed to make Emacs faster and easier to customize. It can serve as framework
|
||||
for your own configuration or a resource for fellow Emacs enthusiasts who want
|
||||
to learn more about our favorite OS.
|
||||
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.
|
||||
|
||||
## Doom's mantras
|
||||
|
||||
- **Gotta go fast.** Startup and run-time performance are high priorities.
|
||||
Expensive functionality (built-in or in plugins) is modified and optimized
|
||||
toward this end, otherwise, they must be opt-in.
|
||||
- **Close to metal.** There's less between you and vanilla Emacs, by design.
|
||||
There's less to grok. Modules should be syntactically sweet and backend logic
|
||||
explicit and abstraction-light. The code itself ought to be designed as if
|
||||
grokking it were part of the user experience; and it is!
|
||||
- **Opinionated, but not stubborn.** Doom is a bundle of reasonable defaults
|
||||
and curated opinions, but you aren't stuck with it. Use as little or as much
|
||||
of it as you like. Use it as-is as a complete Emacs distribution; disable
|
||||
everything and use it as a baseline for your own; or anywhere in between.
|
||||
- **Your system, your rules.** There are more ways to set up your programming
|
||||
environment than there are dislikes on Youtube Rewind '18, so Doom and its
|
||||
plugins promise not to *automatically* (and definitely not *silently*) install
|
||||
system dependencies. This means fonts, packages and programs. `doom doctor`
|
||||
will tell you what's missing though!
|
||||
- **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
|
||||
|
||||
- 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.
|
||||
- Minimalistic good looks inspired by modern editors.
|
||||
- A modular architecture for a more organized Emacs configuration.
|
||||
- A custom elisp library to help you simplify your config.
|
||||
- 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.
|
||||
- Vim-emulation powered by [evil-mode][url:evil-mode], including ports of
|
||||
popular vim plugins and functionality.
|
||||
- A Spacemacs-esque [keybinding scheme][doom:bindings], centered around leader
|
||||
and localleader prefix keys (<kbd>SPC</kbd> and <kbd>SPC</kbd><kbd>m</kbd>, by
|
||||
default).
|
||||
|
@ -104,12 +108,11 @@ to learn more about our favorite OS.
|
|||
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
|
||||
[the_silver_searcher][url:the_silver_searcher] or [ripgrep][url:ripgrep].
|
||||
- Project search (and replace) utilities, powered by [ripgrep][url:ripgrep].
|
||||
- Isolated and persistent workspaces (also substitutes for vim tabs).
|
||||
- An environment variables file generator and loader, so that Emacs can
|
||||
perfectly inherit your shell configuration.
|
||||
- Everything is optional!
|
||||
- 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.
|
||||
|
||||
# Getting Help
|
||||
|
||||
|
@ -122,7 +125,7 @@ We have [a Discord server][url:discord]! Hop on and say hi!
|
|||
Encountered strange behavior or an error? Here are some things to try before you
|
||||
shoot off that bug report:
|
||||
|
||||
- Run `bin/doom refresh`. This ensures Doom is properly set up and its autoloads
|
||||
- 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
|
||||
|
@ -168,11 +171,10 @@ you can do to help; I welcome any contribution!
|
|||
[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/bcZ6P3y
|
||||
[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:the_silver_searcher]: https://github.com/ggreer/the_silver_searcher
|
||||
[url:straight]: https://github.com/raxod502/straight.el
|
||||
|
|
62
bin/doom
62
bin/doom
|
@ -9,10 +9,11 @@
|
|||
:; exec $EMACS --script "$0" -- "$@"
|
||||
:; exit 0
|
||||
|
||||
(let* ((loaddir (file-name-directory (file-truename load-file-name)))
|
||||
(let* ((load-prefer-newer t)
|
||||
(loaddir (file-name-directory (file-truename load-file-name)))
|
||||
(emacsdir (getenv "EMACSDIR"))
|
||||
(user-emacs-directory (or emacsdir (expand-file-name "../" loaddir)))
|
||||
(load-prefer-newer t))
|
||||
(user-emacs-directory
|
||||
(abbreviate-file-name (or emacsdir (expand-file-name "../" loaddir)))))
|
||||
|
||||
(push (expand-file-name "core" user-emacs-directory) load-path)
|
||||
(require 'core)
|
||||
|
@ -51,9 +52,18 @@ with a different private module."
|
|||
(setq doom-auto-accept t)
|
||||
(print! (info "Auto-yes on")))
|
||||
(when help-p
|
||||
(push command args)
|
||||
(when command
|
||||
(push command args))
|
||||
(setq command "help"))
|
||||
|
||||
(when (equal (user-real-uid) 0)
|
||||
(print!
|
||||
(concat "WARNING: This script is running as root. This likely wasn't intentional, and\n"
|
||||
"is unnecessary to use this script. This will cause file permissions errors\n"
|
||||
"later if you use this Doom installation on a non-root account.\n"))
|
||||
(unless (or doom-auto-accept (y-or-n-p "Continue anyway?"))
|
||||
(user-error "Aborted")))
|
||||
|
||||
;; Reload core in case any of the directories were changed.
|
||||
(when (or emacsdir doomdir localdir)
|
||||
(load! "core/core.el" user-emacs-directory))
|
||||
|
@ -69,29 +79,43 @@ with a different private module."
|
|||
((condition-case e
|
||||
(let ((start-time (current-time)))
|
||||
(and (doom-cli-execute command args)
|
||||
(terpri)
|
||||
(print! (success "Finished! (%.4fs)")
|
||||
(float-time
|
||||
(time-subtract (current-time)
|
||||
start-time)))))
|
||||
(user-error
|
||||
(print! (error "%s\n") (error-message-string e))
|
||||
(print! (yellow "See 'doom help %s' for documentation on this command.") (car args)))
|
||||
(print! (yellow "See 'doom help %s' for documentation on this command.") (car args))
|
||||
(error "")) ; Ensure non-zero exit code
|
||||
((debug error)
|
||||
(message "--------------------------------------------------\n")
|
||||
(message "There was an unexpected error:")
|
||||
(message " %s (%s)" (get (car e) 'error-message) (car e))
|
||||
(dolist (item (cdr e))
|
||||
(message " %s" item))
|
||||
(print! (error "There was an unexpected error:"))
|
||||
(print-group!
|
||||
(print! "%s %s" (bold "Type:") (car e))
|
||||
(print! (bold "Message:"))
|
||||
(print-group!
|
||||
(print! "%s" (get (car e) 'error-message)))
|
||||
(print! (bold "Data:"))
|
||||
(print-group!
|
||||
(if (cdr e)
|
||||
(dolist (item (cdr e))
|
||||
(print! "%S" item))
|
||||
(print! "n/a")))
|
||||
(when (featurep 'straight)
|
||||
(when (string-match-p (regexp-quote straight-process-buffer)
|
||||
(error-message-string e))
|
||||
(print! (bold "Straight output:"))
|
||||
(print-group! (print! "%s" (straight--process-get-output))))))
|
||||
(unless debug-on-error
|
||||
(message
|
||||
(concat "\nRun the command again with the -d (or --debug) option to enable debug\n"
|
||||
"mode and, hopefully, generate a stack trace. If you decide to file a bug\n"
|
||||
"report, please include it!\n\n"
|
||||
"Emacs outputs to standard error, so you'll need to redirect stderr to\n"
|
||||
"stdout to pipe this to a file or clipboard!\n\n"
|
||||
" e.g. doom -d install 2>&1 | clipboard-program\n"))
|
||||
(signal 'doom-error e)))))))
|
||||
(terpri)
|
||||
(print!
|
||||
(concat "Run the command again with the -d (or --debug) switch to enable debug\n"
|
||||
"mode and (hopefully) generate a backtrace from this error:\n"
|
||||
"\n %s\n\n"
|
||||
"If you file a bug report, please include it!")
|
||||
(string-join (append (list (file-name-nondirectory load-file-name) "-d" command)
|
||||
args)
|
||||
" "))
|
||||
(error ""))))))) ; Ensure non-zero exit code
|
||||
|
||||
(doom-cli-execute :main (cdr (member "--" argv)))
|
||||
(setq argv nil))
|
||||
|
|
|
@ -22,8 +22,8 @@ fi
|
|||
|
||||
# org-capture key mapped to argument flags
|
||||
# keys=$(emacsclient -e "(+org-capture-available-keys)" | cut -d '"' -f2)
|
||||
while getopts hk opt; do
|
||||
key="\"$opt\""
|
||||
while getopts "hk:" opt; do
|
||||
key="\"$OPTARG\""
|
||||
break
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
|
|
@ -195,7 +195,9 @@ If DERIVED-P, test with `derived-mode-p', otherwise use `eq'."
|
|||
|
||||
;;;###autoload
|
||||
(defun doom-set-buffer-real (buffer flag)
|
||||
"Forcibly mark BUFFER as FLAG (non-nil = real)."
|
||||
"Forcibly mark BUFFER as FLAG (non-nil = real).
|
||||
|
||||
See `doom-real-buffer-p' for an explanation for real buffers."
|
||||
(with-current-buffer buffer
|
||||
(setq doom-real-buffer-p flag)))
|
||||
|
||||
|
@ -251,7 +253,9 @@ regex PATTERN. Returns the number of killed buffers."
|
|||
|
||||
;;;###autoload
|
||||
(defun doom-mark-buffer-as-real-h ()
|
||||
"Hook function that marks the current buffer as real."
|
||||
"Hook function that marks the current buffer as real.
|
||||
|
||||
See `doom-real-buffer-p' for an explanation for real buffers."
|
||||
(doom-set-buffer-real (current-buffer) t))
|
||||
|
||||
|
||||
|
@ -272,6 +276,12 @@ If DONT-SAVE, don't prompt to save modified buffers (discarding their changes)."
|
|||
(set-buffer-modified-p nil)))
|
||||
(doom-kill-buffer-fixup-windows buffer))
|
||||
|
||||
|
||||
(defun doom--message-or-count (interactive message count)
|
||||
(if interactive
|
||||
(message message count)
|
||||
count))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/kill-all-buffers (&optional buffer-list interactive)
|
||||
"Kill all buffers and closes their windows.
|
||||
|
@ -286,14 +296,14 @@ belong to the current project."
|
|||
(if (null buffer-list)
|
||||
(message "No buffers to kill")
|
||||
(save-some-buffers)
|
||||
(delete-other-windows)
|
||||
(when (memq (current-buffer) buffer-list)
|
||||
(switch-to-buffer (doom-fallback-buffer)))
|
||||
(mapc #'doom-kill-buffer-and-windows buffer-list)
|
||||
(delete-other-windows)
|
||||
(when interactive
|
||||
(message "Killed %s buffers"
|
||||
(- (length buffer-list)
|
||||
(length (cl-remove-if-not #'buffer-live-p buffer-list)))))))
|
||||
(mapc #'kill-buffer buffer-list)
|
||||
(doom--message-or-count
|
||||
interactive "Killed %d buffers"
|
||||
(- (length buffer-list)
|
||||
(length (cl-remove-if-not #'buffer-live-p buffer-list))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/kill-other-buffers (&optional buffer-list interactive)
|
||||
|
@ -308,10 +318,10 @@ project."
|
|||
(doom-buffer-list)))
|
||||
t))
|
||||
(mapc #'doom-kill-buffer-and-windows buffer-list)
|
||||
(when interactive
|
||||
(message "Killed %s buffers"
|
||||
(- (length buffer-list)
|
||||
(length (cl-remove-if-not #'buffer-live-p buffer-list))))))
|
||||
(doom--message-or-count
|
||||
interactive "Killed %d other buffers"
|
||||
(- (length buffer-list)
|
||||
(length (cl-remove-if-not #'buffer-live-p buffer-list)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/kill-matching-buffers (pattern &optional buffer-list interactive)
|
||||
|
@ -340,7 +350,11 @@ current project."
|
|||
(list (doom-buried-buffers
|
||||
(if current-prefix-arg (doom-project-buffer-list)))
|
||||
t))
|
||||
(doom/kill-all-buffers buffer-list interactive))
|
||||
(mapc #'kill-buffer buffer-list)
|
||||
(doom--message-or-count
|
||||
interactive "Killed %d buried buffers"
|
||||
(- (length buffer-list)
|
||||
(length (cl-remove-if-not #'buffer-live-p buffer-list)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/kill-project-buffers (project &optional interactive)
|
||||
|
@ -358,9 +372,9 @@ current project."
|
|||
nil)
|
||||
t))
|
||||
(when project
|
||||
(let ((buffers (doom-project-buffer-list project)))
|
||||
(doom-kill-buffers-fixup-windows buffers)
|
||||
(when interactive
|
||||
(message "Killed %d buffer(s)"
|
||||
(- (length buffers)
|
||||
(length (cl-remove-if-not #'buffer-live-p buffers))))))))
|
||||
(let ((buffer-list (doom-project-buffer-list project)))
|
||||
(doom-kill-buffers-fixup-windows buffer-list)
|
||||
(doom--message-or-count
|
||||
interactive "Killed %d project buffers"
|
||||
(- (length buffer-list)
|
||||
(length (cl-remove-if-not #'buffer-live-p buffer-list)))))))
|
||||
|
|
|
@ -1,86 +1,5 @@
|
|||
;;; core/autoload/cli.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; Externs
|
||||
(defvar evil-collection-mode-list)
|
||||
|
||||
;;;###autoload
|
||||
(defun doom--cli-run (command &rest _args)
|
||||
(when (featurep 'general)
|
||||
(general-auto-unbind-keys))
|
||||
(let* ((evil-collection-mode-list nil)
|
||||
(default-directory doom-emacs-dir)
|
||||
(buf (get-buffer-create " *bin/doom*"))
|
||||
(doom-format-backend 'ansi)
|
||||
(ignore-window-parameters t)
|
||||
(noninteractive t)
|
||||
(standard-output
|
||||
(lambda (char)
|
||||
(with-current-buffer buf
|
||||
(insert char)
|
||||
(when (memq char '(?\n ?\r))
|
||||
(ansi-color-apply-on-region (line-beginning-position -1) (line-end-position))
|
||||
(redisplay))))))
|
||||
(doom-initialize t)
|
||||
(setq doom-modules (doom-modules))
|
||||
(doom-initialize-modules t)
|
||||
(doom-initialize-packages t)
|
||||
(with-current-buffer (switch-to-buffer buf)
|
||||
(erase-buffer)
|
||||
(require 'package)
|
||||
(redisplay)
|
||||
(doom-dispatch command nil)
|
||||
(print! (green "\nDone!"))))
|
||||
(when (featurep 'general)
|
||||
(general-auto-unbind-keys 'undo))
|
||||
(message (format! (green "Done!"))))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//autoloads (&optional yes)
|
||||
"TODO"
|
||||
(interactive "P")
|
||||
(let ((doom-auto-accept yes))
|
||||
(doom--cli-run "autoloads")))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//update (&optional yes)
|
||||
"TODO"
|
||||
(interactive "P")
|
||||
(let ((doom-auto-accept yes))
|
||||
(doom--cli-run "update")))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//upgrade (&optional yes)
|
||||
"TODO"
|
||||
(interactive "P")
|
||||
(let ((doom-auto-accept yes))
|
||||
(doom--cli-run "upgrade"))
|
||||
(when (y-or-n-p "You must restart Emacs for the upgrade to take effect. Restart?")
|
||||
(doom/restart-and-restore)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//install (&optional yes)
|
||||
"TODO"
|
||||
(interactive "P")
|
||||
(let ((doom-auto-accept yes))
|
||||
(doom--cli-run "install")))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//autoremove (&optional yes)
|
||||
"TODO"
|
||||
(interactive "P")
|
||||
(let ((doom-auto-accept yes))
|
||||
(doom--cli-run "autoremove")))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//refresh (&optional yes)
|
||||
"TODO"
|
||||
(interactive "P")
|
||||
(let ((doom-auto-accept yes))
|
||||
(doom--cli-run "refresh")))
|
||||
|
||||
|
||||
|
||||
;;
|
||||
;;; Library
|
||||
|
||||
|
@ -113,7 +32,7 @@ Warning: freezes indefinitely on any stdin prompt."
|
|||
:connection-type 'pipe))
|
||||
done-p)
|
||||
(set-process-filter
|
||||
process (lambda (process output)
|
||||
process (lambda (_process output)
|
||||
(princ output (current-buffer))
|
||||
(princ output)))
|
||||
(set-process-sentinel
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
;;; core/autoload/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar doom-bin-dir (concat doom-emacs-dir "bin/"))
|
||||
(defvar doom-bin (concat doom-bin-dir "doom"))
|
||||
|
||||
;;;###autoload
|
||||
(defvar doom-reload-hook nil
|
||||
"A list of hooks to run when `doom/reload' is called.")
|
||||
|
@ -23,8 +26,9 @@
|
|||
(doom-project-find-file doom-private-dir))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/goto-doomblock ()
|
||||
"Open your private init.el and go to your `doom!' block."
|
||||
(defun doom/goto-private-init-file ()
|
||||
"Open your private init.el file.
|
||||
And jumps to your `doom!' block."
|
||||
(interactive)
|
||||
(find-file (expand-file-name "init.el" doom-private-dir))
|
||||
(goto-char
|
||||
|
@ -34,46 +38,58 @@
|
|||
(point))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/goto-config-file ()
|
||||
(defun doom/goto-private-config-file ()
|
||||
"Open your private config.el file."
|
||||
(interactive)
|
||||
(find-file (expand-file-name "config.el" doom-private-dir)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/goto-packages-file ()
|
||||
(defun doom/goto-private-packages-file ()
|
||||
"Open your private packages.el file."
|
||||
(interactive)
|
||||
(find-file (expand-file-name "packages.el" doom-private-dir)))
|
||||
|
||||
|
||||
;;
|
||||
;;; Managements
|
||||
|
||||
(cl-defmacro doom--compile (command &key on-success on-failure)
|
||||
(declare (indent defun))
|
||||
`(with-current-buffer (compile ,command)
|
||||
(add-hook
|
||||
'compilation-finish-functions
|
||||
(lambda (_buf status)
|
||||
(if (equal status "finished\n")
|
||||
,on-success
|
||||
,on-failure))
|
||||
nil 'local)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/reload ()
|
||||
"Reloads your private config.
|
||||
|
||||
This is experimental! It will try to do as `bin/doom refresh' does, but from
|
||||
within this Emacs session. i.e. it reload autoloads files (if necessary),
|
||||
reloads your package list, and lastly, reloads your private config.el.
|
||||
This is experimental! It will try to do as `bin/doom sync' does, but from within
|
||||
this Emacs session. i.e. it reload autoloads files (if necessary), reloads your
|
||||
package list, and lastly, reloads your private config.el.
|
||||
|
||||
Runs `doom-reload-hook' afterwards."
|
||||
(interactive)
|
||||
(or (y-or-n-p
|
||||
(concat "You are about to reload your Doom config from within Emacs. This "
|
||||
"is highly experimental and may cause issues. It is recommended you "
|
||||
"use 'bin/doom refresh' on the command line instead.\n\n"
|
||||
"Reload anyway?"))
|
||||
(user-error "Aborted"))
|
||||
(require 'core-cli)
|
||||
(let ((doom-reloading-p t))
|
||||
(compile (format "%s/bin/doom refresh -f" doom-emacs-dir))
|
||||
(while compilation-in-progress
|
||||
(sit-for 1))
|
||||
(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))
|
||||
(message "Finished!"))
|
||||
(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
|
||||
(user-error "Failed to reload your config")))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/reload-autoloads ()
|
||||
|
@ -83,23 +99,45 @@ This is much faster and safer than `doom/reload', but not as comprehensive. This
|
|||
reloads your package and module visibility, but does not install new packages or
|
||||
remove orphaned ones. It also doesn't reload your private config.
|
||||
|
||||
It is useful to only pull in changes performed by 'doom refresh' on the command
|
||||
It is useful to only pull in changes performed by 'doom sync' on the command
|
||||
line."
|
||||
(interactive)
|
||||
(require 'core-cli)
|
||||
(require 'core-packages)
|
||||
(doom-initialize-packages)
|
||||
(doom-reload-autoloads nil 'force))
|
||||
(doom-cli-reload-autoloads))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/reload-env ()
|
||||
"Regenerates and reloads your shell environment.
|
||||
(defun doom/reload-env (&optional arg)
|
||||
"Regenerates and/or reloads your envvar file.
|
||||
|
||||
Uses the same mechanism as 'bin/doom env reload'."
|
||||
If passed the prefix ARG, clear the envvar file. Uses the same mechanism as
|
||||
'bin/doom env'.
|
||||
|
||||
An envvar file contains a snapshot of your shell environment, which can be
|
||||
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
|
||||
(error "Failed to generate env file")))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/upgrade ()
|
||||
"Run 'doom upgrade' then prompt to restart Emacs."
|
||||
(interactive)
|
||||
(compile (format "%s env" (expand-file-name "bin/doom" doom-emacs-dir)))
|
||||
(while compilation-in-progress
|
||||
(sit-for 1))
|
||||
(unless (file-readable-p doom-env-file)
|
||||
(error "Failed to generate env file"))
|
||||
(doom-load-envvars-file doom-env-file))
|
||||
(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))))
|
||||
|
|
|
@ -23,11 +23,25 @@
|
|||
(when (file-exists-p file)
|
||||
(insert-file-contents file))))
|
||||
|
||||
(defun doom--collect-forms-in (file form)
|
||||
(when (file-readable-p file)
|
||||
(let (forms)
|
||||
(with-temp-buffer
|
||||
(insert-file-contents file)
|
||||
(delay-mode-hooks (emacs-lisp-mode))
|
||||
(while (re-search-forward (format "(%s " (regexp-quote form)) nil t)
|
||||
(unless (doom-point-in-string-or-comment-p)
|
||||
(save-excursion
|
||||
(goto-char (match-beginning 0))
|
||||
(push (sexp-at-point) forms))))
|
||||
(nreverse forms)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-info ()
|
||||
"Returns diagnostic information about the current Emacs session in markdown,
|
||||
ready to be pasted in a bug report on github."
|
||||
(require 'vc-git)
|
||||
(require 'core-packages)
|
||||
(let ((default-directory doom-emacs-dir)
|
||||
(doom-modules (doom-modules)))
|
||||
(cl-letf
|
||||
|
@ -46,7 +60,8 @@ ready to be pasted in a bug report on github."
|
|||
'server-running))))
|
||||
(doom
|
||||
(version . ,doom-version)
|
||||
(build . ,(sh "git" "log" "-1" "--format=%D %h %ci")))
|
||||
(build . ,(sh "git" "log" "-1" "--format=%D %h %ci"))
|
||||
(dir . ,(abbreviate-file-name (file-truename doom-private-dir))))
|
||||
(system
|
||||
(type . ,system-type)
|
||||
(config . ,system-configuration)
|
||||
|
@ -78,24 +93,29 @@ ready to be pasted in a bug report on github."
|
|||
(cdr key))))
|
||||
'("n/a")))
|
||||
(packages
|
||||
,@(or (ignore-errors
|
||||
(let ((doom-interactive-mode t)
|
||||
doom-packages
|
||||
doom-disabled-packages)
|
||||
(doom--read-module-packages-file
|
||||
(doom-path doom-private-dir "packages.el")
|
||||
nil t)
|
||||
(cl-loop for (name . plist) in (nreverse doom-packages)
|
||||
collect
|
||||
(if-let (splist (doom-plist-delete (copy-sequence plist)
|
||||
:modules))
|
||||
(prin1-to-string (cons name splist))
|
||||
name))))
|
||||
,@(or (condition-case e
|
||||
(mapcar
|
||||
#'cdr (doom--collect-forms-in
|
||||
(doom-path doom-private-dir "packages.el")
|
||||
"package!"))
|
||||
(error (format "<%S>" e)))
|
||||
'("n/a")))
|
||||
(unpin
|
||||
,@(or (condition-case e
|
||||
(mapcan #'identity
|
||||
(mapcar
|
||||
#'cdr (doom--collect-forms-in
|
||||
(doom-path doom-private-dir "packages.el")
|
||||
"unpin!")))
|
||||
(error (format "<%S>" e)))
|
||||
'("n/a")))
|
||||
(elpa
|
||||
,@(or (ignore-errors
|
||||
(cl-loop for (name . _) in package-alist
|
||||
collect (format "%s" name)))
|
||||
,@(or (condition-case e
|
||||
(progn
|
||||
(package-initialize)
|
||||
(cl-loop for (name . _) in package-alist
|
||||
collect (format "%s" name)))
|
||||
(error (format "<%S>" e)))
|
||||
'("n/a"))))))))
|
||||
|
||||
|
||||
|
@ -197,7 +217,7 @@ markdown and copies it to your clipboard, ready to be pasted into bug reports!"
|
|||
(prin1-to-string
|
||||
(macroexp-progn
|
||||
(append `((setq noninteractive nil
|
||||
doom-debug-mode t
|
||||
init-file-debug t
|
||||
load-path ',load-path
|
||||
package--init-file-ensured t
|
||||
package-user-dir ,package-user-dir
|
||||
|
@ -209,8 +229,10 @@ markdown and copies it to your clipboard, ready to be pasted into bug reports!"
|
|||
(setq-default buffer-undo-tree (make-undo-tree))))
|
||||
(pcase mode
|
||||
(`vanilla-doom+ ; Doom core + modules - private config
|
||||
`((setq doom-init-modules-p t)
|
||||
(load-file ,user-init-file)
|
||||
`((load-file ,(expand-file-name "core.el" doom-core-dir))
|
||||
(doom-initialize)
|
||||
(doom-initialize-core)
|
||||
(add-hook 'window-setup-hook #'doom-display-benchmark-h)
|
||||
(setq doom-modules ',doom-modules)
|
||||
(maphash (lambda (key plist)
|
||||
(let ((doom--current-module key)
|
||||
|
@ -225,8 +247,9 @@ markdown and copies it to your clipboard, ready to be pasted into bug reports!"
|
|||
(run-hook-wrapped 'doom-init-modules-hook #'doom-try-run-hook)
|
||||
(doom-run-all-startup-hooks-h)))
|
||||
(`vanilla-doom ; only Doom core
|
||||
`((setq doom-init-modules-p t)
|
||||
(load-file ,user-init-file)
|
||||
`((load-file ,(expand-file-name "core.el" doom-core-dir))
|
||||
(doom-initialize)
|
||||
(doom-initialize-core)
|
||||
(doom-run-all-startup-hooks-h)))
|
||||
(`vanilla ; nothing loaded
|
||||
`((package-initialize)))))))
|
||||
|
@ -335,6 +358,10 @@ will be automatically appended to the result."
|
|||
((> (prefix-numeric-value arg) 0)))))
|
||||
(setq doom-debug-mode value
|
||||
debug-on-error value
|
||||
garbage-collection-messages value
|
||||
use-package-verbose value
|
||||
jka-compr-verbose value
|
||||
lsp-log-io value)
|
||||
lsp-log-io value
|
||||
gcmh-verbose value
|
||||
magit-refresh-verbose value)
|
||||
(message "Debug mode %s" (if value "on" "off"))))
|
||||
|
|
|
@ -108,26 +108,26 @@ be relative to it.
|
|||
The search recurses up to DEPTH and no further. DEPTH is an integer.
|
||||
|
||||
MATCH is a string regexp. Only entries that match it will be included."
|
||||
(let (file-name-handler-alist
|
||||
result)
|
||||
(let (result file-name-handler-alist)
|
||||
(dolist (file (mapcan (doom-rpartial #'doom-glob "*") (doom-enlist paths)))
|
||||
(cond ((file-directory-p file)
|
||||
(nconcq! result
|
||||
(and (memq type '(t dirs))
|
||||
(string-match-p match file)
|
||||
(not (and filter (funcall filter file)))
|
||||
(not (and (file-symlink-p file)
|
||||
(not follow-symlinks)))
|
||||
(<= mindepth 0)
|
||||
(list (cond (map (funcall map file))
|
||||
(relative-to (file-relative-name file relative-to))
|
||||
(file))))
|
||||
(and (>= depth 1)
|
||||
(apply #'doom-files-in file
|
||||
(append (list :mindepth (1- mindepth)
|
||||
:depth (1- depth)
|
||||
:relative-to relative-to)
|
||||
rest)))))
|
||||
(appendq!
|
||||
result
|
||||
(and (memq type '(t dirs))
|
||||
(string-match-p match file)
|
||||
(not (and filter (funcall filter file)))
|
||||
(not (and (file-symlink-p file)
|
||||
(not follow-symlinks)))
|
||||
(<= mindepth 0)
|
||||
(list (cond (map (funcall map file))
|
||||
(relative-to (file-relative-name file relative-to))
|
||||
(file))))
|
||||
(and (>= depth 1)
|
||||
(apply #'doom-files-in file
|
||||
(append (list :mindepth (1- mindepth)
|
||||
:depth (1- depth)
|
||||
:relative-to relative-to)
|
||||
rest)))))
|
||||
((and (memq type '(t files))
|
||||
(string-match-p match file)
|
||||
(not (and filter (funcall filter file)))
|
||||
|
@ -178,6 +178,7 @@ single file or nested compound statement of `and' and `or' statements."
|
|||
file))
|
||||
(nth 7 (file-attributes file))))
|
||||
|
||||
(defvar w32-get-true-file-attributes)
|
||||
;;;###autoload
|
||||
(defun doom-directory-size (dir)
|
||||
"Returns the size of FILE (in DIR) in kilobytes."
|
||||
|
@ -202,16 +203,14 @@ single file or nested compound statement of `and' and `or' statements."
|
|||
;;
|
||||
;;; Helpers
|
||||
|
||||
(defun doom--forget-file (old-path &optional new-path)
|
||||
(defun doom--forget-file (path)
|
||||
"Ensure `recentf', `projectile' and `save-place' forget OLD-PATH."
|
||||
(when (bound-and-true-p recentf-mode)
|
||||
(when new-path
|
||||
(recentf-add-file new-path))
|
||||
(recentf-remove-if-non-kept old-path))
|
||||
(recentf-remove-if-non-kept path))
|
||||
(when (and (bound-and-true-p projectile-mode)
|
||||
(doom-project-p)
|
||||
(projectile-file-cached-p old-path (doom-project-root)))
|
||||
(projectile-purge-file-from-cache old-path))
|
||||
(projectile-file-cached-p path (doom-project-root)))
|
||||
(projectile-purge-file-from-cache path))
|
||||
(when (bound-and-true-p save-place-mode)
|
||||
(save-place-forget-unreadable-files)))
|
||||
|
||||
|
@ -220,7 +219,8 @@ single file or nested compound statement of `and' and `or' statements."
|
|||
(vc-file-clearprops path)
|
||||
(vc-resynch-buffer path nil t))
|
||||
(when (featurep 'magit)
|
||||
(magit-refresh)))
|
||||
(when-let (default-directory (magit-toplevel (file-name-directory path)))
|
||||
(magit-refresh))))
|
||||
|
||||
(defun doom--copy-file (old-path new-path &optional force-p)
|
||||
(let* ((new-path (expand-file-name new-path))
|
||||
|
@ -306,11 +306,18 @@ file if it exists, without confirmation."
|
|||
(let ((old-path (buffer-file-name))
|
||||
(new-path (expand-file-name new-path)))
|
||||
(when-let (dest (doom--copy-file old-path new-path force-p))
|
||||
(doom--forget-file old-path)
|
||||
(when (file-exists-p old-path)
|
||||
(delete-file old-path))
|
||||
(mapc #'doom--update-file
|
||||
(delq
|
||||
nil (list (if (ignore-errors
|
||||
(file-equal-p (doom-project-root old-path)
|
||||
(doom-project-root new-path)))
|
||||
nil
|
||||
old-path)
|
||||
new-path)))
|
||||
(kill-current-buffer)
|
||||
(doom--forget-file old-path new-path)
|
||||
(doom--update-file new-path)
|
||||
(find-file new-path)
|
||||
(message "File successfully moved to %s" dest))))
|
||||
(`overwrite-self (error "Cannot overwrite self"))
|
||||
|
@ -339,4 +346,21 @@ file if it exists, without confirmation."
|
|||
(defun doom/sudo-this-file ()
|
||||
"Open the current file as root."
|
||||
(interactive)
|
||||
(find-alternate-file (doom--sudo-file buffer-file-name)))
|
||||
(find-alternate-file (doom--sudo-file (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)))
|
||||
(if-let (buffer (find-file-noselect file))
|
||||
(let ((origin (current-buffer)))
|
||||
(unwind-protect
|
||||
(with-current-buffer buffer
|
||||
(save-buffer))
|
||||
(unless (eq origin buffer)
|
||||
(kill-buffer buffer))))
|
||||
(user-error "Unable to open %S" file))))
|
||||
|
|
|
@ -16,49 +16,51 @@ acceptable values for this variable.")
|
|||
"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.")
|
||||
|
||||
;;;###autoload
|
||||
(defvar doom-change-font-size-hook nil
|
||||
"A hook run after adjusting the font size with `doom/increase-font-size',
|
||||
`doom/decrease-font-size', or `doom/reset-font-size'.")
|
||||
|
||||
|
||||
;;
|
||||
;;; Library
|
||||
|
||||
(defun doom--font-name (fontname frame)
|
||||
(defun doom--font-name (fontname)
|
||||
(when (query-fontset fontname)
|
||||
(when-let (ascii (assq 'ascii (aref (fontset-info fontname frame) 2)))
|
||||
(when-let (ascii (assq 'ascii (aref (fontset-info fontname) 2)))
|
||||
(setq fontname (nth 2 ascii))))
|
||||
(or (x-decompose-font-name fontname)
|
||||
(error "Cannot decompose font name")))
|
||||
|
||||
(defun doom--frame-list (&optional frame)
|
||||
"Return a list consisting of FRAME and all of FRAME's child frames."
|
||||
(let ((frame (or frame (selected-frame))))
|
||||
(cons (selected-frame)
|
||||
(cl-loop for fr in (frame-list)
|
||||
if (eq (frame-parameter fr 'parent-frame) frame)
|
||||
collect fr))))
|
||||
|
||||
(defvar doom--font-scale nil)
|
||||
;;;###autoload
|
||||
(defun doom-adjust-font-size (increment &optional frame)
|
||||
(defun doom-adjust-font-size (increment)
|
||||
"Increase size of font in FRAME by INCREMENT.
|
||||
FRAME parameter defaults to current frame."
|
||||
(let* ((frame (or frame (selected-frame)))
|
||||
(font (frame-parameter frame 'font))
|
||||
(font (doom--font-name font frame)))
|
||||
(let ((new-size (+ (string-to-number (aref font xlfd-regexp-pixelsize-subnum))
|
||||
increment)))
|
||||
(unless (> new-size 0)
|
||||
(error "Font is too small at %d" new-size))
|
||||
(aset font xlfd-regexp-pixelsize-subnum (number-to-string new-size)))
|
||||
;; Set point size & width to "*", so frame width will adjust to new font size
|
||||
(aset font xlfd-regexp-pointsize-subnum "*")
|
||||
(aset font xlfd-regexp-avgwidth-subnum "*")
|
||||
(setq font (x-compose-font-name font))
|
||||
(unless (x-list-fonts font)
|
||||
(error "Cannot change font size"))
|
||||
(set-frame-parameter frame 'font font)))
|
||||
(if (null increment)
|
||||
(progn
|
||||
(set-frame-font doom-font 'keep-size t)
|
||||
(setf (alist-get 'font default-frame-alist)
|
||||
(cond ((stringp doom-font) doom-font)
|
||||
((fontp doom-font) (font-xlfd-name doom-font))
|
||||
((signal 'wrong-type-argument (list '(fontp stringp)
|
||||
doom-font)))))
|
||||
t)
|
||||
(let* ((font (frame-parameter nil 'font))
|
||||
(font (doom--font-name font))
|
||||
(increment (* increment doom-font-increment))
|
||||
(zoom-factor (or doom--font-scale 0)))
|
||||
(let ((new-size (+ (string-to-number (aref font xlfd-regexp-pixelsize-subnum))
|
||||
increment)))
|
||||
(unless (> new-size 0)
|
||||
(error "Font is too small at %d" new-size))
|
||||
(aset font xlfd-regexp-pixelsize-subnum (number-to-string new-size)))
|
||||
;; Set point size & width to "*", so frame width will adjust to new font size
|
||||
(aset font xlfd-regexp-pointsize-subnum "*")
|
||||
(aset font xlfd-regexp-avgwidth-subnum "*")
|
||||
(setq font (x-compose-font-name font))
|
||||
(unless (x-list-fonts font)
|
||||
(error "Cannot change font size"))
|
||||
(set-frame-font font 'keep-size t)
|
||||
(setf (alist-get 'font default-frame-alist) font)
|
||||
(setq doom--font-scale (+ zoom-factor increment))
|
||||
;; Unlike `set-frame-font', `set-frame-parameter' won't trigger this
|
||||
(run-hooks 'after-setting-font-hook))))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -76,20 +78,15 @@ See `doom-init-fonts-h'."
|
|||
|
||||
;;;###autoload
|
||||
(defun doom/increase-font-size (count)
|
||||
"Enlargens the font size across the current frame."
|
||||
"Enlargens the font size across the current and child frames."
|
||||
(interactive "p")
|
||||
(let ((zoom-factor (or (frame-parameter nil 'font-scale) 0))
|
||||
(increment (* count doom-font-increment)))
|
||||
(setq zoom-factor (+ zoom-factor increment))
|
||||
(doom-adjust-font-size increment)
|
||||
(set-frame-parameter nil 'font-scale zoom-factor)
|
||||
(run-hooks 'doom-change-font-size-hook)))
|
||||
(doom-adjust-font-size count))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/decrease-font-size (count)
|
||||
"Shrinks the font size across the current frame."
|
||||
"Shrinks the font size across the current and child frames."
|
||||
(interactive "p")
|
||||
(doom/increase-font-size (- count)))
|
||||
(doom-adjust-font-size (- count)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/reset-font-size ()
|
||||
|
@ -103,13 +100,10 @@ Assuming it has been adjusted via `doom/increase-font-size' and
|
|||
(/= text-scale-mode-amount 0))
|
||||
(text-scale-set 0)
|
||||
(setq success t))
|
||||
(when-let (factor (frame-parameter nil 'font-scale))
|
||||
(set-frame-font doom-font t)
|
||||
(set-frame-parameter nil 'font-scale nil)
|
||||
(when (doom-adjust-font-size nil)
|
||||
(setq success t))
|
||||
(unless success
|
||||
(user-error "The font hasn't been resized"))
|
||||
(run-hooks 'doom-change-font-size-hook)))
|
||||
(user-error "The font hasn't been resized"))))
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode doom-big-font-mode
|
||||
|
@ -123,12 +117,16 @@ This uses `doom/increase-font-size' under the hood, and enlargens the font by
|
|||
:global t
|
||||
(unless doom-font
|
||||
(user-error "`doom-font' must be set to a valid font"))
|
||||
(let ((frame (selected-frame)))
|
||||
(if doom-big-font
|
||||
(progn
|
||||
(set-frame-font (if doom-big-font-mode doom-big-font doom-font)
|
||||
t (doom--frame-list frame))
|
||||
(run-hooks 'doom-change-font-size-hook))
|
||||
(set-frame-font doom-font t (doom--frame-list frame))
|
||||
(when doom-big-font-mode
|
||||
(doom-adjust-font-size doom-big-font-increment frame)))))
|
||||
(if doom-big-font
|
||||
(let ((font (if doom-big-font-mode doom-big-font doom-font)))
|
||||
(set-frame-font font 'keep-size t)
|
||||
(setf (alist-get 'font default-frame-alist)
|
||||
(cond ((stringp doom-font) font)
|
||||
((fontp font) (font-xlfd-name font))
|
||||
((signal 'wrong-type-argument (list '(fontp stringp)
|
||||
font))))))
|
||||
(doom-adjust-font-size
|
||||
(and doom-big-font-mode
|
||||
(integerp doom-big-font-increment)
|
||||
(/= doom-big-font-increment 0)
|
||||
doom-big-font-increment))))
|
||||
|
|
|
@ -106,9 +106,8 @@ Accepts 'ansi and 'text-properties. nil means don't render colors.")
|
|||
;;;###autoload
|
||||
(defun doom--format-print (output)
|
||||
(unless (string-empty-p output)
|
||||
(if (not noninteractive)
|
||||
(message "%s" output)
|
||||
(princ output)
|
||||
(princ output)
|
||||
(when (or noninteractive (not (eq standard-output t)))
|
||||
(terpri)) ; newline
|
||||
t))
|
||||
|
||||
|
@ -213,8 +212,9 @@ into faces or ANSI codes depending on the type of sesssion we're in."
|
|||
|
||||
;;;###autoload
|
||||
(defmacro print! (message &rest args)
|
||||
"Uses `message' in interactive sessions and `princ' otherwise (prints to
|
||||
standard out).
|
||||
"Prints MESSAGE, formatted with ARGS, to stdout.
|
||||
|
||||
Returns non-nil if the message is a non-empty string.
|
||||
|
||||
Can be colored using (color ...) blocks:
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
(lisp-mode :lang common-lisp)
|
||||
(csharp-mode :lang csharp)
|
||||
(clojure-mode :lang clojure)
|
||||
(clojurescript-mode :lang clojure)
|
||||
(graphql-mode :lang data)
|
||||
(toml-mode :lang data)
|
||||
(json-mode :lang data)
|
||||
|
@ -95,7 +96,7 @@ the current major-modea.")
|
|||
"Get information on an active minor mode. Use `describe-minor-mode' for a
|
||||
selection of all minor-modes, active or not."
|
||||
(interactive
|
||||
(list (completing-read "Minor mode: " (doom-active-minor-modes))))
|
||||
(list (completing-read "Describe active mode: " (doom-active-minor-modes))))
|
||||
(let ((symbol
|
||||
(cond ((stringp mode) (intern mode))
|
||||
((symbolp mode) mode)
|
||||
|
@ -104,21 +105,6 @@ selection of all minor-modes, active or not."
|
|||
(helpful-function symbol)
|
||||
(helpful-variable symbol))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/describe-symbol (symbol)
|
||||
"Show help for SYMBOL, a variable, function or macro."
|
||||
(interactive
|
||||
(list (helpful--read-symbol "Symbol: " #'helpful--bound-p)))
|
||||
(let* ((sym (intern-soft symbol))
|
||||
(bound (boundp sym))
|
||||
(fbound (fboundp sym)))
|
||||
(cond ((and sym bound (not fbound))
|
||||
(helpful-variable sym))
|
||||
((and sym fbound (not bound))
|
||||
(helpful-callable sym))
|
||||
((apropos (format "^%s\$" symbol)))
|
||||
((apropos (format "%s" symbol))))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Documentation commands
|
||||
|
@ -132,30 +118,30 @@ selection of all minor-modes, active or not."
|
|||
(depth (if (integerp depth) depth)))
|
||||
(message "Loading search results...")
|
||||
(unwind-protect
|
||||
(delq nil
|
||||
(org-map-entries
|
||||
(lambda ()
|
||||
(cl-destructuring-bind (level _reduced-level _todo _priority text tags)
|
||||
(org-heading-components)
|
||||
(let ((path (org-get-outline-path)))
|
||||
(when (and (or (null depth)
|
||||
(<= level depth))
|
||||
(or (null tags)
|
||||
(not (string-match-p ":TOC" tags))))
|
||||
(propertize
|
||||
(mapconcat
|
||||
'identity
|
||||
(list (mapconcat #'identity
|
||||
(append (when include-files
|
||||
(list (or (+org-get-global-property "TITLE")
|
||||
(file-relative-name buffer-file-name))))
|
||||
path
|
||||
(list (replace-regexp-in-string org-link-any-re "\\4" text)))
|
||||
" > ")
|
||||
(delq
|
||||
nil
|
||||
(org-map-entries
|
||||
(lambda ()
|
||||
(cl-destructuring-bind (level _reduced-level _todo _priority text tags)
|
||||
(org-heading-components)
|
||||
(when (and (or (null depth)
|
||||
(<= level depth))
|
||||
(or (null tags)
|
||||
(not (string-match-p ":TOC" tags))))
|
||||
(let ((path (org-get-outline-path)))
|
||||
(list (string-join
|
||||
(list (string-join
|
||||
(append (when include-files
|
||||
(list (or (+org-get-global-property "TITLE")
|
||||
(file-relative-name (buffer-file-name)))))
|
||||
path
|
||||
(list (replace-regexp-in-string org-link-any-re "\\4" text)))
|
||||
" > ")
|
||||
tags)
|
||||
" ")
|
||||
'location (cons buffer-file-name (point)))))))
|
||||
t 'agenda))
|
||||
(buffer-file-name)
|
||||
(point))))))
|
||||
t 'agenda))
|
||||
(mapc #'kill-buffer org-agenda-new-buffers)
|
||||
(setq org-agenda-new-buffers nil))))
|
||||
|
||||
|
@ -163,17 +149,23 @@ selection of all minor-modes, active or not."
|
|||
;;;###autoload
|
||||
(defun doom-completing-read-org-headings (prompt files &optional depth include-files initial-input extra-candidates)
|
||||
"TODO"
|
||||
(let (ivy-sort-functions-alist)
|
||||
(if-let* ((result (completing-read
|
||||
prompt
|
||||
(append (doom--org-headings files depth include-files)
|
||||
extra-candidates)
|
||||
nil nil initial-input)))
|
||||
(cl-destructuring-bind (file . location)
|
||||
(get-text-property 0 'location result)
|
||||
(let ((alist
|
||||
(append (doom--org-headings files depth include-files)
|
||||
extra-candidates))
|
||||
ivy-sort-functions-alist)
|
||||
(if-let (result (completing-read prompt alist nil nil initial-input))
|
||||
(cl-destructuring-bind (file &optional location)
|
||||
(cdr (assoc result alist))
|
||||
(find-file file)
|
||||
(when location
|
||||
(goto-char location)))
|
||||
(cond ((functionp location)
|
||||
(funcall location))
|
||||
(location
|
||||
(goto-char location)))
|
||||
(ignore-errors
|
||||
(when (outline-invisible-p)
|
||||
(save-excursion
|
||||
(outline-previous-visible-heading 1)
|
||||
(org-show-subtree)))))
|
||||
(user-error "Aborted"))))
|
||||
|
||||
;;;###autoload
|
||||
|
@ -189,7 +181,7 @@ selection of all minor-modes, active or not."
|
|||
(find-file (expand-file-name "index.org" doom-docs-dir)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/help-search (&optional initial-input)
|
||||
(defun doom/help-search-headings (&optional initial-input)
|
||||
"Search Doom's documentation and jump to a headline."
|
||||
(interactive)
|
||||
(doom-completing-read-org-headings
|
||||
|
@ -201,11 +193,29 @@ selection of all minor-modes, active or not."
|
|||
"faq.org")
|
||||
2 t initial-input
|
||||
(mapcar (lambda (x)
|
||||
(propertize (concat "Doom Modules > " x)
|
||||
'location
|
||||
(get-text-property (1- (length x)) 'location x)))
|
||||
(setcar x (concat "Doom Modules > " (car x)))
|
||||
x)
|
||||
(doom--help-modules-list))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/help-search (&optional initial-input)
|
||||
"Preform a text search on all of Doom's documentation."
|
||||
(interactive)
|
||||
(funcall (cond ((fboundp '+ivy-file-search)
|
||||
#'+ivy-file-search)
|
||||
((fboundp '+helm-file-search)
|
||||
#'+helm-file-search)
|
||||
((rgrep
|
||||
(read-regexp
|
||||
"Search for" (or initial-input 'grep-tag-default)
|
||||
'grep-regexp-history)
|
||||
"*.org" doom-emacs-dir)
|
||||
#'ignore))
|
||||
:query initial-input
|
||||
:args '("-g" "*.org")
|
||||
:in doom-emacs-dir
|
||||
:prompt "Search documentation for: "))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/help-news-search (&optional initial-input)
|
||||
"Search headlines in Doom's newsletters."
|
||||
|
@ -298,30 +308,19 @@ without needing to check if they are available."
|
|||
(describe-function fn))))
|
||||
|
||||
(defun doom--help-modules-list ()
|
||||
(cl-loop for path in (doom-module-load-path 'all)
|
||||
(cl-loop for path in (cdr (doom-module-load-path 'all))
|
||||
for (cat . mod) = (doom-module-from-path path)
|
||||
for location = (cons (or (doom-module-locate-path cat mod "README.org")
|
||||
(doom-module-locate-path cat mod))
|
||||
nil)
|
||||
for format = (propertize (format "%s %s" cat mod)
|
||||
'location location)
|
||||
for readme-path = (or (doom-module-locate-path cat mod "README.org")
|
||||
(doom-module-locate-path cat mod))
|
||||
for format = (format "%s %s" cat mod)
|
||||
if (doom-module-p cat mod)
|
||||
collect format
|
||||
collect (list format readme-path)
|
||||
else if (and cat mod)
|
||||
collect
|
||||
(propertize
|
||||
format
|
||||
'face 'font-lock-comment-face
|
||||
'location location)))
|
||||
collect (list (propertize format 'face 'font-lock-comment-face)
|
||||
readme-path)))
|
||||
|
||||
(defun doom--help-current-module-str ()
|
||||
(cond ((and buffer-file-name
|
||||
(eq major-mode 'emacs-lisp-mode)
|
||||
(file-in-directory-p buffer-file-name doom-private-dir)
|
||||
(save-excursion (goto-char (point-min))
|
||||
(re-search-forward "^\\s-*(doom! " nil t))
|
||||
(thing-at-point 'sexp t)))
|
||||
((save-excursion
|
||||
(cond ((save-excursion
|
||||
(require 'smartparens)
|
||||
(ignore-errors
|
||||
(sp-beginning-of-sexp)
|
||||
|
@ -330,45 +329,54 @@ without needing to check if they are available."
|
|||
(let ((sexp (sexp-at-point)))
|
||||
(when (memq (car-safe sexp) '(featurep! require!))
|
||||
(format "%s %s" (nth 1 sexp) (nth 2 sexp)))))))
|
||||
((and buffer-file-name
|
||||
(when-let (mod (doom-module-from-path buffer-file-name))
|
||||
(format "%s %s" (car mod) (cdr mod)))))
|
||||
((when buffer-file-name
|
||||
(when-let (mod (doom-module-from-path buffer-file-name))
|
||||
(unless (memq (car mod) '(:core :private))
|
||||
(format "%s %s" (car mod) (cdr mod))))))
|
||||
((when-let (mod (cdr (assq major-mode doom--help-major-mode-module-alist)))
|
||||
(format "%s %s"
|
||||
(symbol-name (car mod))
|
||||
(symbol-name (cadr mod)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/help-modules (category module)
|
||||
(defun doom/help-modules (category module &optional visit-dir)
|
||||
"Open the documentation for a Doom module.
|
||||
|
||||
CATEGORY is a keyword and MODULE is a symbol. e.g. :editor and 'evil.
|
||||
|
||||
If VISIT-DIR is non-nil, visit the module's directory rather than its
|
||||
documentation.
|
||||
|
||||
Automatically selects a) the module at point (in private init files), b) the
|
||||
module derived from a `featurep!' or `require!' call, c) the module that the
|
||||
current file is in, or d) the module associated with the current major mode (see
|
||||
`doom--help-major-mode-module-alist')."
|
||||
(interactive
|
||||
(let* ((module-string
|
||||
(completing-read "Describe module: "
|
||||
(doom--help-modules-list)
|
||||
nil t nil nil
|
||||
(doom--help-current-module-str)))
|
||||
(key (doom-module-from-path
|
||||
(car (get-text-property 0 'location module-string)))))
|
||||
(list (car key)
|
||||
(cdr key))))
|
||||
(mapcar #'intern
|
||||
(split-string
|
||||
(completing-read "Describe module: "
|
||||
(doom--help-modules-list)
|
||||
nil t nil nil
|
||||
(doom--help-current-module-str))
|
||||
" " t)))
|
||||
(cl-check-type category symbol)
|
||||
(cl-check-type module symbol)
|
||||
(let ((path (doom-module-locate-path category module)))
|
||||
(cl-destructuring-bind (module-string path)
|
||||
(or (assoc (format "%s %s" category module) (doom--help-modules-list))
|
||||
(user-error "'%s %s' is not a valid module" category module))
|
||||
(setq module-string (substring-no-properties module-string))
|
||||
(unless (file-readable-p path)
|
||||
(error "'%s %s' isn't a valid module; it doesn't exist" category module))
|
||||
(if-let* ((readme-path (doom-module-locate-path category module "README.org")))
|
||||
(find-file readme-path)
|
||||
(if (y-or-n-p (format "The '%s %s' module has no README file. Explore its directory?"
|
||||
category module))
|
||||
(doom-project-browse path)
|
||||
(user-error "Aborted module lookup")))))
|
||||
(error "Can't find or read %S module at %S" module-string path))
|
||||
(cond ((not (file-directory-p path))
|
||||
(if visit-dir
|
||||
(doom-project-browse (file-name-directory path))
|
||||
(find-file path)))
|
||||
(visit-dir
|
||||
(doom-project-browse path))
|
||||
((y-or-n-p (format "The %S module has no README file. Explore its directory?"
|
||||
module-string))
|
||||
(doom-project-browse (file-name-directory path)))
|
||||
((user-error "Aborted module lookup")))))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -431,9 +439,9 @@ If prefix arg is present, refresh the cache."
|
|||
(list
|
||||
(intern
|
||||
(completing-read (if guess
|
||||
(format "Select package to search for (default %s): "
|
||||
(format "Select Doom package to search for (default %s): "
|
||||
guess)
|
||||
"Describe package: ")
|
||||
"Describe Doom package: ")
|
||||
packages nil t nil nil
|
||||
(if guess (symbol-name guess))))))))
|
||||
(require 'core-packages)
|
||||
|
@ -511,7 +519,7 @@ If prefix arg is present, refresh the cache."
|
|||
(insert "\n\n")))))
|
||||
|
||||
(defvar doom--package-cache nil)
|
||||
(defun doom--package-list ()
|
||||
(defun doom--package-list (&optional prompt)
|
||||
(let* ((guess (or (function-called-at-point)
|
||||
(symbol-at-point))))
|
||||
(require 'finder-inf nil t)
|
||||
|
@ -527,10 +535,11 @@ If prefix arg is present, refresh the cache."
|
|||
(setq doom--package-cache packages)
|
||||
(unless (memq guess packages)
|
||||
(setq guess nil))
|
||||
(intern (completing-read (if guess
|
||||
(format "Select package to search for (default %s): "
|
||||
guess)
|
||||
"Describe package: ")
|
||||
(intern (completing-read (or prompt
|
||||
(if guess
|
||||
(format "Select package to search for (default %s): "
|
||||
guess)
|
||||
"Describe package: "))
|
||||
packages nil t nil nil
|
||||
(if guess (symbol-name guess)))))))
|
||||
|
||||
|
@ -577,7 +586,7 @@ If prefix arg is present, refresh the cache."
|
|||
|
||||
This only searches `doom-emacs-dir' (typically ~/.emacs.d) and does not include
|
||||
config blocks in your private config."
|
||||
(interactive (list (doom--package-list)))
|
||||
(interactive (list (doom--package-list "Find package config: ")))
|
||||
(cl-destructuring-bind (file line _match)
|
||||
(split-string
|
||||
(completing-read
|
||||
|
@ -591,55 +600,49 @@ config blocks in your private config."
|
|||
(recenter)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/help-package-homepage (package)
|
||||
"Open PACKAGE's repo or homepage in your browser."
|
||||
(interactive (list (doom--package-list)))
|
||||
(browse-url (doom--package-url package)))
|
||||
(defalias 'doom/help-package-homepage #'straight-visit-package-website)
|
||||
|
||||
(defun doom--help-search-prompt (prompt)
|
||||
(let ((query (doom-thing-at-point-or-region)))
|
||||
(if (featurep 'counsel)
|
||||
query
|
||||
(read-string prompt query 'git-grep query))))
|
||||
|
||||
(defvar counsel-rg-base-command)
|
||||
(defun doom--help-search (dirs query prompt)
|
||||
;; REVIEW Replace with deadgrep
|
||||
(unless (executable-find "rg")
|
||||
(user-error "Can't find ripgrep on your system"))
|
||||
(if (fboundp 'counsel-rg)
|
||||
(let ((counsel-rg-base-command
|
||||
(concat counsel-rg-base-command " "
|
||||
(mapconcat #'shell-quote-argument dirs " "))))
|
||||
(counsel-rg query nil "-Lz" prompt))
|
||||
;; TODO Add helm support?
|
||||
(grep-find
|
||||
(string-join
|
||||
(append (list "rg" "-L" "--search-zip" "--no-heading" "--color=never"
|
||||
(shell-quote-argument query))
|
||||
(mapcar #'shell-quote-argument dirs))
|
||||
" "))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/help-search-load-path (query)
|
||||
"Perform a text search on your `load-path'.
|
||||
Uses the symbol at point or the current selection, if available."
|
||||
(interactive
|
||||
(let ((query
|
||||
;; TODO Generalize this later; into something the lookup module and
|
||||
;; project search commands could as well
|
||||
(if (use-region-p)
|
||||
(buffer-substring-no-properties (region-beginning) (region-end))
|
||||
(or (symbol-name (symbol-at-point)) ""))))
|
||||
(list (read-string
|
||||
(format "Search load-path (default: %s): " query)
|
||||
nil 'git-grep query))))
|
||||
;; REVIEW Replace with deadgrep
|
||||
(grep-find
|
||||
(mapconcat
|
||||
#'shell-quote-argument
|
||||
(append (list "rg" "-L" "--search-zip" "--no-heading" "--color=never" query)
|
||||
(cl-remove-if-not #'file-directory-p load-path))
|
||||
" ")))
|
||||
(list (doom--help-search-prompt "Search load-path: ")))
|
||||
(doom--help-search (cl-remove-if-not #'file-directory-p load-path)
|
||||
query "Search load-path: "))
|
||||
|
||||
;; TODO factor our the duplicate code between this and the above
|
||||
;;;###autoload
|
||||
(defun doom/help-search-loaded-files (query)
|
||||
"Perform a text search on your `load-path'.
|
||||
Uses the symbol at point or the current selection, if available."
|
||||
(interactive
|
||||
(let ((query
|
||||
;; TODO Generalize this later; into something the lookup module and
|
||||
;; project search commands could as well.
|
||||
(if (use-region-p)
|
||||
(buffer-substring-no-properties (region-beginning) (region-end))
|
||||
(or (symbol-name (symbol-at-point)) ""))))
|
||||
(list (read-string
|
||||
(format "Search load-path (default: %s): " query)
|
||||
nil 'git-grep query))))
|
||||
(unless (executable-find "rg")
|
||||
(user-error "Can't find ripgrep on your system"))
|
||||
(require 'elisp-refs)
|
||||
;; REVIEW Replace with deadgrep
|
||||
(grep-find
|
||||
(mapconcat
|
||||
#'shell-quote-argument
|
||||
(append (list "rg" "-L" "--search-zip" "--no-heading" "--color=never" query)
|
||||
(cl-remove-if-not #'file-directory-p (elisp-refs--loaded-paths)))
|
||||
" ")))
|
||||
(list (doom--help-search-prompt "Search loaded files: ")))
|
||||
(let ((paths (cl-loop for (file . _) in load-history
|
||||
for filebase = (file-name-sans-extension file)
|
||||
if (file-exists-p! (format "%s.el" filebase))
|
||||
collect it)))
|
||||
(doom--help-search paths query "Search loaded files: ")))
|
||||
|
|
|
@ -13,6 +13,13 @@
|
|||
nil-value)
|
||||
plist)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-package-set (package prop value)
|
||||
"Set PROPERTY in PACKAGE's recipe to VALUE."
|
||||
(setf (alist-get package doom-packages)
|
||||
(plist-put (alist-get package doom-packages)
|
||||
prop value)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-package-recipe (package &optional prop nil-value)
|
||||
"Returns the `straight' recipe PACKAGE was registered with."
|
||||
|
@ -23,6 +30,14 @@
|
|||
nil-value)
|
||||
plist)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-package-recipe-repo (package)
|
||||
"Resolve and return PACKAGE's (symbol) local-repo property."
|
||||
(if-let* ((recipe (cdr (straight-recipes-retrieve package)))
|
||||
(repo (straight-vc-local-repo-name recipe)))
|
||||
repo
|
||||
(symbol-name package)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-package-build-recipe (package &optional prop nil-value)
|
||||
"Returns the `straight' recipe PACKAGE was installed with."
|
||||
|
@ -39,7 +54,7 @@
|
|||
(car (gethash (symbol-name package) straight--build-cache)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-package-dependencies (package &optional recursive noerror)
|
||||
(defun doom-package-dependencies (package &optional recursive _noerror)
|
||||
"Return a list of dependencies for a package."
|
||||
(let ((deps (nth 1 (gethash (symbol-name package) straight--build-cache))))
|
||||
(if recursive
|
||||
|
@ -47,6 +62,7 @@
|
|||
deps))
|
||||
deps)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-package-depending-on (package &optional noerror)
|
||||
"Return a list of packages that depend on the package named NAME."
|
||||
(cl-check-type name symbol)
|
||||
|
@ -155,6 +171,7 @@ was installed with."
|
|||
((debug error)
|
||||
(signal 'doom-package-error
|
||||
(list (doom-module-from-path file)
|
||||
file
|
||||
e))))))
|
||||
|
||||
;;;###autoload
|
||||
|
@ -167,8 +184,7 @@ If ALL-P, gather packages unconditionally across all modules, including disabled
|
|||
ones."
|
||||
(let ((doom-interactive-mode t)
|
||||
(doom-modules (doom-modules))
|
||||
doom-packages
|
||||
doom-disabled-packages)
|
||||
doom-packages)
|
||||
(doom--read-module-packages-file
|
||||
(doom-path doom-core-dir "packages.el") all-p t)
|
||||
(let ((private-packages (doom-path doom-private-dir "packages.el")))
|
||||
|
@ -189,6 +205,67 @@ ones."
|
|||
(doom--read-module-packages-file private-packages all-p t))
|
||||
(nreverse doom-packages)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-package-pinned-list ()
|
||||
"Return an alist mapping package names (strings) to pinned commits (strings)."
|
||||
(let (alist)
|
||||
(dolist (package doom-packages alist)
|
||||
(cl-destructuring-bind (name &key disable ignore pin unpin &allow-other-keys)
|
||||
package
|
||||
(when (and (not ignore)
|
||||
(not disable)
|
||||
(or pin unpin))
|
||||
(setf (alist-get (doom-package-recipe-repo name) alist
|
||||
nil 'remove #'equal)
|
||||
(unless unpin pin)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-package-unpinned-list ()
|
||||
"Return an alist mapping package names (strings) to pinned commits (strings)."
|
||||
(let (alist)
|
||||
(dolist (package doom-packages alist)
|
||||
(cl-destructuring-bind
|
||||
(_ &key recipe disable ignore pin unpin &allow-other-keys)
|
||||
package
|
||||
(when (and (not ignore)
|
||||
(not disable)
|
||||
(or unpin
|
||||
(and (plist-member recipe :pin)
|
||||
(null pin))))
|
||||
(cl-pushnew (doom-package-recipe-repo (car package)) alist
|
||||
:test #'equal))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-package-recipe-list ()
|
||||
"Return straight recipes for non-builtin packages with a local-repo."
|
||||
(let (recipes)
|
||||
(dolist (recipe (hash-table-values straight--recipe-cache))
|
||||
(cl-destructuring-bind (&key local-repo type no-build &allow-other-keys)
|
||||
recipe
|
||||
(unless (or (null local-repo)
|
||||
(eq type 'built-in)
|
||||
no-build)
|
||||
(push recipe recipes))))
|
||||
(nreverse recipes)))
|
||||
|
||||
;;;###autoload
|
||||
(defmacro doom-with-package-recipes (recipes binds &rest body)
|
||||
"TODO"
|
||||
(declare (indent 2))
|
||||
(let ((recipe-var (make-symbol "recipe"))
|
||||
(recipes-var (make-symbol "recipes")))
|
||||
`(let* ((,recipes-var ,recipes)
|
||||
(built ())
|
||||
(straight-use-package-pre-build-functions
|
||||
(cons (lambda (pkg) (cl-pushnew pkg built :test #'equal))
|
||||
straight-use-package-pre-build-functions)))
|
||||
(dolist (,recipe-var ,recipes-var)
|
||||
(cl-block nil
|
||||
(straight--with-plist (append (list :recipe ,recipe-var) ,recipe-var)
|
||||
,(doom-enlist binds)
|
||||
,@body)))
|
||||
(nreverse built))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Main functions
|
||||
|
@ -201,3 +278,48 @@ ones."
|
|||
(message "Reloading packages")
|
||||
(doom-initialize-packages t)
|
||||
(message "Reloading packages...DONE"))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/update-pinned-package-form (&optional select)
|
||||
"Inserts or updates a `:pin' for the `package!' statement at point.
|
||||
|
||||
Grabs the latest commit id of the package using 'git'."
|
||||
(interactive "P")
|
||||
;; REVIEW Better error handling
|
||||
;; TODO Insert a new `package!' if no `package!' at poin
|
||||
(require 'straight)
|
||||
(ignore-errors
|
||||
(while (and (atom (sexp-at-point))
|
||||
(not (bolp)))
|
||||
(forward-sexp -1)))
|
||||
(save-excursion
|
||||
(if (not (eq (sexp-at-point) 'package!))
|
||||
(user-error "Not on a `package!' call")
|
||||
(backward-char)
|
||||
(let* ((recipe (cdr (sexp-at-point)))
|
||||
(package (car recipe))
|
||||
(oldid (doom-package-get package :pin))
|
||||
(id
|
||||
(cdr (doom-call-process
|
||||
"git" "ls-remote"
|
||||
(straight-vc-git--destructure
|
||||
(doom-plist-merge
|
||||
(plist-get (cdr recipe) :recipe)
|
||||
(or (cdr (straight-recipes-retrieve package))
|
||||
(plist-get (cdr (assq package doom-packages)) :recipe)))
|
||||
(upstream-repo upstream-host)
|
||||
(straight-vc-git--encode-url upstream-repo upstream-host))))))
|
||||
(unless id
|
||||
(user-error "No id for %S package" package))
|
||||
(let* ((id (if select
|
||||
(car (split-string (completing-read "Commit: " (split-string id "\n" t))))
|
||||
(car (split-string id))))
|
||||
(id (substring id 0 10)))
|
||||
(if (and oldid (string-match-p (concat "^" oldid) id))
|
||||
(user-error "No update necessary")
|
||||
(if (re-search-forward ":pin +\"\\([^\"]+\\)\"" (cdr (bounds-of-thing-at-point 'sexp)) t)
|
||||
(replace-match id t t nil 1)
|
||||
(thing-at-point--end-of-sexp)
|
||||
(backward-char)
|
||||
(insert " :pin " (prin1-to-string id)))
|
||||
(message "Updated %S: %s -> %s" package oldid id)))))))
|
||||
|
|
|
@ -66,7 +66,7 @@ BODY."
|
|||
|
||||
;;;###autoload
|
||||
(defun doom-plist-merge (from-plist to-plist)
|
||||
"Destructively merge FROM-PLIST onto TO-PLIST"
|
||||
"Non-destructively merge FROM-PLIST onto TO-PLIST"
|
||||
(let ((plist (copy-sequence from-plist)))
|
||||
(while plist
|
||||
(plist-put! to-plist (pop plist) (pop plist)))
|
||||
|
@ -83,11 +83,11 @@ BODY."
|
|||
p))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-plist-delete (plist prop)
|
||||
"Delete PROP from a copy of PLIST."
|
||||
(defun doom-plist-delete (plist &rest props)
|
||||
"Delete PROPS from a copy of PLIST."
|
||||
(let (p)
|
||||
(while plist
|
||||
(if (not (eq prop (car plist)))
|
||||
(if (not (memq (car plist) props))
|
||||
(plist-put! p (car plist) (nth 1 plist)))
|
||||
(setq plist (cddr plist)))
|
||||
p))
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
;;; core/autoload/projects.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar projectile-project-root nil)
|
||||
(defvar projectile-enable-caching)
|
||||
(defvar projectile-require-project-root)
|
||||
|
||||
;;;###autoload (autoload 'projectile-relevant-known-projects "projectile")
|
||||
|
||||
|
|
|
@ -96,9 +96,10 @@ following:
|
|||
;;
|
||||
;;; Commands
|
||||
|
||||
(defvar projectile-enable-caching)
|
||||
;;;###autoload
|
||||
(defun doom/open-scratch-buffer (&optional arg project-p)
|
||||
"Opens the (persistent) scratch buffer in a popup.
|
||||
"Pop up a persistent scratch buffer.
|
||||
|
||||
If passed the prefix ARG, switch to it in the current window.
|
||||
If PROJECT-P is non-nil, open a persistent scratch buffer associated with the
|
||||
|
|
|
@ -47,10 +47,16 @@
|
|||
"TODO"
|
||||
(setq file (expand-file-name (or file (doom-session-file))))
|
||||
(message "Attempting to load %s" file)
|
||||
(cond ((require 'persp-mode nil t)
|
||||
(cond ((not (file-readable-p file))
|
||||
(message "No session file at %S to read from" file))
|
||||
((require 'persp-mode nil t)
|
||||
(unless persp-mode
|
||||
(persp-mode +1))
|
||||
(persp-load-state-from-file file))
|
||||
(let ((allowed (persp-list-persp-names-in-file file)))
|
||||
(cl-loop for name being the hash-keys of *persp-hash*
|
||||
unless (member name allowed)
|
||||
do (persp-kill name))
|
||||
(persp-load-state-from-file file)))
|
||||
((and (require 'frameset nil t)
|
||||
(require 'restart-emacs nil t))
|
||||
(restart-emacs--restore-frames-using-desktop file))
|
||||
|
@ -125,4 +131,7 @@
|
|||
(setq doom-autosave-session nil)
|
||||
(doom/quicksave-session)
|
||||
(restart-emacs
|
||||
(delq nil (list (if debug "--debug-init") "--restore"))))
|
||||
(append (if debug (list "--debug-init"))
|
||||
(when (boundp 'chemacs-current-emacs-profile)
|
||||
(list "--with-profile" chemacs-current-emacs-profile))
|
||||
(list "--restore"))))
|
||||
|
|
|
@ -1,5 +1,17 @@
|
|||
;;; core/autoload/text.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar doom-point-in-comment-functions ()
|
||||
"List of functions to run to determine if point is in a comment.
|
||||
|
||||
Each function takes one argument: the position of the point. Stops on the first
|
||||
function to return non-nil. Used by `doom-point-in-comment-p'.")
|
||||
|
||||
(defvar doom-point-in-string-functions ()
|
||||
"List of functions to run to determine if point is in a string.
|
||||
|
||||
Each function takes one argument: the position of the point. Stops on the first
|
||||
function to return non-nil. Used by `doom-point-in-string-p'.")
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-surrounded-p (pair &optional inline balanced)
|
||||
"Returns t if point is surrounded by a brace delimiter: {[(
|
||||
|
@ -28,31 +40,18 @@ lines, above and below, with only whitespace in between."
|
|||
;;;###autoload
|
||||
(defun doom-point-in-comment-p (&optional pos)
|
||||
"Return non-nil if POS is in a comment.
|
||||
|
||||
POS defaults to the current position."
|
||||
;; REVIEW Should we cache `syntax-ppss'?
|
||||
(let* ((pos (or pos (point)))
|
||||
(ppss (syntax-ppss pos)))
|
||||
(or (nth 4 ppss)
|
||||
(nth 8 ppss)
|
||||
(and (< pos (point-max))
|
||||
(memq (char-syntax (char-after pos)) '(?< ?>))
|
||||
(not (eq (char-after pos) ?\n)))
|
||||
(when-let (s (car (syntax-after pos)))
|
||||
(or (and (/= 0 (logand (lsh 1 16) s))
|
||||
(nth 4 (doom-syntax-ppss (+ pos 2))))
|
||||
(and (/= 0 (logand (lsh 1 17) s))
|
||||
(nth 4 (doom-syntax-ppss (+ pos 1))))
|
||||
(and (/= 0 (logand (lsh 1 18) s))
|
||||
(nth 4 (doom-syntax-ppss (- pos 1))))
|
||||
(and (/= 0 (logand (lsh 1 19) s))
|
||||
(nth 4 (doom-syntax-ppss (- pos 2)))))))))
|
||||
(let ((pos (or pos (point))))
|
||||
(or (run-hook-with-args-until-success 'doom-point-in-comment-functions pos)
|
||||
(sp-point-in-comment pos))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-point-in-string-p (&optional pos)
|
||||
"Return non-nil if POS is in a string."
|
||||
;; REVIEW Should we cache `syntax-ppss'?
|
||||
(nth 3 (syntax-ppss pos)))
|
||||
(let ((pos (or pos (point))))
|
||||
(or (run-hook-with-args-until-success 'doom-point-in-string-functions pos)
|
||||
(sp-point-in-string pos))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-point-in-string-or-comment-p (&optional pos)
|
||||
|
@ -60,74 +59,157 @@ POS defaults to the current position."
|
|||
(or (doom-point-in-string-p pos)
|
||||
(doom-point-in-comment-p pos)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-region-active-p ()
|
||||
"Return non-nil if selection is active.
|
||||
Detects evil visual mode as well."
|
||||
(declare (side-effect-free t))
|
||||
(or (use-region-p)
|
||||
(and (bound-and-true-p evil-local-mode)
|
||||
(evil-visual-state-p))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-region-beginning ()
|
||||
"Return beginning position of selection.
|
||||
Uses `evil-visual-beginning' if available."
|
||||
(declare (side-effect-free t))
|
||||
(if (bound-and-true-p evil-local-mode)
|
||||
evil-visual-beginning
|
||||
(region-beginning)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-region-end ()
|
||||
"Return end position of selection.
|
||||
Uses `evil-visual-end' if available."
|
||||
(declare (side-effect-free t))
|
||||
(if (bound-and-true-p evil-local-mode)
|
||||
evil-visual-end
|
||||
(region-end)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-thing-at-point-or-region (&optional thing prompt)
|
||||
"Grab the current selection, THING at point, or xref identifier at point.
|
||||
|
||||
Returns THING if it is a string. Otherwise, if nothing is found at point and
|
||||
PROMPT is non-nil, prompt for a string (if PROMPT is a string it'll be used as
|
||||
the prompting string). Returns nil if all else fails.
|
||||
|
||||
NOTE: Don't use THING for grabbing symbol-at-point. The xref fallback is smarter
|
||||
in some cases."
|
||||
(declare (side-effect-free t))
|
||||
(cond ((stringp thing)
|
||||
thing)
|
||||
((doom-region-active-p)
|
||||
(buffer-substring-no-properties
|
||||
(doom-region-beginning)
|
||||
(doom-region-end)))
|
||||
(thing
|
||||
(thing-at-point thing t))
|
||||
((require 'xref nil t)
|
||||
;; A little smarter than using `symbol-at-point', though in most cases,
|
||||
;; xref ends up using `symbol-at-point' anyway.
|
||||
(xref-backend-identifier-at-point (xref-find-backend)))
|
||||
(prompt
|
||||
(read-string (if (stringp prompt) prompt "")))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Commands
|
||||
|
||||
(defvar doom--last-backward-pt most-positive-fixnum)
|
||||
(defun doom--bol-bot-eot-eol (&optional pos)
|
||||
(save-excursion
|
||||
(when pos
|
||||
(goto-char pos))
|
||||
(let* ((bol (if visual-line-mode
|
||||
(save-excursion
|
||||
(beginning-of-visual-line)
|
||||
(point))
|
||||
(line-beginning-position)))
|
||||
(bot (save-excursion
|
||||
(goto-char bol)
|
||||
(skip-chars-forward " \t\r")
|
||||
(point)))
|
||||
(eol (if visual-line-mode
|
||||
(save-excursion (end-of-visual-line) (point))
|
||||
(line-end-position)))
|
||||
(eot (or (save-excursion
|
||||
(if (not comment-use-syntax)
|
||||
(progn
|
||||
(goto-char bol)
|
||||
(when (re-search-forward comment-start-skip eol t)
|
||||
(or (match-end 1) (match-beginning 0))))
|
||||
(goto-char eol)
|
||||
(while (and (doom-point-in-comment-p)
|
||||
(> (point) bol))
|
||||
(backward-char))
|
||||
(skip-chars-backward " " bol)
|
||||
(unless (or (eq (char-after) 32) (eolp))
|
||||
(forward-char))
|
||||
(point)))
|
||||
eol)))
|
||||
(list bol bot eot eol))))
|
||||
|
||||
(defvar doom--last-backward-pt nil)
|
||||
;;;###autoload
|
||||
(defun doom/backward-to-bol-or-indent ()
|
||||
(defun doom/backward-to-bol-or-indent (&optional point)
|
||||
"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)
|
||||
(let ((pt (point)))
|
||||
(cl-destructuring-bind (bol . bot)
|
||||
(save-excursion
|
||||
(beginning-of-visual-line)
|
||||
(cons (point)
|
||||
(progn (skip-chars-forward " \t\r")
|
||||
(point))))
|
||||
(interactive "d")
|
||||
(let ((pt (or point (point))))
|
||||
(cl-destructuring-bind (bol bot _eot _eol)
|
||||
(doom--bol-bot-eot-eol pt)
|
||||
(cond ((> pt bot)
|
||||
(goto-char bot))
|
||||
((= pt bol)
|
||||
(goto-char (min doom--last-backward-pt bot))
|
||||
(setq doom--last-backward-pt most-positive-fixnum))
|
||||
(or (and doom--last-backward-pt
|
||||
(= (line-number-at-pos doom--last-backward-pt)
|
||||
(line-number-at-pos pt)))
|
||||
(setq doom--last-backward-pt nil))
|
||||
(goto-char (or doom--last-backward-pt bot))
|
||||
(setq doom--last-backward-pt nil))
|
||||
((<= pt bot)
|
||||
(setq doom--last-backward-pt pt)
|
||||
(goto-char bol))))))
|
||||
|
||||
(defvar doom--last-forward-pt -1)
|
||||
(defvar doom--last-forward-pt nil)
|
||||
;;;###autoload
|
||||
(defun doom/forward-to-last-non-comment-or-eol ()
|
||||
(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")
|
||||
(let ((pt (or point (point))))
|
||||
(cl-destructuring-bind (_bol _bot eot eol)
|
||||
(doom--bol-bot-eot-eol pt)
|
||||
(cond ((< pt eot)
|
||||
(goto-char eot))
|
||||
((= pt eol)
|
||||
(goto-char (or doom--last-forward-pt eot))
|
||||
(setq doom--last-forward-pt nil))
|
||||
((>= pt eot)
|
||||
(setq doom--last-backward-pt pt)
|
||||
(goto-char eol))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/backward-kill-to-bol-and-indent ()
|
||||
"Kill line to the first non-blank character. If invoked again afterwards, kill
|
||||
line to beginning of line. Same as `evil-delete-back-to-indentation'."
|
||||
(interactive)
|
||||
(let ((eol (if (not visual-line-mode)
|
||||
(line-end-position)
|
||||
(save-excursion (end-of-visual-line) (point)))))
|
||||
(if (or (and (< (point) eol)
|
||||
(sp-point-in-comment))
|
||||
(not (sp-point-in-comment eol)))
|
||||
(if (= (point) eol)
|
||||
(progn
|
||||
(goto-char doom--last-forward-pt)
|
||||
(setq doom--last-forward-pt -1))
|
||||
(setq doom--last-forward-pt (point))
|
||||
(goto-char eol))
|
||||
(let* ((bol (save-excursion (beginning-of-visual-line) (point)))
|
||||
(boc (or (save-excursion
|
||||
(if (not comment-use-syntax)
|
||||
(progn
|
||||
(goto-char bol)
|
||||
(when (re-search-forward comment-start-skip eol t)
|
||||
(or (match-end 1) (match-beginning 0))))
|
||||
(goto-char eol)
|
||||
(while (and (sp-point-in-comment)
|
||||
(> (point) bol))
|
||||
(backward-char))
|
||||
(skip-chars-backward " " bol)
|
||||
(point)))
|
||||
eol)))
|
||||
(when (> doom--last-forward-pt boc)
|
||||
(setq boc doom--last-forward-pt))
|
||||
(if (or (= eol (point))
|
||||
(> boc (point)))
|
||||
(progn
|
||||
(goto-char boc)
|
||||
(setq doom--last-forward-pt -1))
|
||||
(setq doom--last-forward-pt (point))
|
||||
(goto-char eol))))))
|
||||
(let ((empty-line-p (save-excursion (beginning-of-line)
|
||||
(looking-at-p "[ \t]*$"))))
|
||||
(funcall (if (fboundp 'evil-delete)
|
||||
#'evil-delete
|
||||
#'delete-region)
|
||||
(point-at-bol) (point))
|
||||
(unless empty-line-p
|
||||
(indent-according-to-mode))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/delete-backward-word (arg)
|
||||
"Like `backward-kill-word', but doesn't affect the kill-ring."
|
||||
(interactive "p")
|
||||
(let (kill-ring)
|
||||
(backward-kill-word arg)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/dumb-indent ()
|
||||
|
@ -155,20 +237,6 @@ true end of the line. The opposite of `doom/backward-to-bol-or-indent'."
|
|||
tab-width
|
||||
(- tab-width movement)))))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/backward-kill-to-bol-and-indent ()
|
||||
"Kill line to the first non-blank character. If invoked again
|
||||
afterwards, kill line to beginning of line."
|
||||
(interactive)
|
||||
(let ((empty-line-p (save-excursion (beginning-of-line)
|
||||
(looking-at-p "[ \t]*$"))))
|
||||
(funcall (if (fboundp 'evil-delete)
|
||||
#'evil-delete
|
||||
#'delete-region)
|
||||
(point-at-bol) (point))
|
||||
(unless empty-line-p
|
||||
(indent-according-to-mode))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/retab (arg &optional beg end)
|
||||
"Converts tabs-to-spaces or spaces-to-tabs within BEG and END (defaults to
|
||||
|
|
|
@ -19,12 +19,13 @@ all themes. It will apply to all themes once they are loaded."
|
|||
`(let ((fn (gensym "doom--customize-themes-h-")))
|
||||
(fset
|
||||
fn (lambda ()
|
||||
(dolist (theme (doom-enlist (or ,theme 'user)))
|
||||
(when (or (eq theme 'user)
|
||||
(custom-theme-enabled-p theme))
|
||||
(apply #'custom-theme-set-faces 'user
|
||||
(mapcan #'doom--custom-theme-set-face
|
||||
(list ,@specs)))))))
|
||||
(let (custom--inhibit-theme-enable)
|
||||
(dolist (theme (doom-enlist (or ,theme 'user)))
|
||||
(when (or (eq theme 'user)
|
||||
(custom-theme-enabled-p theme))
|
||||
(apply #'custom-theme-set-faces theme
|
||||
(mapcan #'doom--custom-theme-set-face
|
||||
(list ,@specs))))))))
|
||||
(when (or doom-init-theme-p (null doom-theme))
|
||||
(funcall fn))
|
||||
(add-hook 'doom-load-theme-hook fn 'append)))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
;;; core/autoload/ui.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;
|
||||
;; Public library
|
||||
;;; Public library
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-resize-window (window new-size &optional horizontal force-p)
|
||||
|
@ -24,7 +24,7 @@ are open."
|
|||
|
||||
|
||||
;;
|
||||
;; Advice
|
||||
;;; Advice
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-recenter-a (&rest _)
|
||||
|
@ -43,7 +43,7 @@ In tty Emacs, messages suppressed completely."
|
|||
|
||||
|
||||
;;
|
||||
;; Hooks
|
||||
;;; Hooks
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-apply-ansi-color-to-compilation-buffer-h ()
|
||||
|
@ -57,9 +57,17 @@ In tty Emacs, messages suppressed completely."
|
|||
"Turn off `show-paren-mode' buffer-locally."
|
||||
(setq-local show-paren-mode nil))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-enable-line-numbers-h ()
|
||||
(display-line-numbers-mode +1))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-disable-line-numbers-h ()
|
||||
(display-line-numbers-mode -1))
|
||||
|
||||
|
||||
;;
|
||||
;; Commands
|
||||
;;; Commands
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/toggle-line-numbers ()
|
||||
|
@ -95,6 +103,7 @@ See `display-line-numbers' for what these values mean."
|
|||
(delete-frame))
|
||||
(save-buffers-kill-emacs)))
|
||||
|
||||
(defvar doom--maximize-last-wconf nil)
|
||||
;;;###autoload
|
||||
(defun doom/window-maximize-buffer ()
|
||||
"Close other windows to focus on this one. Activate again to undo this. If the
|
||||
|
@ -102,41 +111,40 @@ window changes before then, the undo expires.
|
|||
|
||||
Alternatively, use `doom/window-enlargen'."
|
||||
(interactive)
|
||||
(if (and (one-window-p)
|
||||
(assq ?_ register-alist))
|
||||
(jump-to-register ?_)
|
||||
(when (and (bound-and-true-p +popup-mode)
|
||||
(+popup-window-p))
|
||||
(user-error "Cannot maximize a popup, use `+popup/raise' first or use `doom/window-enlargen' instead"))
|
||||
(window-configuration-to-register ?_)
|
||||
(delete-other-windows)))
|
||||
(setq doom--maximize-last-wconf
|
||||
(if (and (null (cdr (cl-remove-if #'window-dedicated-p (window-list))))
|
||||
doom--maximize-last-wconf)
|
||||
(ignore (set-window-configuration doom--maximize-last-wconf))
|
||||
(when (and (bound-and-true-p +popup-mode)
|
||||
(+popup-window-p))
|
||||
(user-error "Cannot maximize a popup, use `+popup/raise' first or use `doom/window-enlargen' instead"))
|
||||
(prog1 (current-window-configuration)
|
||||
(delete-other-windows)))))
|
||||
|
||||
(defvar doom--window-enlargened nil)
|
||||
(defvar doom--enlargen-last-wconf nil)
|
||||
;;;###autoload
|
||||
(defun doom/window-enlargen ()
|
||||
"Enlargen the current window to focus on this one. Does not close other
|
||||
windows (unlike `doom/window-maximize-buffer') Activate again to undo."
|
||||
windows (unlike `doom/window-maximize-buffer'). Activate again to undo."
|
||||
(interactive)
|
||||
(setq doom--window-enlargened
|
||||
(if (and doom--window-enlargened
|
||||
(assq ?_ register-alist))
|
||||
(ignore (ignore-errors (jump-to-register ?_)))
|
||||
(window-configuration-to-register ?_)
|
||||
(let* ((window (selected-window))
|
||||
(dedicated-p (window-dedicated-p window))
|
||||
(preserved-p (window-parameter window 'window-preserved-size))
|
||||
(ignore-window-parameters t))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(when dedicated-p
|
||||
(set-window-dedicated-p window nil))
|
||||
(when preserved-p
|
||||
(set-window-parameter window 'window-preserved-size nil))
|
||||
(maximize-window window))
|
||||
(set-window-dedicated-p window dedicated-p)
|
||||
(when preserved-p
|
||||
(set-window-parameter window 'window-preserved-size preserved-p)))
|
||||
t))))
|
||||
(setq doom--enlargen-last-wconf
|
||||
(if doom--enlargen-last-wconf
|
||||
(ignore (set-window-configuration doom--enlargen-last-wconf))
|
||||
(prog1 (current-window-configuration)
|
||||
(let* ((window (selected-window))
|
||||
(dedicated-p (window-dedicated-p window))
|
||||
(preserved-p (window-parameter window 'window-preserved-size))
|
||||
(ignore-window-parameters t))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(when dedicated-p
|
||||
(set-window-dedicated-p window nil))
|
||||
(when preserved-p
|
||||
(set-window-parameter window 'window-preserved-size nil))
|
||||
(maximize-window window))
|
||||
(set-window-dedicated-p window dedicated-p)
|
||||
(when preserved-p
|
||||
(set-window-parameter window 'window-preserved-size preserved-p))))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/window-maximize-horizontally ()
|
||||
|
@ -179,8 +187,7 @@ narrowing doesn't affect other windows displaying the same buffer. Call
|
|||
Inspired from http://demonastery.org/2013/04/emacs-evil-narrow-region/"
|
||||
(interactive
|
||||
(list (or (bound-and-true-p evil-visual-beginning) (region-beginning))
|
||||
(or (bound-and-true-p evil-visual-end) (region-end))
|
||||
current-prefix-arg))
|
||||
(or (bound-and-true-p evil-visual-end) (region-end))))
|
||||
(unless (region-active-p)
|
||||
(setq beg (line-beginning-position)
|
||||
end (line-end-position)))
|
||||
|
|
|
@ -1,418 +1,244 @@
|
|||
;;; core/cli/autoloads.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar doom-autoload-excluded-packages '("gh")
|
||||
"Packages that have silly or destructive autoload files that try to load
|
||||
"What packages whose autoloads file we won't index.
|
||||
|
||||
These packages have silly or destructive autoload files that try to load
|
||||
everyone in the universe and their dog, causing errors that make babies cry. No
|
||||
one wants that.")
|
||||
|
||||
(defvar doom-autoload-cached-vars
|
||||
'(load-path
|
||||
auto-mode-alist
|
||||
interpreter-mode-alist
|
||||
Info-directory-list
|
||||
doom-disabled-packages)
|
||||
"A list of variables to be cached in `doom-package-autoload-file'.")
|
||||
|
||||
;; externs
|
||||
(defvar autoload-timestamps)
|
||||
(defvar generated-autoload-load-name)
|
||||
(defvar generated-autoload-file)
|
||||
|
||||
(defun doom-cli-reload-autoloads ()
|
||||
"Reloads `doom-autoload-file' and `doom-package-autoload-file' files."
|
||||
(doom-cli-reload-core-autoloads)
|
||||
(doom-cli-reload-package-autoloads))
|
||||
|
||||
;;
|
||||
;;; Commands
|
||||
(defun doom-cli-reload-core-autoloads (&optional file)
|
||||
(print! (start "(Re)generating core autoloads..."))
|
||||
(print-group!
|
||||
(let ((file (or file doom-autoload-file))
|
||||
doom-autoload-cached-vars)
|
||||
(cl-check-type file string)
|
||||
(and (print! (start "Generating core autoloads..."))
|
||||
(doom-cli--write-autoloads
|
||||
file (doom-cli--generate-autoloads
|
||||
(cl-loop for dir
|
||||
in (append (list doom-core-dir)
|
||||
(cdr (doom-module-load-path 'all-p))
|
||||
(list doom-private-dir))
|
||||
if (doom-glob dir "autoload.el") collect it
|
||||
if (doom-glob dir "autoload/*.el") append it)
|
||||
'scan))
|
||||
(print! (start "Byte-compiling core autoloads file..."))
|
||||
(doom-cli--byte-compile-file file)
|
||||
(print! (success "Generated %s")
|
||||
(relpath (byte-compile-dest-file file)
|
||||
doom-emacs-dir))))))
|
||||
|
||||
(defcli! (autoloads a) ()
|
||||
"Regenerates Doom's autoloads files.
|
||||
|
||||
It scans and reads autoload cookies (;;;###autoload) in core/autoload/*.el,
|
||||
modules/*/*/autoload.el and modules/*/*/autoload/*.el, and generates and
|
||||
byte-compiles `doom-autoload-file', as well as `doom-package-autoload-file'
|
||||
(created from the concatenated autoloads files of all installed packages).
|
||||
|
||||
It also caches `load-path', `Info-directory-list', `doom-disabled-packages',
|
||||
`package-activated-list' and `auto-mode-alist'."
|
||||
(straight-check-all)
|
||||
(doom-cli-reload-autoloads nil 'force))
|
||||
(defun doom-cli-reload-package-autoloads (&optional file)
|
||||
(print! (start "(Re)generating package autoloads..."))
|
||||
(print-group!
|
||||
(doom-initialize-packages)
|
||||
(let ((file (or file doom-package-autoload-file)))
|
||||
(cl-check-type file string)
|
||||
(and (print! (start "Generating package autoloads..."))
|
||||
(doom-cli--write-autoloads
|
||||
file
|
||||
(doom-cli--generate-var-cache doom-autoload-cached-vars)
|
||||
(doom-cli--generate-autoloads
|
||||
(mapcar #'straight--autoloads-file
|
||||
(cl-set-difference (hash-table-keys straight--build-cache)
|
||||
doom-autoload-excluded-packages
|
||||
:test #'string=))))
|
||||
(print! (start "Byte-compiling package autoloads file..."))
|
||||
(doom-cli--byte-compile-file file)
|
||||
(print! (success "Generated %s")
|
||||
(relpath (byte-compile-dest-file file)
|
||||
doom-emacs-dir))))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Helpers
|
||||
|
||||
(defun doom--cli-delete-autoloads-file (file)
|
||||
"Delete FILE (an autoloads file) and accompanying *.elc file, if any."
|
||||
(cl-check-type file string)
|
||||
(when (file-exists-p file)
|
||||
(when-let (buf (find-buffer-visiting file))
|
||||
(with-current-buffer buf
|
||||
(set-buffer-modified-p nil))
|
||||
(kill-buffer buf))
|
||||
(delete-file file)
|
||||
(ignore-errors (delete-file (byte-compile-dest-file file)))
|
||||
t))
|
||||
(defun doom-cli--write-autoloads (file &rest forms)
|
||||
(make-directory (file-name-directory file) 'parents)
|
||||
(condition-case-unless-debug e
|
||||
(with-temp-file file
|
||||
(let ((standard-output (current-buffer))
|
||||
(print-quoted t)
|
||||
(print-level nil)
|
||||
(print-length nil))
|
||||
(insert ";; -*- lexical-binding: t; -*-\n"
|
||||
";; This file is autogenerated by Doom, DO NOT EDIT IT!!\n")
|
||||
(dolist (form (delq nil forms))
|
||||
(mapc #'print form))
|
||||
t))
|
||||
(error (delete-file file)
|
||||
(signal 'doom-autoload-error (list file e)))))
|
||||
|
||||
(defun doom--cli-warn-refresh-session-h ()
|
||||
(message "Restart or reload Doom Emacs for changes to take effect:\n")
|
||||
(message " M-x doom/restart-and-restore")
|
||||
(message " M-x doom/restart")
|
||||
(message " M-x doom/reload"))
|
||||
|
||||
(defun doom--cli-byte-compile-file (file)
|
||||
(let ((byte-compile-warnings (if doom-debug-mode byte-compile-warnings))
|
||||
(byte-compile-dynamic t)
|
||||
(byte-compile-dynamic-docstrings t))
|
||||
(condition-case-unless-debug e
|
||||
(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)
|
||||
(prog1 (load file 'noerror 'nomessage 'nosuffix)
|
||||
(when noninteractive
|
||||
(add-hook 'doom-cli-post-success-execute-hook #'doom--cli-warn-refresh-session-h))))
|
||||
((debug error)
|
||||
(let ((backup-file (concat file ".bk")))
|
||||
(print! (warn "Copied backup to %s") (relpath backup-file))
|
||||
(copy-file file backup-file 'overwrite))
|
||||
(doom--cli-delete-autoloads-file file)
|
||||
(signal 'doom-autoload-error (list file e))))))
|
||||
(unless doom-interactive-mode
|
||||
(add-hook 'doom-cli-post-success-execute-hook #'doom-cli--warn-refresh-session-h))
|
||||
(load (byte-compile-dest-file file) nil t)))
|
||||
(error
|
||||
(delete-file (byte-compile-dest-file file))
|
||||
(signal 'doom-autoload-error (list file e)))))
|
||||
|
||||
(defun doom-cli-reload-autoloads (&optional file force-p)
|
||||
"Reloads FILE (an autoload file), if it needs reloading.
|
||||
(defun doom-cli--warn-refresh-session-h ()
|
||||
(print! "Restart or reload Doom Emacs for changes to take effect:")
|
||||
(print-group! (print! "M-x doom/restart-and-restore")
|
||||
(print! "M-x doom/restart")
|
||||
(print! "M-x doom/reload")))
|
||||
|
||||
FILE should be one of `doom-autoload-file' or `doom-package-autoload-file'. If
|
||||
it is nil, it will try to reload both. If FORCE-P (universal argument) do it
|
||||
even if it doesn't need reloading!"
|
||||
(or (null file)
|
||||
(stringp file)
|
||||
(signal 'wrong-type-argument (list 'stringp file)))
|
||||
(if (stringp file)
|
||||
(cond ((file-equal-p file doom-autoload-file)
|
||||
(doom-cli-reload-core-autoloads force-p))
|
||||
((file-equal-p file doom-package-autoload-file)
|
||||
(doom-cli-reload-package-autoloads force-p))
|
||||
((error "Invalid autoloads file: %s" file)))
|
||||
(doom-cli-reload-core-autoloads force-p)
|
||||
(doom-cli-reload-package-autoloads force-p)))
|
||||
(defun doom-cli--generate-var-cache (vars)
|
||||
`((setq ,@(cl-loop for var in vars
|
||||
append `(,var ',(symbol-value var))))))
|
||||
|
||||
(defun doom-cli--filter-form (form &optional expand)
|
||||
(let ((func (car-safe form)))
|
||||
(cond ((memq func '(provide custom-autoload))
|
||||
nil)
|
||||
((and (eq func 'add-to-list)
|
||||
(memq (doom-unquote (cadr form))
|
||||
doom-autoload-cached-vars))
|
||||
nil)
|
||||
((not (eq func 'autoload))
|
||||
form)
|
||||
((and expand (not (file-name-absolute-p (nth 2 form))))
|
||||
(defvar doom--autoloads-path-cache nil)
|
||||
(setf (nth 2 form)
|
||||
(let ((path (nth 2 form)))
|
||||
(or (cdr (assoc path doom--autoloads-path-cache))
|
||||
(when-let* ((libpath (locate-library path))
|
||||
(libpath (file-name-sans-extension libpath))
|
||||
(libpath (abbreviate-file-name libpath)))
|
||||
(push (cons path libpath) doom--autoloads-path-cache)
|
||||
libpath)
|
||||
path)))
|
||||
form)
|
||||
(form))))
|
||||
|
||||
;;
|
||||
;;; Doom autoloads
|
||||
|
||||
(defun doom--cli-generate-header (func)
|
||||
(goto-char (point-min))
|
||||
(insert ";; -*- lexical-binding:t; -*-\n"
|
||||
";; This file is autogenerated by `" (symbol-name func) "', DO NOT EDIT !!\n\n"))
|
||||
|
||||
(defun doom--cli-generate-autoloads (targets)
|
||||
(let ((n 0))
|
||||
(dolist (file targets)
|
||||
(insert
|
||||
(with-temp-buffer
|
||||
(cond ((not (doom-file-cookie-p file "if" t))
|
||||
(print! (debug "Ignoring %s") (relpath file)))
|
||||
|
||||
((let ((generated-autoload-load-name (file-name-sans-extension file)))
|
||||
(autoload-generate-file-autoloads file (current-buffer)))
|
||||
(print! (debug "Nothing in %s") (relpath file)))
|
||||
|
||||
((cl-incf n)
|
||||
(print! (debug "Scanning %s...") (relpath file))))
|
||||
(buffer-string))))
|
||||
(print! (class (if (> n 0) 'success 'info)
|
||||
"Scanned %d file(s)")
|
||||
n)))
|
||||
|
||||
(defun doom--cli-expand-autoload-paths (&optional allow-internal-paths)
|
||||
(let ((load-path
|
||||
;; NOTE With `doom-private-dir' in `load-path', Doom autoloads files
|
||||
;; will be unable to declare autoloads for the built-in autoload.el
|
||||
;; Emacs package, should $DOOMDIR/autoload.el exist. Not sure why
|
||||
;; they'd want to though, so it's an acceptable compromise.
|
||||
(append (list doom-private-dir)
|
||||
doom-modules-dirs
|
||||
(straight--directory-files (straight--build-dir) nil t)
|
||||
load-path)))
|
||||
(defvar doom--autoloads-path-cache nil)
|
||||
(while (re-search-forward "^\\s-*(\\(?:custom-\\)?autoload\\s-+'[^ ]+\\s-+\"\\([^\"]*\\)\"" nil t)
|
||||
(let ((path (match-string 1)))
|
||||
(replace-match
|
||||
(or (cdr (assoc path doom--autoloads-path-cache))
|
||||
(when-let* ((libpath (or (and allow-internal-paths
|
||||
(locate-library path nil (cons doom-emacs-dir doom-modules-dirs)))
|
||||
(locate-library path)))
|
||||
(libpath (file-name-sans-extension libpath))
|
||||
(libpath (abbreviate-file-name libpath)))
|
||||
(push (cons path libpath) doom--autoloads-path-cache)
|
||||
libpath)
|
||||
path)
|
||||
t t nil 1)))))
|
||||
|
||||
(defun doom--cli-generate-autodefs-1 (path &optional member-p)
|
||||
(let (forms)
|
||||
(defun doom-cli--generate-autoloads-autodefs (file buffer module &optional module-enabled-p)
|
||||
(with-temp-buffer
|
||||
(insert-file-contents file)
|
||||
(while (re-search-forward "^;;;###autodef *\\([^\n]+\\)?\n" nil t)
|
||||
(let* ((sexp (sexp-at-point))
|
||||
(alt-sexp (match-string 1))
|
||||
(type (car sexp))
|
||||
(name (doom-unquote (cadr sexp)))
|
||||
(origin (doom-module-from-path path)))
|
||||
(cond
|
||||
((and (not member-p)
|
||||
alt-sexp)
|
||||
(push (read alt-sexp) forms))
|
||||
|
||||
((memq type '(defun defmacro cl-defun cl-defmacro))
|
||||
(cl-destructuring-bind (_ _name arglist &rest body) sexp
|
||||
(appendq!
|
||||
forms
|
||||
(list (if member-p
|
||||
(make-autoload sexp path)
|
||||
(let ((docstring
|
||||
(format "THIS FUNCTION DOES NOTHING BECAUSE %s IS DISABLED\n\n%s"
|
||||
origin
|
||||
(if (stringp (car body))
|
||||
(pop body)
|
||||
"No documentation."))))
|
||||
(condition-case-unless-debug e
|
||||
(if alt-sexp
|
||||
(read alt-sexp)
|
||||
(append
|
||||
(list (pcase type
|
||||
(`defun 'defmacro)
|
||||
(`cl-defun `cl-defmacro)
|
||||
(_ type))
|
||||
name arglist docstring)
|
||||
(cl-loop for arg in arglist
|
||||
if (and (symbolp arg)
|
||||
(not (keywordp arg))
|
||||
(not (memq arg cl--lambda-list-keywords)))
|
||||
collect arg into syms
|
||||
else if (listp arg)
|
||||
collect (car arg) into syms
|
||||
finally return (if syms `((ignore ,@syms))))))
|
||||
('error
|
||||
(print! "- Ignoring autodef %s (%s)" name e)
|
||||
nil))))
|
||||
`(put ',name 'doom-module ',origin)))))
|
||||
|
||||
((eq type 'defalias)
|
||||
(cl-destructuring-bind (_type name target &optional docstring) sexp
|
||||
(let ((name (doom-unquote name))
|
||||
(target (doom-unquote target)))
|
||||
(unless member-p
|
||||
(setq target #'ignore
|
||||
docstring
|
||||
(format "THIS FUNCTION DOES NOTHING BECAUSE %s IS DISABLED\n\n%s"
|
||||
origin docstring)))
|
||||
(appendq! forms `((put ',name 'doom-module ',origin)
|
||||
(defalias ',name #',target ,docstring))))))
|
||||
|
||||
(member-p (push sexp forms)))))
|
||||
forms))
|
||||
|
||||
(defun doom--cli-generate-autodefs (targets enabled-targets)
|
||||
(goto-char (point-max))
|
||||
(search-backward ";;;***" nil t)
|
||||
(save-excursion (insert "\n"))
|
||||
(dolist (path targets)
|
||||
(insert
|
||||
(with-temp-buffer
|
||||
(insert-file-contents path)
|
||||
(if-let (forms (doom--cli-generate-autodefs-1 path (member path enabled-targets)))
|
||||
(concat (mapconcat #'prin1-to-string (nreverse forms) "\n")
|
||||
"\n")
|
||||
"")))))
|
||||
|
||||
(defun doom--cli-cleanup-autoloads ()
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward "^;;\\(;[^\n]*\\| no-byte-compile: t\\)\n" nil t)
|
||||
(replace-match "" t t)))
|
||||
|
||||
(defun doom-cli-reload-core-autoloads (&optional force-p)
|
||||
"Refreshes `doom-autoload-file', if necessary (or if FORCE-P is non-nil).
|
||||
|
||||
It scans and reads autoload cookies (;;;###autoload) in core/autoload/*.el,
|
||||
modules/*/*/autoload.el and modules/*/*/autoload/*.el, and generates
|
||||
`doom-autoload-file'.
|
||||
|
||||
Run this whenever your `doom!' block, or a module autoload file, is modified."
|
||||
(require 'autoload)
|
||||
(let* ((default-directory doom-emacs-dir)
|
||||
(doom-modules (doom-modules))
|
||||
(let* ((standard-output buffer)
|
||||
(form (read (current-buffer)))
|
||||
(altform (match-string 1))
|
||||
(definer (car-safe form))
|
||||
(symbol (doom-unquote (cadr form))))
|
||||
(cond ((and (not module-enabled-p) altform)
|
||||
(print (read altform)))
|
||||
((memq definer '(defun defmacro cl-defun cl-defmacro))
|
||||
(if module-enabled-p
|
||||
(print (make-autoload form file))
|
||||
(cl-destructuring-bind (_ _ arglist &rest body) form
|
||||
(print
|
||||
(if altform
|
||||
(read altform)
|
||||
(append
|
||||
(list (pcase definer
|
||||
(`defun 'defmacro)
|
||||
(`cl-defun `cl-defmacro)
|
||||
(_ type))
|
||||
symbol arglist
|
||||
(format "THIS FUNCTION DOES NOTHING BECAUSE %s IS DISABLED\n\n%s"
|
||||
module
|
||||
(if (stringp (car body))
|
||||
(pop body)
|
||||
"No documentation.")))
|
||||
(cl-loop for arg in arglist
|
||||
if (and (symbolp arg)
|
||||
(not (keywordp arg))
|
||||
(not (memq arg cl--lambda-list-keywords)))
|
||||
collect arg into syms
|
||||
else if (listp arg)
|
||||
collect (car arg) into syms
|
||||
finally return (if syms `((ignore ,@syms)))))))))
|
||||
(print `(put ',symbol 'doom-module ',module)))
|
||||
((eq definer 'defalias)
|
||||
(cl-destructuring-bind (_ _ target &optional docstring) form
|
||||
(unless module-enabled-p
|
||||
(setq target #'ignore
|
||||
docstring
|
||||
(format "THIS FUNCTION DOES NOTHING BECAUSE %s IS DISABLED\n\n%s"
|
||||
module docstring)))
|
||||
(print `(put ',symbol 'doom-module ',module))
|
||||
(print `(defalias ',symbol #',(doom-unquote target) ,docstring))))
|
||||
(module-enabled-p (print form)))))))
|
||||
|
||||
(defun doom-cli--generate-autoloads-buffer (file)
|
||||
(let* (;; Prevent `autoload-find-file' from firing file hooks, e.g. adding
|
||||
;; to recentf.
|
||||
find-file-hook
|
||||
write-file-functions
|
||||
;; Prevent a possible source of crashes when there's a syntax error
|
||||
;; in the autoloads file
|
||||
debug-on-error
|
||||
;; The following bindings are in `package-generate-autoloads'.
|
||||
;; Presumably for a good reason, so I just copied them
|
||||
(noninteractive t)
|
||||
(backup-inhibited t)
|
||||
(version-control 'never)
|
||||
(case-fold-search nil) ; reduce magic
|
||||
(autoload-timestamps nil)
|
||||
case-fold-search ; reduce magic
|
||||
autoload-timestamps ; reduce noise in generated files
|
||||
;; Needed for `autoload-generate-file-autoloads'
|
||||
(generated-autoload-load-name (file-name-sans-extension file))
|
||||
(target-buffer (current-buffer))
|
||||
(module (doom-module-from-path file))
|
||||
(module-enabled-p (and (or (memq (car module) '(:core :private))
|
||||
(doom-module-p (car module) (cdr module)))
|
||||
(doom-file-cookie-p file "if" t))))
|
||||
(save-excursion
|
||||
(when module-enabled-p
|
||||
(quiet! (autoload-generate-file-autoloads file target-buffer)))
|
||||
(doom-cli--generate-autoloads-autodefs
|
||||
file target-buffer module module-enabled-p))))
|
||||
|
||||
;; Where we'll store the files we'll scan for autoloads. This should
|
||||
;; contain *all* autoload files, even in disabled modules, so we can
|
||||
;; scan those for autodefs. We start with the core libraries.
|
||||
(targets (doom-glob doom-core-dir "autoload/*.el"))
|
||||
;; A subset of `targets' in enabled modules
|
||||
(active-targets (copy-sequence targets)))
|
||||
|
||||
(dolist (path (doom-module-load-path 'all-p))
|
||||
(when-let* ((files (cons (doom-glob path "autoload.el")
|
||||
(doom-files-in (doom-path path "autoload")
|
||||
:match "\\.el$")))
|
||||
(files (delq nil files)))
|
||||
(appendq! targets files)
|
||||
(when (or (doom-module-from-path path 'enabled-only)
|
||||
(file-equal-p path doom-private-dir))
|
||||
(appendq! active-targets files))))
|
||||
|
||||
(print! (start "Checking core autoloads file"))
|
||||
(print-group!
|
||||
(if (and (not force-p)
|
||||
(file-exists-p doom-autoload-file)
|
||||
(not (file-newer-than-file-p doom-emacs-dir doom-autoload-file))
|
||||
(not (cl-loop for dir
|
||||
in (append (doom-glob doom-private-dir "init.el*")
|
||||
targets)
|
||||
if (file-newer-than-file-p dir doom-autoload-file)
|
||||
return t)))
|
||||
(ignore
|
||||
(print! (success "Skipping core autoloads, they are up-to-date"))
|
||||
(doom-load-autoloads-file doom-autoload-file))
|
||||
(if (doom--cli-delete-autoloads-file doom-autoload-file)
|
||||
(print! (success "Deleted old %s") (filename doom-autoload-file))
|
||||
(make-directory (file-name-directory doom-autoload-file) t))
|
||||
|
||||
(print! (start "Regenerating core autoloads file"))
|
||||
(print-group!
|
||||
(with-temp-file doom-autoload-file
|
||||
(doom--cli-generate-header 'doom-cli-reload-core-autoloads)
|
||||
(save-excursion
|
||||
(doom--cli-generate-autoloads active-targets)
|
||||
(print! (success "Generated new autoloads.el")))
|
||||
;; Replace autoload paths (only for module autoloads) with absolute
|
||||
;; paths for faster resolution during load and simpler `load-path'
|
||||
(save-excursion
|
||||
(doom--cli-expand-autoload-paths 'allow-internal-paths)
|
||||
(print! (success "Expanded module autoload paths")))
|
||||
;; Generates stub definitions for functions/macros defined in disabled
|
||||
;; modules, so that you will never get a void-function when you use
|
||||
;; them.
|
||||
(save-excursion
|
||||
(doom--cli-generate-autodefs targets (reverse active-targets))
|
||||
(print! (success "Generated autodefs")))
|
||||
;; Remove byte-compile-inhibiting file variables so we can byte-compile
|
||||
;; the file, and autoload comments.
|
||||
(doom--cli-cleanup-autoloads)
|
||||
(print! (success "Cleaned up autoloads"))))
|
||||
;; Byte compile it to give the file a chance to reveal errors (and buy us a
|
||||
;; few marginal performance boosts)
|
||||
(print! "> Byte-compiling %s..." (relpath doom-autoload-file))
|
||||
(when (doom--cli-byte-compile-file doom-autoload-file)
|
||||
(print-group!
|
||||
(print! (success "Compiled %s") (relpath doom-autoload-file)))))
|
||||
t)))
|
||||
|
||||
|
||||
;;
|
||||
;;; Package autoloads
|
||||
|
||||
(defun doom--generate-package-autoloads ()
|
||||
"Concatenates package autoload files, let-binds `load-file-name' around
|
||||
them,and remove unnecessary `provide' statements or blank links."
|
||||
(dolist (pkg (hash-table-keys straight--build-cache))
|
||||
(unless (member pkg doom-autoload-excluded-packages)
|
||||
(let ((file (straight--autoloads-file pkg)))
|
||||
(when (file-exists-p file)
|
||||
(insert-file-contents file)
|
||||
(save-excursion
|
||||
(while (re-search-forward "\\(?:\\_<load-file-name\\|#\\$\\)\\_>" nil t)
|
||||
;; `load-file-name' is meaningless in a concatenated
|
||||
;; mega-autoloads file, so we replace references to it and #$ with
|
||||
;; the file they came from.
|
||||
(unless (doom-point-in-string-or-comment-p)
|
||||
(replace-match (prin1-to-string (abbreviate-file-name file))
|
||||
t t))))
|
||||
(while (re-search-forward "^\\(?:;;\\(.*\n\\)\\|\n\\|(provide '[^\n]+\\)" nil t)
|
||||
(unless (doom-point-in-string-p)
|
||||
(replace-match "" t t)))
|
||||
(unless (bolp) (insert "\n")))))))
|
||||
|
||||
(defun doom--generate-var-cache ()
|
||||
"Print a `setq' form for expensive-to-initialize variables, so we can cache
|
||||
them in Doom's autoloads file."
|
||||
(doom-initialize-packages)
|
||||
(prin1 `(setq load-path ',load-path
|
||||
auto-mode-alist ',auto-mode-alist
|
||||
Info-directory-list ',Info-directory-list
|
||||
doom-disabled-packages ',doom-disabled-packages)
|
||||
(current-buffer)))
|
||||
|
||||
(defun doom--cleanup-package-autoloads ()
|
||||
"Remove (some) forms that modify `load-path' or `auto-mode-alist'.
|
||||
|
||||
These variables are cached all at once and at later, so these removed statements
|
||||
served no purpose but to waste cycles."
|
||||
(while (re-search-forward "^\\s-*\\((\\(?:add-to-list\\|\\(?:when\\|if\\) (boundp\\)\\s-+'\\(?:load-path\\|auto-mode-alist\\)\\)" nil t)
|
||||
(goto-char (match-beginning 1))
|
||||
(kill-sexp)))
|
||||
|
||||
(defun doom-cli-reload-package-autoloads (&optional force-p)
|
||||
"Compiles `doom-package-autoload-file' from the autoloads files of all
|
||||
installed packages. It also caches `load-path', `Info-directory-list',
|
||||
`doom-disabled-packages', `package-activated-list' and `auto-mode-alist'.
|
||||
|
||||
Will do nothing if none of your installed packages have been modified. If
|
||||
FORCE-P (universal argument) is non-nil, regenerate it anyway.
|
||||
|
||||
This should be run whenever your `doom!' block or update your packages."
|
||||
(defun doom-cli--generate-autoloads (files &optional scan)
|
||||
(require 'autoload)
|
||||
(print! (start "Checking package autoloads file"))
|
||||
(print-group!
|
||||
(if (and (not force-p)
|
||||
(file-exists-p doom-package-autoload-file)
|
||||
(not (file-newer-than-file-p package-user-dir doom-package-autoload-file))
|
||||
(not (cl-loop for dir in (straight--directory-files (straight--build-dir))
|
||||
if (cl-find-if
|
||||
(lambda (dir)
|
||||
(file-newer-than-file-p dir doom-package-autoload-file))
|
||||
(doom-glob (straight--build-dir dir) "*.el"))
|
||||
return t))
|
||||
(not (cl-loop with doom-modules = (doom-modules)
|
||||
for key being the hash-keys of doom-modules
|
||||
for path = (doom-module-path (car key) (cdr key) "packages.el")
|
||||
if (file-newer-than-file-p path doom-package-autoload-file)
|
||||
return t)))
|
||||
(ignore
|
||||
(print! (success "Skipping package autoloads, they are up-to-date"))
|
||||
(doom-load-autoloads-file doom-package-autoload-file))
|
||||
(let (;; The following bindings are in `package-generate-autoloads'.
|
||||
;; Presumably for a good reason, so I just copied them
|
||||
(noninteractive t)
|
||||
(backup-inhibited t)
|
||||
(version-control 'never)
|
||||
(case-fold-search nil) ; reduce magic
|
||||
(autoload-timestamps nil))
|
||||
|
||||
(if (doom--cli-delete-autoloads-file doom-package-autoload-file)
|
||||
(print! (success "Deleted old %s") (filename doom-package-autoload-file))
|
||||
(make-directory (file-name-directory doom-autoload-file) t))
|
||||
|
||||
(print! (start "Regenerating package autoloads file"))
|
||||
(print-group!
|
||||
(with-temp-file doom-package-autoload-file
|
||||
(doom--cli-generate-header 'doom-cli-reload-package-autoloads)
|
||||
|
||||
(save-excursion
|
||||
;; Cache important and expensive-to-initialize state here.
|
||||
(doom--generate-var-cache)
|
||||
(print! (success "Cached package state"))
|
||||
;; Concatenate the autoloads of all installed packages.
|
||||
(doom--generate-package-autoloads)
|
||||
(print! (success "Package autoloads included")))
|
||||
|
||||
;; Replace autoload paths (only for module autoloads) with absolute
|
||||
;; paths for faster resolution during load and simpler `load-path'
|
||||
(save-excursion
|
||||
(doom--cli-expand-autoload-paths)
|
||||
(print! (success "Expanded module autoload paths")))
|
||||
|
||||
;; Remove `load-path' and `auto-mode-alist' modifications (most of them,
|
||||
;; at least); they are cached later, so all those membership checks are
|
||||
;; unnecessary overhead.
|
||||
(doom--cleanup-package-autoloads)
|
||||
(print! (success "Removed load-path/auto-mode-alist entries"))))
|
||||
;; Byte compile it to give the file a chance to reveal errors (and buy us a
|
||||
;; few marginal performance boosts)
|
||||
(print! (start "Byte-compiling %s...") (relpath doom-package-autoload-file))
|
||||
(when (doom--cli-byte-compile-file doom-package-autoload-file)
|
||||
(print-group!
|
||||
(print! (success "Compiled %s") (relpath doom-package-autoload-file))))))
|
||||
t))
|
||||
(let (autoloads)
|
||||
(dolist (file
|
||||
(cl-remove-if-not #'file-readable-p files)
|
||||
(nreverse (delq nil autoloads)))
|
||||
(with-temp-buffer
|
||||
(print! (debug "- Scanning %s") (relpath file doom-emacs-dir))
|
||||
(if scan
|
||||
(doom-cli--generate-autoloads-buffer file)
|
||||
(insert-file-contents file))
|
||||
(save-excursion
|
||||
(let ((filestr (prin1-to-string file)))
|
||||
(while (re-search-forward "\\_<load-file-name\\_>" nil t)
|
||||
;; `load-file-name' is meaningless in a concatenated
|
||||
;; mega-autoloads file, so we replace references to it with the
|
||||
;; file they came from.
|
||||
(let ((ppss (save-excursion (syntax-ppss))))
|
||||
(or (nth 3 ppss)
|
||||
(nth 4 ppss)
|
||||
(replace-match filestr t t))))))
|
||||
(let ((load-file-name file)
|
||||
(load-path
|
||||
(append (list doom-private-dir)
|
||||
doom-modules-dirs
|
||||
load-path)))
|
||||
(condition-case _
|
||||
(while t
|
||||
(push (doom-cli--filter-form (read (current-buffer))
|
||||
scan)
|
||||
autoloads))
|
||||
(end-of-file)))))))
|
||||
|
|
|
@ -27,6 +27,7 @@ and your private config files, respectively. To recompile your packages, use
|
|||
(let ((filename (file-name-nondirectory path)))
|
||||
(or (string-prefix-p "." filename)
|
||||
(string-prefix-p "test-" filename)
|
||||
(string-suffix-p ".example.el" filename)
|
||||
(not (equal (file-name-extension path) "el"))
|
||||
(member filename (list "packages.el" "doctor.el")))))
|
||||
|
||||
|
@ -92,7 +93,8 @@ If RECOMPILE-P is non-nil, only recompile out-of-date files."
|
|||
;; But first we must be sure that Doom and your private config have been
|
||||
;; fully loaded. Which usually aren't so in an noninteractive session.
|
||||
(let ((doom-interactive-mode 'byte-compile))
|
||||
(doom-initialize 'force)
|
||||
(doom-initialize)
|
||||
(doom-initialize-packages)
|
||||
(doom-initialize-core))
|
||||
|
||||
;;
|
||||
|
@ -122,9 +124,9 @@ If RECOMPILE-P is non-nil, only recompile out-of-date files."
|
|||
(cl-return nil))
|
||||
|
||||
(print!
|
||||
(info (if recompile-p
|
||||
"Recompiling stale elc files..."
|
||||
"Byte-compiling your config (may take a while)...")))
|
||||
(start (if recompile-p
|
||||
"Recompiling stale elc files..."
|
||||
"Byte-compiling your config (may take a while)...")))
|
||||
(print-group!
|
||||
(require 'use-package)
|
||||
(condition-case e
|
||||
|
@ -199,4 +201,5 @@ module. This does not include your byte-compiled, third party packages.'"
|
|||
finally do
|
||||
(print! (if success
|
||||
(success "All elc files deleted")
|
||||
(info "No elc files to clean"))))))
|
||||
(info "No elc files to clean"))))
|
||||
t))
|
||||
|
|
|
@ -136,7 +136,7 @@ in."
|
|||
(`darwin "~/Library/Fonts/"))
|
||||
(require 'all-the-icons nil t))
|
||||
(with-temp-buffer
|
||||
(insert (cdr (doom-call-process "fc-list")))
|
||||
(insert (cdr (doom-call-process "fc-list" "" "file")))
|
||||
(dolist (font all-the-icons-font-names)
|
||||
(if (save-excursion (re-search-backward font nil t))
|
||||
(success! "Found font %s" font)
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
(defcli! env
|
||||
((clear-p ["-c" "--clear"] "Clear and delete your envvar file")
|
||||
(outputfile ["-o" PATH]
|
||||
"Generate the envvar file at PATH. Note that envvar files that aren't in
|
||||
`doom-env-file' won't be loaded automatically at startup. You will need to
|
||||
load them manually from your private config with the `doom-load-envvars-file'
|
||||
"Generate the envvar file at PATH. Envvar files that aren't in
|
||||
`doom-env-file' won't be loaded automatically at startup. You will need to load
|
||||
them manually from your private config with the `doom-load-envvars-file'
|
||||
function."))
|
||||
"Creates or regenerates your envvars file.
|
||||
|
||||
|
@ -19,8 +19,8 @@ This is useful in cases where you cannot guarantee that Emacs (or the daemon)
|
|||
will be launched from the correct environment (e.g. on MacOS or through certain
|
||||
app launchers on Linux).
|
||||
|
||||
This file is automatically regenerated when you run this command or 'doom
|
||||
refresh'. However, 'doom refresh' will only regenerate this file if it exists.
|
||||
This file is automatically regenerated when you run this command or 'doom sync'.
|
||||
However, 'doom sync' will only regenerate this file if it exists.
|
||||
|
||||
Why this over exec-path-from-shell?
|
||||
|
||||
|
@ -36,7 +36,7 @@ Why this over exec-path-from-shell?
|
|||
|
||||
I'd rather it inherit your shell environment /correctly/ (and /completely/)
|
||||
or not at all. It frontloads the debugging process rather than hiding it
|
||||
until it you least want to deal with it."
|
||||
until you least want to deal with it."
|
||||
(let ((env-file (expand-file-name (or outputfile doom-env-file))))
|
||||
(cond (clear-p
|
||||
(unless (file-exists-p env-file)
|
||||
|
@ -57,18 +57,20 @@ Why this over exec-path-from-shell?
|
|||
;; Helpers
|
||||
|
||||
(defvar doom-env-ignored-vars
|
||||
'("^PWD$"
|
||||
"^PS1$"
|
||||
"^R?PROMPT$"
|
||||
"^DBUS_SESSION_BUS_ADDRESS$"
|
||||
'("^DBUS_SESSION_BUS_ADDRESS$"
|
||||
"^GPG_AGENT_INFO$"
|
||||
"^GPG_TTY$"
|
||||
"^HOME$"
|
||||
"^PS1$"
|
||||
"^PWD$"
|
||||
"^R?PROMPT$"
|
||||
"^SSH_AGENT_PID$"
|
||||
"^SSH_AUTH_SOCK$"
|
||||
;; Doom envvars
|
||||
"^INSECURE$"
|
||||
"^DEBUG$"
|
||||
"^YES$"
|
||||
"^TERM$"
|
||||
;; Doom envvars
|
||||
"^DEBUG$"
|
||||
"^INSECURE$"
|
||||
"^YES$"
|
||||
"^__")
|
||||
"Environment variables to not save in `doom-env-file'.
|
||||
|
||||
|
@ -100,7 +102,7 @@ default, on Linux, this is '$SHELL -ic /usr/bin/env'. Variables in
|
|||
(goto-char (point-min))
|
||||
(insert
|
||||
(concat
|
||||
"# -*- mode: dotenv -*-\n"
|
||||
"# -*- 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"
|
||||
|
@ -109,7 +111,7 @@ default, on Linux, this is '$SHELL -ic /usr/bin/env'. Variables in
|
|||
"#\n"
|
||||
(if (file-equal-p env-file doom-env-file)
|
||||
(concat "# It is NOT safe to edit this file. Changes will be overwritten next time you\n"
|
||||
"# run 'doom refresh'. To create a safe-to-edit envvar file use:\n#\n"
|
||||
"# run 'doom sync'. To create a safe-to-edit envvar file use:\n#\n"
|
||||
"# doom env -o ~/.doom.d/myenv\n#\n"
|
||||
"# And load it with (doom-load-envvars-file \"~/.doom.d/myenv\").\n")
|
||||
(concat "# This file is safe to edit by hand, but needs to be loaded manually with:\n#\n"
|
||||
|
@ -120,7 +122,7 @@ default, on Linux, this is '$SHELL -ic /usr/bin/env'. Variables in
|
|||
;; user's interactive shell, therefore we just dump
|
||||
;; `process-environment' to a file.
|
||||
(dolist (env process-environment)
|
||||
(if (cl-find-if (doom-rpartial #'string-match-p env)
|
||||
(if (cl-find-if (doom-rpartial #'string-match-p (car (split-string env "=")))
|
||||
doom-env-ignored-vars)
|
||||
(print! (info "Ignoring %s") env)
|
||||
(insert env "\n")))
|
||||
|
|
|
@ -27,7 +27,9 @@
|
|||
until (memq arg cl--lambda-list-keywords)
|
||||
collect (format "[%s]" (upcase (symbol-name arg)))))
|
||||
" ")
|
||||
"")))
|
||||
""))
|
||||
(when-let (aliases (doom-cli-aliases cli))
|
||||
(print! "Aliases: %s" (string-join aliases ", "))))
|
||||
|
||||
(defun doom--cli-print-desc (cli &optional short)
|
||||
(print! "%s"
|
||||
|
@ -43,7 +45,6 @@
|
|||
(print! (bold "Options:"))
|
||||
(print-group!
|
||||
(cl-loop for opt in optlist
|
||||
for flags = (doom-cli-option-flags opt)
|
||||
for desc = (doom-cli-option-desc opt)
|
||||
for args = (doom-cli-option-args opt)
|
||||
for flagstr = (string-join (doom-cli-option-flags opt) ", ")
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
(noenv-p ["--no-env"] "Don't generate an envvars file (see 'doom help env')")
|
||||
(noinstall-p ["--no-install"] "Don't auto-install packages")
|
||||
(nofonts-p ["--no-fonts"] "Don't install (or prompt to install) all-the-icons fonts")
|
||||
&rest args)
|
||||
&rest _args)
|
||||
"Installs and sets up Doom Emacs for the first time.
|
||||
|
||||
This command does the following:
|
||||
|
@ -46,24 +46,20 @@ DOOMDIR environment variable. e.g.
|
|||
(print! (success "Done!")))))
|
||||
'(("init.el" .
|
||||
(lambda ()
|
||||
(insert-file-contents (doom-path doom-emacs-dir "init.example.el"))))
|
||||
(insert-file-contents
|
||||
(doom-path doom-emacs-dir "init.example.el"))))
|
||||
("config.el" .
|
||||
(lambda ()
|
||||
(insert! ";;; %sconfig.el -*- lexical-binding: t; -*-\n\n"
|
||||
";; Place your private configuration here\n"
|
||||
((relpath doom-private-dir)))))
|
||||
(insert-file-contents
|
||||
(doom-path doom-core-dir "templates/config.example.el"))))
|
||||
("packages.el" .
|
||||
(lambda ()
|
||||
(insert! ";; -*- no-byte-compile: t; -*-\n;;; %spackages.el\n\n"
|
||||
";;; Examples:\n"
|
||||
";; (package! some-package)\n"
|
||||
";; (package! another-package :recipe (:host github :repo \"username/repo\"))\n"
|
||||
";; (package! builtin-package :disable t)\n"
|
||||
((relpath doom-private-dir))))))))
|
||||
(insert-file-contents
|
||||
(doom-path doom-core-dir "templates/packages.example.el")))))))
|
||||
|
||||
;; In case no init.el was present the first time `doom-initialize-modules' was
|
||||
;; called in core.el (e.g. on first install)
|
||||
(doom-initialize 'force)
|
||||
(doom-initialize 'force 'noerror)
|
||||
(doom-initialize-modules)
|
||||
|
||||
;; Ask if user would like an envvar file generated
|
||||
|
@ -72,7 +68,7 @@ DOOMDIR environment variable. e.g.
|
|||
(if (file-exists-p doom-env-file)
|
||||
(print! (info "Envvar file already exists, skipping"))
|
||||
(when (or doom-auto-accept
|
||||
(y-or-n-p "Generate an env file? (see `doom help env` for details)"))
|
||||
(y-or-n-p "Generate an envvar file? (see `doom help env` for details)"))
|
||||
(doom-cli-reload-env-file 'force-p))))
|
||||
|
||||
;; Install Doom packages
|
||||
|
@ -82,16 +78,24 @@ DOOMDIR environment variable. e.g.
|
|||
(doom-cli-packages-install))
|
||||
|
||||
(print! "Regenerating autoloads files")
|
||||
(doom-cli-reload-autoloads nil 'force-p)
|
||||
|
||||
(if nofonts-p
|
||||
(print! (warn "Not installing fonts, as requested"))
|
||||
(when (or doom-auto-accept
|
||||
(y-or-n-p "Download and install all-the-icon's fonts?"))
|
||||
(require 'all-the-icons)
|
||||
(let ((window-system (cond (IS-MAC 'ns)
|
||||
(IS-LINUX 'x))))
|
||||
(all-the-icons-install-fonts 'yes))))
|
||||
(doom-cli-reload-autoloads)
|
||||
|
||||
(cond (nofonts-p)
|
||||
(IS-WINDOWS
|
||||
(print! (warn "Doom cannot install all-the-icons' fonts on Windows!\n"))
|
||||
(print-group!
|
||||
(print!
|
||||
(concat "You'll have to do so manually:\n\n"
|
||||
" 1. Launch Doom Emacs\n"
|
||||
" 2. Execute 'M-x all-the-icons-install-fonts' to download the fonts\n"
|
||||
" 3. Open the download location in windows explorer\n"
|
||||
" 4. Open each font file to install them"))))
|
||||
((or doom-auto-accept
|
||||
(y-or-n-p "Download and install all-the-icon's fonts?"))
|
||||
(require 'all-the-icons)
|
||||
(let ((window-system (cond (IS-MAC 'ns)
|
||||
(IS-LINUX 'x))))
|
||||
(all-the-icons-install-fonts 'yes))))
|
||||
|
||||
(when (file-exists-p "~/.emacs")
|
||||
(print! (warn "A ~/.emacs file was detected. This conflicts with Doom and should be deleted!")))
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/cli/packages.el
|
||||
|
||||
(defcli! (update u) ()
|
||||
(defcli! (update u)
|
||||
((discard-p ["--discard"] "All local changes to packages are discarded"))
|
||||
"Updates packages.
|
||||
|
||||
This works by fetching all installed package repos and checking the distance
|
||||
|
@ -10,10 +11,11 @@ between HEAD and FETCH_HEAD. This can take a while.
|
|||
This excludes packages whose `package!' declaration contains a non-nil :freeze
|
||||
or :ignore property."
|
||||
(straight-check-all)
|
||||
(doom-cli-reload-core-autoloads)
|
||||
(when (doom-cli-packages-update)
|
||||
(doom-cli-reload-package-autoloads 'force-p))
|
||||
t)
|
||||
(let ((doom-auto-discard discard-p))
|
||||
(doom-cli-reload-core-autoloads)
|
||||
(when (doom-cli-packages-update)
|
||||
(doom-cli-reload-package-autoloads))
|
||||
t))
|
||||
|
||||
(defcli! (build b)
|
||||
((rebuild-p ["-r"] "Only rebuild packages that need rebuilding"))
|
||||
|
@ -23,7 +25,7 @@ This ensures that all needed files are symlinked from their package repo and
|
|||
their elisp files are byte-compiled. This is especially necessary if you upgrade
|
||||
Emacs (as byte-code is generally not forward-compatible)."
|
||||
(when (doom-cli-packages-build (not rebuild-p))
|
||||
(doom-cli-reload-package-autoloads 'force-p))
|
||||
(doom-cli-reload-package-autoloads))
|
||||
t)
|
||||
|
||||
(defcli! (purge p)
|
||||
|
@ -46,7 +48,7 @@ list remains lean."
|
|||
(not norepos-p)
|
||||
(not nobuilds-p)
|
||||
regraft-p)
|
||||
(doom-cli-reload-package-autoloads 'force-p))
|
||||
(doom-cli-reload-package-autoloads))
|
||||
t)
|
||||
|
||||
;; (defcli! rollback () ; TODO doom rollback
|
||||
|
@ -57,138 +59,186 @@ list remains lean."
|
|||
;;
|
||||
;;; Library
|
||||
|
||||
(defun doom--same-commit-p (abbrev-ref ref)
|
||||
(and (stringp abbrev-ref)
|
||||
(stringp ref)
|
||||
(string-match-p (concat "^" (regexp-quote abbrev-ref))
|
||||
ref)))
|
||||
|
||||
(defun doom--abbrev-commit (commit &optional full)
|
||||
(if full commit (substring commit 0 7)))
|
||||
|
||||
(defun doom--commit-log-between (start-ref end-ref)
|
||||
(and (straight--call
|
||||
"git" "log" "--oneline" "--no-merges"
|
||||
"-n" "25" end-ref (concat "^" (regexp-quote start-ref)))
|
||||
(straight--process-get-output)))
|
||||
|
||||
(defun doom-cli-packages-install ()
|
||||
"Installs missing packages.
|
||||
|
||||
This function will install any primary package (i.e. a package with a `package!'
|
||||
declaration) or dependency thereof that hasn't already been."
|
||||
(print! (start "Installing & building packages..."))
|
||||
(print-group!
|
||||
(let ((n 0))
|
||||
(dolist (package (hash-table-keys straight--recipe-cache))
|
||||
(straight--with-plist (gethash package straight--recipe-cache)
|
||||
(local-repo)
|
||||
(let ((existed-p (file-directory-p (straight--repos-dir package))))
|
||||
(condition-case-unless-debug e
|
||||
(and (straight-use-package (intern package) nil nil (make-string (1- (or doom-format-indent 1)) 32))
|
||||
(not existed-p)
|
||||
(file-directory-p (straight--repos-dir package))
|
||||
(cl-incf n))
|
||||
(error
|
||||
(signal 'doom-package-error
|
||||
(list e (straight--process-get-output))))))))
|
||||
(if (= n 0)
|
||||
(ignore (print! (success "No packages need to be installed")))
|
||||
(print! (success "Installed & built %d packages") n)
|
||||
t))))
|
||||
(straight--transaction-finalize)
|
||||
(print! (start "Installing packages..."))
|
||||
(let ((pinned (doom-package-pinned-list)))
|
||||
(print-group!
|
||||
(if-let (built
|
||||
(doom-with-package-recipes (doom-package-recipe-list)
|
||||
(recipe package type local-repo)
|
||||
(condition-case-unless-debug e
|
||||
(straight-use-package (intern package))
|
||||
(error
|
||||
(signal 'doom-package-error
|
||||
(list package e (straight--process-get-output)))))))
|
||||
(print! (success "Installed %d packages")
|
||||
(length built))
|
||||
(print! (info "No packages need to be installed"))
|
||||
nil))))
|
||||
|
||||
|
||||
(defun doom-cli-packages-build (&optional force-p)
|
||||
"(Re)build all packages."
|
||||
(straight--transaction-finalize)
|
||||
(print! (start "(Re)building %spackages...") (if force-p "all " ""))
|
||||
(print-group!
|
||||
(let ((n 0))
|
||||
(if force-p
|
||||
(let ((straight--packages-to-rebuild :all)
|
||||
(straight--packages-not-to-rebuild (make-hash-table :test #'equal)))
|
||||
(dolist (package (hash-table-keys straight--recipe-cache))
|
||||
(straight-use-package
|
||||
(intern package) nil (lambda (_) (cl-incf n) nil)
|
||||
(make-string (1- (or doom-format-indent 1)) 32))))
|
||||
(dolist (recipe (hash-table-values straight--recipe-cache))
|
||||
(straight--with-plist recipe (package local-repo no-build)
|
||||
(unless (or no-build (null local-repo))
|
||||
;; REVIEW We do these modification checks manually because
|
||||
;; Straight's checks seem to miss stale elc files. Need
|
||||
;; more tests to confirm this.
|
||||
(when (or (ignore-errors
|
||||
(gethash package straight--packages-to-rebuild))
|
||||
(gethash package straight--cached-package-modifications)
|
||||
(not (file-directory-p (straight--build-dir package)))
|
||||
(cl-loop for file
|
||||
in (doom-files-in (straight--build-dir package)
|
||||
:match "\\.el$"
|
||||
:full t)
|
||||
for elc-file = (byte-compile-dest-file file)
|
||||
if (and (file-exists-p elc-file)
|
||||
(file-newer-than-file-p file elc-file))
|
||||
return t))
|
||||
(let ((straight-use-package-pre-build-functions
|
||||
straight-use-package-pre-build-functions))
|
||||
(add-hook 'straight-use-package-pre-build-functions
|
||||
(lambda (&rest _) (cl-incf n)))
|
||||
(let ((straight--packages-to-rebuild :all)
|
||||
(straight--packages-not-to-rebuild (make-hash-table :test #'equal)))
|
||||
(straight-use-package
|
||||
(intern package) nil nil
|
||||
(make-string (or doom-format-indent 0) 32)))
|
||||
(straight--byte-compile-package recipe)
|
||||
(dolist (dep (straight--get-dependencies package))
|
||||
(when-let (recipe (gethash dep straight--recipe-cache))
|
||||
(straight--byte-compile-package recipe)))))))))
|
||||
(if (= n 0)
|
||||
(ignore (print! (success "No packages need rebuilding")))
|
||||
(doom--finalize-straight)
|
||||
(print! (success "Rebuilt %d package(s)" n))
|
||||
t))))
|
||||
(let ((straight-check-for-modifications
|
||||
(when (file-directory-p (straight--modified-dir))
|
||||
'(find-when-checking)))
|
||||
(straight--allow-find
|
||||
(and straight-check-for-modifications
|
||||
(executable-find straight-find-executable)
|
||||
t))
|
||||
(straight--packages-not-to-rebuild
|
||||
(or straight--packages-not-to-rebuild (make-hash-table :test #'equal)))
|
||||
(straight--packages-to-rebuild
|
||||
(or (if force-p :all straight--packages-to-rebuild)
|
||||
(make-hash-table :test #'equal)))
|
||||
(recipes (doom-package-recipe-list)))
|
||||
(unless force-p
|
||||
(straight--make-build-cache-available))
|
||||
(if-let (built
|
||||
(doom-with-package-recipes recipes (package local-repo)
|
||||
(unless force-p
|
||||
;; Ensure packages with outdated files/bytecode are rebuilt
|
||||
(let ((build-dir (straight--build-dir package))
|
||||
(repo-dir (straight--repos-dir local-repo)))
|
||||
(and (or (file-newer-than-file-p repo-dir build-dir)
|
||||
(file-exists-p (straight--modified-dir (or local-repo package)))
|
||||
;; Doesn't make sense to compare el and elc files
|
||||
;; when the former isn't a symlink to their source.
|
||||
(when straight-use-symlinks
|
||||
(cl-loop for file
|
||||
in (doom-files-in build-dir :match "\\.el$" :full t)
|
||||
for elc-file = (byte-compile-dest-file file)
|
||||
if (and (file-exists-p elc-file)
|
||||
(file-newer-than-file-p file elc-file))
|
||||
return t)))
|
||||
(puthash package t straight--packages-to-rebuild))))
|
||||
(straight-use-package (intern package))))
|
||||
(print! (success "Rebuilt %d package(s)") (length built))
|
||||
(print! (success "No packages need rebuilding"))
|
||||
nil))))
|
||||
|
||||
|
||||
(defun doom-cli-packages-update ()
|
||||
"Updates packages."
|
||||
(straight--transaction-finalize)
|
||||
(print! (start "Updating packages (this may take a while)..."))
|
||||
(let ((straight--packages-to-rebuild (make-hash-table :test #'equal))
|
||||
(total (hash-table-count straight--repo-cache))
|
||||
(i 1)
|
||||
errors)
|
||||
(print-group!
|
||||
(dolist (recipe (hash-table-values straight--repo-cache))
|
||||
(straight--with-plist recipe (package type local-repo)
|
||||
(let* ((repo-dir (straight--repos-dir))
|
||||
(pinned (doom-package-pinned-list))
|
||||
(packages-to-rebuild (make-hash-table :test 'equal))
|
||||
(repos-to-rebuild (make-hash-table :test 'equal))
|
||||
(recipes (doom-package-recipe-list))
|
||||
(total (length recipes))
|
||||
(esc (unless doom-debug-mode "\033[1A"))
|
||||
(i 0)
|
||||
errors)
|
||||
(doom-with-package-recipes recipes (recipe package type local-repo)
|
||||
(cl-incf i)
|
||||
(print-group!
|
||||
(unless (straight--repository-is-available-p recipe)
|
||||
(print! (error "(%d/%d) Couldn't find local repo for %s") i total package)
|
||||
(cl-return))
|
||||
(when (gethash local-repo repos-to-rebuild)
|
||||
(puthash package t packages-to-rebuild)
|
||||
(print! (success "(%d/%d) %s was updated indirectly (with %s)") i total package local-repo)
|
||||
(cl-return))
|
||||
(let ((default-directory (straight--repos-dir local-repo)))
|
||||
(unless (file-in-directory-p default-directory repo-dir)
|
||||
(print! (warn "(%d/%d) Skipping %s because it is local") i total package)
|
||||
(cl-return))
|
||||
(condition-case-unless-debug e
|
||||
(let* ((default-directory (straight--repos-dir local-repo))
|
||||
(commit (straight-vc-get-commit type local-repo)))
|
||||
(if (not (straight-vc-fetch-from-remote recipe))
|
||||
(print! (warn "(%d/%d) Failed to fetch %s" i total package))
|
||||
(let ((output (straight--process-get-output)))
|
||||
(straight-merge-package package)
|
||||
(let ((newcommit (straight-vc-get-commit type local-repo)))
|
||||
(if (string= commit newcommit)
|
||||
(print! (info "(%d/%d) %s is up-to-date") i total package)
|
||||
(let ((ref (straight-vc-get-commit type local-repo))
|
||||
(target-ref (cdr (assoc local-repo pinned)))
|
||||
output)
|
||||
(or (cond
|
||||
((not (stringp target-ref))
|
||||
(print! (start "\033[K(%d/%d) Fetching %s...%s") i total package esc)
|
||||
(when (straight-vc-fetch-from-remote recipe)
|
||||
(setq output (straight--process-get-output))
|
||||
(straight-merge-package package)
|
||||
(setq target-ref (straight-vc-get-commit type local-repo))
|
||||
(or (not (doom--same-commit-p target-ref ref))
|
||||
(cl-return))))
|
||||
|
||||
((doom--same-commit-p target-ref ref)
|
||||
(print! (info "\033[K(%d/%d) %s is up-to-date...%s") i total package esc)
|
||||
(cl-return))
|
||||
|
||||
((straight-vc-commit-present-p recipe target-ref)
|
||||
(print! (start "\033[K(%d/%d) Checking out %s (%s)...%s")
|
||||
i total package (doom--abbrev-commit target-ref) esc)
|
||||
(straight-vc-check-out-commit recipe target-ref)
|
||||
(or (not (eq type 'git))
|
||||
(setq output (doom--commit-log-between ref target-ref)))
|
||||
(doom--same-commit-p target-ref (straight-vc-get-commit type local-repo)))
|
||||
|
||||
((print! (start "\033[K(%d/%d) Re-cloning %s...") i total local-repo esc)
|
||||
(let ((repo (straight--repos-dir local-repo)))
|
||||
(ignore-errors
|
||||
(delete-directory (straight--build-dir package) 'recursive))
|
||||
(puthash package t straight--packages-to-rebuild)
|
||||
(print! (success "(%d/%d) %s updated (%s -> %s)") i total package
|
||||
(substring commit 0 7)
|
||||
(substring newcommit 0 7))
|
||||
(unless (string-empty-p output)
|
||||
(print-group!
|
||||
(print! (info "%s") output)
|
||||
(when (eq type 'git)
|
||||
(straight--call "git" "log" "--oneline" newcommit (concat "^" commit))
|
||||
(print-group!
|
||||
(print! "%s" (straight--process-get-output))))))))))
|
||||
(cl-incf i))
|
||||
(delete-directory repo 'recursive))
|
||||
(print-group!
|
||||
(straight-use-package (intern package) nil 'no-build))
|
||||
(prog1 (file-directory-p repo)
|
||||
(or (not (eq type 'git))
|
||||
(setq output (doom--commit-log-between ref target-ref)))))))
|
||||
(progn
|
||||
(print! (warn "\033[K(%d/%d) Failed to fetch %s")
|
||||
i total local-repo)
|
||||
(unless (string-empty-p output)
|
||||
(print-group! (print! (info "%s" output))))
|
||||
(cl-return)))
|
||||
(puthash local-repo t repos-to-rebuild)
|
||||
(puthash package t packages-to-rebuild)
|
||||
(unless (string-empty-p output)
|
||||
(print! (start "\033[K(%d/%d) Updating %s...") i total local-repo)
|
||||
(print-group! (print! (indent 2 output))))
|
||||
(print! (success "\033[K(%d/%d) %s updated (%s -> %s)")
|
||||
i total local-repo
|
||||
(doom--abbrev-commit ref)
|
||||
(doom--abbrev-commit target-ref)))
|
||||
(user-error
|
||||
(signal 'user-error (error-message-string e)))
|
||||
(error
|
||||
(print! (warn "(%d/%d) Encountered error with %s" i total package))
|
||||
(print! (warn "\033[K(%d/%d) Encountered error with %s" i total package))
|
||||
(print-group!
|
||||
(print! (error "%s" e))
|
||||
(print! (error "%s") e)
|
||||
(print-group! (print! (info "%s" (straight--process-get-output)))))
|
||||
(push package errors)))))
|
||||
(when errors
|
||||
(print! (error "There were %d errors, the offending packages are: %s")
|
||||
(length errors) (string-join errors ", ")))
|
||||
(if (hash-table-empty-p straight--packages-to-rebuild)
|
||||
(ignore
|
||||
(print! (success "All %d packages are up-to-date")
|
||||
(hash-table-count straight--repo-cache)))
|
||||
(let ((count (hash-table-count straight--packages-to-rebuild))
|
||||
(packages (hash-table-keys straight--packages-to-rebuild)))
|
||||
(sort packages #'string-lessp)
|
||||
(doom--finalize-straight)
|
||||
(doom-cli-packages-build)
|
||||
(print! (success "Updated %d package(s)") count))
|
||||
t))))
|
||||
(push package errors))))))
|
||||
(princ "\033[K")
|
||||
(when errors
|
||||
(print! (error "Encountered %d error(s), the offending packages: %s")
|
||||
(length errors) (string-join errors ", ")))
|
||||
(if (hash-table-empty-p packages-to-rebuild)
|
||||
(ignore (print! (success "All %d packages are up-to-date") total))
|
||||
(let ((default-directory (straight--build-dir)))
|
||||
(mapc (doom-rpartial #'delete-directory 'recursive)
|
||||
(hash-table-keys packages-to-rebuild)))
|
||||
(print! (success "Updated %d package(s)")
|
||||
(hash-table-count packages-to-rebuild))
|
||||
(doom-cli-packages-build)
|
||||
t)))
|
||||
|
||||
|
||||
;;; PURGE (for the emperor)
|
||||
|
@ -204,34 +254,44 @@ declaration) or dependency thereof that hasn't already been."
|
|||
(if (not builds)
|
||||
(progn (print! (info "No builds to purge"))
|
||||
0)
|
||||
(length
|
||||
(delq nil (mapcar #'doom--cli-packages-purge-build builds)))))
|
||||
(print! (start "Purging straight builds..." (length builds)))
|
||||
(print-group!
|
||||
(length
|
||||
(delq nil (mapcar #'doom--cli-packages-purge-build builds))))))
|
||||
|
||||
(defun doom--cli-packages-regraft-repo (repo)
|
||||
(cl-defun doom--cli-packages-regraft-repo (repo)
|
||||
(let ((default-directory (straight--repos-dir repo)))
|
||||
(if (not (file-directory-p ".git"))
|
||||
(ignore (print! (warn "repos/%s is not a git repo, skipping" repo)))
|
||||
(let ((before-size (doom-directory-size default-directory)))
|
||||
(straight--call "git" "reset" "--hard")
|
||||
(straight--call "git" "clean" "-ffd")
|
||||
(if (not (car (straight--call "git" "replace" "--graft" "HEAD")))
|
||||
(print! (info "repos/%s is already compact" repo))
|
||||
(straight--call "git" "gc")
|
||||
(print! (success "Regrafted repos/%s (from %0.1fKB to %0.1fKB)")
|
||||
repo before-size (doom-directory-size default-directory))
|
||||
(print-group! (print! "%s" (straight--process-get-output)))))
|
||||
(unless (file-directory-p ".git")
|
||||
(print! (warn "\033[Krepos/%s is not a git repo, skipping" repo))
|
||||
(cl-return))
|
||||
(unless (file-in-directory-p default-directory straight-base-dir)
|
||||
(print! (warn "\033[KSkipping repos/%s because it is local" repo))
|
||||
(cl-return))
|
||||
(let ((before-size (doom-directory-size default-directory)))
|
||||
(straight--call "git" "reset" "--hard")
|
||||
(straight--call "git" "clean" "-ffd")
|
||||
(if (not (car (straight--call "git" "replace" "--graft" "HEAD")))
|
||||
(print! (info "\033[Krepos/%s is already compact\033[1A" repo))
|
||||
(straight--call "git" "reflog" "expire" "--expire=all" "--all")
|
||||
(straight--call "git" "gc" "--prune=now")
|
||||
(print! (success "\033[KRegrafted repos/%s (from %0.1fKB to %0.1fKB)")
|
||||
repo before-size (doom-directory-size default-directory))
|
||||
(print-group! (print! "%s" (straight--process-get-output))))
|
||||
t)))
|
||||
|
||||
(defun doom--cli-packages-regraft-repos (repos)
|
||||
(if (not repos)
|
||||
(progn (print! (info "No repos to regraft"))
|
||||
0)
|
||||
(print! (start "Regrafting %d repos..." (length repos)))
|
||||
(let ((before-size (doom-directory-size (straight--repos-dir))))
|
||||
(prog1 (print-group! (delq nil (mapcar #'doom--cli-packages-regraft-repo repos)))
|
||||
(let ((after-size (doom-directory-size (straight--repos-dir))))
|
||||
(print! (success "Finished regrafting. Size before: %0.1fKB and after: %0.1fKB (%0.1fKB)")
|
||||
before-size after-size
|
||||
(- after-size before-size)))))))
|
||||
(print-group!
|
||||
(prog1 (delq nil (mapcar #'doom--cli-packages-regraft-repo repos))
|
||||
(princ "\033[K")
|
||||
(let ((after-size (doom-directory-size (straight--repos-dir))))
|
||||
(print! (success "Finished regrafting. Size before: %0.1fKB and after: %0.1fKB (%0.1fKB)")
|
||||
before-size after-size
|
||||
(- after-size before-size))))))))
|
||||
|
||||
(defun doom--cli-packages-purge-repo (repo)
|
||||
(let ((repo-dir (straight--repos-dir repo)))
|
||||
|
@ -247,22 +307,29 @@ declaration) or dependency thereof that hasn't already been."
|
|||
(if (not repos)
|
||||
(progn (print! (info "No repos to purge"))
|
||||
0)
|
||||
(length
|
||||
(delq nil (mapcar #'doom--cli-packages-purge-repo repos)))))
|
||||
(print! (start "Purging straight repositories..."))
|
||||
(print-group!
|
||||
(length
|
||||
(delq nil (mapcar #'doom--cli-packages-purge-repo repos))))))
|
||||
|
||||
(defun doom--cli-packages-purge-elpa ()
|
||||
(unless (bound-and-true-p package--initialized)
|
||||
(package-initialize))
|
||||
(let ((packages (cl-loop for (package desc) in package-alist
|
||||
for dir = (package-desc-dir desc)
|
||||
if (file-in-directory-p dir package-user-dir)
|
||||
collect (cons package dir))))
|
||||
(if (not package-alist)
|
||||
(require 'core-packages)
|
||||
(let ((dirs (doom-files-in package-user-dir :type t :depth 0)))
|
||||
(if (not dirs)
|
||||
(progn (print! (info "No ELPA packages to purge"))
|
||||
0)
|
||||
(mapc (doom-rpartial #'delete-directory 'recursive)
|
||||
(mapcar #'cdr packages))
|
||||
(length packages))))
|
||||
(print! (start "Purging ELPA packages..."))
|
||||
(dolist (path dirs (length dirs))
|
||||
(condition-case e
|
||||
(print-group!
|
||||
(if (file-directory-p path)
|
||||
(delete-directory path 'recursive)
|
||||
(delete-file path))
|
||||
(print! (success "Deleted %s") (filename path)))
|
||||
(error
|
||||
(print! (error "Failed to delete %s because: %s")
|
||||
(filename path)
|
||||
e)))))))
|
||||
|
||||
(defun doom-cli-packages-purge (&optional elpa-p builds-p repos-p regraft-repos-p)
|
||||
"Auto-removes orphaned packages and repos.
|
||||
|
@ -273,7 +340,7 @@ a `package!' declaration) or isn't depended on by another primary package.
|
|||
If BUILDS-P, include straight package builds.
|
||||
If REPOS-P, include straight repos.
|
||||
If ELPA-P, include packages installed with package.el (M-x package-install)."
|
||||
(print! (start "Searching for orphaned packages to purge (for the emperor)..."))
|
||||
(print! (start "Purging orphaned packages (for the emperor)..."))
|
||||
(cl-destructuring-bind (&optional builds-to-purge repos-to-purge repos-to-regraft)
|
||||
(let ((rdirs (straight--directory-files (straight--repos-dir) nil nil 'sort))
|
||||
(bdirs (straight--directory-files (straight--build-dir) nil nil 'sort)))
|
||||
|
@ -302,6 +369,4 @@ If ELPA-P, include packages installed with package.el (M-x package-install)."
|
|||
(print! (info "Skipping regrafting"))
|
||||
(and (doom--cli-packages-regraft-repos repos-to-regraft)
|
||||
(setq success t)))
|
||||
(when success
|
||||
(doom--finalize-straight)
|
||||
t)))))
|
||||
success))))
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
(defcli! test (&rest targets)
|
||||
"Run Doom unit tests."
|
||||
:bare t
|
||||
(doom-initialize 'force)
|
||||
(doom-initialize 'force 'noerror)
|
||||
(require 'ansi-color)
|
||||
(let (files error read-files)
|
||||
(let (files read-files)
|
||||
(unless targets
|
||||
(setq targets
|
||||
(cons doom-core-dir
|
||||
|
@ -48,11 +48,11 @@
|
|||
doom-auto-accept t)
|
||||
(require 'core ,(locate-library "core"))
|
||||
(require 'core-cli)
|
||||
(doom-initialize 'force)
|
||||
(doom-initialize 'force 'noerror)
|
||||
(doom-initialize-modules)
|
||||
(doom-cli-reload-core-autoloads 'force)
|
||||
(doom-cli-reload-core-autoloads)
|
||||
(when (doom-cli-packages-install)
|
||||
(doom-cli-reload-package-autoloads 'force)))))
|
||||
(doom-cli-reload-package-autoloads)))))
|
||||
(unless (zerop status)
|
||||
(error "Failed to bootstrap unit tests"))))
|
||||
(with-temp-buffer
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
;;; core/cli/upgrade.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defcli! (upgrade up)
|
||||
((force-p ["-f" "--force"]))
|
||||
((force-p ["-f" "--force"] "Discard local changes to Doom and packages, and upgrade anyway")
|
||||
(packages-only-p ["-p" "--packages"] "Only upgrade packages, not Doom"))
|
||||
"Updates Doom and packages.
|
||||
|
||||
This requires that ~/.emacs.d is a git repo, and is the equivalent of the
|
||||
|
@ -10,15 +11,20 @@ following shell commands:
|
|||
cd ~/.emacs.d
|
||||
git pull --rebase
|
||||
bin/doom clean
|
||||
bin/doom refresh
|
||||
bin/doom sync
|
||||
bin/doom update"
|
||||
:bare t
|
||||
(when (doom-cli-upgrade doom-auto-accept force-p)
|
||||
(require 'core-packages)
|
||||
(doom-initialize)
|
||||
(doom-initialize-packages)
|
||||
(when (doom-cli-packages-update)
|
||||
(doom-cli-reload-package-autoloads 'force))))
|
||||
(let ((doom-auto-discard force-p))
|
||||
(if (delq
|
||||
nil (list
|
||||
(unless packages-only-p
|
||||
(doom-cli-upgrade doom-auto-accept doom-auto-discard))
|
||||
(doom-cli-execute "refresh")
|
||||
(when (doom-cli-packages-update)
|
||||
(doom-cli-reload-package-autoloads)
|
||||
t)))
|
||||
(print! (success "Done! Restart Emacs for changes to take effect."))
|
||||
(print! "Nothing to do. Doom is up-to-date!"))))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -33,7 +39,7 @@ following shell commands:
|
|||
(cl-destructuring-bind (success . stdout)
|
||||
(doom-call-process "git" "status" "--porcelain" "-uno")
|
||||
(if (= 0 success)
|
||||
(string-match-p "[^ \t\n]" (buffer-string))
|
||||
(split-string stdout "\n" t)
|
||||
(error "Failed to check working tree in %s" dir))))
|
||||
|
||||
|
||||
|
@ -52,21 +58,22 @@ following shell commands:
|
|||
"Couldn't detect what branch you're on. Is Doom detached?")))
|
||||
|
||||
;; We assume that a dirty .emacs.d is intentional and abort
|
||||
(when (doom--working-tree-dirty-p default-directory)
|
||||
(when-let (dirty (doom--working-tree-dirty-p default-directory))
|
||||
(if (not force-p)
|
||||
(user-error! "%s\n\n%s"
|
||||
(user-error! "%s\n\n%s\n\n %s"
|
||||
(format "Refusing to upgrade because %S has been modified." (path doom-emacs-dir))
|
||||
"Either stash/undo your changes or run 'doom upgrade -f' to discard local changes.")
|
||||
"Either stash/undo your changes or run 'doom upgrade -f' to discard local changes."
|
||||
(string-join dirty "\n"))
|
||||
(print! (info "You have local modifications in Doom's source. Discarding them..."))
|
||||
(doom-call-process "git" "reset" "--hard" (format "origin/%s" branch))
|
||||
(doom-call-process "git" "clean" "-ffd")))
|
||||
|
||||
(doom-call-process "git" "remote" "remove" doom-repo-remote)
|
||||
(unwind-protect
|
||||
(progn
|
||||
(let (result)
|
||||
(or (zerop (car (doom-call-process "git" "remote" "add" doom-repo-remote doom-repo-url)))
|
||||
(error "Failed to add %s to remotes" doom-repo-remote))
|
||||
(or (zerop (car (doom-call-process "git" "fetch" "--tags" doom-repo-remote branch)))
|
||||
(or (zerop (car (setq result (doom-call-process "git" "fetch" "--tags" doom-repo-remote branch))))
|
||||
(error "Failed to fetch from upstream"))
|
||||
|
||||
(let ((this-rev (vc-git--rev-parse "HEAD"))
|
||||
|
@ -99,13 +106,11 @@ following shell commands:
|
|||
(print! (start "Upgrading Doom Emacs..."))
|
||||
(print-group!
|
||||
(doom-clean-byte-compiled-files)
|
||||
(unless (and (zerop (car (doom-call-process "git" "reset" "--hard" target-remote)))
|
||||
(equal (vc-git--rev-parse "HEAD") new-rev))
|
||||
(if (and (zerop (car (doom-call-process "git" "reset" "--hard" target-remote)))
|
||||
(equal (vc-git--rev-parse "HEAD") new-rev))
|
||||
(print! (info "%s") (cdr result))
|
||||
(error "Failed to check out %s" (substring new-rev 0 10)))
|
||||
(print! (success "Finished upgrading Doom Emacs")))
|
||||
(doom-cli-execute "refresh" (if auto-accept-p '("-y")))
|
||||
t)
|
||||
|
||||
(print! (success "Done! Restart Emacs for changes to take effect."))))))
|
||||
t)))))
|
||||
(ignore-errors
|
||||
(doom-call-process "git" "remote" "remove" doom-repo-remote))))))
|
||||
|
|
184
core/core-cli.el
184
core/core-cli.el
|
@ -1,14 +1,5 @@
|
|||
;;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
|
||||
(require 'seq)
|
||||
|
||||
;; Eagerly load these libraries because we may be in a session that hasn't been
|
||||
;; fully initialized (e.g. where autoloads files haven't been generated or
|
||||
;; `load-path' populated).
|
||||
(mapc (doom-rpartial #'load nil (not doom-debug-mode) 'nosuffix)
|
||||
(file-expand-wildcards (concat doom-core-dir "autoload/*.el")))
|
||||
|
||||
|
||||
;;
|
||||
;;; Variables
|
||||
|
||||
|
@ -17,6 +8,9 @@
|
|||
commands like `doom-cli-packages-install', `doom-cli-packages-update' and
|
||||
`doom-packages-autoremove'.")
|
||||
|
||||
(defvar doom-auto-discard (getenv "FORCE")
|
||||
"If non-nil, discard all local changes while updating.")
|
||||
|
||||
(defvar doom--cli-p nil)
|
||||
(defvar doom--cli-commands (make-hash-table :test 'equal))
|
||||
(defvar doom--cli-groups (make-hash-table :test 'equal))
|
||||
|
@ -187,13 +181,14 @@ BODY will be run when this dispatcher is called."
|
|||
:plist plist
|
||||
:fn
|
||||
(lambda (--alist--)
|
||||
(ignore --alist--)
|
||||
(let ,(cl-loop for opt in speclist
|
||||
for optsym = (if (listp opt) (car opt) opt)
|
||||
unless (memq optsym cl--lambda-list-keywords)
|
||||
collect (list optsym `(cdr (assq ',optsym --alist--))))
|
||||
,@(unless (plist-get plist :bare)
|
||||
'((unless doom-init-p
|
||||
(doom-initialize 'force)
|
||||
(doom-initialize 'force 'noerror)
|
||||
(doom-initialize-modules))))
|
||||
,@body)))
|
||||
doom--cli-commands)
|
||||
|
@ -209,15 +204,127 @@ BODY will be run when this dispatcher is called."
|
|||
,@body))
|
||||
|
||||
|
||||
;;
|
||||
;;; Straight hacks
|
||||
|
||||
(defvar doom--cli-straight-discard-options
|
||||
'("^Delete remote \"[^\"]+\", re-create it with correct "
|
||||
"^Reset branch "
|
||||
"^Abort merge$"
|
||||
"^Discard changes$"))
|
||||
|
||||
;; HACK Remove dired & magit options from prompt, since they're inaccessible in
|
||||
;; noninteractive sessions.
|
||||
(advice-add #'straight-vc-git--popup-raw :override #'straight--popup-raw)
|
||||
|
||||
;; HACK Replace GUI popup prompts (which hang indefinitely in tty Emacs) with
|
||||
;; simple prompts.
|
||||
(defadvice! doom--straight-fallback-to-y-or-n-prompt-a (orig-fn &optional prompt)
|
||||
:around #'straight-are-you-sure
|
||||
(or doom-auto-accept
|
||||
(if noninteractive
|
||||
(y-or-n-p (format! "%s" (or prompt "")))
|
||||
(funcall orig-fn prompt))))
|
||||
|
||||
(defadvice! doom--straight-fallback-to-tty-prompt-a (orig-fn prompt actions)
|
||||
"Modifies straight to prompt on the terminal when in noninteractive sessions."
|
||||
:around #'straight--popup-raw
|
||||
(if (not noninteractive)
|
||||
(funcall orig-fn prompt actions)
|
||||
;; We can't intercept C-g, so no point displaying any options for this key
|
||||
;; when C-c is the proper way to abort batch Emacs.
|
||||
(delq! "C-g" actions 'assoc)
|
||||
;; HACK These are associated with opening dired or magit, which isn't
|
||||
;; possible in tty Emacs, so...
|
||||
(delq! "e" actions 'assoc)
|
||||
(delq! "g" actions 'assoc)
|
||||
(if doom-auto-discard
|
||||
(cl-loop with doom-auto-accept = t
|
||||
for (_key desc func) in actions
|
||||
when desc
|
||||
when (cl-find-if (doom-rpartial #'string-match-p desc)
|
||||
doom--cli-straight-discard-options)
|
||||
return (funcall func))
|
||||
(print! (start "%s") (red prompt))
|
||||
(print-group!
|
||||
(terpri)
|
||||
(let (options)
|
||||
(print-group!
|
||||
(print! " 1) Abort")
|
||||
(cl-loop for (_key desc func) in actions
|
||||
when desc
|
||||
do (push func options)
|
||||
and do
|
||||
(print! "%2s) %s" (1+ (length options))
|
||||
(if (cl-find-if (doom-rpartial #'string-match-p desc)
|
||||
doom--cli-straight-discard-options)
|
||||
(concat desc " (Recommended)")
|
||||
desc))))
|
||||
(terpri)
|
||||
(let* ((options
|
||||
(cons (lambda ()
|
||||
(let ((doom-format-indent 0))
|
||||
(terpri)
|
||||
(print! (warn "Aborted")))
|
||||
(kill-emacs 1))
|
||||
(nreverse options)))
|
||||
(prompt
|
||||
(format! "How to proceed? (%s) "
|
||||
(mapconcat #'number-to-string
|
||||
(number-sequence 1 (length options))
|
||||
", ")))
|
||||
answer fn)
|
||||
(while (null (nth (setq answer (1- (read-number prompt)))
|
||||
options))
|
||||
(print! (warn "%s is not a valid answer, try again.")
|
||||
answer))
|
||||
(funcall (nth answer options))))))))
|
||||
|
||||
(defadvice! doom--straight-respect-print-indent-a (args)
|
||||
"Indent straight progress messages to respect `doom-format-indent', so we
|
||||
don't have to pass whitespace to `straight-use-package's fourth argument
|
||||
everywhere we use it (and internally)."
|
||||
:filter-args #'straight-use-package
|
||||
(cl-destructuring-bind
|
||||
(melpa-style-recipe &optional no-clone no-build cause interactive)
|
||||
args
|
||||
(list melpa-style-recipe no-clone no-build
|
||||
(if (and (not cause)
|
||||
(boundp 'doom-format-indent)
|
||||
(> doom-format-indent 0))
|
||||
(make-string (1- (or doom-format-indent 1)) 32)
|
||||
cause)
|
||||
interactive)))
|
||||
|
||||
|
||||
;;
|
||||
;;; Dependencies
|
||||
|
||||
(require 'seq)
|
||||
|
||||
;; Eagerly load these libraries because we may be in a session that hasn't been
|
||||
;; fully initialized (e.g. where autoloads files haven't been generated or
|
||||
;; `load-path' populated).
|
||||
(load! "autoload/cli")
|
||||
(load! "autoload/debug")
|
||||
(load! "autoload/files")
|
||||
(load! "autoload/format")
|
||||
(load! "autoload/plist")
|
||||
|
||||
|
||||
;;
|
||||
;;; CLI Commands
|
||||
|
||||
(load! "cli/help")
|
||||
(load! "cli/install")
|
||||
|
||||
(defcli! (refresh re)
|
||||
((if-necessary-p ["-n" "--if-necessary"] "Only regenerate autoloads files if necessary"))
|
||||
"Ensure Doom is properly set up.
|
||||
(defcligroup! "Maintenance"
|
||||
"For managing your config and packages"
|
||||
(defcli! (sync s refresh re)
|
||||
((if-necessary-p ["-n" "--if-necessary"] "Only regenerate autoloads files if necessary")
|
||||
(inhibit-envvar-p ["-e"] "Don't regenerate the envvar file")
|
||||
(prune-p ["-p" "--prune"] "Purge orphaned packages & regraft repos"))
|
||||
"Synchronize your config with Doom Emacs.
|
||||
|
||||
This is the equivalent of running autoremove, install, autoloads, then
|
||||
recompile. Run this whenever you:
|
||||
|
@ -230,22 +337,34 @@ recompile. Run this whenever you:
|
|||
It will ensure that unneeded packages are removed, all needed packages are
|
||||
installed, autoloads files are up-to-date and no byte-compiled files have gone
|
||||
stale."
|
||||
(print! (green "Initiating a refresh of Doom Emacs...\n"))
|
||||
(let (success)
|
||||
(when (file-exists-p doom-env-file)
|
||||
(doom-cli-reload-env-file 'force))
|
||||
(doom-cli-reload-core-autoloads (not if-necessary-p))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(and (doom-cli-packages-install)
|
||||
(setq success t))
|
||||
(and (doom-cli-packages-build)
|
||||
(setq success t))
|
||||
(and (doom-cli-packages-purge nil 'builds-p nil)
|
||||
(setq success t)))
|
||||
(doom-cli-reload-package-autoloads (or success (not if-necessary-p)))
|
||||
(doom-cli-byte-compile nil 'recompile))
|
||||
t))
|
||||
:bare t
|
||||
(let (success)
|
||||
;; Ensures that no pre-existing state pollutes the generation of the new
|
||||
;; autoloads files.
|
||||
(dolist (file (list doom-autoload-file doom-package-autoload-file))
|
||||
(delete-file file)
|
||||
(delete-file (byte-compile-dest-file file)))
|
||||
|
||||
(doom-initialize 'force 'noerror)
|
||||
(doom-initialize-modules)
|
||||
|
||||
(print! (start "Synchronizing your config with Doom Emacs..."))
|
||||
(print-group!
|
||||
(when (and (not inhibit-envvar-p)
|
||||
(file-exists-p doom-env-file))
|
||||
(doom-cli-reload-env-file 'force))
|
||||
|
||||
(doom-cli-reload-core-autoloads)
|
||||
(doom-cli-packages-install)
|
||||
(doom-cli-packages-build)
|
||||
(doom-cli-packages-purge prune-p 'builds-p prune-p prune-p)
|
||||
(doom-cli-reload-package-autoloads)
|
||||
t)))
|
||||
|
||||
(load! "cli/env")
|
||||
(load! "cli/upgrade")
|
||||
(load! "cli/packages")
|
||||
(load! "cli/autoloads"))
|
||||
|
||||
(defcligroup! "Diagnostics"
|
||||
"For troubleshooting and diagnostics"
|
||||
|
@ -253,13 +372,6 @@ stale."
|
|||
(load! "cli/debug")
|
||||
(load! "cli/test"))
|
||||
|
||||
(defcligroup! "Maintenance"
|
||||
"For managing your config and packages"
|
||||
(load! "cli/env")
|
||||
(load! "cli/upgrade")
|
||||
(load! "cli/packages")
|
||||
(load! "cli/autoloads"))
|
||||
|
||||
(defcligroup! "Compilation"
|
||||
"For compiling Doom and your config"
|
||||
(load! "cli/byte-compile"))
|
||||
|
|
|
@ -12,11 +12,14 @@ successfully sets indent_style/indent_size.")
|
|||
(defvar-local doom-large-file-p nil)
|
||||
(put 'doom-large-file-p 'permanent-local t)
|
||||
|
||||
(defvar doom-large-file-size 1
|
||||
"The threshold above which Doom enables emergency optimizations.
|
||||
(defvar doom-large-file-size-alist '(("." . 1.0))
|
||||
"An alist mapping regexps (like `auto-mode-alist') to filesize thresholds.
|
||||
|
||||
This threshold is in MB. See `doom--optimize-for-large-files-a' for
|
||||
implementation details.")
|
||||
If a file is opened and discovered to be larger than the threshold, Doom
|
||||
performs emergency optimizations to prevent Emacs from hanging, crashing or
|
||||
becoming unusably slow.
|
||||
|
||||
These thresholds are in MB, and is used by `doom--optimize-for-large-files-a'.")
|
||||
|
||||
(defvar doom-large-file-excluded-modes
|
||||
'(so-long-mode special-mode archive-mode tar-mode jka-compr
|
||||
|
@ -31,7 +34,7 @@ implementation details.")
|
|||
(defadvice! doom--optimize-for-large-files-a (orig-fn &rest args)
|
||||
"Set `doom-large-file-p' if the file is too large.
|
||||
|
||||
Uses `doom-large-file-size' to determine when a file is too large. When
|
||||
Uses `doom-large-file-size-alist' to determine when a file is too large. When
|
||||
`doom-large-file-p' is set, other plugins can detect this and reduce their
|
||||
runtime costs (or disable themselves) to ensure the buffer is as fast as
|
||||
possible."
|
||||
|
@ -39,19 +42,24 @@ possible."
|
|||
(if (setq doom-large-file-p
|
||||
(and buffer-file-name
|
||||
(not doom-large-file-p)
|
||||
(file-readable-p buffer-file-name)
|
||||
(> (nth 7 (file-attributes buffer-file-name))
|
||||
(* 1024 1024 doom-large-file-size))))
|
||||
(file-exists-p buffer-file-name)
|
||||
(ignore-errors
|
||||
(> (nth 7 (file-attributes buffer-file-name))
|
||||
(* 1024 1024
|
||||
(assoc-default buffer-file-name doom-large-file-size-alist
|
||||
#'string-match-p))))))
|
||||
(prog1 (apply orig-fn args)
|
||||
(if (memq major-mode doom-large-file-excluded-modes)
|
||||
(setq doom-large-file-p nil)
|
||||
(so-long-minor-mode +1)
|
||||
(when (fboundp 'so-long-minor-mode) ; in case the user disabled it
|
||||
(so-long-minor-mode +1))
|
||||
(message "Large file detected! Cutting a few corners to improve performance...")))
|
||||
(apply orig-fn args)))
|
||||
|
||||
;; Resolve symlinks when opening files, so that any operations are conducted
|
||||
;; from the file's true directory (like `find-file').
|
||||
(setq find-file-visit-truename t)
|
||||
(setq find-file-visit-truename t
|
||||
vc-follow-symlinks t)
|
||||
|
||||
;; Disable the warning "X and Y are the same file". It's fine to ignore this
|
||||
;; warning as it will redirect you to the existing buffer anyway.
|
||||
|
@ -123,16 +131,14 @@ possible."
|
|||
;;
|
||||
(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))
|
||||
|
||||
;; Save clipboard contents into kill-ring before replacing them
|
||||
(setq save-interprogram-paste-before-kill t)
|
||||
|
||||
;; 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).
|
||||
(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))))
|
||||
(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)))))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -140,6 +146,7 @@ possible."
|
|||
|
||||
(push '("/LICENSE\\'" . text-mode) auto-mode-alist)
|
||||
(push '("\\.log\\'" . text-mode) auto-mode-alist)
|
||||
(push '("\\.env\\'" . sh-mode) auto-mode-alist)
|
||||
|
||||
|
||||
;;
|
||||
|
@ -188,17 +195,14 @@ possible."
|
|||
(not (file-remote-p file)))
|
||||
(file-truename file)
|
||||
file))
|
||||
(setq recentf-filename-handlers '(doom--recent-file-truename abbreviate-file-name))
|
||||
|
||||
(setq recentf-save-file (concat doom-cache-dir "recentf")
|
||||
(setq recentf-filename-handlers
|
||||
'(substring-no-properties
|
||||
doom--recent-file-truename
|
||||
abbreviate-file-name)
|
||||
recentf-save-file (concat doom-cache-dir "recentf")
|
||||
recentf-auto-cleanup 'never
|
||||
recentf-max-menu-items 0
|
||||
recentf-max-saved-items 200
|
||||
recentf-exclude
|
||||
(list "\\.\\(?:gz\\|gif\\|svg\\|png\\|jpe?g\\)$" "^/tmp/" "^/ssh:"
|
||||
"\\.?ido\\.last$" "\\.revive$" "/TAGS$" "^/var/folders/.+$"
|
||||
;; ignore private DOOM temp files
|
||||
(concat "^" (recentf-apply-filename-handlers doom-local-dir))))
|
||||
recentf-max-saved-items 200)
|
||||
|
||||
(add-hook! '(doom-switch-window-hook write-file-functions)
|
||||
(defun doom--recentf-touch-buffer-h ()
|
||||
|
@ -250,6 +254,11 @@ possible."
|
|||
:after-while #'save-place-find-file-hook
|
||||
(if buffer-file-name (ignore-errors (recenter))))
|
||||
|
||||
(defadvice! doom--inhibit-saveplace-in-long-files-a (orig-fn &rest args)
|
||||
:around #'save-place-to-alist
|
||||
(unless doom-large-file-p
|
||||
(apply orig-fn args)))
|
||||
|
||||
(defadvice! doom--dont-prettify-saveplace-cache-a (orig-fn)
|
||||
"`save-place-alist-to-file' uses `pp' to prettify the contents of its cache.
|
||||
`pp' can be expensive for longer lists, and there's no reason to prettify cache
|
||||
|
@ -265,6 +274,7 @@ files, so we replace calls to `pp' with the much faster `prin1'."
|
|||
(use-package! server
|
||||
:when (display-graphic-p)
|
||||
:after-call pre-command-hook after-find-file focus-out-hook
|
||||
:defer 1
|
||||
:init
|
||||
(when-let (name (getenv "EMACS_SERVER_NAME"))
|
||||
(setq server-name name))
|
||||
|
@ -358,6 +368,10 @@ files, so we replace calls to `pp' with the much faster `prin1'."
|
|||
:around #'dtrt-indent-mode
|
||||
(let ((dtrt-indent-run-after-smie dtrt-indent-run-after-smie))
|
||||
(cl-letf* ((old-smie-config-guess (symbol-function 'smie-config-guess))
|
||||
(old-smie-config--guess (symbol-function 'symbol-config--guess))
|
||||
((symbol-function 'symbol-config--guess)
|
||||
(lambda (beg end)
|
||||
(funcall old-smie-config--guess beg (min end 10000))))
|
||||
((symbol-function 'smie-config-guess)
|
||||
(lambda ()
|
||||
(condition-case e (funcall old-smie-config-guess)
|
||||
|
@ -372,12 +386,11 @@ files, so we replace calls to `pp' with the much faster `prin1'."
|
|||
;; a better *help* buffer
|
||||
:commands helpful--read-symbol
|
||||
:init
|
||||
(define-key!
|
||||
[remap describe-function] #'helpful-callable
|
||||
[remap describe-command] #'helpful-command
|
||||
[remap describe-variable] #'helpful-variable
|
||||
[remap describe-key] #'helpful-key
|
||||
[remap describe-symbol] #'doom/describe-symbol)
|
||||
(global-set-key [remap describe-function] #'helpful-callable)
|
||||
(global-set-key [remap describe-command] #'helpful-command)
|
||||
(global-set-key [remap describe-variable] #'helpful-variable)
|
||||
(global-set-key [remap describe-key] #'helpful-key)
|
||||
(global-set-key [remap describe-symbol] #'helpful-symbol)
|
||||
|
||||
(defun doom-use-helpful-a (orig-fn &rest args)
|
||||
"Force ORIG-FN to use helpful instead of the old describe-* commands."
|
||||
|
@ -413,23 +426,25 @@ files, so we replace calls to `pp' with the much faster `prin1'."
|
|||
(require 'smartparens-config)
|
||||
|
||||
;; Overlays are too distracting and not terribly helpful. show-parens does
|
||||
;; this for us already, so...
|
||||
;; this for us already (and is faster), so...
|
||||
(setq sp-highlight-pair-overlay nil
|
||||
sp-highlight-wrap-overlay nil
|
||||
sp-highlight-wrap-tag-overlay nil)
|
||||
;; But if someone does want overlays enabled, evil users will be stricken with
|
||||
;; an off-by-one issue where smartparens assumes you're outside the pair when
|
||||
;; you're really at the last character in insert mode. We must correct this
|
||||
;; vile injustice.
|
||||
(setq sp-show-pair-from-inside t)
|
||||
;; ...and stay highlighted until we've truly escaped the pair!
|
||||
(setq sp-cancel-autoskip-on-backward-movement nil)
|
||||
(with-eval-after-load 'evil
|
||||
;; But if someone does want overlays enabled, evil users will be stricken
|
||||
;; with an off-by-one issue where smartparens assumes you're outside the
|
||||
;; pair when you're really at the last character in insert mode. We must
|
||||
;; correct this vile injustice.
|
||||
(setq sp-show-pair-from-inside t)
|
||||
;; ...and stay highlighted until we've truly escaped the pair!
|
||||
(setq sp-cancel-autoskip-on-backward-movement nil))
|
||||
|
||||
;; The default is 100, because smartparen's scans are relatively expensive
|
||||
;; (especially with large pair lists for somoe modes), we halve it, as a
|
||||
;; (especially with large pair lists for some modes), we reduce it, as a
|
||||
;; better compromise between performance and accuracy.
|
||||
(setq sp-max-prefix-length 50)
|
||||
;; This speeds up smartparens. No pair has any business being longer than 4
|
||||
;; characters; if they must, the modes that need it set it buffer-locally.
|
||||
(setq sp-max-prefix-length 25)
|
||||
;; No pair has any business being longer than 4 characters; if they must, set
|
||||
;; it buffer-locally. It's less work for smartparens.
|
||||
(setq sp-max-pair-length 4)
|
||||
;; This isn't always smart enough to determine when we're in a string or not.
|
||||
;; See https://github.com/Fuco1/smartparens/issues/783.
|
||||
|
@ -437,13 +452,13 @@ files, so we replace calls to `pp' with the much faster `prin1'."
|
|||
|
||||
;; Silence some harmless but annoying echo-area spam
|
||||
(dolist (key '(:unmatched-expression :no-matching-tag))
|
||||
(setf (cdr (assq key sp-message-alist)) nil))
|
||||
(setf (alist-get key sp-message-alist) nil))
|
||||
|
||||
(add-hook! 'minibuffer-setup-hook
|
||||
(defun doom-init-smartparens-in-minibuffer-maybe-h ()
|
||||
"Enable `smartparens-mode' in the minibuffer, during `eval-expression' or
|
||||
`evil-ex'."
|
||||
(when (memq this-command '(eval-expression evil-ex))
|
||||
"Enable `smartparens-mode' in the minibuffer, during `eval-expression',
|
||||
`pp-eval-expression' or `evil-ex'."
|
||||
(when (memq this-command '(eval-expression pp-eval-expression evil-ex))
|
||||
(smartparens-mode))))
|
||||
|
||||
;; You're likely writing lisp in the minibuffer, therefore, disable these
|
||||
|
@ -481,6 +496,10 @@ files, so we replace calls to `pp' with the much faster `prin1'."
|
|||
(delq! 'buffer-read-only so-long-variable-overrides 'assq)
|
||||
;; ...but at least reduce the level of syntax highlighting
|
||||
(add-to-list 'so-long-variable-overrides '(font-lock-maximum-decoration . 1))
|
||||
;; ...and insist that save-place not operate in large/long files
|
||||
(add-to-list 'so-long-variable-overrides '(save-place-alist . nil))
|
||||
;; Text files could possibly be too long too
|
||||
(add-to-list 'so-long-target-modes 'text-mode)
|
||||
;; But disable everything else that may be unnecessary/expensive for large
|
||||
;; or wide buffers.
|
||||
(appendq! so-long-minor-modes
|
||||
|
@ -494,14 +513,26 @@ files, so we replace calls to `pp' with the much faster `prin1'."
|
|||
auto-composition-mode
|
||||
undo-tree-mode
|
||||
highlight-indent-guides-mode
|
||||
hl-fill-column-mode)))
|
||||
hl-fill-column-mode))
|
||||
(defun doom-buffer-has-long-lines-p ()
|
||||
;; HACK Fix #2183: `so-long-detected-long-line-p' tries to parse comment
|
||||
;; syntax, but in some buffers comment state isn't initialized, leading
|
||||
;; to a wrong-type-argument: stringp error.
|
||||
(let ((so-long-skip-leading-comments (bound-and-true-p comment-use-syntax)))
|
||||
;; HACK If visual-line-mode is on in a text-mode, then long lines are
|
||||
;; normal and can be ignored.
|
||||
(unless (and visual-line-mode (derived-mode-p 'text-mode))
|
||||
(so-long-detected-long-line-p))))
|
||||
(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-auto-save-history t
|
||||
(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
|
||||
|
@ -532,16 +563,18 @@ files, so we replace calls to `pp' with the much faster `prin1'."
|
|||
(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
|
||||
:config
|
||||
(appendq! ws-butler-global-exempt-modes
|
||||
'(special-mode comint-mode term-mode eshell-mode))
|
||||
(ws-butler-global-mode))
|
||||
:config (ws-butler-global-mode +1))
|
||||
|
||||
(provide 'core-editor)
|
||||
;;; core-editor.el ends here
|
||||
|
|
120
core/core-lib.el
120
core/core-lib.el
|
@ -93,6 +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))
|
||||
(lambda (&rest pre-args)
|
||||
(apply fn (append pre-args args))))
|
||||
|
||||
|
@ -101,14 +102,18 @@ at the values with which this function was called."
|
|||
;;; Sugars
|
||||
|
||||
(defmacro λ! (&rest body)
|
||||
"Expands to (lambda () (interactive) ,@body)."
|
||||
(declare (doc-string 1))
|
||||
"Expands to (lambda () (interactive) ,@body).
|
||||
A factory for quickly producing interaction commands, particularly for keybinds
|
||||
or aliases."
|
||||
(declare (doc-string 1) (pure t) (side-effect-free t))
|
||||
`(lambda () (interactive) ,@body))
|
||||
(defalias 'lambda! 'λ!)
|
||||
|
||||
(defun λ!! (command &optional arg)
|
||||
"Expands to a command that interactively calls COMMAND with prefix ARG."
|
||||
(declare (doc-string 1))
|
||||
"Expands to a command that interactively calls COMMAND with prefix ARG.
|
||||
A factory for quickly producing interactive, prefixed commands for keybinds or
|
||||
aliases."
|
||||
(declare (doc-string 1) (pure t) (side-effect-free t))
|
||||
(lambda () (interactive)
|
||||
(let ((current-prefix-arg arg))
|
||||
(call-interactively command))))
|
||||
|
@ -128,8 +133,62 @@ at the values with which this function was called."
|
|||
(when-let (path (file!))
|
||||
(directory-file-name (file-name-directory path))))
|
||||
|
||||
(defmacro after! (package &rest body)
|
||||
"Evaluate BODY after PACKAGE have loaded.
|
||||
|
||||
PACKAGE is a symbol or list of them. These are package names, not modes,
|
||||
functions or variables. It can be:
|
||||
|
||||
- An unquoted package symbol (the name of a package)
|
||||
(after! helm BODY...)
|
||||
- An unquoted list of package symbols (i.e. BODY is evaluated once both magit
|
||||
and git-gutter have loaded)
|
||||
(after! (magit git-gutter) BODY...)
|
||||
- An unquoted, nested list of compound package lists, using any combination of
|
||||
:or/:any and :and/:all
|
||||
(after! (:or package-a package-b ...) BODY...)
|
||||
(after! (:and package-a package-b ...) BODY...)
|
||||
(after! (:and package-a (:or package-b package-c) ...) BODY...)
|
||||
Without :or/:any/:and/:all, :and/:all are implied.
|
||||
|
||||
This is a wrapper around `eval-after-load' that:
|
||||
|
||||
1. Suppresses warnings for disabled packages at compile-time
|
||||
2. No-ops for package that are disabled by the user (via `package!')
|
||||
3. Supports compound package statements (see below)
|
||||
4. Prevents eager expansion pulling in autoloaded macros all at once"
|
||||
(declare (indent defun) (debug t))
|
||||
(if (symbolp package)
|
||||
(unless (memq package (bound-and-true-p doom-disabled-packages))
|
||||
(list (if (or (not (bound-and-true-p byte-compile-current-file))
|
||||
(require package nil 'noerror))
|
||||
#'progn
|
||||
#'with-no-warnings)
|
||||
(let ((body (macroexp-progn body)))
|
||||
`(if (featurep ',package)
|
||||
,body
|
||||
;; We intentionally avoid `with-eval-after-load' to prevent
|
||||
;; eager macro expansion from pulling (or failing to pull) in
|
||||
;; autoloaded macros/packages.
|
||||
(eval-after-load ',package ',body)))))
|
||||
(let ((p (car package)))
|
||||
(cond ((not (keywordp p))
|
||||
`(after! (:and ,@package) ,@body))
|
||||
((memq p '(:or :any))
|
||||
(macroexp-progn
|
||||
(cl-loop for next in (cdr package)
|
||||
collect `(after! ,next ,@body))))
|
||||
((memq p '(:and :all))
|
||||
(dolist (next (cdr package))
|
||||
(setq body `((after! ,next ,@body))))
|
||||
(car body))))))
|
||||
|
||||
(defmacro setq! (&rest settings)
|
||||
"A stripped-down `customize-set-variable' with the syntax of `setq'."
|
||||
"A stripped-down `customize-set-variable' with the syntax of `setq'.
|
||||
|
||||
Use this instead of `setq' when you know a variable has a custom setter (a :set
|
||||
property in its `defcustom' declaration). This trigger setters. `setq' does
|
||||
not."
|
||||
(macroexp-progn
|
||||
(cl-loop for (var val) on settings by 'cddr
|
||||
collect `(funcall (or (get ',var 'custom-set) #'set)
|
||||
|
@ -150,10 +209,6 @@ This is a variadic `cl-pushnew'."
|
|||
"Append LISTS to SYM in place."
|
||||
`(setq ,sym (append ,sym ,@lists)))
|
||||
|
||||
(defmacro nconcq! (sym &rest lists)
|
||||
"Append LISTS to SYM by altering them in place."
|
||||
`(setq ,sym (nconc ,sym ,@lists)))
|
||||
|
||||
(defmacro delq! (elt list &optional fetcher)
|
||||
"`delq' ELT from LIST in-place.
|
||||
|
||||
|
@ -164,6 +219,15 @@ If FETCHER is a function, ELT is used as the key in LIST (an alist)."
|
|||
elt)
|
||||
,list)))
|
||||
|
||||
(defmacro letenv! (envvars &rest body)
|
||||
"Lexically bind ENVVARS in BODY, like `let' but for `process-environment'."
|
||||
(declare (indent 1))
|
||||
`(let ((process-environment (copy-sequence process-environment)))
|
||||
(dolist (var (list ,@(cl-loop for (var val) in envvars
|
||||
collect `(cons ,var ,val))))
|
||||
(setenv (car var) (cdr var)))
|
||||
,@body))
|
||||
|
||||
(defmacro add-load-path! (&rest dirs)
|
||||
"Add DIRS to `load-path', relative to the current file.
|
||||
The current file is the file from which `add-to-load-path!' is used."
|
||||
|
@ -203,13 +267,14 @@ If N and M = 1, there's no benefit to using this macro over `add-hook'.
|
|||
|
||||
This macro accepts, in order:
|
||||
|
||||
1. Optional properties :local and/or :append, which will make the hook
|
||||
1. The mode(s) or hook(s) to add to. This is either an unquoted mode, an
|
||||
unquoted list of modes, a quoted hook variable or a quoted list of hook
|
||||
variables.
|
||||
2. Optional properties :local and/or :append, which will make the hook
|
||||
buffer-local or append to the list of hooks (respectively),
|
||||
2. The hook(s) to be added to: either an unquoted mode, an unquoted list of
|
||||
modes, a quoted hook variable or a quoted list of hook variables. If
|
||||
unquoted, '-hook' will be appended to each symbol.
|
||||
3. The function(s) to be added: this can be one function, a list thereof, a
|
||||
list of `defun's, or body forms (implicitly wrapped in a closure).
|
||||
3. The function(s) to be added: this can be one function, a quoted list
|
||||
thereof, a list of `defun's, or body forms (implicitly wrapped in a
|
||||
lambda).
|
||||
|
||||
\(fn HOOKS [:append :local] FUNCTIONS)"
|
||||
(declare (indent (lambda (indent-point state)
|
||||
|
@ -408,10 +473,27 @@ DOCSTRING and BODY are as in `defun'.
|
|||
where-alist))
|
||||
`(progn
|
||||
(defun ,symbol ,arglist ,docstring ,@body)
|
||||
,(when where-alist
|
||||
`(dolist (targets (list ,@(nreverse where-alist)))
|
||||
(dolist (target (cdr targets))
|
||||
(advice-add target (car targets) #',symbol)))))))
|
||||
(dolist (targets (list ,@(nreverse where-alist)))
|
||||
(dolist (target (cdr targets))
|
||||
(advice-add target (car targets) #',symbol))))))
|
||||
|
||||
(defmacro undefadvice! (symbol _arglist &optional docstring &rest body)
|
||||
"Undefine an advice called SYMBOL.
|
||||
|
||||
This has the same signature as `defadvice!' an exists as an easy undefiner when
|
||||
testing advice (when combined with `rotate-text').
|
||||
|
||||
\(fn SYMBOL ARGLIST &optional DOCSTRING &rest [WHERE PLACES...] BODY\)"
|
||||
(declare (doc-string 3) (indent defun))
|
||||
(let (where-alist)
|
||||
(unless (stringp docstring)
|
||||
(push docstring body))
|
||||
(while (keywordp (car body))
|
||||
(push `(cons ,(pop body) (doom-enlist ,(pop body)))
|
||||
where-alist))
|
||||
`(dolist (targets (list ,@(nreverse where-alist)))
|
||||
(dolist (target (cdr targets))
|
||||
(advice-remove target #',symbol)))))
|
||||
|
||||
(provide 'core-lib)
|
||||
;;; core-lib.el ends here
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
|
||||
(defconst doom-obsolete-modules
|
||||
'((:feature (version-control (:emacs vc) (:ui vc-gutter))
|
||||
(spellcheck (:tools flyspell))
|
||||
(syntax-checker (:tools flycheck))
|
||||
(spellcheck (:checkers spell))
|
||||
(syntax-checker (:checkers syntax))
|
||||
(evil (:editor evil))
|
||||
(snippets (:editor snippets))
|
||||
(file-templates (:editor file-templates))
|
||||
|
@ -24,7 +24,9 @@
|
|||
(debugger (:tools debugger)))
|
||||
(:tools (rotate-text (:editor rotate-text))
|
||||
(vterm (:term vterm))
|
||||
(password-store (:tools pass)))
|
||||
(password-store (:tools pass))
|
||||
(flycheck (:checkers syntax))
|
||||
(flyspell (:checkers spell)))
|
||||
(:emacs (electric-indent (:emacs electric))
|
||||
(hideshow (:editor fold))
|
||||
(eshell (:term eshell))
|
||||
|
@ -40,7 +42,7 @@
|
|||
Each entry is a three-level tree. For example:
|
||||
|
||||
(:feature (version-control (:emacs vc) (:ui vc-gutter))
|
||||
(spellcheck (:tools flyspell))
|
||||
(spellcheck (:checkers spell))
|
||||
(syntax-checker (:tools flycheck)))
|
||||
|
||||
This marks :feature version-control, :feature spellcheck and :feature
|
||||
|
@ -76,6 +78,7 @@ non-nil."
|
|||
(when (or force-p (not doom-init-modules-p))
|
||||
(setq doom-init-modules-p t
|
||||
doom-modules nil)
|
||||
(load custom-file 'noerror 'nomessage)
|
||||
(when (load! "init" doom-private-dir t)
|
||||
(when doom-modules
|
||||
(maphash (lambda (key plist)
|
||||
|
@ -101,11 +104,10 @@ non-nil."
|
|||
(defun doom-module-p (category module &optional flag)
|
||||
"Returns t if CATEGORY MODULE is enabled (ie. present in `doom-modules')."
|
||||
(declare (pure t) (side-effect-free t))
|
||||
(let ((plist (gethash (cons category module) doom-modules)))
|
||||
(and plist
|
||||
(or (null flag)
|
||||
(memq flag (plist-get plist :flags)))
|
||||
t)))
|
||||
(when-let (plist (gethash (cons category module) doom-modules))
|
||||
(or (null flag)
|
||||
(and (memq flag (plist-get plist :flags))
|
||||
t))))
|
||||
|
||||
(defun doom-module-get (category module &optional property)
|
||||
"Returns the plist for CATEGORY MODULE. Gets PROPERTY, specifically, if set."
|
||||
|
@ -186,7 +188,8 @@ If ENABLED-ONLY, return nil if the containing module isn't enabled."
|
|||
(cdr doom--current-module))
|
||||
doom--current-module)
|
||||
doom--current-module)
|
||||
(doom-module-from-path (file!)))
|
||||
(ignore-errors
|
||||
(doom-module-from-path (file!))))
|
||||
(let* ((file-name-handler-alist nil)
|
||||
(path (file-truename (or path (file!)))))
|
||||
(save-match-data
|
||||
|
@ -332,14 +335,15 @@ This value is cached. If REFRESH-P, then don't use the cached value."
|
|||
(defmacro doom! (&rest modules)
|
||||
"Bootstraps DOOM Emacs and its modules.
|
||||
|
||||
If the first item in MODULES doesn't satisfy `keywordp', MODULES is evaluated,
|
||||
otherwise, MODULES is a multiple-property list (a plist where each key can have
|
||||
multiple, linear values).
|
||||
|
||||
The bootstrap process involves making sure the essential directories exist, core
|
||||
packages are installed, `doom-autoload-file' is loaded, `doom-packages-file'
|
||||
cache exists (and is loaded) and, finally, loads your private init.el (which
|
||||
should contain your `doom!' block).
|
||||
|
||||
If the cache exists, much of this function isn't run, which substantially
|
||||
reduces startup time.
|
||||
|
||||
The overall load order of Doom is as follows:
|
||||
|
||||
~/.emacs.d/init.el
|
||||
|
@ -358,9 +362,10 @@ The overall load order of Doom is as follows:
|
|||
Module load order is determined by your `doom!' block. See `doom-modules-dirs'
|
||||
for a list of all recognized module trees. Order defines precedence (from most
|
||||
to least)."
|
||||
`(let ((modules ',modules))
|
||||
(unless (keywordp (car modules))
|
||||
(setq modules (eval modules t)))
|
||||
`(let ((modules
|
||||
,@(if (keywordp (car modules))
|
||||
(list (list 'quote modules))
|
||||
modules)))
|
||||
(unless doom-modules
|
||||
(setq doom-modules
|
||||
(make-hash-table :test 'equal
|
||||
|
@ -524,7 +529,7 @@ Module FLAGs are set in your config's `doom!' block, typically in
|
|||
:config (default +flag1 -flag2)
|
||||
|
||||
CATEGORY and MODULE can be omitted When this macro is used from inside a module
|
||||
(except your DOOMDIR, which is a special moduel). e.g. (featurep! +flag)"
|
||||
(except your DOOMDIR, which is a special module). e.g. (featurep! +flag)"
|
||||
(and (cond (flag (memq flag (doom-module-get category module :flags)))
|
||||
(module (doom-module-p category module))
|
||||
(doom--current-flags (memq category doom--current-flags))
|
||||
|
@ -535,66 +540,16 @@ 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))
|
||||
|
||||
(defmacro after! (package &rest body)
|
||||
"Evaluate BODY after PACKAGE have loaded.
|
||||
|
||||
PACKAGE is a symbol or list of them. These are package names, not modes,
|
||||
functions or variables. It can be:
|
||||
|
||||
- An unquoted package symbol (the name of a package)
|
||||
(after! helm BODY...)
|
||||
- An unquoted list of package symbols (i.e. BODY is evaluated once both magit
|
||||
and git-gutter have loaded)
|
||||
(after! (magit git-gutter) BODY...)
|
||||
- An unquoted, nested list of compound package lists, using any combination of
|
||||
:or/:any and :and/:all
|
||||
(after! (:or package-a package-b ...) BODY...)
|
||||
(after! (:and package-a package-b ...) BODY...)
|
||||
(after! (:and package-a (:or package-b package-c) ...) BODY...)
|
||||
Without :or/:any/:and/:all, :and/:all are implied.
|
||||
|
||||
This is a wrapper around `eval-after-load' that:
|
||||
|
||||
1. Suppresses warnings for disabled packages at compile-time
|
||||
2. No-ops for package that are disabled by the user (via `package!')
|
||||
3. Supports compound package statements (see below)
|
||||
4. Prevents eager expansion pulling in autoloaded macros all at once"
|
||||
(declare (indent defun) (debug t))
|
||||
(if (symbolp package)
|
||||
(unless (memq package (bound-and-true-p doom-disabled-packages))
|
||||
(list (if (or (not (bound-and-true-p byte-compile-current-file))
|
||||
(require package nil 'noerror))
|
||||
#'progn
|
||||
#'with-no-warnings)
|
||||
(let ((body (macroexp-progn body)))
|
||||
`(if (featurep ',package)
|
||||
,body
|
||||
;; We intentionally avoid `with-eval-after-load' to prevent
|
||||
;; eager macro expansion from pulling (or failing to pull) in
|
||||
;; autoloaded macros/packages.
|
||||
(eval-after-load ',package ',body)))))
|
||||
(let ((p (car package)))
|
||||
(cond ((not (keywordp p))
|
||||
`(after! (:and ,@package) ,@body))
|
||||
((memq p '(:or :any))
|
||||
(macroexp-progn
|
||||
(cl-loop for next in (cdr package)
|
||||
collect `(after! ,next ,@body))))
|
||||
((memq p '(:and :all))
|
||||
(dolist (next (cdr package))
|
||||
(setq body `((after! ,next ,@body))))
|
||||
(car body))))))
|
||||
|
||||
;; DEPRECATED
|
||||
(defmacro def-package! (&rest args)
|
||||
(make-obsolete 'def-package! 'use-package! "2.0.9")
|
||||
(message "`def-package!' is renamed and is now deprecated; use `use-package!' instead")
|
||||
(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)
|
||||
(make-obsolete 'def-package-hook! 'use-package-hook! "2.0.9")
|
||||
(message "`def-package-hook!' is renamed and is now deprecated; use `use-package-hook!' instead")
|
||||
(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
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
;;
|
||||
;; + `bin/doom install`: a wizard that guides you through setting up Doom and
|
||||
;; your private config for the first time.
|
||||
;; + `bin/doom refresh`: your go-to command for making sure Doom is in optimal
|
||||
;; + `bin/doom sync`: your go-to command for making sure Doom is in optimal
|
||||
;; condition. It ensures all unneeded packages are removed, all needed ones
|
||||
;; are installed, and all metadata associated with them is generated.
|
||||
;; + `bin/doom upgrade`: upgrades Doom Emacs and your packages to the latest
|
||||
|
@ -43,7 +43,7 @@
|
|||
package's name as a symbol, and whose CDR is the plist supplied to its
|
||||
`package!' declaration. Set by `doom-initialize-packages'.")
|
||||
|
||||
(defvar doom-core-packages '(straight use-package async)
|
||||
(defvar doom-core-packages '(straight use-package)
|
||||
"A list of packages that must be installed (and will be auto-installed if
|
||||
missing) and shouldn't be deleted.")
|
||||
|
||||
|
@ -72,8 +72,7 @@ missing) and shouldn't be deleted.")
|
|||
|
||||
;; Ensure that, if we do need package.el, it is configured correctly. You really
|
||||
;; shouldn't be using it, but it may be convenient for quick package testing.
|
||||
(setq package--init-file-ensured t
|
||||
package-enable-at-startup nil
|
||||
(setq package-enable-at-startup nil
|
||||
package-user-dir (concat doom-local-dir "elpa/")
|
||||
package-gnupghome-dir (expand-file-name "gpg" package-user-dir)
|
||||
;; I omit Marmalade because its packages are manually submitted rather
|
||||
|
@ -84,6 +83,8 @@ missing) and shouldn't be deleted.")
|
|||
("melpa" . ,(concat proto "://melpa.org/packages/"))
|
||||
("org" . ,(concat proto "://orgmode.org/elpa/")))))
|
||||
|
||||
(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
|
||||
|
@ -109,73 +110,17 @@ missing) and shouldn't be deleted.")
|
|||
;; certain things to work (like magit and org), but we can deal with that
|
||||
;; when we cross that bridge.
|
||||
straight-vc-git-default-clone-depth 1
|
||||
;; Straight's own emacsmirror mirror is a little smaller and faster.
|
||||
straight-recipes-emacsmirror-use-mirror t
|
||||
;; Prefix declarations are unneeded bulk added to our autoloads file. Best
|
||||
;; we just don't have to deal with them at all.
|
||||
autoload-compute-prefixes nil)
|
||||
autoload-compute-prefixes nil
|
||||
;; We handle it ourselves
|
||||
straight-fix-org nil)
|
||||
|
||||
(defun doom--finalize-straight ()
|
||||
(mapc #'funcall (delq nil (mapcar #'cdr straight--transaction-alist)))
|
||||
(setq straight--transaction-alist nil))
|
||||
|
||||
;;; Getting straight to behave in batch mode
|
||||
(when noninteractive
|
||||
;; HACK Remove dired & magit options from prompt, since they're inaccessible
|
||||
;; in noninteractive sessions.
|
||||
(advice-add #'straight-vc-git--popup-raw :override #'straight--popup-raw))
|
||||
|
||||
;; HACK Replace GUI popup prompts (which hang indefinitely in tty Emacs) with
|
||||
;; simple prompts.
|
||||
(defadvice! doom--straight-fallback-to-y-or-n-prompt-a (orig-fn &optional prompt)
|
||||
:around #'straight-are-you-sure
|
||||
(if noninteractive
|
||||
(y-or-n-p (format! "%s" (or prompt "")))
|
||||
(funcall orig-fn prompt)))
|
||||
|
||||
(defadvice! doom--straight-fallback-to-tty-prompt-a (orig-fn prompt actions)
|
||||
"Modifies straight to prompt on the terminal when in noninteractive sessions."
|
||||
:around #'straight--popup-raw
|
||||
(if (not noninteractive)
|
||||
(funcall orig-fn prompt actions)
|
||||
;; We can't intercept C-g, so no point displaying any options for this key
|
||||
;; Just use C-c
|
||||
(delq! "C-g" actions 'assoc)
|
||||
;; HACK These are associated with opening dired or magit, which isn't
|
||||
;; possible in tty Emacs, so...
|
||||
(delq! "e" actions 'assoc)
|
||||
(delq! "g" actions 'assoc)
|
||||
(let ((options (list (lambda ()
|
||||
(let ((doom-format-indent 0))
|
||||
(terpri)
|
||||
(print! (error "Aborted")))
|
||||
(kill-emacs)))))
|
||||
(print! (start "%s") (red prompt))
|
||||
(terpri)
|
||||
(print-group!
|
||||
(print-group!
|
||||
(print! " 1) Abort")
|
||||
(dolist (action actions)
|
||||
(cl-destructuring-bind (_key desc func) action
|
||||
(when desc
|
||||
(push func options)
|
||||
(print! "%2s) %s" (length options) desc)))))
|
||||
(terpri)
|
||||
(let ((options (nreverse options))
|
||||
answer fn)
|
||||
(while
|
||||
(not
|
||||
(setq
|
||||
fn (ignore-errors
|
||||
(nth (1- (setq answer
|
||||
(read-number
|
||||
(format! "How to proceed? (%s) "
|
||||
(mapconcat #'number-to-string
|
||||
(number-sequence 1 (length options))
|
||||
", ")))))
|
||||
options))))
|
||||
(print! (warn "%s is not a valid answer, try again.") answer))
|
||||
(funcall fn))))))
|
||||
(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)
|
||||
(doom-package-pinned-list)))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -190,7 +135,7 @@ This ensure `doom-packages' is populated, if isn't aren't already. Use this
|
|||
before any of straight's or Doom's package management's API to ensure all the
|
||||
necessary package metadata is initialized and available for them."
|
||||
(unless doom-init-packages-p
|
||||
(setq force-p t))
|
||||
(setq force-p t))
|
||||
(when (or force-p (not (bound-and-true-p package--initialized)))
|
||||
(doom-log "Initializing package.el")
|
||||
(require 'package)
|
||||
|
@ -198,63 +143,69 @@ necessary package metadata is initialized and available for them."
|
|||
(when (or force-p (not doom-packages))
|
||||
(doom-log "Initializing straight")
|
||||
(setq doom-init-packages-p t)
|
||||
(unless (fboundp 'straight--reset-caches)
|
||||
(doom-ensure-straight)
|
||||
(require 'straight))
|
||||
(straight--reset-caches)
|
||||
(mapc #'straight-use-recipes doom-core-package-sources)
|
||||
(straight-register-package
|
||||
`(straight :type git :host github
|
||||
:repo ,(format "%s/straight.el" straight-repository-user)
|
||||
:files ("straight*.el")
|
||||
:branch ,straight-repository-branch
|
||||
:no-byte-compile t))
|
||||
(doom-ensure-straight)
|
||||
(mapc #'straight-use-package doom-core-packages)
|
||||
(doom-log "Initializing doom-packages")
|
||||
(setq doom-disabled-packages nil
|
||||
doom-pinned-packages nil
|
||||
doom-packages (doom-package-list))
|
||||
(cl-loop for (pkg . plist) in doom-packages
|
||||
for ignored = (plist-get plist :ignore)
|
||||
for disabled = (plist-get plist :disable)
|
||||
if disabled
|
||||
do (cl-pushnew pkg doom-disabled-packages)
|
||||
else if (not ignored)
|
||||
do (with-demoted-errors "Package error: %s"
|
||||
(straight-register-package
|
||||
(if-let (recipe (plist-get plist :recipe))
|
||||
(let ((plist (straight-recipes-retrieve pkg)))
|
||||
`(,pkg ,@(doom-plist-merge recipe (cdr plist))))
|
||||
pkg))))
|
||||
(unless doom-interactive-mode
|
||||
(add-hook 'kill-emacs-hook #'doom--finalize-straight))))
|
||||
(dolist (package doom-packages)
|
||||
(let ((name (car package)))
|
||||
(with-plist! (cdr package) (recipe modules disable ignore pin)
|
||||
(if ignore
|
||||
(doom-log "Ignoring package %S" name)
|
||||
(if (not disable)
|
||||
(with-demoted-errors "Package error: %s"
|
||||
(when recipe
|
||||
(straight-override-recipe (cons name recipe)))
|
||||
(straight-register-package name))
|
||||
(doom-log "Disabling package %S" name)
|
||||
(cl-pushnew name doom-disabled-packages)
|
||||
;; Warn about disabled core packages
|
||||
(when (cl-find :core modules :key #'car)
|
||||
(print! (warn "%s\n%s")
|
||||
(format "You've disabled %S" name)
|
||||
(indent 2 (concat "This is a core package. Disabling it will cause errors, as Doom assumes\n"
|
||||
"core packages are always available. Disable their minor-modes or hooks instead.")))))))))))
|
||||
|
||||
(defun doom-ensure-straight ()
|
||||
"Ensure `straight' is installed and was compiled with this version of Emacs."
|
||||
(defvar bootstrap-version)
|
||||
(let* (;; Force straight to install into ~/.emacs.d/.local/straight instead of
|
||||
;; ~/.emacs.d/straight by pretending `doom-local-dir' is our .emacs.d.
|
||||
(user-emacs-directory straight-base-dir)
|
||||
(bootstrap-file (doom-path straight-base-dir "straight/repos/straight.el/straight.el"))
|
||||
(bootstrap-version 5))
|
||||
(make-directory (doom-path straight-base-dir "straight/build") 'parents)
|
||||
(unless (featurep 'straight)
|
||||
(unless (or (require 'straight nil t)
|
||||
(file-readable-p bootstrap-file))
|
||||
(with-current-buffer
|
||||
(url-retrieve-synchronously
|
||||
(format "https://raw.githubusercontent.com/raxod502/straight.el/%s/install.el"
|
||||
straight-repository-branch)
|
||||
'silent 'inhibit-cookies)
|
||||
(goto-char (point-max))
|
||||
(eval-print-last-sexp)))
|
||||
(load bootstrap-file nil t))))
|
||||
(unless (fboundp 'straight--reset-caches)
|
||||
(defvar bootstrap-version)
|
||||
(let* (;; Force straight to install into ~/.emacs.d/.local/straight instead of
|
||||
;; ~/.emacs.d/straight by pretending `doom-local-dir' is our .emacs.d.
|
||||
(user-emacs-directory straight-base-dir)
|
||||
(bootstrap-file (doom-path straight-base-dir "straight/repos/straight.el/straight.el"))
|
||||
(bootstrap-version 5))
|
||||
(make-directory (doom-path straight-base-dir "straight/build") 'parents)
|
||||
(or (require 'straight nil t)
|
||||
(file-readable-p bootstrap-file)
|
||||
(with-current-buffer
|
||||
(url-retrieve-synchronously
|
||||
(format "https://raw.githubusercontent.com/raxod502/straight.el/%s/install.el"
|
||||
straight-repository-branch)
|
||||
'silent 'inhibit-cookies)
|
||||
(goto-char (point-max))
|
||||
(eval-print-last-sexp)))
|
||||
(load bootstrap-file nil t))
|
||||
(require 'straight))
|
||||
(straight--reset-caches)
|
||||
(setq straight-recipe-repositories nil
|
||||
straight-recipe-overrides nil)
|
||||
(mapc #'straight-use-recipes doom-core-package-sources)
|
||||
(straight-register-package
|
||||
`(straight :type git :host github
|
||||
:repo ,(format "%s/straight.el" straight-repository-user)
|
||||
:files ("straight*.el")
|
||||
:branch ,straight-repository-branch
|
||||
:no-byte-compile t)))
|
||||
|
||||
|
||||
;;
|
||||
;;; Module package macros
|
||||
|
||||
(cl-defmacro package!
|
||||
(name &rest plist &key built-in recipe ignore _disable _freeze)
|
||||
(name &rest plist &key built-in recipe ignore _pin _disable)
|
||||
"Declares a package and how to install it (if applicable).
|
||||
|
||||
This macro is declarative and does not load nor install packages. It is used to
|
||||
|
@ -266,31 +217,38 @@ Only use this macro in a module's packages.el file.
|
|||
Accepts the following properties:
|
||||
|
||||
:recipe RECIPE
|
||||
Takes a MELPA-style recipe (see `quelpa-recipe' in `quelpa' for an example);
|
||||
for packages to be installed from external sources.
|
||||
Specifies a straight.el recipe to allow you to acquire packages from external
|
||||
sources. See https://github.com/raxod502/straight.el#the-recipe-format for
|
||||
details on this recipe.
|
||||
:disable BOOL
|
||||
Do not install or update this package AND disable all of its `use-package!'
|
||||
blocks.
|
||||
and `after!' blocks.
|
||||
:ignore FORM
|
||||
Do not install this package.
|
||||
:freeze FORM
|
||||
Do not update this package if FORM is non-nil.
|
||||
:built-in BOOL
|
||||
Same as :ignore if the package is a built-in Emacs package. If set to
|
||||
'prefer, will use built-in package if it is present.
|
||||
:pin STR|nil
|
||||
Pin this package to commit hash STR. Setting this to nil will unpin this
|
||||
package if previously pinned.
|
||||
:built-in BOOL|'prefer
|
||||
Same as :ignore if the package is a built-in Emacs package. This is more to
|
||||
inform help commands like `doom/help-packages' that this is a built-in
|
||||
package. If set to 'prefer, the package will not be installed if it is
|
||||
already provided by Emacs.
|
||||
|
||||
Returns t if package is successfully registered, and nil if it was disabled
|
||||
elsewhere."
|
||||
(declare (indent defun))
|
||||
(when (and recipe (keywordp (car-safe recipe)))
|
||||
(plist-put! plist :recipe `(quote ,recipe)))
|
||||
;; :built-in t is basically an alias for :ignore (locate-library NAME)
|
||||
(when built-in
|
||||
(when (and (not ignore) (equal built-in '(quote prefer)))
|
||||
(when (and (not ignore)
|
||||
(equal built-in '(quote prefer)))
|
||||
(setq built-in `(locate-library ,(symbol-name name) nil doom--initial-load-path)))
|
||||
(plist-delete! plist :built-in)
|
||||
(plist-put! plist :ignore built-in))
|
||||
`(let* ((name ',name)
|
||||
(plist (cdr (assq name doom-packages))))
|
||||
;; Record what module this declaration was found in
|
||||
(let ((module-list (plist-get plist :modules))
|
||||
(module ',(doom-module-from-path)))
|
||||
(unless (member module module-list)
|
||||
|
@ -298,27 +256,31 @@ elsewhere."
|
|||
(append module-list
|
||||
(list module)
|
||||
nil))))
|
||||
|
||||
;; Merge given plist with pre-existing one
|
||||
(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
|
||||
(condition-case e
|
||||
(cl-destructuring-bind
|
||||
(&key _local-repo _files _flavor _no-build
|
||||
_type _repo _host _branch _remote _nonrecursive _fork _depth)
|
||||
(plist-get plist :recipe))
|
||||
(when-let (recipe (plist-get plist :recipe))
|
||||
(cl-destructuring-bind
|
||||
(&key local-repo _files _flavor
|
||||
_no-build _no-byte-compile _no-autoloads
|
||||
_type _repo _host _branch _remote _nonrecursive _fork _depth)
|
||||
recipe
|
||||
;; Expand :local-repo from current directory
|
||||
(when local-repo
|
||||
(plist-put! plist :recipe
|
||||
(plist-put recipe :local-repo
|
||||
(expand-file-name local-repo ,(dir!)))))))
|
||||
(error
|
||||
(signal 'doom-package-error
|
||||
(cons ,(symbol-name name)
|
||||
(error-message-string e)))))
|
||||
|
||||
;; This is the only side-effect of this macro!
|
||||
(setf (alist-get name doom-packages) plist)
|
||||
(if (not (plist-get plist :disable)) t
|
||||
(doom-log "Disabling package %S" name)
|
||||
(cl-pushnew name doom-disabled-packages)
|
||||
nil)))
|
||||
(with-no-warnings
|
||||
(not (plist-get plist :disable)))))
|
||||
|
||||
(defmacro disable-packages! (&rest packages)
|
||||
"A convenience macro for disabling packages in bulk.
|
||||
|
@ -327,5 +289,43 @@ Only use this macro in a module's (or your private) packages.el file."
|
|||
(cl-loop for p in packages
|
||||
collect `(package! ,p :disable t))))
|
||||
|
||||
(defmacro unpin! (&rest targets)
|
||||
"Unpin packages in TARGETS.
|
||||
|
||||
This unpins packages, so that 'doom upgrade' downloads their latest version. It
|
||||
can be used one of five ways:
|
||||
|
||||
+ To disable pinning wholesale: (unpin! t)
|
||||
+ To unpin individual packages: (unpin! packageA packageB ...)
|
||||
+ To unpin all packages in a group of modules: (unpin! :lang :tools ...)
|
||||
+ To unpin packages in individual modules:
|
||||
(unpin! (:lang python javascript) (:tools docker))
|
||||
|
||||
Or any combination of the above.
|
||||
|
||||
This macro should only be used from the user's private packages.el. No module
|
||||
should use it!"
|
||||
(if (memq t targets)
|
||||
`(mapc (doom-rpartial #'doom-package-set :unpin t)
|
||||
(mapcar #'car doom-packages))
|
||||
(let (forms)
|
||||
(dolist (target targets)
|
||||
(cl-check-type target (or symbol keyword list))
|
||||
(cond
|
||||
((symbolp target)
|
||||
(push `(doom-package-set ',target :unpin t) forms))
|
||||
((or (keywordp target)
|
||||
(listp target))
|
||||
(cl-destructuring-bind (category . modules) (doom-enlist target)
|
||||
(dolist (pkg doom-packages)
|
||||
(let ((pkg-modules (plist-get (cdr pkg) :modules)))
|
||||
(and (assq category pkg-modules)
|
||||
(or (null modules)
|
||||
(cl-loop for module in modules
|
||||
if (member (cons category module) pkg-modules)
|
||||
return t))
|
||||
(push `(doom-package-set ',(car pkg) :unpin t) forms))))))))
|
||||
(macroexp-progn forms))))
|
||||
|
||||
(provide 'core-packages)
|
||||
;;; core-packages.el ends here
|
||||
|
|
|
@ -31,15 +31,11 @@ Emacs.")
|
|||
:init
|
||||
(setq projectile-cache-file (concat doom-cache-dir "projectile.cache")
|
||||
projectile-enable-caching doom-interactive-mode
|
||||
projectile-known-projects-file (concat doom-cache-dir "projectile.projects")
|
||||
projectile-require-project-root t
|
||||
projectile-globally-ignored-files '(".DS_Store" "Icon
" "TAGS")
|
||||
projectile-globally-ignored-file-suffixes '(".elc" ".pyc" ".o")
|
||||
projectile-ignored-projects '("~/" "/tmp")
|
||||
projectile-kill-buffers-filter 'kill-only-files
|
||||
projectile-files-cache-expire 604800 ; expire after a week
|
||||
projectile-sort-order 'recentf
|
||||
projectile-use-git-grep t) ; use git-grep for text searches
|
||||
projectile-known-projects-file (concat doom-cache-dir "projectile.projects")
|
||||
projectile-ignored-projects '("~/" "/tmp"))
|
||||
|
||||
(global-set-key [remap evil-jump-to-tag] #'projectile-find-tag)
|
||||
(global-set-key [remap find-tag] #'projectile-find-tag)
|
||||
|
@ -47,6 +43,21 @@ Emacs.")
|
|||
:config
|
||||
(projectile-mode +1)
|
||||
|
||||
;; 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.
|
||||
;;
|
||||
;; In the interest of performance, we reduce the number of project root marker
|
||||
;; files/directories projectile searches for when resolving the project root.
|
||||
(setq projectile-project-root-files-bottom-up
|
||||
|
@ -54,20 +65,14 @@ Emacs.")
|
|||
".git") ; Git VCS root dir
|
||||
(when (executable-find "hg")
|
||||
'(".hg")) ; Mercurial VCS root dir
|
||||
(when (executable-find "fossil")
|
||||
'(".fslckout" ; Fossil VCS root dir
|
||||
"_FOSSIL_")) ; Fossil VCS root DB on Windows
|
||||
(when (executable-find "bzr")
|
||||
'(".bzr")) ; Bazaar VCS root dir
|
||||
(when (executable-find "darcs")
|
||||
'("_darcs"))) ; Darcs VCS root dir
|
||||
'(".bzr"))) ; Bazaar VCS root dir
|
||||
;; This will be filled by other modules. We build this list manually so
|
||||
;; projectile doesn't perform so many file checks every time it resolves
|
||||
;; a project's root -- particularly when a file has no project.
|
||||
projectile-project-root-files '("TAGS")
|
||||
projectile-project-root-files-top-down-recurring '(".svn" "Makefile"))
|
||||
projectile-project-root-files '()
|
||||
projectile-project-root-files-top-down-recurring '("Makefile"))
|
||||
|
||||
;; a more generic project root file
|
||||
(push (abbreviate-file-name doom-local-dir) projectile-globally-ignored-directories)
|
||||
|
||||
;; Disable commands that won't work, as is, and that Doom already provides a
|
||||
|
@ -125,10 +130,11 @@ c) are not valid projectile projects."
|
|||
;; that is significantly faster than git ls-files or find, and it respects
|
||||
;; .gitignore. This is recommended in the projectile docs.
|
||||
((executable-find doom-projectile-fd-binary)
|
||||
(setq projectile-git-command (concat
|
||||
doom-projectile-fd-binary
|
||||
" . --color=never --type f -0 -H -E .git")
|
||||
projectile-generic-command projectile-git-command
|
||||
(setq projectile-generic-command
|
||||
(format "%s . --color=never --type f -0 -H -E .git"
|
||||
doom-projectile-fd-binary)
|
||||
projectile-git-command projectile-generic-command
|
||||
projectile-git-submodule-command nil
|
||||
;; ensure Windows users get fd's benefits
|
||||
projectile-indexing-method 'alien))
|
||||
|
||||
|
@ -138,25 +144,16 @@ c) are not valid projectile projects."
|
|||
(concat "rg -0 --files --color=never --hidden"
|
||||
(cl-loop for dir in projectile-globally-ignored-directories
|
||||
concat (format " --glob '!%s'" dir)))
|
||||
projectile-git-command projectile-generic-command
|
||||
projectile-git-submodule-command nil
|
||||
;; ensure Windows users get rg's benefits
|
||||
projectile-indexing-method 'alien)
|
||||
;; fix breakage on windows in git projects
|
||||
(unless (executable-find "tr")
|
||||
(setq projectile-git-submodule-command nil)))
|
||||
projectile-indexing-method 'alien))
|
||||
|
||||
((not (executable-find "tr"))
|
||||
;; Fix breakage on windows in git projects with submodules, since Windows
|
||||
;; doesn't have tr
|
||||
(IS-WINDOWS
|
||||
(setq projectile-git-submodule-command nil)))
|
||||
|
||||
(defadvice! doom--projectile-cache-timers-a ()
|
||||
"Persist `projectile-projects-cache-time' across sessions, so that
|
||||
`projectile-files-cache-expire' checks won't reset when restarting Emacs."
|
||||
:before #'projectile-serialize-cache
|
||||
(projectile-serialize projectile-projects-cache-time doom-projectile-cache-timer-file))
|
||||
;; Restore it
|
||||
(when (file-readable-p doom-projectile-cache-timer-file)
|
||||
(setq projectile-projects-cache-time
|
||||
(projectile-unserialize doom-projectile-cache-timer-file)))
|
||||
|
||||
(defadvice! doom--projectile-default-generic-command-a (orig-fn &rest args)
|
||||
"If projectile can't tell what kind of project you're in, it issues an error
|
||||
when using many of projectile's command, e.g. `projectile-compile-command',
|
||||
|
@ -171,12 +168,11 @@ the command instead."
|
|||
;; Projectile root-searching functions can cause an infinite loop on TRAMP
|
||||
;; connections, so disable them.
|
||||
;; TODO Is this still necessary?
|
||||
(defadvice! doom--projectile-locate-dominating-file-a (orig-fn file name)
|
||||
(defadvice! doom--projectile-locate-dominating-file-a (file _name)
|
||||
"Don't traverse the file system if on a remote connection."
|
||||
:around #'projectile-locate-dominating-file
|
||||
(when (and (stringp file)
|
||||
(not (file-remote-p file nil t)))
|
||||
(funcall orig-fn file name))))
|
||||
:before-while #'projectile-locate-dominating-file
|
||||
(and (stringp file)
|
||||
(not (file-remote-p file nil t)))))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -195,16 +191,15 @@ state are passed in.")
|
|||
on-load
|
||||
on-enter
|
||||
on-exit)
|
||||
"Define a project minor-mode named NAME (a symbol) and declare where and how
|
||||
it is activated. Project modes allow you to configure 'sub-modes' for
|
||||
major-modes that are specific to a folder, project structure, framework or
|
||||
whatever arbitrary context you define. These project modes can have their own
|
||||
settings, keymaps, hooks, snippets, etc.
|
||||
"Define a project minor mode named NAME and where/how it is activated.
|
||||
|
||||
Project modes allow you to configure 'sub-modes' for major-modes that are
|
||||
specific to a folder, project structure, framework or whatever arbitrary context
|
||||
you define. These project modes can have their own settings, keymaps, hooks,
|
||||
snippets, etc.
|
||||
|
||||
This creates NAME-hook and NAME-map as well.
|
||||
|
||||
A project can be enabled through .dir-locals.el too, by setting `doom-project'.
|
||||
|
||||
PLIST may contain any of these properties, which are all checked to see if NAME
|
||||
should be activated. If they are *all* true, NAME is activated.
|
||||
|
||||
|
|
197
core/core-ui.el
197
core/core-ui.el
|
@ -173,7 +173,12 @@ read-only or not file-visiting."
|
|||
|
||||
(setq hscroll-margin 2
|
||||
hscroll-step 1
|
||||
scroll-conservatively 10
|
||||
;; Emacs spends too much effort recentering the screen if you scroll the
|
||||
;; cursor more than N lines past window edges (where N is the settings of
|
||||
;; `scroll-conservatively'). This is especially slow in larger files
|
||||
;; during large-scale scrolling commands. If kept over 100, the window is
|
||||
;; never automatically recentered.
|
||||
scroll-conservatively 101
|
||||
scroll-margin 0
|
||||
scroll-preserve-screen-position t
|
||||
;; Reduce cursor lag by a tiny bit by not auto-adjusting `window-vscroll'
|
||||
|
@ -216,19 +221,21 @@ read-only or not file-visiting."
|
|||
|
||||
(setq confirm-nonexistent-file-or-buffer t)
|
||||
|
||||
(defadvice! doom--switch-to-fallback-buffer-maybe-a (orig-fn)
|
||||
(defadvice! doom--switch-to-fallback-buffer-maybe-a (&rest _)
|
||||
"Switch to `doom-fallback-buffer' if on last real buffer.
|
||||
|
||||
Advice for `kill-current-buffer'. If in a dedicated window, delete it. If there
|
||||
are no real buffers left OR if all remaining buffers are visible in other
|
||||
windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
||||
`kill-current-buffer'."
|
||||
:around #'kill-current-buffer
|
||||
:before-until #'kill-current-buffer
|
||||
(let ((buf (current-buffer)))
|
||||
(cond ((window-dedicated-p)
|
||||
(delete-window))
|
||||
(delete-window)
|
||||
t)
|
||||
((eq buf (doom-fallback-buffer))
|
||||
(message "Can't kill the fallback buffer."))
|
||||
(message "Can't kill the fallback buffer.")
|
||||
t)
|
||||
((doom-real-buffer-p buf)
|
||||
(if (and buffer-file-name
|
||||
(buffer-modified-p buf)
|
||||
|
@ -247,8 +254,8 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
|||
(switch-to-buffer (doom-fallback-buffer)))
|
||||
(unless (delq (selected-window) (get-buffer-window-list buf nil t))
|
||||
(kill-buffer buf)))
|
||||
(run-hooks 'buffer-list-update-hook)))
|
||||
((funcall orig-fn)))))
|
||||
(run-hooks 'buffer-list-update-hook))
|
||||
t))))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -270,40 +277,46 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
|||
(setq frame-title-format '("%b – Doom Emacs")
|
||||
icon-title-format frame-title-format)
|
||||
|
||||
;; Don't resize emacs in steps, it looks weird.
|
||||
;; Don't resize windows & frames in steps; it's prohibitive to prevent the user
|
||||
;; from resizing it to exact dimensions, and looks weird.
|
||||
(setq window-resize-pixelwise t
|
||||
frame-resize-pixelwise t)
|
||||
|
||||
(unless EMACS27+ ; We already do this in early-init.el
|
||||
;; Disable tool and scrollbars; Doom encourages keyboard-centric workflows, so
|
||||
;; these are just clutter (the scrollbar also impacts Emacs' performance).
|
||||
(push '(menu-bar-lines . 0) default-frame-alist)
|
||||
(push '(tool-bar-lines . 0) default-frame-alist)
|
||||
(push '(vertical-scroll-bars) default-frame-alist))
|
||||
(unless (assq 'menu-bar-lines default-frame-alist)
|
||||
;; We do this in early-init.el too, but in case the user is on Emacs 26 we do
|
||||
;; it here too: disable tool and scrollbars, as Doom encourages
|
||||
;; keyboard-centric workflows, so these are just clutter (the scrollbar also
|
||||
;; impacts performance).
|
||||
(add-to-list 'default-frame-alist '(menu-bar-lines . 0))
|
||||
(add-to-list 'default-frame-alist '(tool-bar-lines . 0))
|
||||
(add-to-list 'default-frame-alist '(vertical-scroll-bars)))
|
||||
|
||||
;; Sets `ns-appearance' and `ns-transparent-titlebar' on GUI frames (and fixes
|
||||
;; mismatching text color in the frame title)
|
||||
(when IS-MAC
|
||||
;; Curse Lion and its sudden but inevitable fullscreen mode!
|
||||
;; NOTE Meaningless to railwaycat's emacs-mac build
|
||||
(setq ns-use-native-fullscreen nil
|
||||
;; Visit files opened outside of Emacs in existing frame, rather than a
|
||||
;; new one
|
||||
ns-pop-up-frames nil)
|
||||
(setq ns-use-native-fullscreen nil)
|
||||
|
||||
;; Sets ns-transparent-titlebar and ns-appearance frame parameters as is
|
||||
;; appropriate for the loaded theme.
|
||||
;; Visit files opened outside of Emacs in existing frame, not a new one
|
||||
(setq ns-pop-up-frames nil)
|
||||
|
||||
;; Sets `ns-transparent-titlebar' and `ns-appearance' frame parameters so
|
||||
;; window borders will match the enabled theme.
|
||||
(and (or (daemonp)
|
||||
(display-graphic-p))
|
||||
(require 'ns-auto-titlebar nil t)
|
||||
(ns-auto-titlebar-mode +1))
|
||||
|
||||
(add-hook! 'after-make-frame-functions
|
||||
(defun doom-init-menu-bar-in-gui-frames-h (frame)
|
||||
"On MacOS, the menu bar isn't part of the frame. Disabling it makes MacOS
|
||||
treat Emacs as a non-application window."
|
||||
(when (display-graphic-p frame)
|
||||
(set-frame-parameter frame 'menu-bar-lines 1)))))
|
||||
;; HACK On MacOS, disabling the menu bar makes MacOS treat Emacs as a
|
||||
;; non-application window -- which means it doesn't automatically capture
|
||||
;; focus when it is started, among other things. We enable menu-bar-lines
|
||||
;; there, but we still want it disabled in terminal frames because there
|
||||
;; it activates an ugly menu bar.
|
||||
(add-hook! '(window-setup-hook after-make-frame-functions)
|
||||
(defun doom-init-menu-bar-in-gui-frames-h (&optional frame)
|
||||
"Re-enable menu-bar-lines in GUI frames."
|
||||
(when-let (frame (or frame (selected-frame)))
|
||||
(when (display-graphic-p frame)
|
||||
(set-frame-parameter frame 'menu-bar-lines 1))))))
|
||||
|
||||
;; The native border "consumes" a pixel of the fringe on righter-most splits,
|
||||
;; `window-divider' does not. Available since Emacs 25.1.
|
||||
|
@ -317,13 +330,15 @@ treat Emacs as a non-application window."
|
|||
|
||||
;; always avoid GUI
|
||||
(setq use-dialog-box nil)
|
||||
;; Don't display floating tooltips; display their contents in the echo-area.
|
||||
(if (bound-and-true-p tooltip-mode) (tooltip-mode -1))
|
||||
;; native linux tooltips are ugly
|
||||
;; Don't display floating tooltips; display their contents in the echo-area,
|
||||
;; because native tooltips are ugly.
|
||||
(when (bound-and-true-p tooltip-mode)
|
||||
(tooltip-mode -1))
|
||||
;; ...especially on linux
|
||||
(when IS-LINUX
|
||||
(setq x-gtk-use-system-tooltips nil))
|
||||
|
||||
;; Favor vertical splits over horizontal ones
|
||||
;; Favor vertical splits over horizontal ones. Screens are usually wide.
|
||||
(setq split-width-threshold 160
|
||||
split-height-threshold nil)
|
||||
|
||||
|
@ -332,7 +347,7 @@ treat Emacs as a non-application window."
|
|||
;;; Minibuffer
|
||||
|
||||
;; Allow for minibuffer-ception. Sometimes we need another minibuffer command
|
||||
;; _while_ we're in the minibuffer.
|
||||
;; while we're in the minibuffer.
|
||||
(setq enable-recursive-minibuffers t)
|
||||
|
||||
;; Show current key-sequence in minibuffer, like vim does. Any feedback after
|
||||
|
@ -345,11 +360,6 @@ treat Emacs as a non-application window."
|
|||
;; But don't let the minibuffer grow beyond this size
|
||||
max-mini-window-height 0.15)
|
||||
|
||||
;; Disable help mouse-overs for mode-line segments (i.e. :help-echo text).
|
||||
;; They're generally unhelpful and only add confusing visual clutter.
|
||||
(setq mode-line-default-help-echo nil
|
||||
show-help-function nil)
|
||||
|
||||
;; Typing yes/no is obnoxious when y/n will do
|
||||
(fset #'yes-or-no-p #'y-or-n-p)
|
||||
|
||||
|
@ -406,19 +416,20 @@ treat Emacs as a non-application window."
|
|||
(setq hl-line-sticky-flag nil
|
||||
global-hl-line-sticky-flag nil)
|
||||
|
||||
;; Disable `hl-line' in evil-visual mode (temporarily). `hl-line' can make the
|
||||
;; selection region harder to see while in evil visual mode.
|
||||
(after! evil
|
||||
(defvar doom-buffer-hl-line-mode nil)
|
||||
(add-hook! 'evil-visual-state-entry-hook
|
||||
(defun doom-disable-hl-line-h ()
|
||||
(when hl-line-mode
|
||||
(setq-local doom-buffer-hl-line-mode t)
|
||||
(hl-line-mode -1))))
|
||||
(add-hook! 'evil-visual-state-exit-hook
|
||||
(defun doom-enable-hl-line-maybe-h ()
|
||||
(when doom-buffer-hl-line-mode
|
||||
(hl-line-mode +1))))))
|
||||
;; 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)
|
||||
|
||||
(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)
|
||||
(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
|
||||
(hl-line-mode +1)))))
|
||||
|
||||
|
||||
(use-package! winner
|
||||
|
@ -464,15 +475,23 @@ treat Emacs as a non-application window."
|
|||
all-the-icons-wicon
|
||||
all-the-icons-material
|
||||
all-the-icons-alltheicon)
|
||||
:init
|
||||
(defadvice! doom--disable-all-the-icons-in-tty-a (orig-fn &rest args)
|
||||
"Return a blank string in tty Emacs, which doesn't support multiple fonts."
|
||||
:around '(all-the-icons-octicon all-the-icons-material
|
||||
all-the-icons-faicon all-the-icons-fileicon
|
||||
all-the-icons-wicon all-the-icons-alltheicon)
|
||||
(if (display-multi-font-p)
|
||||
(apply orig-fn args)
|
||||
"")))
|
||||
:config
|
||||
(cond ((daemonp)
|
||||
(defadvice! doom--disable-all-the-icons-in-tty-a (orig-fn &rest args)
|
||||
"Return a blank string in tty Emacs, which doesn't support multiple fonts."
|
||||
:around '(all-the-icons-octicon all-the-icons-material
|
||||
all-the-icons-faicon all-the-icons-fileicon
|
||||
all-the-icons-wicon all-the-icons-alltheicon)
|
||||
(if (or (not after-init-time) (display-multi-font-p))
|
||||
(apply orig-fn args)
|
||||
"")))
|
||||
((not (display-graphic-p))
|
||||
(defadvice! doom--disable-all-the-icons-in-tty-a (&rest _)
|
||||
"Return a blank string for tty users."
|
||||
:override '(all-the-icons-octicon all-the-icons-material
|
||||
all-the-icons-faicon all-the-icons-fileicon
|
||||
all-the-icons-wicon all-the-icons-alltheicon)
|
||||
""))))
|
||||
|
||||
;;;###package hide-mode-line-mode
|
||||
(add-hook! '(completion-list-mode-hook Man-mode-hook)
|
||||
|
@ -499,15 +518,19 @@ treat Emacs as a non-application window."
|
|||
;;
|
||||
;;; Line numbers
|
||||
|
||||
;; Explicitly define a width to reduce computation
|
||||
(setq-default display-line-numbers-width 3)
|
||||
|
||||
;; line numbers in most modes
|
||||
;; Show absolute line numbers for narrowed regions makes it easier to tell the
|
||||
;; buffer is narrowed, and where you are, exactly.
|
||||
(setq-default display-line-numbers-widen t)
|
||||
|
||||
;; Enable line numbers in most text-editing modes. We avoid
|
||||
;; `global-display-line-numbers-mode' because there are many special and
|
||||
;; temporary modes where we don't need/want them.
|
||||
(add-hook! '(prog-mode-hook text-mode-hook conf-mode-hook)
|
||||
#'display-line-numbers-mode)
|
||||
|
||||
(defun doom-enable-line-numbers-h () (display-line-numbers-mode +1))
|
||||
(defun doom-disable-line-numbers-h () (display-line-numbers-mode -1))
|
||||
|
||||
|
||||
;;
|
||||
;;; Theme & font
|
||||
|
@ -521,22 +544,30 @@ behavior). Do not set this directly, this is let-bound in `doom-init-theme-h'.")
|
|||
|
||||
(defun doom-init-fonts-h ()
|
||||
"Loads `doom-font'."
|
||||
(cond (doom-font
|
||||
(cl-pushnew
|
||||
(cons 'font
|
||||
(cond ((stringp doom-font) doom-font)
|
||||
((fontp doom-font) (font-xlfd-name doom-font))
|
||||
((signal 'wrong-type-argument (list '(fontp stringp)
|
||||
doom-font)))))
|
||||
default-frame-alist
|
||||
:key #'car :test #'eq))
|
||||
((display-graphic-p)
|
||||
(setq doom-font (face-attribute 'default :font)))))
|
||||
(cond
|
||||
(doom-font
|
||||
(cl-pushnew
|
||||
;; Avoiding `set-frame-font' because it does a lot of extra, expensive
|
||||
;; work we can avoid by setting the font frame parameter instead.
|
||||
(cons 'font
|
||||
(cond ((stringp doom-font) doom-font)
|
||||
((fontp doom-font) (font-xlfd-name doom-font))
|
||||
((signal 'wrong-type-argument (list '(fontp stringp)
|
||||
doom-font)))))
|
||||
default-frame-alist
|
||||
:key #'car :test #'eq))
|
||||
((display-graphic-p)
|
||||
;; We try our best to record your system font, so `doom-big-font-mode'
|
||||
;; can still use it to compute a larger font size with.
|
||||
(setq font-use-system-font t
|
||||
doom-font (face-attribute 'default :font)))))
|
||||
|
||||
(defun doom-init-extra-fonts-h (&optional frame)
|
||||
"Loads `doom-variable-pitch-font',`doom-serif-font' and `doom-unicode-font'."
|
||||
(condition-case e
|
||||
(with-selected-frame (or frame (selected-frame))
|
||||
(when doom-font
|
||||
(set-face-attribute 'fixed-pitch nil :font doom-font))
|
||||
(when doom-serif-font
|
||||
(set-face-attribute 'fixed-pitch-serif nil :font doom-serif-font))
|
||||
(when doom-variable-pitch-font
|
||||
|
@ -616,7 +647,21 @@ startup (or theme switch) time, so long as `doom--prefer-theme-elc' is non-nil."
|
|||
;;
|
||||
;;; Fixes/hacks
|
||||
|
||||
;; doesn't exist in terminal Emacs; we define it to prevent errors
|
||||
;; Doom doesn't support `customize' and it never will. It's a clumsy interface
|
||||
;; that sets variables at a time where it can be easily and unpredictably
|
||||
;; overwritten. Configure things from your $DOOMDIR instead.
|
||||
(dolist (sym '(customize-option customize-browse customize-group customize-face
|
||||
customize-rogue customize-saved customize-apropos
|
||||
customize-changed customize-unsaved customize-variable
|
||||
customize-set-value customize-customized customize-set-variable
|
||||
customize-apropos-faces customize-save-variable
|
||||
customize-apropos-groups customize-apropos-options
|
||||
customize-changed-options customize-save-customized))
|
||||
(put sym 'disabled "Doom doesn't support `customize', configure Emacs from $DOOMDIR/config.el instead"))
|
||||
(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.
|
||||
(unless (fboundp 'define-fringe-bitmap)
|
||||
(fset 'define-fringe-bitmap #'ignore))
|
||||
|
||||
|
|
168
core/core.el
168
core/core.el
|
@ -23,13 +23,18 @@
|
|||
|
||||
;; This is consulted on every `require', `load' and various path/io functions.
|
||||
;; You get a minor speed up by nooping this.
|
||||
(setq file-name-handler-alist nil)
|
||||
(unless noninteractive
|
||||
(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 ()
|
||||
(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
|
||||
(require 'core-lib)
|
||||
|
||||
(autoload 'doom-initialize-packages "core-packages")
|
||||
|
||||
|
||||
;;
|
||||
;;; Global variables
|
||||
|
@ -49,10 +54,6 @@ DEBUG envvar will enable this at startup.")
|
|||
(defvar doom-interactive-mode (not noninteractive)
|
||||
"If non-nil, Emacs is in interactive mode.")
|
||||
|
||||
(defvar doom-gc-cons-threshold 16777216 ; 16mb
|
||||
"The default value to use for `gc-cons-threshold'. If you experience freezing,
|
||||
decrease this. If you experience stuttering, increase this.")
|
||||
|
||||
;;; Directories/files
|
||||
(defconst doom-emacs-dir
|
||||
(eval-when-compile (file-truename user-emacs-directory))
|
||||
|
@ -115,7 +116,7 @@ This file is compiled from the autoloads files of all installed packages
|
|||
combined.")
|
||||
|
||||
(defconst doom-env-file (concat doom-local-dir "env")
|
||||
"The location of your envvar file, generated by `doom env refresh`.
|
||||
"The location of your envvar file, generated by `doom env`.
|
||||
|
||||
This file contains environment variables scraped from your shell environment,
|
||||
which is loaded at startup (if it exists). This is helpful if Emacs can't
|
||||
|
@ -134,6 +135,9 @@ users).")
|
|||
;;
|
||||
;;; Emacs core configuration
|
||||
|
||||
;; lo', longer logs ahoy, so we may reliably locate lapses in doom's logic
|
||||
(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)
|
||||
|
@ -194,11 +198,12 @@ users).")
|
|||
(when IS-WINDOWS
|
||||
(setq abbreviated-home-dir "\\`'"))
|
||||
|
||||
;; Don't litter `doom-emacs-dir'
|
||||
;; Don't litter `doom-emacs-dir'. We don't use `no-littering' because it's a
|
||||
;; mote too opinionated for our needs.
|
||||
(setq abbrev-file-name (concat doom-local-dir "abbrev.el")
|
||||
async-byte-compile-log-file (concat doom-etc-dir "async-bytecomp.log")
|
||||
bookmark-default-file (concat doom-etc-dir "bookmarks")
|
||||
custom-file (concat doom-private-dir "init.el")
|
||||
custom-file (concat doom-local-dir "custom.el")
|
||||
custom-theme-directory (concat doom-private-dir "themes/")
|
||||
desktop-dirname (concat doom-etc-dir "desktop")
|
||||
desktop-base-file-name "autosave"
|
||||
|
@ -210,7 +215,6 @@ users).")
|
|||
tramp-auto-save-directory (concat doom-cache-dir "tramp-auto-save/")
|
||||
tramp-backup-directory-alist backup-directory-alist
|
||||
tramp-persistency-file-name (concat doom-cache-dir "tramp-persistency.el")
|
||||
tramp-histfile-override (concat doom-cache-dir "tramp-histfile.el")
|
||||
url-cache-directory (concat doom-cache-dir "url/")
|
||||
url-configuration-directory (concat doom-etc-dir "url/")
|
||||
gamegrid-user-score-file-directory (concat doom-etc-dir "games/"))
|
||||
|
@ -227,7 +231,8 @@ users).")
|
|||
;; 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.
|
||||
(setq-default bidi-display-reordering 'left-to-right)
|
||||
(setq-default bidi-display-reordering 'left-to-right
|
||||
bidi-paragraph-direction 'left-to-right)
|
||||
|
||||
;; Reduce rendering/line scan work for Emacs by not rendering cursors or regions
|
||||
;; in non-focused windows.
|
||||
|
@ -246,8 +251,8 @@ users).")
|
|||
;; Don't ping things that look like domain names.
|
||||
(setq ffap-machine-p-known 'reject)
|
||||
|
||||
;; Performance on Windows is considerably worse than elsewhere. We'll need
|
||||
;; everything we can get.
|
||||
;; 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)
|
||||
|
@ -257,39 +262,34 @@ users).")
|
|||
;; been determined.
|
||||
(setq inhibit-compacting-font-caches t))
|
||||
|
||||
;; Remove command line options that aren't relevant to our current OS; that
|
||||
;; means less to process at startup.
|
||||
;; Remove command line options that aren't relevant to our current OS; means
|
||||
;; slightly less to process at startup.
|
||||
(unless IS-MAC (setq command-line-ns-option-alist nil))
|
||||
(unless IS-LINUX (setq command-line-x-option-alist nil))
|
||||
|
||||
;; Restore `file-name-handler-alist' because it is necessary for handling
|
||||
;; encrypted or compressed files, among other things.
|
||||
(defun doom-restore-file-name-handler-alist-h ()
|
||||
(setq file-name-handler-alist doom--initial-file-name-handler-alist))
|
||||
(add-hook 'emacs-startup-hook #'doom-restore-file-name-handler-alist-h)
|
||||
;; Delete files to trash on macOS, as an extra layer of precaution against
|
||||
;; accidentally deleting wanted files.
|
||||
(setq delete-by-moving-to-trash IS-MAC)
|
||||
|
||||
;; To speed up minibuffer commands (like helm and ivy), we defer garbage
|
||||
;; collection while the minibuffer is active.
|
||||
(defun doom-defer-garbage-collection-h ()
|
||||
"Increase `gc-cons-threshold' to stave off garbage collection."
|
||||
(setq gc-cons-threshold most-positive-fixnum))
|
||||
;; 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
|
||||
(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
|
||||
(add-hook 'focus-out-hook #'gcmh-idle-garbage-collect)))
|
||||
|
||||
(defun doom-restore-garbage-collection-h ()
|
||||
"Restore `gc-cons-threshold' to a reasonable value so the GC can do its job."
|
||||
;; Defer it so that commands launched immediately after will enjoy the
|
||||
;; benefits.
|
||||
(run-at-time
|
||||
1 nil (lambda () (setq gc-cons-threshold doom-gc-cons-threshold))))
|
||||
|
||||
(add-hook 'minibuffer-setup-hook #'doom-defer-garbage-collection-h)
|
||||
(add-hook 'minibuffer-exit-hook #'doom-restore-garbage-collection-h)
|
||||
|
||||
;; Not restoring these to their defaults will cause stuttering/freezes.
|
||||
(add-hook 'emacs-startup-hook #'doom-restore-garbage-collection-h)
|
||||
|
||||
;; When Emacs loses focus seems like a great time to do some garbage collection
|
||||
;; all sneaky breeky like, so we can return to a fresh(er) Emacs.
|
||||
(add-hook 'focus-out-hook #'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)
|
||||
(advice-add #'tty-run-terminal-initialization :override #'ignore)
|
||||
(add-hook! 'window-setup-hook
|
||||
(defun doom-init-tty-h ()
|
||||
(advice-remove #'tty-run-terminal-initialization #'ignore)
|
||||
(tty-run-terminal-initialization (selected-frame) nil t))))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -396,9 +396,7 @@ If this is a daemon session, load them all immediately instead."
|
|||
;;; Bootstrap helpers
|
||||
|
||||
(defun doom-try-run-hook (hook)
|
||||
"Run HOOK (a hook function), but handle errors better, to make debugging
|
||||
issues easier.
|
||||
|
||||
"Run HOOK (a hook function) with better error handling.
|
||||
Meant to be used with `run-hook-wrapped'."
|
||||
(doom-log "Running doom hook: %s" hook)
|
||||
(condition-case e
|
||||
|
@ -421,27 +419,29 @@ If RETURN-P, return the message as a string instead of displaying it."
|
|||
(setq doom-init-time
|
||||
(float-time (time-subtract (current-time) before-init-time))))))
|
||||
|
||||
(defun doom-load-autoloads-file (file)
|
||||
"Tries to load FILE (an autoloads file). Return t on success, throws an error
|
||||
in interactive sessions, nil otherwise (but logs a warning)."
|
||||
(defun doom-load-autoloads-file (file &optional noerror)
|
||||
"Tries to load FILE (an autoloads file).
|
||||
Return t on success, nil otherwise (but logs a warning)."
|
||||
(condition-case e
|
||||
(let (command-switch-alist)
|
||||
(load (substring file 0 -3) 'noerror 'nomessage))
|
||||
(load (substring file 0 -3) noerror 'nomessage)
|
||||
((debug error)
|
||||
(message "Autoload file error: %s -> %s" (file-name-nondirectory file) e)
|
||||
nil)))
|
||||
|
||||
(defun doom-load-envvars-file (file &optional noerror)
|
||||
"Read and set envvars from FILE."
|
||||
"Read and set envvars from FILE.
|
||||
If NOERROR is non-nil, don't throw an error if the file doesn't exist or is
|
||||
unreadable. Returns the names of envvars that were changed."
|
||||
(if (not (file-readable-p file))
|
||||
(unless noerror
|
||||
(signal 'file-error (list "Couldn't read envvar file" file)))
|
||||
(let (environment)
|
||||
(let (envvars environment)
|
||||
(with-temp-buffer
|
||||
(save-excursion
|
||||
(insert "\n")
|
||||
(insert-file-contents file))
|
||||
(while (re-search-forward "\n *\\([^#= \n]*\\)=" nil t)
|
||||
(push (match-string 1) envvars)
|
||||
(push (buffer-substring
|
||||
(match-beginning 1)
|
||||
(1- (or (save-excursion
|
||||
|
@ -450,24 +450,26 @@ in interactive sessions, nil otherwise (but logs a warning)."
|
|||
(point-max))))
|
||||
environment)))
|
||||
(when environment
|
||||
(setq-default
|
||||
process-environment (nreverse environment)
|
||||
exec-path (append (parse-colon-path (getenv "PATH"))
|
||||
(list exec-directory))
|
||||
shell-file-name (or (getenv "SHELL")
|
||||
shell-file-name))
|
||||
process-environment))))
|
||||
(setq process-environment
|
||||
(append (nreverse environment) process-environment)
|
||||
exec-path
|
||||
(if (member "PATH" envvars)
|
||||
(append (split-string (getenv "PATH") path-separator t)
|
||||
(list exec-directory))
|
||||
exec-path)
|
||||
shell-file-name
|
||||
(if (member "SHELL" envvars)
|
||||
(or (getenv "SHELL") shell-file-name)
|
||||
shell-file-name))
|
||||
envvars))))
|
||||
|
||||
(defun doom-initialize (&optional force-p)
|
||||
(defun doom-initialize (&optional force-p noerror)
|
||||
"Bootstrap Doom, if it hasn't already (or if FORCE-P is non-nil).
|
||||
|
||||
The bootstrap process involves making sure 1) the essential directories exist,
|
||||
2) the core packages are installed, 3) `doom-autoload-file' and
|
||||
`doom-package-autoload-file' exist and have been loaded, and 4) Doom's core
|
||||
files are loaded.
|
||||
|
||||
If the cache exists, much of this function isn't run, which substantially
|
||||
reduces startup time.
|
||||
The bootstrap process ensures that the essential directories exist, all core
|
||||
packages are installed, `doom-autoload-file' and `doom-package-autoload-file'
|
||||
exist and are loaded, and that `core-packages' is auto-loaded when `package' or
|
||||
`straight' are.
|
||||
|
||||
The overall load order of Doom is as follows:
|
||||
|
||||
|
@ -496,7 +498,9 @@ to least)."
|
|||
load-path doom--initial-load-path
|
||||
process-environment doom--initial-process-environment)
|
||||
|
||||
;; Load shell environment, optionally generated from 'doom env'
|
||||
;; Load shell environment, optionally generated from 'doom env'. No need to
|
||||
;; do so if we're in terminal Emacs, because Emacs will correctly inherit
|
||||
;; your shell environment there.
|
||||
(when (and (or (display-graphic-p)
|
||||
(daemonp))
|
||||
(file-exists-p doom-env-file))
|
||||
|
@ -506,12 +510,12 @@ to least)."
|
|||
(let (;; `doom-autoload-file' tells Emacs where to load all its functions
|
||||
;; from. This includes everything in core/autoload/*.el and autoload
|
||||
;; files in enabled modules.
|
||||
(core-autoloads-p (doom-load-autoloads-file doom-autoload-file))
|
||||
(core-autoloads-p (doom-load-autoloads-file doom-autoload-file noerror))
|
||||
;; Loads `doom-package-autoload-file', which loads a concatenated
|
||||
;; package autoloads file which caches `load-path', `auto-mode-alist',
|
||||
;; `Info-directory-list', and `doom-disabled-packages'. A big
|
||||
;; reduction in startup time.
|
||||
(pkg-autoloads-p (doom-load-autoloads-file doom-package-autoload-file)))
|
||||
(pkg-autoloads-p (doom-load-autoloads-file doom-package-autoload-file noerror)))
|
||||
|
||||
(if (and core-autoloads-p pkg-autoloads-p (not force-p))
|
||||
;; In case we want to use package.el or straight via M-x
|
||||
|
@ -522,12 +526,17 @@ to least)."
|
|||
(require 'core-packages)
|
||||
(doom-initialize-packages)))
|
||||
|
||||
;; Eagerly load these libraries because we may be in a session that hasn't been
|
||||
;; fully initialized (e.g. where autoloads files haven't been generated or
|
||||
;; `load-path' populated).
|
||||
(mapc (doom-rpartial #'load nil (not doom-debug-mode) 'nosuffix)
|
||||
(file-expand-wildcards (concat doom-core-dir "autoload/*.el")))
|
||||
|
||||
;; Create all our core directories to quell file errors
|
||||
(dolist (dir (list doom-local-dir
|
||||
doom-etc-dir
|
||||
doom-cache-dir))
|
||||
(unless (file-directory-p dir)
|
||||
(make-directory dir 'parents)))
|
||||
(mapc (doom-rpartial #'make-directory 'parents)
|
||||
(list doom-local-dir
|
||||
doom-etc-dir
|
||||
doom-cache-dir))
|
||||
|
||||
;; Ensure the package management system (and straight) are ready for
|
||||
;; action (and all core packages/repos are installed)
|
||||
|
@ -535,13 +544,16 @@ to least)."
|
|||
(doom-initialize-packages force-p))
|
||||
|
||||
(unless (or (and core-autoloads-p pkg-autoloads-p)
|
||||
force-p
|
||||
(not doom-interactive-mode))
|
||||
noerror)
|
||||
(unless core-autoloads-p
|
||||
(warn "Your Doom core autoloads file is missing"))
|
||||
(unless pkg-autoloads-p
|
||||
(warn "Your package autoloads file is missing"))
|
||||
(signal 'doom-autoload-error (list "Run `bin/doom refresh' to generate them"))))
|
||||
(signal 'doom-autoload-error (list "Run `bin/doom refresh' to generate them")))
|
||||
|
||||
(when doom-interactive-mode
|
||||
(add-hook 'window-setup-hook #'doom-display-benchmark-h 'append)
|
||||
(add-to-list 'command-switch-alist (cons "--restore" #'doom-restore-session-handler))))
|
||||
t))
|
||||
|
||||
(defun doom-initialize-core ()
|
||||
|
|
|
@ -2,39 +2,46 @@
|
|||
;;; core/packages.el
|
||||
|
||||
;; core.el
|
||||
(package! dotenv-mode)
|
||||
(package! auto-minor-mode)
|
||||
(package! auto-minor-mode :pin "17cfa1b548")
|
||||
(package! gcmh :pin "8867533a73")
|
||||
|
||||
;; core-ui.el
|
||||
(package! all-the-icons)
|
||||
(package! hide-mode-line)
|
||||
(package! highlight-numbers)
|
||||
(package! rainbow-delimiters)
|
||||
(package! restart-emacs)
|
||||
(package! all-the-icons :pin "1416f37984")
|
||||
(package! hide-mode-line :pin "88888825b5")
|
||||
(package! highlight-numbers :pin "8b4744c7f4")
|
||||
(package! rainbow-delimiters :pin "5125f4e476")
|
||||
(package! restart-emacs :pin "9aa90d3df9")
|
||||
|
||||
;; core-editor.el
|
||||
(package! better-jumper)
|
||||
(package! dtrt-indent)
|
||||
(package! helpful)
|
||||
(package! ns-auto-titlebar :ignore (not IS-MAC))
|
||||
(package! pcre2el)
|
||||
(package! smartparens)
|
||||
(package! better-jumper :pin "6d240032ca")
|
||||
(package! dtrt-indent :pin "48221c928b")
|
||||
(package! helpful :pin "c54e9ddbd6")
|
||||
(when IS-MAC
|
||||
(package! ns-auto-titlebar :pin "1efc30d385"))
|
||||
(package! pcre2el :pin "0b5b2a2c17")
|
||||
(package! smartparens :pin "be8d5c9a63")
|
||||
(package! so-long
|
||||
:built-in 'prefer
|
||||
:built-in 'prefer ; included in Emacs 27+
|
||||
;; REVIEW so-long is slated to be published to ELPA eventually, but until then
|
||||
;; I've created my own mirror for it because git.savannah.gnu.org runs on a
|
||||
;; potato.
|
||||
:recipe (:host github :repo "hlissner/emacs-so-long"))
|
||||
(package! undo-tree
|
||||
;; Version 0.6.5 is on ELPA which lacks a fix we need, so we install 0.6.6
|
||||
;; from emacsmirror/undo-tree instead.
|
||||
:recipe (:host github :repo "emacsmirror/undo-tree"))
|
||||
(package! ws-butler)
|
||||
(package! xclip)
|
||||
;; I've created my own mirror for it because git.savannah.gnu.org runs
|
||||
;; 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")
|
||||
(unless IS-WINDOWS
|
||||
(package! xclip :pin "d022cf947d"))
|
||||
|
||||
;; core-projects.el
|
||||
(package! projectile)
|
||||
(package! projectile :pin "341150c0e7")
|
||||
|
||||
;; core-keybinds.el
|
||||
(package! general)
|
||||
(package! which-key)
|
||||
(package! general :pin "f6e928622d")
|
||||
(package! which-key :pin "7b068f3e95")
|
||||
|
||||
;; autoload/cache.el
|
||||
(package! persistent-soft :pin "a1e0ddf2a1")
|
||||
|
|
|
@ -15,7 +15,7 @@ Before you doom yourself, there are a few things you should know:
|
|||
give you clues about what is wrong.
|
||||
|
||||
3. Use `bin/doom upgrade` to update Doom. Doing it any other way may require
|
||||
additional work. When in doubt, run `bin/doom refresh`.
|
||||
additional work. When in doubt, run `bin/doom sync`.
|
||||
|
||||
4. Check out `bin/doom help` to see what else `bin/doom` can do (and it is
|
||||
recommended you add ~/.emacs.d/bin to your PATH).
|
||||
|
|
53
core/templates/config.example.el
Normal file
53
core/templates/config.example.el
Normal file
|
@ -0,0 +1,53 @@
|
|||
;;; $DOOMDIR/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; Place your private configuration here! Remember, you do not need to run 'doom
|
||||
;; sync' after modifying this file!
|
||||
|
||||
|
||||
;; Some functionality uses this to identify you, e.g. GPG configuration, email
|
||||
;; clients, file templates and snippets.
|
||||
(setq user-full-name "John Doe"
|
||||
user-mail-address "john@doe.com")
|
||||
|
||||
;; Doom exposes five (optional) variables for controlling fonts in Doom. Here
|
||||
;; are the three important ones:
|
||||
;;
|
||||
;; + `doom-font'
|
||||
;; + `doom-variable-pitch-font'
|
||||
;; + `doom-big-font' -- used for `doom-big-font-mode'; use this for
|
||||
;; presentations or streaming.
|
||||
;;
|
||||
;; They all accept either a font-spec, font string ("Input Mono-12"), or xlfd
|
||||
;; font string. You generally only need these two:
|
||||
(setq doom-font (font-spec :family "monospace" :size 14))
|
||||
|
||||
;; There are two ways to load a theme. Both assume the theme is installed and
|
||||
;; available. You can either set `doom-theme' or manually load a theme with the
|
||||
;; `load-theme' function. This is the default:
|
||||
(setq doom-theme 'doom-one)
|
||||
|
||||
;; If you use `org' and don't want your org files in the default location below,
|
||||
;; change `org-directory'. It must be set before org loads!
|
||||
(setq org-directory "~/org/")
|
||||
|
||||
;; This determines the style of line numbers in effect. If set to `nil', line
|
||||
;; numbers are disabled. For relative line numbers, set this to `relative'.
|
||||
(setq display-line-numbers-type t)
|
||||
|
||||
|
||||
;; Here are some additional functions/macros that could help you configure Doom:
|
||||
;;
|
||||
;; - `load!' for loading external *.el files relative to this one
|
||||
;; - `use-package' for configuring packages
|
||||
;; - `after!' for running code after a package has loaded
|
||||
;; - `add-load-path!' for adding directories to the `load-path', relative to
|
||||
;; this file. Emacs searches the `load-path' when you load packages with
|
||||
;; `require' or `use-package'.
|
||||
;; - `map!' for binding new keys
|
||||
;;
|
||||
;; To get information about any of these functions/macros, move the cursor over
|
||||
;; the highlighted symbol at press 'K' (non-evil users must press 'C-c g k').
|
||||
;; This will open documentation for it, including demos of how they are used.
|
||||
;;
|
||||
;; You can also try 'gd' (or 'C-c g d') to jump to their definition and see how
|
||||
;; they are implemented.
|
51
core/templates/packages.example.el
Normal file
51
core/templates/packages.example.el
Normal file
|
@ -0,0 +1,51 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; $DOOMDIR/packages.el
|
||||
|
||||
;; 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:
|
||||
;(unpin! pinned-package)
|
||||
;; Use it to unpin multiple packages
|
||||
;(unpin! pinned-package another-pinned-package)
|
||||
|
||||
|
||||
;; To install SOME-PACKAGE from MELPA, ELPA or emacsmirror:
|
||||
;(package! some-package)
|
||||
|
||||
;; To install a package directly from a particular repo, you'll need to specify
|
||||
;; a `:recipe'. You'll find documentation on what `:recipe' accepts here:
|
||||
;; https://github.com/raxod502/straight.el#the-recipe-format
|
||||
;(package! another-package
|
||||
; :recipe (:host github :repo "username/repo"))
|
||||
|
||||
;; If the package you are trying to install does not contain a PACKAGENAME.el
|
||||
;; file, or is located in a subdirectory of the repo, you'll need to specify
|
||||
;; `:files' in the `:recipe':
|
||||
;(package! this-package
|
||||
; :recipe (:host github :repo "username/repo"
|
||||
; :files ("some-file.el" "src/lisp/*.el")))
|
||||
|
||||
;; If you'd like to disable a package included with Doom, for whatever reason,
|
||||
;; you can do so here with the `:disable' property:
|
||||
;(package! builtin-package :disable t)
|
||||
|
||||
;; You can override the recipe of a built in package without having to specify
|
||||
;; all the properties for `:recipe'. These will inherit the rest of its recipe
|
||||
;; from Doom or MELPA/ELPA/Emacsmirror:
|
||||
;(package! builtin-package :recipe (:nonrecursive t))
|
||||
;(package! builtin-package-2 :recipe (:repo "myfork/package"))
|
||||
|
||||
;; Specify a `:branch' to install a package from a particular branch or tag.
|
||||
;; This is required for some packages whose default branch isn't 'master' (which
|
||||
;; our package manager can't deal with; see raxod502/straight.el#279)
|
||||
;(package! builtin-package :recipe (:branch "develop"))
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
(eval-and-compile
|
||||
(setq doom-interactive-mode 'test)
|
||||
(doom-initialize 'force)
|
||||
(doom-initialize 'force 'noerror)
|
||||
(require 'buttercup)
|
||||
(setq split-width-threshold 0
|
||||
split-height-threshold 0
|
||||
|
|
|
@ -101,12 +101,6 @@
|
|||
(expect (appendq! list '(d e f))
|
||||
:to-equal '(a b c d e f)))))
|
||||
|
||||
(describe "nconcq!"
|
||||
(it "nconc's a list to a list symbol"
|
||||
(let ((list '(a b c)))
|
||||
(expect (nconcq! list '(d e f))
|
||||
:to-equal '(a b c d e f)))))
|
||||
|
||||
(describe "delq!"
|
||||
(it "delete's a symbol from a list"
|
||||
(let ((list '(a b c)))
|
||||
|
|
|
@ -13,15 +13,15 @@
|
|||
(setq doom-init-p nil))
|
||||
|
||||
(it "initializes once"
|
||||
(expect (doom-initialize))
|
||||
(expect (not (doom-initialize)))
|
||||
(expect (not (doom-initialize)))
|
||||
(expect (doom-initialize nil 'noerror))
|
||||
(expect (not (doom-initialize nil 'noerror)))
|
||||
(expect (not (doom-initialize nil 'noerror)))
|
||||
(expect doom-init-p))
|
||||
|
||||
(it "initializes multiple times, if forced"
|
||||
(expect (doom-initialize))
|
||||
(expect (not (doom-initialize)))
|
||||
(expect (doom-initialize 'force)))
|
||||
(expect (doom-initialize nil 'noerror))
|
||||
(expect (not (doom-initialize nil 'noerror)))
|
||||
(expect (doom-initialize 'force 'noerror)))
|
||||
|
||||
(describe "package initialization"
|
||||
(before-each
|
||||
|
@ -29,18 +29,18 @@
|
|||
|
||||
(it "initializes packages if core autoload file doesn't exist"
|
||||
(let ((doom-autoload-file "doesnotexist"))
|
||||
(doom-initialize))
|
||||
(expect (doom-initialize nil 'noerror))
|
||||
(expect 'doom-initialize-packages :to-have-been-called))
|
||||
|
||||
(it "doesn't initialize packages if core autoload file was loaded"
|
||||
(let ((doom-interactive-mode t))
|
||||
(spy-on 'doom-load-autoloads-file :and-return-value t)
|
||||
(doom-initialize)
|
||||
(doom-initialize nil 'noerror)
|
||||
(expect 'doom-load-autoloads-file :to-have-been-called-with doom-package-autoload-file)
|
||||
(expect 'doom-initialize-packages :to-have-been-called)))
|
||||
|
||||
(it "initializes packages when forced"
|
||||
(doom-initialize 'force)
|
||||
(doom-initialize 'force 'noerror)
|
||||
(expect 'doom-initialize-packages :to-have-been-called)))
|
||||
|
||||
(describe "autoloads files"
|
||||
|
@ -49,15 +49,14 @@
|
|||
(spy-on 'warn :and-return-value t))
|
||||
|
||||
(it "loads autoloads files"
|
||||
(ignore-errors (doom-initialize))
|
||||
(ignore-errors (doom-initialize nil 'noerror))
|
||||
(expect 'doom-load-autoloads-file
|
||||
:to-have-been-called-with doom-autoload-file)
|
||||
(expect 'doom-load-autoloads-file
|
||||
:to-have-been-called-with doom-package-autoload-file))
|
||||
|
||||
(it "throws doom-autoload-error in interactive session where autoload files don't exist"
|
||||
(let ((doom-interactive-mode t)
|
||||
(doom-autoload-file "doesnotexist")
|
||||
(it "throws doom-autoload-error when autoload files don't exist"
|
||||
(let ((doom-autoload-file "doesnotexist")
|
||||
(doom-package-autoload-file "doesnotexist"))
|
||||
(expect (doom-initialize) :to-throw 'doom-autoload-error)))))
|
||||
|
||||
|
@ -117,7 +116,7 @@
|
|||
|
||||
(it "returns the new value for `process-environment'"
|
||||
(expect (doom-load-envvars-file doom-env-file)
|
||||
:to-equal '("A=1" "B=2" "C=3")))
|
||||
:to-have-same-items-as '("A" "B" "C")))
|
||||
|
||||
(it "alters environment variables"
|
||||
(dolist (key '("A" "B" "C"))
|
||||
|
|
146
docs/api.org
146
docs/api.org
|
@ -5,11 +5,12 @@ This appendix serves as a reference on how to use Doom Emacs' standard library.
|
|||
It is integrated into Helpful, in Doom.
|
||||
|
||||
* Table of Contents :TOC_3:
|
||||
- [[#examples-for-dooms-core-library][Examples for Doom's core library]]
|
||||
- [[#examples-for-dooms-library][Examples for Doom's library]]
|
||||
- [[#core-lib][core-lib]]
|
||||
- [[#add-hook][add-hook!]]
|
||||
- [[#add-transient-hook][add-transient-hook!]]
|
||||
- [[#after][after!]]
|
||||
- [[#appendq][appendq!]]
|
||||
- [[#custom-set-faces][custom-set-faces!]]
|
||||
- [[#custom-theme-set-faces][custom-theme-set-faces!]]
|
||||
- [[#defer-feature][defer-feature!]]
|
||||
|
@ -19,21 +20,24 @@ It is integrated into Helpful, in Doom.
|
|||
- [[#file-exists-p][file-exists-p!]]
|
||||
- [[#lambda][lambda!]]
|
||||
- [[#lambda-1][lambda!!]]
|
||||
- [[#letenv][letenv!]]
|
||||
- [[#load][load!]]
|
||||
- [[#map][map!]]
|
||||
- [[#package][package!]]
|
||||
- [[#pushnew][pushnew!]]
|
||||
- [[#prependq][prependq!]]
|
||||
- [[#quiet][quiet!]]
|
||||
- [[#remove-hook][remove-hook!]]
|
||||
- [[#setq][setq!]]
|
||||
- [[#setq-hook][setq-hook!]]
|
||||
- [[#unsetq-hook][unsetq-hook!]]
|
||||
- [[#use-package][use-package!]]
|
||||
- [[#interesting-snippets][Interesting snippets]]
|
||||
- [[#persist-emacs-initial-frame-size-across-sessions][Persist Emacs' initial frame size across sessions]]
|
||||
- [[#center-emacs-initial-frame-with-a-fixed-size][Center Emacs' initial frame with a fixed size]]
|
||||
- [[#persist-emacs-initial-frame-position-dimensions-andor-full-screen-state-across-sessions][Persist Emacs' initial frame position, dimensions and/or full-screen state across sessions]]
|
||||
- [[#update-cursor-shape-under-terminal-emacs][Update cursor shape under terminal Emacs]]
|
||||
|
||||
* Examples for Doom's core library
|
||||
* Examples for Doom's library
|
||||
** core-lib
|
||||
*** add-hook!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
|
@ -90,6 +94,26 @@ It is integrated into Helpful, in Doom.
|
|||
(after! rustic ...)
|
||||
(after! python ...)
|
||||
#+END_SRC
|
||||
*** appendq!
|
||||
#+BEGIN_SRC elisp
|
||||
(let ((x '(a b c)))
|
||||
(appendq! x '(c d e))
|
||||
x)
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
: (a b c c d e)
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
(let ((x '(a b c))
|
||||
(y '(c d e))
|
||||
(z '(f g)))
|
||||
(appendq! x y z '(h))
|
||||
x)
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
: (a b c c d e f g h)
|
||||
|
||||
*** custom-set-faces!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
|
@ -214,8 +238,47 @@ It is integrated into Helpful, in Doom.
|
|||
#+RESULTS:
|
||||
: /home/hlissner/.emacs.d/LICENSE
|
||||
|
||||
*** TODO lambda!
|
||||
*** TODO lambda!!
|
||||
*** lambda!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
(map! "C-j" (lambda! (newline) (indent-according-to-mode)))
|
||||
|
||||
;; The `λ!' short-form alias exists. If you have the snippets module enabled and
|
||||
;; Doom's default snippets, the 'lam' snippet will expand into 'λ!'. Otherwise,
|
||||
;; you can use `lambda!'.
|
||||
(map! "C-j" (λ! (newline) (indent-according-to-mode)))
|
||||
#+END_SRC
|
||||
*** lambda!!
|
||||
When ~newline~ is passed a numerical prefix argument (=C-u 5 M-x newline=), it
|
||||
inserts N newlines. We can use ~lambda!!~ to easily create a keybinds that bakes
|
||||
in the prefix arg into the command call:
|
||||
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
(map! "C-j" (lambda!! #'newline 5))
|
||||
|
||||
;; The `λ!!' short-form alias exists. If you have the snippets module enabled
|
||||
;; and Doom's default snippets, a 'lam' snippet is available to expand into
|
||||
;; 'λ!'. Otherwise, you can use `lambda!!'.
|
||||
(map! "C-j" (λ!! #'newline 5))
|
||||
#+END_SRC
|
||||
|
||||
Or to create aliases for functions that behave differently:
|
||||
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
(fset 'insert-5-newlines (lambda!! #'newline 5))
|
||||
|
||||
;; The equivalent of C-u M-x org-global-cycle, which resets the org document to
|
||||
;; its startup visibility settings.
|
||||
(fset 'org-reset-global-visibility (lambda!! #'org-global-cycle '(4))
|
||||
#+END_SRC
|
||||
*** letenv!
|
||||
#+BEGIN_SRC elisp
|
||||
(letenv! (("SHELL" "/bin/sh"))
|
||||
(shell-command-to-string "echo $SHELL"))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
: "/bin/sh\n"
|
||||
|
||||
*** load!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
;;; Lets say we're in ~/.doom.d/config.el
|
||||
|
@ -269,9 +332,9 @@ These are side-by-side comparisons, showing how to bind keys with and without
|
|||
(map! :map lua-mode-map "SPC m b" nil)
|
||||
|
||||
;; bind multiple keys
|
||||
(global-set-key "C-x x" #'do-something)
|
||||
(global-set-key "C-x y" #'do-something-else)
|
||||
(global-set-key "C-x z" #'do-another-thing)
|
||||
(global-set-key (kbd "C-x x") #'do-something)
|
||||
(global-set-key (kbd "C-x y") #'do-something-else)
|
||||
(global-set-key (kbd "C-x z") #'do-another-thing)
|
||||
(map! "C-x x" #'do-something
|
||||
"C-x y" #'do-something-else
|
||||
"C-x z" #'do-another-thing)
|
||||
|
@ -325,7 +388,7 @@ These are side-by-side comparisons, showing how to bind keys with and without
|
|||
*** package!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
;; To install a package that can be found on ELPA or any of the sources
|
||||
;; specified in `doom-core-package-sources':
|
||||
;; specified in `straight-recipe-repositories':
|
||||
(package! evil)
|
||||
(package! js2-mode)
|
||||
(package! rainbow-delimiters)
|
||||
|
@ -342,22 +405,49 @@ These are side-by-side comparisons, showing how to bind keys with and without
|
|||
;; you can tell the package manager not to clone the repo recursively:
|
||||
(package! ansible :recipe (:nonrecursive t))
|
||||
|
||||
;; To install a particular branch, commit or tag:
|
||||
(package! evil
|
||||
;; if :host and :fetcher aren't specified, the package manager will fall back
|
||||
;; to evil's default source provided by their (M)ELPA recipes:
|
||||
:recipe (:commit "e7bc39de2f961505e8e112da8c1b315ae8afce52"))
|
||||
|
||||
;; To pin a package to a specific commit:
|
||||
(package! evil :pin "e7bc39de2f9")
|
||||
;; ...or branch:
|
||||
(package! evil :recipe (:branch "stable"))
|
||||
|
||||
(package! evil :recipe (:tag "1.2.9"))
|
||||
;; To unpin a pinned package:
|
||||
(package! evil :pin nil)
|
||||
|
||||
;; If you share your config between two computers, and don't want bin/doom
|
||||
;; refresh to delete packages used only on one system, use :ignore
|
||||
(package! evil :ignore (not (equal system-name "my-desktop")))
|
||||
#+END_SRC
|
||||
|
||||
*** TODO pushnew!
|
||||
*** pushnew!
|
||||
#+BEGIN_SRC elisp
|
||||
(let ((list '(a b c)))
|
||||
(pushnew! list 'c 'd 'e)
|
||||
list)
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
: (e d a b c)
|
||||
|
||||
*** prependq!
|
||||
#+BEGIN_SRC elisp
|
||||
(let ((x '(a b c)))
|
||||
(prependq! x '(c d e))
|
||||
x)
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
: (c d e a b c)
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
(let ((x '(a b c))
|
||||
(y '(c d e))
|
||||
(z '(f g)))
|
||||
(prependq! x y z '(h))
|
||||
x)
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
: (c d e f g h a b c)
|
||||
|
||||
*** quiet!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
;; Enters recentf-mode without extra output
|
||||
|
@ -381,6 +471,14 @@ These are side-by-side comparisons, showing how to bind keys with and without
|
|||
;; Removing arbitrary forms (must be exactly the same as the definition)
|
||||
(remove-hook! (one-mode second-mode) (setq v 5) (setq a 2))
|
||||
#+END_SRC
|
||||
*** setq!
|
||||
#+BEGIN_SRC elisp
|
||||
;; Each of these have a setter associated with them, which must be triggered in
|
||||
;; order for their new values to have an effect.
|
||||
(setq! evil-want-Y-yank-to-eol nil
|
||||
evil-want-C-u-scroll nil
|
||||
evil-want-C-d-scroll nil)
|
||||
#+END_SRC
|
||||
*** setq-hook!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
;; Set multiple variables after a hook
|
||||
|
@ -423,15 +521,15 @@ These are side-by-side comparisons, showing how to bind keys with and without
|
|||
:defer-incrementally t)
|
||||
#+END_SRC
|
||||
* Interesting snippets
|
||||
** Persist Emacs' initial frame size across sessions
|
||||
** Center Emacs' initial frame with a fixed size
|
||||
#+BEGIN_SRC elisp
|
||||
(let ((display-height (display-pixel-height))
|
||||
(display-width (display-pixel-width)))
|
||||
(add-to-list 'initial-frame-alist
|
||||
`((left . ,(/ new-frame-width 2))
|
||||
(top . ,(/ new-frame-height 2))
|
||||
(width . ,(/ display-width 2))
|
||||
(height . ,(/ display-height 2)))))
|
||||
(pushnew! initial-frame-alist
|
||||
`(left . ,(/ display-width 2))
|
||||
`(top . ,(/ display-height 2))
|
||||
`(width . ,display-width)
|
||||
`(height . ,display-height)))
|
||||
#+END_SRC
|
||||
|
||||
** Persist Emacs' initial frame position, dimensions and/or full-screen state across sessions
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#+TITLE: Contributing
|
||||
#+STARTUP: nofold
|
||||
|
||||
I can't say Doom Emacs is a one man show anymore. It wouldn't have gotten this
|
||||
far without the help of folks like you! Still, I struggle to maintain it all;
|
||||
especially the modules I do not use. If Doom has been useful to you, consider
|
||||
pitching in and helping me out.
|
||||
Doom Emacs is an active and ongoing project, maintained mostly by a single
|
||||
person, but includes the efforts of 200 contributors and growing. There is no
|
||||
shortage of things that need doing; bugs that need stomping, features that need
|
||||
implementing, and documentation that needs documenting. If Doom's been useful to
|
||||
you, convert some caffiene into code; it'd be a huge help!
|
||||
|
||||
Help can range from reporting bugs, proposing enhancements, submitting code and
|
||||
documentation, or just spreading the good word. To ensure no toes get stepped on
|
||||
or wires crossed, this guide was created to help you help us.
|
||||
You are welcome to [[https://discord.gg/qvGgnVx][join us on our Discord server]], otherwise read on to learn how
|
||||
to contribute to our fine corner of the interwebs.
|
||||
|
||||
* Table of Contents :TOC_3:
|
||||
- [[#where-can-i-help][Where can I help?]]
|
||||
|
@ -32,19 +32,20 @@ or wires crossed, this guide was created to help you help us.
|
|||
- [[#contributing-documentation][Contributing documentation]]
|
||||
- [[#contributing-to-dooms-manual][Contributing to Doom's manual]]
|
||||
- [[#contributing-module-documentation][Contributing module documentation]]
|
||||
- [[#help-keep-packages-up-to-date][Help keep packages up-to-date!]]
|
||||
- [[#other-ways-to-support-doom-emacs][Other ways to support Doom Emacs]]
|
||||
- [[#special-thanks][Special thanks]]
|
||||
|
||||
* Where can I help?
|
||||
+ Our [[https://github.com/hlissner/doom-emacs/issues][issue tracker]] has many issues. If you find one that you have an answer to,
|
||||
please don't hold back!
|
||||
it would be a huge help!
|
||||
+ Look for issues tagged [[https://github.com/hlissner/doom-emacs/labels/good%20first%20issue][good first issue]]. These were judged to have a low
|
||||
barrier of entry.
|
||||
+ Look for issues tagged [[https://github.com/hlissner/doom-emacs/labels/help%20wanted][help wanted]]. These tend to be a little (or a lot)
|
||||
harder, and are issues outside my own expertise.
|
||||
+ If you've encountered a bug, [[https://github.com/hlissner/doom-emacs/issues/new/choose][file a bug report]].
|
||||
+ The [[https://github.com/hlissner/doom-emacs/projects/3][development roadmap board]] is a rough timeline of what is being worked on
|
||||
and when. It will give you some idea of what will change and where you can
|
||||
and when. It will give you an idea of what will change and where you can
|
||||
redirect your efforts.
|
||||
+ The [[https://github.com/hlissner/doom-emacs/projects/2][plugins under review board]] lists third party plugins being considered (or
|
||||
rejected) for inclusion in Doom Emacs. Approved and unclaimed packages are
|
||||
|
@ -54,30 +55,21 @@ or wires crossed, this guide was created to help you help us.
|
|||
cause) perhaps you can address them at the source.
|
||||
|
||||
* TODO Reporting issues
|
||||
So you've found a problem. Before you fire off that bug report, there are a few
|
||||
things you should try first:
|
||||
You've found a problem and you're ready to fire off that bug report. Hold up!
|
||||
Before you do that, [[file:getting_started.org::*Troubleshoot][have a look at our Troubleshooting guide]]. If none of these
|
||||
suggestions pan out, /then/ it is time to file a bug report.
|
||||
|
||||
+ Make sure your configuration (or Doom Emacs) is *not* byte-compiled. Run ~doom
|
||||
clean~ to ensure it isn't. *Byte-compilation interferes with debugging!*
|
||||
+ Run ~bin/doom refresh~ to ensure all plugins are installed and autoload files
|
||||
generated.
|
||||
+ Run ~bin/doom doctor~ to diagnose common issues with your system.
|
||||
+ Check [[file:faq.org::*Common%20Issues][Common Issues]] in the FAQ to see if yours is a known issue.
|
||||
+ If you happen to know what module(s) are relevant to your issue, check their
|
||||
documentation (press =<leader> h m= to jump to a module's documentation). Your
|
||||
issue may be documented.
|
||||
+ If possible, check if the issue can be reproduced in vanilla Emacs (Emacs
|
||||
without Doom) and/or vanilla Doom (Doom without your private config). To test
|
||||
this, use ~M-x doom/sandbox~ (bound to =<leader> h E=). [[file:getting_started.org::*Use the sandbox][A guide for using the
|
||||
sandbox can be found in the manual]].
|
||||
+ Make sure your issue hasn't already been reported by searching the [[https://github.com/hlissner/doom-emacs/issues][issue
|
||||
tracker]].
|
||||
+ Make sure your issue hasn't been resolved on the =develop= branch of Doom.
|
||||
An effective bug report is informative. Please try to provide:
|
||||
|
||||
If these suggestions haven't worked for you, it's time [[https://github.com/hlissner/doom-emacs/issues/new/choose][to write a bug report]].
|
||||
Please make sure of the following before you submit:
|
||||
+ A backtrace of all mentioned errors.
|
||||
+ A step-by-step reproduction of the issue.
|
||||
+ Information about your Doom config and system environment.
|
||||
+ Screenshots/casts of the issue (if possible).
|
||||
|
||||
** TODO Collect backtraces of any error messages
|
||||
This section will show you how to collect this information.
|
||||
|
||||
** Acquire a backtrace from errors
|
||||
See "[[file:getting_started.org::*How to extract a backtrace from an error][How to extract a backtrace from an error]]" in the [[file:getting_started.org][Getting Started]] guide.
|
||||
|
||||
** TODO Create a step-by-step reproduction guide
|
||||
|
||||
|
@ -165,6 +157,11 @@ contact via our [[https://discord.gg/bcZ6P3y][Discord server]] or [[mailto:henri
|
|||
|
||||
** TODO Contributing module documentation
|
||||
|
||||
* TODO Help keep packages up-to-date!
|
||||
Doom pins all its packages to reduce the likelihood of upstream breakage leaking
|
||||
into Doom Emacs. However, we may miss when a package releases hotfixes for
|
||||
critical issues. Let us know or PR a bump to our pinned packages.
|
||||
|
||||
* TODO Other ways to support Doom Emacs
|
||||
|
||||
* TODO Special thanks
|
||||
|
|
610
docs/faq.org
610
docs/faq.org
|
@ -20,11 +20,6 @@
|
|||
- [[#should-i-fork-doom-to-customize-it][Should I fork Doom to customize it?]]
|
||||
- [[#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-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?]]
|
||||
- [[#how-do-i-change-where-an-existing-package-is-installed-from][How do I change where an existing package is installed from?]]
|
||||
- [[#how-do-i-disable-a-package-completely][How do I disable a package completely?]]
|
||||
- [[#how-do-i-reconfigure-a-package-included-in-doom][How do I reconfigure a package included in Doom?]]
|
||||
- [[#how-do-i-change-the-theme][How do I change the theme?]]
|
||||
- [[#how-do-i-change-the-fonts][How do I change the fonts?]]
|
||||
- [[#how-do-i-bind-my-own-keys-or-change-existing-ones][How do I bind my own keys (or change existing ones)?]]
|
||||
|
@ -32,12 +27,20 @@
|
|||
- [[#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)?]]
|
||||
- [[#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-refresh][When to run ~doom refresh~]]
|
||||
- [[#when-to-run-doom-sync][When to run ~doom sync~]]
|
||||
- [[#how-to-suppress-confirmation-prompts-while-bindoom-is-running][How to suppress confirmation prompts while ~bin/doom~ is running]]
|
||||
- [[#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?]]
|
||||
- [[#how-do-i-change-where-an-existing-package-is-installed-from][How do I change where an existing package is installed from?]]
|
||||
- [[#how-do-i-disable-a-package-completely][How do I disable a package completely?]]
|
||||
- [[#how-do-i-reconfigure-a-package-included-in-doom][How do I reconfigure a package included in Doom?]]
|
||||
- [[#where-does-straight-clonebuild-packages-to][Where does straight clone/build packages to?]]
|
||||
- [[#defaults][Defaults]]
|
||||
- [[#why-ivy-over-helm][Why Ivy over Helm?]]
|
||||
- [[#why-are-there-no-default-keybinds-for-smartparens-for-evil-users][Why are there no default keybinds for Smartparens (for evil users)?]]
|
||||
|
@ -55,34 +58,38 @@
|
|||
- [[#changes-to-my-config-arent-taking-effect][Changes to my config aren't taking effect]]
|
||||
- [[#the-frame-goes-black-on-macos-while-in-full-screen-mode][The frame goes black on MacOS, while in full-screen mode]]
|
||||
- [[#doom-crashes-when][Doom crashes when...]]
|
||||
- [[#cant-load-my-theme-unable-to-find-theme-file-for-x-errors][Can't load my theme; ~unable to find theme file for X~ errors]]
|
||||
- [[#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?]]
|
||||
- [[#contributing][Contributing]]
|
||||
|
||||
* General
|
||||
** Why is it called Doom?
|
||||
An homage to idsoftware's classic game, whose open sourced code was my first
|
||||
exposure to programming.
|
||||
It's an homage to idsoftware's classic game, whose open sourced code was
|
||||
Henrik's (Doom's maintainer) first exposure to programming.
|
||||
|
||||
Also, if you're obsessed enough with a text editor that you write a community
|
||||
config for it, you're doomed from the get go.
|
||||
And if you're obsessed enough with a text editor that you write a community
|
||||
config for it, you're doomed from the start.
|
||||
|
||||
** Does Doom work on Windows?
|
||||
Windows support is weak and will generally lag behind Linux/MacOS support, so
|
||||
your mileage will vary. However, many have reported success installing Doom
|
||||
Emacs on Windows (using WSL, WSL2 or scope/chocolatey). You'll find install
|
||||
instructions for Windows in the [[file:getting_started.org::On Windows][Getting Starting guide]].
|
||||
Windows support is weak and generally lags behind Linux/MacOS support, so your
|
||||
mileage will vary. However, some have reported success using Doom Emacs on
|
||||
Windows (using WSL, WSL2 or scoop/chocolatey). You'll find install instructions
|
||||
in the [[file:getting_started.org::On Windows][Getting Starting guide]].
|
||||
|
||||
If you're a Windows user, help us improve our documentation on Windows support!
|
||||
If you're a Windows user, help us improve our documentation!
|
||||
|
||||
** Is Doom only for vimmers?
|
||||
Henrik is a dyed-in-the-wool vimmer with more than a decade of vim muscle
|
||||
memory. Vim's is the only paradigm he truly knows, so vimmers will always be his
|
||||
primary audience.
|
||||
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.
|
||||
|
||||
That's not to say Doom won't work without evil, only that it is less polished in
|
||||
that respect. Our growing non-evil userbase are slowly improving the situation
|
||||
however. We welcome suggestions and PRs to help accommodate a non-evil workflow.
|
||||
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
|
||||
accommodate a non-evil workflow.
|
||||
|
||||
If you'd still like a go at it, see the [[file:../modules/editor/evil/README.org::Removing%20evil-mode][Removing evil-mode]] section in the
|
||||
If you'd still like a go at it, see the [[file:../modules/editor/evil/README.org::Removing%20evil-mode][removing evil-mode]] section in the
|
||||
[[file:../modules/editor/evil/README.org][:editor evil]] module's documentation.
|
||||
|
||||
** I am a beginner. Can I use Doom?
|
||||
|
@ -115,12 +122,12 @@ To paraphrase (and expand upon) a [[https://www.reddit.com/r/emacs/comments/6pa0
|
|||
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 package management
|
||||
can be scripted on the command line and enables a number of startup
|
||||
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.
|
||||
|
||||
** Why such a complicated package management system?
|
||||
Doom had ++four++ *five* goals for its package management system:
|
||||
Doom had +four+ *five* goals for its package management system:
|
||||
|
||||
1. *Scriptability:* package management should be shell-scriptable, so updating
|
||||
can be automated.
|
||||
|
@ -129,15 +136,15 @@ Doom had ++four++ *five* goals for its package management system:
|
|||
are out-of-date through official channels, have changed hands, have a
|
||||
superior fork, or aren't available in ELPA repos.
|
||||
3. *Performance:* lazy-loading the package management system is a tremendous
|
||||
boon to start up speed. Initializing package.el and quelpa (and/or checking
|
||||
that your packages are installed) every time you start up is expensive.
|
||||
boon to start up speed. Initializing package.el and straight (and/or checking
|
||||
that your packages are installed) each time you start up is expensive.
|
||||
4. *Organization:* an Emacs configuration grows so quickly, in complexity and
|
||||
size. A clear separation of concerns (configuration of packages from their
|
||||
installation) is more organized.
|
||||
5. *Reproducibility:* /This goal hasn't been implemented yet/, but all our work
|
||||
up until now is aimed at this goal. Emacs is a tumultuous ecosystem; packages
|
||||
break left and right, and we rely on hundreds of them. Eventually, we want
|
||||
package versions to be locked to versions of Doom so that Doom installs are
|
||||
package versions to be locked to Doom's releases so that Doom installs are
|
||||
reproducible.
|
||||
|
||||
** How does Doom start up so quickly?
|
||||
|
@ -155,10 +162,10 @@ up ~gc-cons-threshold~ (and perhaps ~gc-cons-percentage~) temporarily:
|
|||
;; ... your emacs config here ...
|
||||
#+END_SRC
|
||||
|
||||
However, it is important to reset it eventually (as late as possible). Not doing
|
||||
so will cause garbage collection freezes during long-term interactive use.
|
||||
Conversely, a ~gc-cons-threshold~ that is too small will cause stuttering. We
|
||||
use 16mb as our default.
|
||||
However, it is important to reset it eventually. Not doing so will cause garbage
|
||||
collection freezes during long-term interactive use. Conversely, a
|
||||
~gc-cons-threshold~ that is too small will cause stuttering. We use 16mb as our
|
||||
default.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(add-hook 'emacs-startup-hook
|
||||
|
@ -185,14 +192,16 @@ helm and ivy). Here is how Doom does it:
|
|||
(add-hook 'minibuffer-exit-hook #'doom-restore-garbage-collection-h)
|
||||
#+END_SRC
|
||||
|
||||
Another alternative (which is [[https://github.com/hlissner/doom-emacs/blob/develop/core/core.el#L269-L274][what Doom uses]]) is to use the [[https://gitlab.com/koral/gcmh/][gcmh]] package to
|
||||
stave off the GC until you are idle or unfocus the Emacs frame.
|
||||
|
||||
*** Unset ~file-name-handler-alist~ temporarily
|
||||
Emacs consults this variable every time a file is read or library loaded, or
|
||||
when certain functions in the file API are used (like ~expand-file-name~ or
|
||||
~file-truename~).
|
||||
|
||||
They do so to check if a special handler is needed to read it, but none of these
|
||||
handlers are necessary for the initialization work we do at startup, so it is
|
||||
generally safe to disable it (temporarily!):
|
||||
Emacs does to check if a special handler is needed to read that file, but none
|
||||
of them are (typically) necessary at startup, so we disable them (temporarily!):
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defvar doom--file-name-handler-alist file-name-handler-alist)
|
||||
|
@ -209,60 +218,38 @@ generally safe to disable it (temporarily!):
|
|||
(setq file-name-handler-alist doom--file-name-handler-alist)))
|
||||
#+END_SRC
|
||||
|
||||
It is important to restore this variable, otherwise you won't be able to use
|
||||
TRAMP and Emacs will be unable to read compressed/encrypted files.
|
||||
|
||||
*** Cut down on ~load-path~ lookups
|
||||
Each ~load~ and ~require~ call (without an second argument) costs an O(n) lookup
|
||||
on ~load-path~. The average Doom config has approximately 260 packages including
|
||||
dependencies, and around 40 built-in packages. That means a minimum of 300
|
||||
entries in ~load-path~ with a worst case of =n=300= for /each/ package load (but
|
||||
realistically, =n= will be somewhere between =2= and =20=).
|
||||
|
||||
The cost isn't great, but it does add up. There isn't much to do about this,
|
||||
except be mindful of it where we can:
|
||||
|
||||
+ Paths in Doom's autoloads file are replaced with absolute ones, thus incurring
|
||||
no lookup cost to lazy load them.
|
||||
+ The ~load!~ macro is used instead of ~require~ where possible. This builds
|
||||
paths with string concatenation (which is baked in at compile time, removing
|
||||
most of the associated cost).
|
||||
+ ~load-path~ is let-bound to a subset of itself where possible (the
|
||||
~doom--initial-load-path~ variable contains the value of ~load-path~ before it
|
||||
was touched by Doom).
|
||||
Don't forget to restore ~file-name-handler-alist~, otherwise TRAMP won't work
|
||||
and compressed/encrypted files won't open.
|
||||
|
||||
*** Concatenate package autoloads
|
||||
When you install a package, a PACKAGE-autoloads.el file is generated. This file
|
||||
contains a map of autoloaded functions and snippets declared by the package
|
||||
(that's what those ~;;;###autoload~ comments are for in packages). They tell
|
||||
Emacs where to find them, when they are eventually called. In your conventional
|
||||
Emacs config, every single one of these autoloads files are loaded immediately
|
||||
at startup.
|
||||
contains a map of autoloaded functions and snippets declared by the package.
|
||||
They tell Emacs where to find them when they are eventually called. In your
|
||||
conventional Emacs config, every one of these autoloads files are loaded
|
||||
immediately at startup (when ~package-initialize~ is called).
|
||||
|
||||
Since you'll commonly have hundreds of packages, loading hundreds of autoloads
|
||||
file can hurt startup times. We get around this by concatenating these autoloads
|
||||
files into one giant one (in =~/.emacs.d/.local/autoloads.pkg.el=) when you run
|
||||
~doom refresh~.
|
||||
file can hurt startup times, especially without an SSD. We get around this by
|
||||
concatenating these files into one giant one when you run ~doom sync~.
|
||||
|
||||
Emacs 27+ will introduce a ~package-quickstart~ feature that will do this for
|
||||
you -- the =straight= package manager does this for you too -- but Doom Emacs
|
||||
has its own specialized mechanism for doing this, and has tacked a number of
|
||||
Doom-specific optimizations on top of it.
|
||||
Emacs 27+ introduces a ~package-quickstart~ command does this for you, and
|
||||
=straight=, our package manager, does this for you too, but [[https://github.com/hlissner/doom-emacs/tree/develop/core/cli/autoloads.el][Doom Emacs has its
|
||||
own specialized mechanism]] for this, topped off with a few Doom-specific
|
||||
optimizations.
|
||||
|
||||
*** Lazy load package management system(s)
|
||||
Initializing package.el or straight.el at startup is expensive. We can save some
|
||||
time by delaying that initialization until we actually need these libraries (and
|
||||
only eagerly load them when we're doing package management, e.g. when we run
|
||||
~doom refresh~).
|
||||
load them only when we're doing package management, e.g. when we run ~doom
|
||||
sync~).
|
||||
|
||||
Among other things, ~doom refresh~ does a lot for us. It generates concatenated
|
||||
Among other things, ~doom sync~ does a lot for us. It generates concatenated
|
||||
autoloads files; caches expensive variables like caches ~load-path~,
|
||||
~Info-directory-list~ and ~auto-mode-alist~; and preforms all your package
|
||||
management activities there -- far away from your interactive sessions.
|
||||
|
||||
How exactly Doom accomplishes all this is a little complex, so instead, here is
|
||||
a boiled-down version you can use in your own configs (for package.el, not
|
||||
straight.el):
|
||||
How exactly Doom accomplishes all this is a long story, so here is a boiled-down
|
||||
version you can use in your own configs (for package.el, not straight.el):
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defvar cache-file "~/.emacs.d/cache/autoloads")
|
||||
|
@ -273,26 +260,12 @@ straight.el):
|
|||
(package-initialize)
|
||||
(with-temp-buffer
|
||||
(cl-pushnew doom-core-dir load-path :test #'string=)
|
||||
(dolist (spec package-alist)
|
||||
(when-let (desc (cdr spec))
|
||||
(let ((file (concat (package--autoloads-file-name desc) ".el")))
|
||||
(when (file-readable-p file)
|
||||
;; Ensure that the contents of this autoloads file believes they
|
||||
;; haven't been moved:
|
||||
(insert "(let ((load-file-name " (prin1-to-string (abbreviate-file-name file)) "))\n")
|
||||
(insert-file-contents file)
|
||||
(save-excursion
|
||||
;; Delete forms that modify `load-path' and `auto-mode-alist', we
|
||||
;; will set them once, later.
|
||||
(while (re-search-forward "^\\s-*\\((\\(?:add-to-list\\|\\(?:when\\|if\\) (boundp\\)\\s-+'\\(?:load-path\\|auto-mode-alist\\)\\)" nil t)
|
||||
(goto-char (match-beginning 1))
|
||||
(kill-sexp)))
|
||||
;; Remove unnecessary comment lines and (provide ...) forms
|
||||
(while (re-search-forward "^\\(?:;;\\(.*\n\\)\\|\n\\|(provide '[^\n]+\\)" nil t)
|
||||
(unless (nth 8 (syntax-ppss))
|
||||
(replace-match "" t t)))
|
||||
(unless (bolp) (insert "\n"))
|
||||
(insert ")\n")))))
|
||||
(dolist (desc (delq nil (mapcar #'cdr package-alist)))
|
||||
(let ((load-file-name (concat (package--autoloads-file-name desc) ".el")))
|
||||
(when (file-readable-p load-file-name)
|
||||
(condition-case _
|
||||
(while t (insert (read (current-buffer))))
|
||||
(end-of-file)))))
|
||||
(prin1 `(setq load-path ',load-path
|
||||
auto-mode-alist ',auto-mode-alist
|
||||
Info-directory-list ',Info-directory-list)
|
||||
|
@ -304,10 +277,9 @@ straight.el):
|
|||
#+END_SRC
|
||||
|
||||
You'll need to delete ~cache-files~ any time you install, remove, or update a
|
||||
new package, however. In that case you could advise ~package-install~ and
|
||||
~package-delete~ to call ~initialize~ when they succeed. Or, you could make
|
||||
~initialize~ interactive and call it manually when you determine it's necessary.
|
||||
Up to you!
|
||||
new package. You could advise ~package-install~ and ~package-delete~ to call
|
||||
~initialize~ when they succeed, or make ~initialize~ interactive and call it
|
||||
manually when necessary. Up to you!
|
||||
|
||||
Note: package.el is sneaky, and will initialize itself if you're not careful.
|
||||
*Not on my watch, criminal scum!*
|
||||
|
@ -322,20 +294,21 @@ Note: package.el is sneaky, and will initialize itself if you're not careful.
|
|||
*** Lazy load more than everything
|
||||
~use-package~ can defer your packages. Using it is a no-brainer, but Doom goes a
|
||||
little further with lazy loading. There are some massive plugins out there. For
|
||||
many of them, ordinary lazy loading techniques simply don't work. To name a few:
|
||||
some of them, ordinary lazy loading techniques don't work. To name a few:
|
||||
|
||||
+ The =lang/org= module defers loading babel packages until their src blocks are
|
||||
executed. You no longer need ~org-babel-do-load-languages~ in your config.
|
||||
executed or read. You no longer need ~org-babel-do-load-languages~ in your
|
||||
config -- in fact, you shouldn't use it at all!
|
||||
+ Company and yasnippet are loaded as late as possible (waiting until the user
|
||||
opens a non-read-only, file-visiting buffer (that isn't in fundamental-mode)).
|
||||
+ The =evil-easymotion= package has many keybinds. You'd need to load the
|
||||
package for them to all take effect, so instead, =gs= is bound to a command
|
||||
that loads the package and then invisibly populates =gs=, then simulates the
|
||||
=gs= keypress as though those new keys had always been there.
|
||||
+ A number of packages are "incrementally" loaded. This is a Doom feature where,
|
||||
after a few seconds of idle time post-startup, Doom will load packages
|
||||
piecemeal while Emacs. It will quickly abort if it detects input, as to make
|
||||
the process as subtle as possible.
|
||||
+ The =evil-easymotion= package binds many keys, none of which are available
|
||||
until you load the package. Instead of loading it at startup, =gs= is bound to
|
||||
a command that loads the package, populates =gs=, then simulates the =gs= key
|
||||
press as though those new keys had always been there.
|
||||
+ Doom loads some packages "incrementally". i.e. after a few seconds of idle
|
||||
time post-startup, Doom loads packages piecemeal (one dependency at a time)
|
||||
while Emacs. It aborts if it detects input, as to make the process as subtle
|
||||
as possible.
|
||||
|
||||
For example, instead of loading =org= (a giant package), it will load these
|
||||
dependencies, one at a time, before finally loading =org=:
|
||||
|
@ -349,21 +322,6 @@ many of them, ordinary lazy loading techniques simply don't work. To name a few:
|
|||
This ensures packages load as quickly as possible when you first load an org
|
||||
file.
|
||||
|
||||
*** +Exploit byte-compilation!+
|
||||
It used to be that byte-compilation bought a 40-60% improvement in startup
|
||||
times, because expensive operations (like ~package-initialize~ or
|
||||
~exec-path-from-shell~) were evaluated at compile time, but Doom has changed.
|
||||
|
||||
I've since adopted a pre-cache approach (when running ~doom refresh~), which
|
||||
brings these startup benefits to uncompiled Emacs. This renders byte-compilation
|
||||
significantly less beneficial for startup time.
|
||||
|
||||
That said, compilation will still benefit Doom's snappiness in general.
|
||||
|
||||
Run ~doom compile :core~ to only compile Doom's core files, or ~doom compile~ to
|
||||
compile the /entire/ config (=~/.emacs.d= and =~/.doom.d=) -- which may take a
|
||||
while.
|
||||
|
||||
*** Use [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html][lexical-binding]] everywhere
|
||||
Add ~;; -*- lexical-binding: t; -*-~ to the top of your elisp files. This can
|
||||
break code if you've written it to depend on undeclared dynamic variables, but
|
||||
|
@ -376,32 +334,30 @@ find more about it in:
|
|||
+ [[http://nullprogram.com/blog/2016/12/22/]["Some Performance Advantages of Lexical Scope."]]
|
||||
|
||||
** Why is startup time important? Why not use the daemon?
|
||||
One of my motivations for a config that starts up fast (aside from the learning
|
||||
experience) was to shape Emacs into a viable alternative to vim for one-shot
|
||||
editing in the terminal (without ~-Q~). This also facilitates:
|
||||
The central motivation for a config that starts up fast (aside from the learning
|
||||
experience) was to have a viable alternative to vim for quick, one-shot editing
|
||||
in the terminal (without ~-Q~).
|
||||
|
||||
- Running multiple, independent instances of Emacs (e.g. on a per-project basis, or
|
||||
for nix-shell users, or to isolate one instance for IRC from an instance for
|
||||
writing code, etc).
|
||||
Besides that, it happens to facilitate:
|
||||
|
||||
- Running multiple, independent instances of Emacs (e.g. on a per-project basis,
|
||||
or for nix-shell users, or to isolate one instance for IRC from an instance
|
||||
for writing code, etc).
|
||||
- Quicker restarting of Emacs, to reload package settings or recover from
|
||||
disastrous errors which can leave Emacs in a broken state.
|
||||
- Faster integration with "edit in Emacs" solutions (like [[https://github.com/alpha22jp/atomic-chrome][atomic-chrome]]), and
|
||||
the potential to use them without a running daemon.
|
||||
without a daemon.
|
||||
|
||||
What's more, I don't like using more tools than I need. We should not need a
|
||||
second program just to make the first run comfortably.
|
||||
What's more, I believe a daemon shouldn't be necessary to get a sane startup
|
||||
time out of Emacs.
|
||||
|
||||
** How do I use Doom alongside other Emacs configs?
|
||||
I recommend [[https://github.com/plexus/chemacs][Chemacs]]. You can think of it as a bootloader for Emacs. You'll [[file:getting_started.org::*Alongside other Emacs configs (with Chemacs)][find
|
||||
instructions on how to use it with Doom in the user manual]].
|
||||
|
||||
If you only want to try it out without affecting your current config, it is safe
|
||||
to install Doom anywhere you like. The ~bin/doom~ utility will only address the
|
||||
config the script is located under.
|
||||
|
||||
You'll still need a separate folder for personal configuration (=~/.doom.d= or
|
||||
=~/.config/doom= by default), but the =-p PATH= flag (or ~DOOMDIR~ environment
|
||||
variable) will allow you to use a different location:
|
||||
=~/.config/doom= by default), but the =--doomdir PATH= switch (or ~DOOMDIR~
|
||||
environment variable) will allow you to use a different location:
|
||||
|
||||
#+BEGIN_SRC bash
|
||||
# First install Doom somewhere
|
||||
|
@ -467,153 +423,57 @@ 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
|
||||
adding ~package!~ declarations to =packagse.el=, and enable/disable modules in
|
||||
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~.
|
||||
|
||||
Check out the [[file:getting_started.org::Customize][Customize section]] in the [[file:getting_started.org][Getting Started]] guide for details.
|
||||
|
||||
** How do I enable or disable a Doom module?
|
||||
You'll find your ~doom!~ block in =~/.doom.d/init.el=. This block contains a
|
||||
list of modules you want enabled and what order to load them in. Disable modules
|
||||
by commenting them out with semicolons. To enable them, remove those leading
|
||||
semicolons:
|
||||
Comment or uncomment the module in your ~doom!~ block, found in
|
||||
=$DOOMDIR/init.el=.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(doom! :lang
|
||||
python ; this is enabled
|
||||
;;ruby ; this is disabled
|
||||
rust)
|
||||
#+END_SRC
|
||||
|
||||
Remember to run ~bin/doom refresh~ afterwards, on the command line, to sync your
|
||||
Remember to run ~bin/doom sync~ afterwards, on the command line, to sync your
|
||||
module list with Doom.
|
||||
|
||||
You can find a comprehensive list of modules in the [[file:index.org::*Module list][Module Index]].
|
||||
|
||||
** How do I install a package from ELPA?
|
||||
Add a ~package!~ declaration to =~/.doom.d/packages.el= for each package you
|
||||
want installed.
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
(package! winum)
|
||||
#+END_SRC
|
||||
|
||||
Remember to run ~doom refresh~ afterwards to ensure the package is installed.
|
||||
|
||||
You'll find more information in the "[[file:getting_started.org::*Installing%20packages][Installing packages]]" section of the [[file:getting_started.org][Getting
|
||||
Started]] guide.
|
||||
|
||||
** How do I install a package from github/another source?
|
||||
The ~package!~ macro can be passed a MELPA style recipe, allowing you to install
|
||||
packages from just about anywhere:
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
(package! evil :recipe (:host github :repo "hlissner/my-evil-fork"))
|
||||
#+END_SRC
|
||||
|
||||
Remember to run ~doom refresh~ every time you modify you package list, to ensure
|
||||
your packages are set up and installed.
|
||||
|
||||
You can find more information about the recipe format [[https://github.com/raxod502/straight.el#the-recipe-format][in the straight.el package
|
||||
readme]].
|
||||
|
||||
#+begin_quote
|
||||
If a MELPA recipe exists for the package you are writing a ~package!~
|
||||
declaration for, you may omit keywords and Doom's package manager will fill them
|
||||
in with values from its original recipe.
|
||||
#+end_quote
|
||||
|
||||
You'll find more information in the "[[file:getting_started.org::*Installing%20packages%20from%20external%20sources][Installing packages from external sources]]"
|
||||
section of the [[file:getting_started.org][Getting Started]] guide.
|
||||
|
||||
** How do I change where an existing package is installed from?
|
||||
~package!~ declarations in your private =packages.el= file have precedence over
|
||||
modules (even your own). Simply add a new one for that package with the new
|
||||
recipe.
|
||||
|
||||
You'll find more information in the "[[file:getting_started.org::*Changing%20a%20built-in%20recipe%20for%20a%20package][Changing a built-in recipe for a package]]"
|
||||
section of the [[file:getting_started.org][Getting Started]] guide.
|
||||
|
||||
** How do I disable a package completely?
|
||||
With the ~package!~ macro's ~:disable~ property:
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
;;; in DOOMDIR/packages.el
|
||||
(package! irony :disable t)
|
||||
#+END_SRC
|
||||
|
||||
Remember to run ~doom refresh~ afterwards to ensure that the package is
|
||||
uninstalled and disabled.
|
||||
|
||||
You'll find more information in the "[[file:getting_started.org::*Disabling%20packages][Disabling packages]]" section of the [[file:getting_started.org][Getting
|
||||
Started]] guide.
|
||||
|
||||
** How do I reconfigure a package included in Doom?
|
||||
~use-package!~ and ~after!~ (wrappers around ~use-package~ and
|
||||
~eval-after-load~, respectively) are your bread and butter for configuring
|
||||
packages in Doom.
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
;; Takes a feature symbol or a library name (string)
|
||||
(after! evil
|
||||
(setq evil-magic nil))
|
||||
|
||||
;; Takes a major-mode, a quoted hook function or a list of either
|
||||
(add-hook! python-mode
|
||||
(setq python-shell-interpreter "bpython"))
|
||||
|
||||
(use-package! hl-todo
|
||||
;; if you omit :defer, :hook, :commands, or :after, then the package is loaded
|
||||
;; immediately. By using :hook here, the `hl-todo` package won't be loaded
|
||||
;; until prog-mode-hook is triggered (by activating a major mode derived from
|
||||
;; it, e.g. python-mode)
|
||||
:hook (prog-mode . hl-todo-mode)
|
||||
:init
|
||||
;; code here will run immediately
|
||||
:config
|
||||
;; code here will run after the package is loaded
|
||||
(setq hl-todo-highlight-punctuation ":"))
|
||||
|
||||
;; There's also `setq-hook!' for setting variables buffer-locally
|
||||
(setq-hook! python-mode python-indent-offset 2)
|
||||
#+END_SRC
|
||||
|
||||
See the "[[file:getting_started.org::*Configuring%20Doom][Configuring Doom]]" section of the [[file:getting_started.org][Getting Started]] guide for more
|
||||
explanation and examples.
|
||||
See the "[[file:getting_started.org::*Configuration modules][Configuration modules]]" section of the [[file:getting_started.org][Getting Started]] guide for more
|
||||
information.
|
||||
|
||||
** How do I change the theme?
|
||||
There are two ways to load a theme. Both assume the theme is installed and
|
||||
available. They are:
|
||||
available. You can either set ~doom-theme~ or manually load a theme with the
|
||||
~load-theme~ function.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
;;; in ~/.doom.d/config.el
|
||||
;;; add to ~/.doom.d/config.el
|
||||
(setq doom-theme 'doom-tomorrow-night)
|
||||
;; or
|
||||
(load-theme 'doom-tomorrow-night t)
|
||||
#+END_SRC
|
||||
|
||||
#+begin_quote
|
||||
At the moment, the only difference between the two is that ~doom-theme~ is
|
||||
loaded when Emacs has finished initializing at startup and ~load-theme~ loads
|
||||
the theme immediately. Which you choose depends on your needs, but I recommend
|
||||
setting ~doom-theme~ because, if I later discover a better way to load themes, I
|
||||
can easily change how Doom uses ~doom-theme~, but I can't (easily) control how
|
||||
you use the ~load-theme~ function.
|
||||
#+end_quote
|
||||
|
||||
*** Installing a third party theme
|
||||
To install a theme from a third party plugin, say, [[https://github.com/bbatsov/solarized-emacs][solarized]], you need only
|
||||
install it, then load it:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
;; in ~/.doom.d/packages.el
|
||||
(package! solarized)
|
||||
;;; add to ~/.doom.d/packages.el
|
||||
(package! solarized-theme)
|
||||
|
||||
;; in ~/.doom.d/config.el
|
||||
;;; add to ~/.doom.d/config.el
|
||||
(setq doom-theme 'solarized-dark)
|
||||
#+END_SRC
|
||||
|
||||
Don't forget to run ~doom refresh~ afterwards to ensure the package is
|
||||
installed.
|
||||
Don't forget to run ~doom sync~ after adding that ~package!~ statement to ensure
|
||||
the package is installed.
|
||||
|
||||
** How do I change the fonts?
|
||||
Doom exposes five (optional) variables for controlling fonts in Doom, they are:
|
||||
|
@ -624,12 +484,12 @@ Doom exposes five (optional) variables for controlling fonts in Doom, they are:
|
|||
+ ~doom-unicode-font~
|
||||
+ ~doom-big-font~ (used for ~doom-big-font-mode~)
|
||||
|
||||
Each of these will accept either a =font-spec=, font string (="Input Mono-12"=),
|
||||
or [[https://wiki.archlinux.org/index.php/X_Logical_Font_Description][xlfd font string]].
|
||||
They all accept either a =font-spec=, font string (="Input Mono-12"=), or [[https://wiki.archlinux.org/index.php/X_Logical_Font_Description][xlfd
|
||||
font string]].
|
||||
|
||||
e.g.
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
;; ~/.doom.d/config.el
|
||||
;;; Add to ~/.doom.d/config.el
|
||||
(setq doom-font (font-spec :family "Input Mono Narrow" :size 12 :weight 'semi-light)
|
||||
doom-variable-pitch-font (font-spec :family "Fira Sans") ; inherits `doom-font''s :size
|
||||
doom-unicode-font (font-spec :family "Input Mono Narrow" :size 12)
|
||||
|
@ -697,7 +557,7 @@ These variables control what key to use for leader and localleader keys:
|
|||
|
||||
e.g.
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
;; in ~/.doom.d/config.el
|
||||
;;; add to ~/.doom.d/config.el
|
||||
(setq doom-leader-key ","
|
||||
doom-localleader-key "\\")
|
||||
#+END_SRC
|
||||
|
@ -705,13 +565,9 @@ e.g.
|
|||
** How do I change the style of line-numbers (or disable them altogether)?
|
||||
Doom uses the ~display-line-numbers~ package, which is built into Emacs 26+.
|
||||
|
||||
#+begin_quote
|
||||
This package has been backported for Emacs 25 users, but is powered by =nlinum=
|
||||
there (which will be removed when we drop 25 support).
|
||||
#+end_quote
|
||||
|
||||
*** Disabling line numbers entirely
|
||||
#+BEGIN_SRC elisp
|
||||
;;; add to ~/.doom.d/config.el
|
||||
(setq display-line-numbers-type nil)
|
||||
;; or
|
||||
(remove-hook! '(prog-mode-hook text-mode-hook conf-mode-hook)
|
||||
|
@ -720,16 +576,25 @@ there (which will be removed when we drop 25 support).
|
|||
|
||||
*** Switching to relative line numbers (permanently)
|
||||
To change the style of line numbers, change the value of the
|
||||
~display-line-numbers-type~ variable. It accepts =t= (normal line numbers),
|
||||
='relative= (relative line numbers), ='visual= (relative line numbers in screen
|
||||
space) and =nil= (no line numbers).
|
||||
~display-line-numbers-type~ variable. It accepts the following values:
|
||||
|
||||
You'll find more precise documentation on the variable through =SPC h v
|
||||
display-line-numbers-type= or =C-h v display-line-numbers-type=.
|
||||
#+begin_example
|
||||
t normal line numbers
|
||||
'relative relative line numbers
|
||||
'visual relative line numbers in screen space
|
||||
nil no line numbers
|
||||
#+end_example
|
||||
|
||||
#+begin_quote
|
||||
The ~'visual~ option is unavailable in Emacs 25.
|
||||
#+end_quote
|
||||
For example:
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
;;; add to ~/.doom.d/config.el
|
||||
(setq display-line-numbers-type 'relative)
|
||||
#+END_SRC
|
||||
|
||||
You'll find more precise documentation on the variable through =<help> v
|
||||
display-line-numbers-type= (=<help>= is =SPC h= for evil users, =C-h=
|
||||
otherwise).
|
||||
|
||||
*** Switching the style of line numbers (temporarily)
|
||||
Use ~M-x doom/toggle-line-numbers~ (bound to =SPC t l= by default) to cycle
|
||||
|
@ -748,6 +613,19 @@ rules.
|
|||
You'll find more comprehensive documentation on ~set-popup-rule!~ in its
|
||||
docstring (available through =SPC h f= -- or =C-h f= for non-evil users).
|
||||
|
||||
** How do I change the appearance a face (or faces)?
|
||||
Doom provides the ~custom-set-faces!~ and ~custom-theme-set-faces!~ macros as a
|
||||
convenience.
|
||||
|
||||
#+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 =<help> f custom-set-faces\!= (or =M-x helpful-function custom-set-faces\!=)
|
||||
for documentation and examples on how to use it. =<help>= is =SPC h= for evil
|
||||
users and =C-h= for non-evil users.
|
||||
|
||||
** Can Doom be customized without restarting Emacs?
|
||||
Short answer: You can, but you shouldn't.
|
||||
|
||||
|
@ -757,20 +635,17 @@ tools for experienced Emacs users to skirt around it (most of the time):
|
|||
- Evaluate your changes on-the-fly with ~+eval/region~ (bound to the =gr=
|
||||
operator for evil users) or ~eval-last-sexp~ (bound to =C-x C-e=). Changes
|
||||
take effect immediately.
|
||||
- On-the-fly evaluation won't work for all changes. For instance, changing your
|
||||
~doom!~ block (i.e. the list of modules for Doom to enable) will always
|
||||
require a restart (and ~bin/doom refresh~).
|
||||
- On-the-fly evaluation won't work for all changes. e.g. Changing your ~doom!~
|
||||
block (i.e. the list of modules for Doom to enable).
|
||||
|
||||
Doom provides ~M-x doom/reload~ for your convenience, which will run ~doom
|
||||
refresh~, restart the Doom initialization process, and re-evaluate your
|
||||
personal config, but this won't clear pre-existing state. That may or may not
|
||||
be a problem, this hasn't be thoroughly tested and Doom cannot anticipate
|
||||
complications arising from your private config.
|
||||
|
||||
If you intend to use ~doom/reload~, you must design your config to be
|
||||
idempotent.
|
||||
- Many ~bin/doom~ commands are available as elisp commands with the ~doom//*~
|
||||
prefix. e.g. ~doom//refresh~, ~doom//update~, etc. Feel free to use them, but
|
||||
But rather than running ~doom sync~ and restarting Emacs, Doom provides ~M-x
|
||||
doom/reload~ for your convenience (bound to =SPC h r r= and =C-h r r=). This
|
||||
runs ~doom sync~, restarts the Doom initialization process and re-evaluates
|
||||
your personal config. However, this won't clear pre-existing state; Doom won't
|
||||
unload modules/packages that have already been loaded and it can't anticipate
|
||||
complications arising from a private config that isn't idempotent.
|
||||
- Some ~bin/doom~ commands are available as elisp commands. e.g. ~doom/reload~
|
||||
for ~doom sync~, ~doom/upgrade~ for ~doom upgrade~ ~doom//s~, ~doom//update~, etc. Feel free to use them, but
|
||||
consider them highly experimental and subject to change without notice.
|
||||
- You can quickly restart Emacs and restore the last session with
|
||||
~doom/restart-and-restore~ (bound to =SPC q r=).
|
||||
|
@ -792,7 +667,7 @@ commands that you may find particularly useful:
|
|||
|
||||
+ ~doom doctor~ :: Diagnose common issues in your environment and list missing
|
||||
external dependencies for your enabled modules.
|
||||
+ ~doom refresh~ :: Ensures that all missing packages are installed, orphaned
|
||||
+ ~doom sync~ :: Ensures that all missing packages are installed, orphaned
|
||||
packages are removed, and metadata properly generated.
|
||||
+ ~doom install~ :: Install any missing packages.
|
||||
+ ~doom update~ :: Update all packages that Doom's (enabled) modules use.
|
||||
|
@ -806,12 +681,12 @@ commands that you may find particularly useful:
|
|||
|
||||
#+BEGIN_SRC bash
|
||||
git pull
|
||||
doom refresh
|
||||
doom sync
|
||||
doom update
|
||||
#+END_SRC
|
||||
|
||||
** When to run ~doom refresh~
|
||||
As a rule of thumb you should run ~doom refresh~ whenever you:
|
||||
** When to run ~doom sync~
|
||||
As a rule of thumb you should run ~doom sync~ whenever you:
|
||||
|
||||
+ Update Doom with ~git pull~ instead of ~doom upgrade~,
|
||||
+ Change your ~doom!~ block in =$DOOMDIR/init.el=,
|
||||
|
@ -820,8 +695,8 @@ As a rule of thumb you should run ~doom refresh~ whenever you:
|
|||
+ Install an Emacs package or dependency outside of Emacs (i.e. through your OS
|
||||
package manager).
|
||||
|
||||
If anything is misbehaving, it's a good idea to run ~doom refresh~ first. ~doom
|
||||
refresh~ is responsible for regenerating your autoloads file (which tells Doom
|
||||
If anything is misbehaving, it's a good idea to run ~doom sync~ first. ~doom
|
||||
sync~ is responsible for regenerating your autoloads file (which tells Doom
|
||||
where to find lazy-loaded functions and libraries), installing missing packages,
|
||||
and uninstall orphaned (unneeded) packages.
|
||||
|
||||
|
@ -835,9 +710,32 @@ doom --yes update
|
|||
YES=1 doom update
|
||||
#+END_SRC
|
||||
|
||||
* Package Management
|
||||
** How do I install a package from ELPA?
|
||||
See the "[[file:getting_started.org::*Installing%20packages][Installing packages]]" section of the [[file:getting_started.org][Getting Started]] guide.
|
||||
|
||||
** How do I install a package from github/another source?
|
||||
See the "[[file:getting_started.org::*Installing%20packages%20from%20external%20sources][Installing packages from external sources]]" section of the [[file:getting_started.org][Getting
|
||||
Started]] guide.
|
||||
|
||||
** How do I change where an existing package is installed from?
|
||||
See the "[[file:getting_started.org::*Changing a recipe for a included package][Changing a recipe for a included package]]" section of the [[file:getting_started.org][Getting
|
||||
Started]] guide.
|
||||
|
||||
** How do I disable a package completely?
|
||||
See the "[[file:getting_started.org::*Disabling%20packages][disabling packages]]" section of the [[file:getting_started.org][Getting Started]] guide.
|
||||
|
||||
** How do I reconfigure a package included in Doom?
|
||||
See the "[[file:getting_started.org::*Configuring packages][configuring packages]]" section of the Getting Started guide.
|
||||
|
||||
** Where does straight clone/build packages to?
|
||||
Straight clones packages to =~/.emacs.d/.local/straight/repos/REPO-NAME=, then
|
||||
later symlinks and byte-compiles them to
|
||||
=~/.emacs.d/.local/straight/build/PACKAGE-NAME= when they are "built".
|
||||
|
||||
* Defaults
|
||||
** Why Ivy over Helm?
|
||||
Short answer: I chose ivy because it is the simpler of the two.
|
||||
Short answer: ivy is simpler to maintain.
|
||||
|
||||
Long answer: Features and performance appear to be the main talking points when
|
||||
comparing the two, but as far as I'm concerned they are equal in both respects
|
||||
|
@ -898,39 +796,38 @@ putting in the time to learn them.
|
|||
Otherwise, it is trivial to install expand-region and binds keys to it yourself:
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
;; in ~/.doom.d/packages.el
|
||||
;;; add to ~/.doom.d/packages.el
|
||||
(package! expand-region)
|
||||
|
||||
;; in ~/.doom.d/config.el
|
||||
;;; add to ~/.doom.d/config.el
|
||||
(map! :nv "C-=" #'er/contract-region
|
||||
:nv "C-+" #'er/expand-region)
|
||||
#+END_SRC
|
||||
|
||||
** Why not use exec-path-from-shell instead of ~doom env~?
|
||||
In a nutshell, the ~doom env~ approach is a faster and more robust solution.
|
||||
The ~doom env~ approach is a faster and more reliable solution.
|
||||
|
||||
1. ~exec-path-from-shell~ must spawn (at least) one process at startup to scrape
|
||||
your shell environment. This can be arbitrarily slow depending on the user's
|
||||
shell configuration. A single program (like pyenv or nvm) or config framework
|
||||
(like oh-my-zsh) could undo all of Doom's startup optimizations in one fell
|
||||
swoop.
|
||||
your shell environment. This can be slow depending on the user's shell
|
||||
configuration. A single program (like pyenv or nvm) or config framework (like
|
||||
oh-my-zsh) could undo Doom's startup optimizations in one fell swoop.
|
||||
|
||||
2. ~exec-path-from-shell~ only scrapes /some/ state from your shell. You have to
|
||||
be proactive in order to get it to capture all the envvars relevant to your
|
||||
development environment.
|
||||
2. ~exec-path-from-shell~ takes a whitelist approach and captures only ~PATH~
|
||||
and ~MANPATH~ by default. You must be proactive in order to capture all the
|
||||
envvars relevant to your development environment and tools.
|
||||
|
||||
I'd rather it inherit your shell environment /correctly/ (and /completely/)
|
||||
or not at all. It frontloads the debugging process rather than hiding it
|
||||
until it you least want to deal with it.
|
||||
~doom env~ takes the blacklist approach and captures all of your shell
|
||||
environment. This front loads the debugging process, which is nicer than dealing
|
||||
with it later, while you're getting work done.
|
||||
|
||||
That said, if you still want ~exec-path-from-shell~, it is trivial to install
|
||||
yourself:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
;; in ~/.doom.d/packages.el
|
||||
;;; add to ~/.doom.d/packages.el
|
||||
(package! exec-path-from-shell)
|
||||
|
||||
;; in ~/.doom.d/config.el
|
||||
;;; add to ~/.doom.d/config.el
|
||||
(require 'exec-path-from-shell)
|
||||
(when (display-graphic-p)
|
||||
(exec-path-from-shell-initialize))
|
||||
|
@ -941,16 +838,16 @@ TL;DR: =ws-butler= is less imposing.
|
|||
Don't be that guy who PRs 99 whitespace adjustments around his one-line
|
||||
contribution. Don't automate this aggressive behavior by attaching
|
||||
~delete-trailing-whitespace~ (or ~whitespace-cleanup~) to ~before-save-hook~. If
|
||||
you have rambunctious colleagues peppering trailing whitespace into your project,
|
||||
you need to have a talk (with wiffle bats, preferably) rather than play this
|
||||
passive-aggressive game of whack-a-mole.
|
||||
you have rambunctious colleagues peppering trailing whitespace into your
|
||||
project, you need to have a talk (with wiffle bats, preferably) rather than play
|
||||
a passive-aggressive game of whack-a-mole.
|
||||
|
||||
Here at Doom Inc we believe that operations that mutate entire files should
|
||||
never be automated. Rather, they should be invoked deliberately -- by someone
|
||||
that is aware of the potential consequences. This is where =ws-butler= comes in.
|
||||
It only cleans up whitespace /on the lines you've touched/ *and* it leaves
|
||||
behind virtual whitespace (which is never written to the file, but remains there
|
||||
so your cursor doesn't get thrown around in all that cleanup work).
|
||||
Here at Doom Inc we believe that operations that mutate entire files should not
|
||||
be automated. Rather, they should be invoked deliberately, when and where it is
|
||||
needed, by someone that is aware of the potential consequences. This is where
|
||||
=ws-butler= comes in. It only cleans up whitespace /on the lines you've touched/
|
||||
*and* it leaves behind virtual whitespace (which is never written to the file)
|
||||
so your cursor doesn't get thrown around in all that cleanup work.
|
||||
|
||||
In any case, if you had used =ws-butler= from the beginning, trailing whitespace
|
||||
and newlines would never be a problem!
|
||||
|
@ -987,14 +884,14 @@ manually (e.g. by double-clicking each file in explorer).
|
|||
** ~void-variable~ and ~void-function~ errors on startup
|
||||
The most common culprit for these types of errors are:
|
||||
|
||||
1. An out-of-date autoloads file. To regenerate it, run ~doom refresh~.
|
||||
1. An out-of-date autoloads file. Run ~doom sync~ to regenerate them.
|
||||
|
||||
To avoid this issue, remember to run ~doom refresh~ whenever you modify your
|
||||
To avoid this issue, remember to run ~doom sync~ whenever you modify your
|
||||
~doom!~ block in =~/.doom.d/init.el=, or add ~package!~ declarations to
|
||||
=~/.doom.d/packages.el=. Or if you modify =~/.emacs.d/.local= by hand, for
|
||||
whatever reason.
|
||||
|
||||
See ~doom help refresh~ for details on what this command does and when you
|
||||
See ~doom help sync~ for details on what this command does and when you
|
||||
should use it.
|
||||
|
||||
2. Emacs byte-code isn't forward compatible. If you've recently switched to a
|
||||
|
@ -1025,7 +922,7 @@ issues #1 and #3: generate an envvar file by running ~doom env~. This scrapes
|
|||
your shell environment into a file that is loaded when Doom Emacs starts up.
|
||||
Check out ~doom help env~ for details on how this works.
|
||||
|
||||
For issue #2, you'll need to investigate your launcher. [[https://discord.gg/bcZ6P3y][Our Discord]] is a good
|
||||
For issue #2, you'll need to investigate your launcher. [[https://discord.gg/qvGgnVx][Our Discord]] is a good
|
||||
place to ask about it.
|
||||
|
||||
** There's artefacting on my icon fonts in GUI Emacs ([[https://github.com/hlissner/doom-emacs/issues/956][#956]])
|
||||
|
@ -1052,8 +949,8 @@ If you still want to restore the old behavior, simply disable evil-snipe-mode:
|
|||
1. Make sure you don't have both =~/.doom.d= and =~/.config/doom= directories.
|
||||
Doom will ignore the former if the latter exists.
|
||||
|
||||
2. Remember to run ~doom refresh~ when it is necessary. To get to know when,
|
||||
exactly, you should run this command, run ~doom help refresh~.
|
||||
2. Remember to run ~doom sync~ when it is necessary. To get to know when,
|
||||
exactly, you should run this command, run ~doom help sync~.
|
||||
|
||||
If neither of these solve your issue, try ~bin/doom doctor~. It will detect a
|
||||
variety of common issues, and may give you some clues as to what is wrong.
|
||||
|
@ -1068,7 +965,6 @@ known fix for this. To work around it, you must either:
|
|||
support it),
|
||||
|
||||
3. Install Emacs via the =emacs-mac= homebrew formula.
|
||||
|
||||
** Doom crashes when...
|
||||
Here are a few common causes for random crashes:
|
||||
|
||||
|
@ -1091,4 +987,82 @@ Here are a few common causes for random crashes:
|
|||
|
||||
Or disable the =:ui doom-dashboard= & =:tools magit= modules (see [[https://github.com/hlissner/doom-emacs/issues/1170][#1170]]).
|
||||
|
||||
** Can't load my theme; ~unable to find theme file for X~ errors
|
||||
This means Emacs can't find the X-theme.el file for the theme you want to load.
|
||||
Emacs will search for this file in ~custom-theme-load-path~ and
|
||||
~custom-theme-directory~. There are a couple reasons why it can't be found:
|
||||
|
||||
1. It is generally expected that third party themes will [[https://github.com/hlissner/emacs-doom-themes/blob/master/doom-themes.el#L400-L405][add themselves]] to
|
||||
~custom-theme-load-path~, but you will occasionally encounter a theme that
|
||||
does not. This should be reported upstream.
|
||||
|
||||
In the meantime, you can get around this by eagerly loading the package:
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
(require 'third-party-theme)
|
||||
(setq doom-theme 'third-party)
|
||||
#+END_SRC
|
||||
2. You've appended ~-theme~ to the end of your theme's name.
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
(setq doom-theme 'third-party-theme)
|
||||
#+END_SRC
|
||||
|
||||
When you load a theme Emacs searches for ~X-theme.el~. If you set
|
||||
~doom-theme~ to ~'third-party-theme~, it will search for
|
||||
~third-party-theme-theme.el~. This is rarely intentional. Omit the ~-theme~
|
||||
suffix.
|
||||
3. Did you run ~doom sync~ after adding your third party theme plugin's
|
||||
~package!~ declaration to =~/.doom.d/packages.el=?
|
||||
** TRAMP connections hang forever when connecting
|
||||
You'll find solutions [[https://www.emacswiki.org/emacs/TrampMode#toc7][on the emacswiki]].
|
||||
** An upstream package was broken and I can't update it
|
||||
Sometimes, if you've installed a [[https://github.com/hlissner/doom-emacs/issues/2213][broken package]] which was subsequently fixed
|
||||
upstream, you can't run ~doom update~ to get the latest fixes due to evaluation
|
||||
errors.
|
||||
|
||||
In those cases, you need to delete the broken local copy before you can install
|
||||
the new one, which is achieved by either deleting it from
|
||||
=~/.emacs.d/.local/straight/repos=, or by cycling the module that installs it:
|
||||
|
||||
1. Comment out the broken module/package.
|
||||
2. Run ~doom sync~.
|
||||
3. Uncomment the module/package.
|
||||
4. Run ~doom sync~.
|
||||
|
||||
** Why do I see ugly indentation highlights for tabs?
|
||||
[[https://github.com/hlissner/doom-emacs/blob/develop/core/core-ui.el#L132-L150][Doom highlights non-standard indentation]]. i.e. Indentation that doesn't match
|
||||
the indent style you've set for that file. Spaces are Doom's default style for
|
||||
most languages (excluding languages where tabs are the norm, like Go).
|
||||
|
||||
There are a couple ways to address this:
|
||||
|
||||
1. Fix your indentation! If it's highlighted, you have tabs when you should have
|
||||
spaces (or spaces when you should be using tabs).
|
||||
|
||||
Two easy commands for that:
|
||||
|
||||
- =M-x tabify=
|
||||
- =M-x untabify=
|
||||
|
||||
2. Change ~indent-tabs-mode~ (nil = spaces, t = tabs) in =~/.doom.d/config.el=:
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
;; use tab indentation everywhere
|
||||
(setq-default indent-tabs-mode t)
|
||||
|
||||
;; or only in certain modes
|
||||
(setq-hook! 'sh-mode-hook indent-tabs-mode t) ; shell scripts
|
||||
(setq-hook! '(c-mode-hook c++-mode-hook) indent-tabs-mode t) ; C/C++
|
||||
#+END_SRC
|
||||
|
||||
3. Use [[https://editorconfig.org/][editorconfig]] to configure code style on a per-project basis. If you
|
||||
enable Doom's =:tools editorconfig= module, Doom will recognize
|
||||
=.editorconfigrc= files.
|
||||
|
||||
4. Or trust in dtrt-indent; a plugin Doom uses to analyze and detect indentation
|
||||
when you open a file (that isn't in a project with an editorconfig file).
|
||||
This isn't foolproof, and won't work for files that have no content in them,
|
||||
but it can help in one-off scenarios.
|
||||
|
||||
* TODO Contributing
|
||||
|
|
File diff suppressed because it is too large
Load diff
251
docs/index.org
251
docs/index.org
|
@ -1,16 +1,20 @@
|
|||
#+TITLE: Doom Emacs Documentation
|
||||
#+STARTUP: nofold
|
||||
|
||||
Doom Emacs is a configuration for [[https://www.gnu.org/software/emacs/][GNU Emacs]] written by a stubborn,
|
||||
shell-dwelling, and melodramatic ex-vimmer. It is designed to be a foundation
|
||||
for your own Emacs configuration or a resource for enthusiasts to learn more
|
||||
about our favorite OS.
|
||||
Doom is a configuration framework for [[https://www.gnu.org/software/emacs/][GNU Emacs 26.3+]] 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.
|
||||
|
||||
Doom is an opinionated collection of reasonable (and optional) defaults with a
|
||||
focus on performance (both runtime and startup) and on abstraction-light,
|
||||
readable code design, so that there is less between you and Emacs.
|
||||
|
||||
#+begin_quote
|
||||
Github fails to render org links to sub-sections, so it is recommended that you
|
||||
view the documentation from within Doom Emacs by pressing =<help> d h= (=<help>=
|
||||
is =SPC h= for evil users and =C-h= for vanilla users) or searching it with
|
||||
=<help> d /=.
|
||||
The documentation is designed to be viewed within Doom Emacs. Access it by
|
||||
pressing =SPC h d h= (or =C-h d h= for non-evil users), or search it with =SPC h
|
||||
d s= (or =C-h d s=).
|
||||
#+end_quote
|
||||
|
||||
* Table of Contents :TOC:
|
||||
|
@ -20,53 +24,47 @@ is =SPC h= for evil users and =C-h= for vanilla users) or searching it with
|
|||
- [[#frequently-asked-questions][Frequently Asked Questions]]
|
||||
- [[#contributing][Contributing]]
|
||||
- [[#workflow-tips-tricks--tutorials][Workflow Tips, Tricks & Tutorials]]
|
||||
- [[#module-appendix][Module Appendix]]
|
||||
- [[#community-resources][Community Resources]]
|
||||
- [[#asking-for-help][Asking for help]]
|
||||
- [[#project-roadmap][Project roadmap]]
|
||||
- [[#tutorials--guides][Tutorials & guides]]
|
||||
- [[#module-list][Module list]]
|
||||
- [[#app][:app]]
|
||||
- [[#completion][:completion]]
|
||||
- [[#config][:config]]
|
||||
- [[#editor][:editor]]
|
||||
- [[#emacs][:emacs]]
|
||||
- [[#email][:email]]
|
||||
- [[#input][:input]]
|
||||
- [[#lang][:lang]]
|
||||
- [[#term][:term]]
|
||||
- [[#tools][:tools]]
|
||||
- [[#ui][:ui]]
|
||||
- [[#projects-that-supportcompliment-doom][Projects that support/compliment Doom]]
|
||||
- [[#similar-projects][Similar projects]]
|
||||
|
||||
* TODO Release Notes
|
||||
|
||||
* Documentation
|
||||
** [[file:getting_started.org][Getting Started]]
|
||||
- [[file:getting_started.org::*Install][Install]] - How to install Emacs, Doom and its plugins
|
||||
- [[file:getting_started.org::*Update][Update]] - Keep Doom and its packages up-to-date
|
||||
- [[file:getting_started.org::*Customize][Customize]] - A primer on customizing and reconfiguring Doom
|
||||
- [[file:getting_started.org::*Troubleshoot][Troubleshoot]] - How to debug Emacs & Doom, find help or look up documentation
|
||||
- [[file:getting_started.org::*Install][Install]]
|
||||
- [[file:getting_started.org::*Update & Rollback][Update & Rollback]]
|
||||
- [[file:getting_started.org::*Configure][Configure]]
|
||||
- [[file:getting_started.org::*Migrate][Migrate]]
|
||||
- [[file:getting_started.org::*Troubleshoot][Troubleshoot]]
|
||||
|
||||
** [[file:faq.org][Frequently Asked Questions]]
|
||||
- [[file:faq.org::*General][General]]
|
||||
- [[file:faq.org::*Configuration][Configuration]]
|
||||
- [[file:faq.org::*Package Management][Package Management]]
|
||||
- [[file:faq.org::*Defaults][Defaults]]
|
||||
- [[file:faq.org::Common Issues][Common Issues]]
|
||||
- [[file:faq.org::Contributing][Contributing]]
|
||||
|
||||
** TODO [[file:contributing.org][Contributing]]
|
||||
- [[file:contributing.org::*Where can I help?][Where to get help]]
|
||||
- Writing an effective bug report
|
||||
- Suggesting features, keybinds or enhancements
|
||||
- Contributing code
|
||||
- Contributing documentation
|
||||
- [[file:contributing.org::*Where can I help?][Where to get help?]]
|
||||
- Reporting issues
|
||||
- Suggesting features, keybinds and enhancements
|
||||
- Contributing code or documentation
|
||||
- Other ways to support Doom Emacs
|
||||
- Special thanks
|
||||
|
||||
** TODO [[file:workflow.org][Workflow Tips, Tricks & Tutorials]]
|
||||
|
||||
** [[file:modules.org][Module Appendix]]
|
||||
|
||||
* Community Resources
|
||||
** Asking for help
|
||||
- [[https://discord.gg/bcZ6P3y][Our Discord server]]
|
||||
- [[https://discord.gg/qvGgnVx][Our Discord server]]
|
||||
- [[https://github.com/hlissner/doom-emacs/issues][Our issue tracker]]
|
||||
|
||||
** Project roadmap
|
||||
|
@ -79,11 +77,12 @@ is =SPC h= for evil users and =C-h= for vanilla users) or searching it with
|
|||
|
||||
** Tutorials & guides
|
||||
+ *Doom Emacs*
|
||||
- (video) [[https://www.youtube.com/watch?v=dr_iBj91eeI][Doom Emacs - Getting Started by DistroTube]]
|
||||
- (video) [[https://www.youtube.com/playlist?list=PLhXZp00uXBk4np17N39WvB80zgxlZfVwj][DoomCasts]]
|
||||
- [[https://noelwelsh.com/posts/2019-01-10-doom-emacs.html][Noel's crash course on Doom Emacs]]
|
||||
- [[https://medium.com/@aria_39488/getting-started-with-doom-emacs-a-great-transition-from-vim-to-emacs-9bab8e0d8458][Getting Started with Doom Emacs -- a great transition from Vim to Emacs]]
|
||||
- [[https://medium.com/@aria_39488/the-niceties-of-evil-in-doom-emacs-cabb46a9446b][The Niceties of evil in Doom Emacs]]
|
||||
- [[https://www.youtube.com/playlist?list=PLhXZp00uXBk4np17N39WvB80zgxlZfVwj][DoomCasts (youtube series)]]
|
||||
- [[https://www.youtube.com/watch?v=GK3fij-D1G8][Org-mode, literate programming in (Doom) Emacs]]
|
||||
- (video) [[https://www.youtube.com/watch?v=GK3fij-D1G8][Org-mode, literate programming in (Doom) Emacs]]
|
||||
+ *Emacs & Emacs Lisp*
|
||||
- [[https://www.gnu.org/software/emacs/manual/html_node/elisp/index.html][The Official Emacs manual]]
|
||||
- A variety of Emacs resources - https://github.com/ema2159/awesome-emacs
|
||||
|
@ -92,186 +91,16 @@ is =SPC h= for evil users and =C-h= for vanilla users) or searching it with
|
|||
- http://steve-yegge.blogspot.com/2008/01/emergency-elisp.html
|
||||
- Workflows for customizing Emacs and its packages (and its C/C++ modes):
|
||||
- https://david.rothlis.net/emacs/customize_c.html
|
||||
+ *Tools in Emacs*
|
||||
- [[https://www.emacswiki.org/emacs/Calc_Tutorials_by_Andrew_Hyatt][How to use M-x calc]]
|
||||
- *Tools in Emacs*
|
||||
- [[https://www.emacswiki.org/emacs/Calc_Tutorials_by_Andrew_Hyatt][How to use M-x calc]]
|
||||
+ *Vim & Evil*
|
||||
- [[https://gist.github.com/dmsul/8bb08c686b70d5a68da0e2cb81cd857f][A crash course on modal editing and Ex commands]]
|
||||
|
||||
* Module list
|
||||
** :app
|
||||
Application modules are complex and opinionated modules that transform Emacs
|
||||
toward a specific purpose. They may have additional dependencies and should be
|
||||
loaded last, before =:config= modules.
|
||||
** Projects that support/compliment Doom
|
||||
+ [[https://github.com/plexus/chemacs][plexus/chemacs]]
|
||||
+ [[https://github.com/r-darwish/topgrade][r-darwish/topgrade]]
|
||||
|
||||
+ [[file:../modules/app/calendar/README.org][calendar]] - TODO
|
||||
+ [[file:../modules/app/irc/README.org][irc]] - how neckbeards socialize
|
||||
+ rss =+org= - an RSS client in Emacs
|
||||
+ twitter - A twitter client for Emacs
|
||||
+ [[file:../modules/app/write/README.org][write]] =+wordnut +langtool= - Transforms emacs into an IDE for writers, and for
|
||||
writing fiction, notes, papers and so on.
|
||||
|
||||
** :completion
|
||||
Modules that provide new interfaces or frameworks for completion, including code
|
||||
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
|
||||
|
||||
** :config
|
||||
Modules that configure Emacs one way or another, or focus on making it easier
|
||||
for you to customize it yourself. It is best to load these last.
|
||||
|
||||
+ literate - For users with literate configs. This will tangle+compile a
|
||||
config.org in your ~doom-private-dir~ when it changes.
|
||||
+ [[file:../modules/config/default/README.org][default]] =+bindings +smartparens= - The default module sets reasonable defaults
|
||||
for Emacs. It also provides a Spacemacs-inspired keybinding scheme and a
|
||||
smartparens config. Use it as a reference for your own modules.
|
||||
|
||||
** :editor
|
||||
Modules that affect and augment your ability to manipulate or insert text.
|
||||
|
||||
+ [[file:../modules/editor/evil/README.org][evil]] =+everywhere= - transforms Emacs into Vim
|
||||
+ [[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 - run Emacs commands without modifier keys
|
||||
+ [[file:../modules/editor/lispy/README.org][lispy]] - TODO
|
||||
+ multiple-cursors - TODO
|
||||
+ objed - TODO
|
||||
+ [[file:../modules/editor/parinfer/README.org][parinfer]] - TODO
|
||||
+ rotate-text - TODO
|
||||
+ [[file:../modules/editor/snippets/README.org][snippets]] - Snippet expansion for lazy typists
|
||||
+ [[file:../modules/editor/word-wrap/README.org][word-wrap]] - soft wrapping with language-aware indent
|
||||
|
||||
** :emacs
|
||||
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
|
||||
+ vc - TODO
|
||||
|
||||
** :email
|
||||
+ [[file:../modules/email/mu4e/README.org][mu4e]] =+gmail= - TODO
|
||||
+ notmuch - TODO
|
||||
+ wanderlust =+gmail= - TODO
|
||||
|
||||
** :input
|
||||
+ chinese - TODO
|
||||
+ japanese - TODO
|
||||
|
||||
** :lang
|
||||
Modules that bring support for a language or group of languages to Emacs.
|
||||
|
||||
+ agda - TODO
|
||||
+ assembly - TODO
|
||||
+ [[file:../modules/lang/cc/README.org][cc]] =+lsp= - TODO
|
||||
+ clojure - TODO
|
||||
+ common-lisp - TODO
|
||||
+ [[file:../modules/lang/coq/README.org][coq]] - TODO
|
||||
+ crystal - TODO
|
||||
+ [[file:../modules/lang/csharp/README.org][csharp]] - TODO
|
||||
+ data - TODO
|
||||
+ [[file:../modules/lang/elixir/README.org][elixir]] =+lsp= - TODO
|
||||
+ elm - TODO
|
||||
+ emacs-lisp - TODO
|
||||
+ erlang - TODO
|
||||
+ [[file:../modules/lang/ess/README.org][ess]] - TODO
|
||||
+ [[file:../modules/lang/faust/README.org][faust]] - TODO
|
||||
+ [[file:../modules/lang/fsharp/README.org][fsharp]] - TODO
|
||||
+ [[file:../modules/lang/go/README.org][go]] =+lsp= - TODO
|
||||
+ [[file:../modules/lang/haskell/README.org][haskell]] =+intero +dante +lsp= - TODO
|
||||
+ hy - TODO
|
||||
+ [[file:../modules/lang/idris/README.org][idris]] - TODO
|
||||
+ java =+meghanada +lsp= - TODO
|
||||
+ [[file:../modules/lang/javascript/README.org][javascript]] =+lsp= - TODO
|
||||
+ julia - TODO
|
||||
+ kotlin - TODO
|
||||
+ [[file:../modules/lang/latex/README.org][latex]] - TODO
|
||||
+ lean - TODO
|
||||
+ ledger - TODO
|
||||
+ lua =+moonscript= - TODO
|
||||
+ [[file:../modules/lang/markdown/README.org][markdown]] =+grip= - TODO
|
||||
+ [[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]] =+dragndrop +gnuplot +hugo +ipython +pandoc +pomodoro +present= - TODO
|
||||
+ [[file:../modules/lang/perl/README.org][perl]] - TODO
|
||||
+ [[file:../modules/lang/php/README.org][php]] =+lsp= - TODO
|
||||
+ plantuml - TODO
|
||||
+ purescript - TODO
|
||||
+ [[file:../modules/lang/python/README.org][python]] =+lsp +pyenv +conda= - TODO
|
||||
+ qt - TODO
|
||||
+ racket - TODO
|
||||
+ [[file:../modules/lang/rest/README.org][rest]] - TODO
|
||||
+ ruby =+lsp +rvm +rbenv= - TODO
|
||||
+ [[file:../modules/lang/rust/README.org][rust]] =+lsp= - TODO
|
||||
+ scala =+lsp= - TODO
|
||||
+ [[file:../modules/lang/scheme/README.org][scheme]] - TODO
|
||||
+ [[file:../modules/lang/sh/README.org][sh]] =+fish +lsp= - TODO
|
||||
+ [[file:../modules/lang/solidity/README.org][solidity]] - TODO
|
||||
+ swift =+lsp= - TODO
|
||||
+ terra - TODO
|
||||
+ web =+lsp= - HTML and CSS (SCSS/SASS/LESS/Stylus) support.
|
||||
|
||||
** :term
|
||||
Modules that offer terminal emulation.
|
||||
|
||||
+ eshell - TODO
|
||||
+ shell - TODO
|
||||
+ term - TODO
|
||||
+ [[file:../modules/term/vterm/README.org][vterm]] - TODO
|
||||
|
||||
** :tools
|
||||
Small modules that give Emacs access to external tools & services.
|
||||
|
||||
+ ansible - TODO
|
||||
+ debugger - A (nigh-)universal debugger in Emacs
|
||||
+ [[file:../modules/tools/direnv/README.org][direnv]] - TODO
|
||||
+ [[file:../modules/tools/docker/README.org][docker]] - TODO
|
||||
+ [[file:../modules/tools/editorconfig/README.org][editorconfig]] - TODO
|
||||
+ [[file:../modules/tools/ein/README.org][ein]] - TODO
|
||||
+ [[file:../modules/tools/eval/README.org][eval]] =+overlay= - REPL & code evaluation support for a variety of languages
|
||||
+ flycheck - Live error/warning highlights
|
||||
+ flyspell - Spell checking
|
||||
+ gist - TODO
|
||||
+ [[file:../modules/tools/lookup/README.org][lookup]] =+docsets= - Universal jump-to & documentation lookup backend
|
||||
+ [[file:../modules/tools/lsp/README.org][lsp]] - TODO
|
||||
+ macos - TODO
|
||||
+ magit - TODO
|
||||
+ make - TODO
|
||||
+ pass - TODO
|
||||
+ pdf - TODO
|
||||
+ prodigy - TODO
|
||||
+ rgb - TODO
|
||||
+ terraform - TODO
|
||||
+ tmux - TODO
|
||||
+ upload - TODO
|
||||
+ [[file:../modules/tools/wakatime/README.org][wakatime]] - TODO
|
||||
|
||||
** :ui
|
||||
Aesthetic modules that affect the Emacs interface or user experience.
|
||||
|
||||
+ [[file:../modules/ui/deft/README.org][deft]] - TODO
|
||||
+ [[file:../modules/ui/doom/README.org][doom]] - TODO
|
||||
+ [[file:../modules/ui/doom-dashboard/README.org][doom-dashboard]] - TODO
|
||||
+ [[file:../modules/ui/doom-quit/README.org][doom-quit]] - TODO
|
||||
+ fill-column - TODO
|
||||
+ [[file:../modules/ui/hl-todo/README.org][hl-todo]] - TODO
|
||||
+ hydra - TODO
|
||||
+ indent-guides - TODO
|
||||
+ [[file:../modules/ui/modeline/README.org][modeline]] - TODO
|
||||
+ [[file:../modules/ui/nav-flash/README.org][nav-flash]] - TODO
|
||||
+ [[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/tabs/README.org][tabs]] - TODO
|
||||
+ treemacs - TODO
|
||||
+ [[file:../modules/ui/unicode/README.org][unicode]] - TODO
|
||||
+ vc-gutter - TODO
|
||||
+ vi-tilde-fringe - TODO
|
||||
+ [[file:../modules/ui/window-select/README.org][window-select]] =+switch-window +numbers= - TODO
|
||||
+ [[file:../modules/ui/workspaces/README.org][workspaces]] - Isolated workspaces
|
||||
** Similar projects
|
||||
+ [[https://github.com/purcell/emacs.d][purcell/emacs.d]]
|
||||
+ [[https://github.com/seagle0128/.emacs.d][seagle0128/.emacs.d]]
|
||||
+ [[https://github.com/syl20bnr/spacemacs][syl20bnr/spacemacs]]
|
||||
|
|
201
docs/modules.org
Normal file
201
docs/modules.org
Normal file
|
@ -0,0 +1,201 @@
|
|||
#+TITLE: Module Appendix
|
||||
#+STARTUP: nofold
|
||||
|
||||
Functionality in Doom is divided into collections of code called modules (à la
|
||||
Spacemacs' layers). A module is a bundle of packages, configuration and
|
||||
commands, organized into a unit that can be enabled or disabled by adding or
|
||||
removing them from your ~doom!~ block (found in =$DOOMDIR/init.el=).
|
||||
|
||||
* Table of Contents :TOC:
|
||||
- [[#app][:app]]
|
||||
- [[#checkers][:checkers]]
|
||||
- [[#completion][:completion]]
|
||||
- [[#config][:config]]
|
||||
- [[#editor][:editor]]
|
||||
- [[#emacs][:emacs]]
|
||||
- [[#email][:email]]
|
||||
- [[#input][:input]]
|
||||
- [[#lang][:lang]]
|
||||
- [[#term][:term]]
|
||||
- [[#tools][:tools]]
|
||||
- [[#ui][:ui]]
|
||||
|
||||
* :app
|
||||
Application modules are complex and opinionated modules that transform Emacs
|
||||
toward a specific purpose. They may have additional dependencies and should be
|
||||
loaded last, before =:config= modules.
|
||||
|
||||
+ [[file:../modules/app/calendar/README.org][calendar]] - TODO
|
||||
+ [[file:../modules/app/irc/README.org][irc]] - how neckbeards socialize
|
||||
+ rss =+org= - an RSS client in Emacs
|
||||
+ [[file:../modules/app/twitter/README.org][twitter]] - A twitter client for Emacs
|
||||
|
||||
* :checkers
|
||||
+ syntax =+childframe= - Live error/warning highlights
|
||||
+ spell =+everywhere= - Spell checking
|
||||
+ grammar - TODO
|
||||
|
||||
* :completion
|
||||
Modules that provide new interfaces or frameworks for completion, including code
|
||||
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
|
||||
|
||||
* :config
|
||||
Modules that configure Emacs one way or another, or focus on making it easier
|
||||
for you to customize it yourself. It is best to load these last.
|
||||
|
||||
+ literate - For users with literate configs. This will tangle+compile a
|
||||
config.org in your ~doom-private-dir~ when it changes.
|
||||
+ [[file:../modules/config/default/README.org][default]] =+bindings +smartparens= - The default module sets reasonable defaults
|
||||
for Emacs. It also provides a Spacemacs-inspired keybinding scheme and a
|
||||
smartparens config. Use it as a reference for your own modules.
|
||||
|
||||
* :editor
|
||||
Modules that affect and augment your ability to manipulate or insert text.
|
||||
|
||||
+ [[file:../modules/editor/evil/README.org][evil]] =+everywhere= - transforms Emacs into Vim
|
||||
+ [[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
|
||||
+ [[file:../modules/editor/lispy/README.org][lispy]] - TODO
|
||||
+ multiple-cursors - TODO
|
||||
+ [[file:../modules/editor/objed/README.org][objed]] - TODO
|
||||
+ [[file:../modules/editor/parinfer/README.org][parinfer]] - TODO
|
||||
+ rotate-text - TODO
|
||||
+ [[file:../modules/editor/snippets/README.org][snippets]] - Snippet expansion for lazy typists
|
||||
+ [[file:../modules/editor/word-wrap/README.org][word-wrap]] - soft wrapping with language-aware indent
|
||||
|
||||
* :emacs
|
||||
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
|
||||
+ vc - TODO
|
||||
|
||||
* :email
|
||||
+ [[file:../modules/email/mu4e/README.org][mu4e]] =+gmail= - TODO
|
||||
+ notmuch - TODO
|
||||
+ wanderlust =+gmail= - TODO
|
||||
|
||||
* :input
|
||||
+ [[file:../modules/input/chinese/README.org][chinese]] - TODO
|
||||
+ [[file:../modules/input/japanese/README.org][japanese]] - TODO
|
||||
|
||||
* :lang
|
||||
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:/mnt/projects/conf/doom-emacs/modules/lang/clojure/README.org][clojure]] =+lsp= - TODO
|
||||
+ common-lisp - TODO
|
||||
+ [[file:../modules/lang/coq/README.org][coq]] - TODO
|
||||
+ crystal - TODO
|
||||
+ [[file:../modules/lang/csharp/README.org][csharp]] - TODO
|
||||
+ data - TODO
|
||||
+ [[file:../modules/lang/elixir/README.org][elixir]] =+lsp= - TODO
|
||||
+ elm - TODO
|
||||
+ emacs-lisp - TODO
|
||||
+ erlang - TODO
|
||||
+ [[file:../modules/lang/ess/README.org][ess]] =+lsp= - TODO
|
||||
+ [[file:../modules/lang/faust/README.org][faust]] - TODO
|
||||
+ [[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
|
||||
+ hy - TODO
|
||||
+ [[file:../modules/lang/idris/README.org][idris]] - TODO
|
||||
+ java =+meghanada +lsp= - TODO
|
||||
+ [[file:../modules/lang/javascript/README.org][javascript]] =+lsp= - JavaScript, TypeScript, and CoffeeScript support
|
||||
+ julia - TODO
|
||||
+ kotlin =+lsp+= - TODO
|
||||
+ [[file:../modules/lang/latex/README.org][latex]] =+latexmk +cdlatex= - TODO
|
||||
+ lean - TODO
|
||||
+ [[file:../modules/lang/ledger/README.org][ledger]] - TODO
|
||||
+ lua =+moonscript= - TODO
|
||||
+ [[file:../modules/lang/markdown/README.org][markdown]] =+grip= - TODO
|
||||
+ [[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/perl/README.org][perl]] - TODO
|
||||
+ [[file:../modules/lang/php/README.org][php]] =+lsp= - TODO
|
||||
+ plantuml - TODO
|
||||
+ purescript - TODO
|
||||
+ [[file:../modules/lang/python/README.org][python]] =+lsp +pyenv +conda= - TODO
|
||||
+ qt - TODO
|
||||
+ racket - TODO
|
||||
+ [[file:../modules/lang/rest/README.org][rest]] - TODO
|
||||
+ ruby =+lsp +rvm +rbenv= - TODO
|
||||
+ [[file:../modules/lang/rust/README.org][rust]] =+lsp= - TODO
|
||||
+ scala =+lsp= - TODO
|
||||
+ [[file:../modules/lang/scheme/README.org][scheme]] - TODO
|
||||
+ [[file:../modules/lang/sh/README.org][sh]] =+fish +lsp= - TODO
|
||||
+ [[file:../modules/lang/solidity/README.org][solidity]] - TODO
|
||||
+ swift =+lsp= - TODO
|
||||
+ terra - TODO
|
||||
+ web =+lsp= - HTML and CSS (SCSS/SASS/LESS/Stylus) support.
|
||||
|
||||
* :term
|
||||
Modules that offer terminal emulation.
|
||||
|
||||
+ eshell - TODO
|
||||
+ shell - TODO
|
||||
+ term - TODO
|
||||
+ [[file:../modules/term/vterm/README.org][vterm]] - TODO
|
||||
|
||||
* :tools
|
||||
Small modules that give Emacs access to external tools & services.
|
||||
|
||||
+ ansible - TODO
|
||||
+ debugger - 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
|
||||
+ [[file:../modules/tools/ein/README.org][ein]] - TODO
|
||||
+ [[file:../modules/tools/eval/README.org][eval]] =+overlay= - REPL & code evaluation support for a variety of languages
|
||||
+ gist - TODO
|
||||
+ [[file:../modules/tools/lookup/README.org][lookup]] =+dictionary +docsets= - Universal jump-to & documentation lookup
|
||||
backend
|
||||
+ [[file:../modules/tools/lsp/README.org][lsp]] - TODO
|
||||
+ macos - TODO
|
||||
+ magit - TODO
|
||||
+ make - TODO
|
||||
+ pass - TODO
|
||||
+ pdf - TODO
|
||||
+ prodigy - TODO
|
||||
+ rgb - TODO
|
||||
+ [[file:../modules/tools/terraform/README.org][terraform]]
|
||||
+ tmux - TODO
|
||||
+ upload - TODO
|
||||
|
||||
* :ui
|
||||
Aesthetic modules that affect the Emacs interface or user experience.
|
||||
|
||||
+ [[file:../modules/ui/deft/README.org][deft]] - TODO
|
||||
+ [[file:../modules/ui/doom/README.org][doom]] - TODO
|
||||
+ [[file:../modules/ui/doom-dashboard/README.org][doom-dashboard]] - TODO
|
||||
+ [[file:../modules/ui/doom-quit/README.org][doom-quit]] - TODO
|
||||
+ fill-column - TODO
|
||||
+ [[file:../modules/ui/hl-todo/README.org][hl-todo]] - TODO
|
||||
+ [[file:../modules/ui/hydra/README.org][hydra]] - TODO
|
||||
+ indent-guides - TODO
|
||||
+ [[file:../modules/ui/modeline/README.org][modeline]] - TODO
|
||||
+ [[file:../modules/ui/nav-flash/README.org][nav-flash]] - TODO
|
||||
+ [[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/tabs/README.org][tabs]] - TODO
|
||||
+ treemacs - TODO
|
||||
+ [[file:../modules/ui/unicode/README.org][unicode]] - TODO
|
||||
+ vc-gutter - TODO
|
||||
+ vi-tilde-fringe - TODO
|
||||
+ [[file:../modules/ui/window-select/README.org][window-select]] =+switch-window +numbers= - TODO
|
||||
+ [[file:../modules/ui/workspaces/README.org][workspaces]] - Isolated workspaces
|
||||
+ [[file:../modules/ui/zen/README.org][zen]] - Distraction-free coding (or writing)
|
|
@ -1,7 +1,15 @@
|
|||
#+TITLE: Workflow tips, tricks & tutorials
|
||||
#+TITLE: Getting to know Doom Emacs
|
||||
#+STARTUP: nofold
|
||||
|
||||
This page is a WIP.
|
||||
Once you've installed Doom and launched it, the next step of your masochistic
|
||||
journey is to master it. This guide will walk you through many Doom-centric
|
||||
workflows you'll commonly find in a text editor (and beyond). It isn't
|
||||
exhaustive because I don't have enough lives to make it so.
|
||||
|
||||
#+begin_quote
|
||||
If you feel like we've missed something, don't hesitate to let us know! You're
|
||||
welcome to [[https://discord.gg/qvGgnVx][join us on our Discord server]].
|
||||
#+end_quote
|
||||
|
||||
* Table of Contents :TOC:
|
||||
- [[#day-1-in-doom-emacs][Day 1 in Doom Emacs]]
|
||||
|
@ -14,6 +22,7 @@ This page is a WIP.
|
|||
- [[#pipe-text-through-ex-commands-and-programs][Pipe text through ex commands and programs]]
|
||||
- [[#transposingswapping-text][Transposing/swapping text]]
|
||||
- [[#managing-your-projects][Managing your projects]]
|
||||
- [[#reconfiguring-emacs-on-a-per-project-basis][Reconfiguring Emacs on a per-project basis]]
|
||||
- [[#search--replace][Search & replace]]
|
||||
- [[#project-wide-text-search][Project-wide text search]]
|
||||
- [[#search--replace-1][Search & replace]]
|
||||
|
@ -32,6 +41,8 @@ This page is a WIP.
|
|||
- [[#using-emacs-for][Using Emacs for...]]
|
||||
- [[#writing-fiction][Writing fiction]]
|
||||
- [[#writing-papers][Writing papers]]
|
||||
- [[#note-keeping][Note-keeping]]
|
||||
- [[#a-personal-organizer][A Personal Organizer]]
|
||||
- [[#composing-music][Composing music]]
|
||||
- [[#game-development][Game development]]
|
||||
- [[#web-development][Web development]]
|
||||
|
@ -48,6 +59,9 @@ This page is a WIP.
|
|||
** TODO Pipe text through ex commands and programs
|
||||
** TODO Transposing/swapping text
|
||||
* TODO Managing your projects
|
||||
** TODO Reconfiguring Emacs on a per-project basis
|
||||
*** TODO .dir-locals.el
|
||||
*** TODO editorconfig
|
||||
* TODO Search & replace
|
||||
** TODO Project-wide text search
|
||||
** TODO Search & replace
|
||||
|
@ -66,6 +80,8 @@ This page is a WIP.
|
|||
* TODO Using Emacs for...
|
||||
** TODO Writing fiction
|
||||
** TODO Writing papers
|
||||
** TODO Note-keeping
|
||||
** TODO A Personal Organizer
|
||||
** TODO Composing music
|
||||
** TODO Game development
|
||||
** TODO Web development
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
;; loaded, but after `early-init-file'. Doom handles package initialization, so
|
||||
;; we must prevent Emacs from doing it early!
|
||||
(setq package-enable-at-startup nil)
|
||||
(advice-add #'package--ensure-init-file :override #'ignore)
|
||||
|
||||
;; Prevent the glimpse of un-styled Emacs by disabling these UI elements early.
|
||||
(push '(menu-bar-lines . 0) default-frame-alist)
|
||||
|
|
11
init.el
11
init.el
|
@ -28,14 +28,13 @@
|
|||
;;; License: MIT
|
||||
|
||||
;; A big contributor to startup times is garbage collection. We up the gc
|
||||
;; threshold to temporarily prevent it from running, then reset it later with
|
||||
;; `doom-restore-garbage-collection-h'. Not resetting it will cause
|
||||
;; stuttering/freezes.
|
||||
;; threshold to temporarily prevent it from running, then reset it later by
|
||||
;; enabling `gcmh-mode'. Not resetting it will cause stuttering/freezes.
|
||||
(setq gc-cons-threshold most-positive-fixnum)
|
||||
|
||||
;; In noninteractive sessions, prioritize non-byte-compiled source files to
|
||||
;; prevent the use of stale byte-code. Otherwise, it saves us a little IO time
|
||||
;; to skip the mtime checks on every *.elc file we load.
|
||||
;; to skip the mtime checks on every *.elc file.
|
||||
(setq load-prefer-newer noninteractive)
|
||||
|
||||
(let (file-name-handler-alist)
|
||||
|
@ -51,6 +50,4 @@
|
|||
(if noninteractive
|
||||
(doom-initialize-packages)
|
||||
(doom-initialize-core)
|
||||
(doom-initialize-modules)
|
||||
(add-hook 'window-setup-hook #'doom-display-benchmark-h)
|
||||
(add-to-list 'command-switch-alist (cons "--restore" #'doom-restore-session-handler)))
|
||||
(doom-initialize-modules))
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
;;; init.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copy this file to ~/.doom.d/init.el or ~/.config/doom/init.el ('doom install'
|
||||
;; will do this for you). The `doom!' block below controls what modules are
|
||||
;; enabled and in what order they will be loaded. Remember to run 'doom refresh'
|
||||
;; 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.
|
||||
|
||||
;; 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
|
||||
;; flags as well (those symbols that start with a plus).
|
||||
;;
|
||||
;; More information about these modules (and what flags they support) can be
|
||||
;; found in modules/README.org.
|
||||
;; Alternatively, press 'gd' (or 'C-c g d') on a module to browse its
|
||||
;; directory (for easy access to its source code).
|
||||
|
||||
(doom! :input
|
||||
;;chinese
|
||||
|
@ -42,6 +48,7 @@
|
|||
vi-tilde-fringe ; fringe tildes to mark beyond EOB
|
||||
window-select ; visually switch windows
|
||||
workspaces ; tab emulation, persistence & separate workspaces
|
||||
;;zen ; distraction-free coding or writing
|
||||
|
||||
:editor
|
||||
(evil +everywhere); come to the dark side, we have cookies
|
||||
|
@ -69,6 +76,11 @@
|
|||
;;term ; terminals in Emacs
|
||||
;;vterm ; another terminals in Emacs
|
||||
|
||||
:checkers
|
||||
syntax ; tasing you for every semicolon you forget
|
||||
;;spell ; tasing you for misspelling mispelling
|
||||
;;grammar ; tasing grammar mistake every you make
|
||||
|
||||
:tools
|
||||
;;ansible
|
||||
;;debugger ; FIXME stepping through code, to help you add bugs
|
||||
|
@ -77,8 +89,6 @@
|
|||
;;editorconfig ; let someone else argue about tabs vs spaces
|
||||
;;ein ; tame Jupyter notebooks with emacs
|
||||
(eval +overlay) ; run code, run (also, repls)
|
||||
flycheck ; tasing you for every semicolon you forget
|
||||
;;flyspell ; tasing you for misspelling mispelling
|
||||
;;gist ; interacting with github gists
|
||||
(lookup ; helps you navigate your code and documentation
|
||||
+docsets) ; ...or in Dash docsets locally
|
||||
|
@ -93,7 +103,6 @@
|
|||
;;terraform ; infrastructure as code
|
||||
;;tmux ; an API for interacting with tmux
|
||||
;;upload ; map local to remote projects via ssh/ftp
|
||||
;;wakatime
|
||||
|
||||
:lang
|
||||
;;agda ; types of types of types of types...
|
||||
|
@ -112,8 +121,9 @@
|
|||
;;ess ; emacs speaks statistics
|
||||
;;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
|
||||
;;(haskell +intero) ; a language that's lazier than I am
|
||||
;;(haskell +dante) ; a language that's lazier than I am
|
||||
;;hy ; readability of scheme w/ speed of python
|
||||
;;idris ;
|
||||
;;(java +meghanada) ; the poster child for carpal tunnel syndrome
|
||||
|
@ -122,6 +132,7 @@
|
|||
;;kotlin ; a better, slicker Java(Script)
|
||||
;;latex ; writing papers in Emacs has never been so fun
|
||||
;;lean
|
||||
;;factor
|
||||
;;ledger ; an accounting system in Emacs
|
||||
;;lua ; one-based indices? one-based indices
|
||||
markdown ; writing docs for people to ignore
|
||||
|
@ -131,8 +142,8 @@
|
|||
(org ; organize your plain life in plain text
|
||||
+dragndrop ; drag & drop files/images into org buffers
|
||||
;;+hugo ; use Emacs for hugo blogging
|
||||
+ipython ; ipython/jupyter support for babel
|
||||
+pandoc ; export-with-pandoc support
|
||||
;;+jupyter ; ipython/jupyter support for babel
|
||||
;;+pandoc ; export-with-pandoc support
|
||||
;;+pomodoro ; be fruitful with the tomato technique
|
||||
+present) ; using org-mode for presentations
|
||||
;;perl ; write code no one else can comprehend
|
||||
|
@ -164,7 +175,6 @@
|
|||
;;irc ; how neckbeards socialize
|
||||
;;(rss +org) ; emacs as an RSS reader
|
||||
;;twitter ; twitter client https://twitter.com/vnought
|
||||
;;write ; emacs for writers (fiction, notes, papers, etc.)
|
||||
|
||||
:config
|
||||
;;literate
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
(defvar +calendar--wconf nil)
|
||||
|
||||
(defun +calendar--init ()
|
||||
(if-let* ((win (cl-loop for win in (doom-visible-windows)
|
||||
if (string-match-p "^\\*cfw:" (buffer-name (window-buffer win)))
|
||||
return win)))
|
||||
(if-let (win (cl-find-if (lambda (b) (string-match-p "^\\*cfw:" (buffer-name b)))
|
||||
(doom-visible-windows)
|
||||
:key #'window-buffer))
|
||||
(select-window win)
|
||||
(call-interactively +calendar-open-function)))
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; app/calendar/packages.el
|
||||
|
||||
(package! calfw)
|
||||
(package! calfw-org)
|
||||
(package! org-gcal)
|
||||
(package! calfw :pin "03abce9762")
|
||||
(package! calfw-org :pin "03abce9762")
|
||||
(package! org-gcal :pin "6821e34967")
|
||||
|
|
|
@ -7,8 +7,11 @@
|
|||
- [[#description][Description]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#dependencies][Dependencies]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#macos][macOS]]
|
||||
- [[#debian--ubuntu][Debian / Ubuntu]]
|
||||
- [[#arch-linux][Arch Linux]]
|
||||
- [[#nixos][NixOS]]
|
||||
- [[#features][Features]]
|
||||
- [[#an-irc-client-in-emacs][An IRC Client in Emacs]]
|
||||
- [[#configuration][Configuration]]
|
||||
|
@ -17,7 +20,7 @@
|
|||
- [[#troubleshooting][Troubleshooting]]
|
||||
|
||||
* Description
|
||||
This module turns adds an IRC client to Emacs with OS notifications.
|
||||
This module turns Emacs into an IRC client, capable of OS notifications.
|
||||
|
||||
** Module Flags
|
||||
This module provides no flags.
|
||||
|
@ -26,11 +29,27 @@ This module provides no flags.
|
|||
+ [[https://github.com/jorgenschaefer/circe][circe]]
|
||||
+ [[https://github.com/eqyiel/circe-notifications][circe-notifications]]
|
||||
|
||||
* Dependencies
|
||||
This module requires =gnutls-cli= or =openssl= for secure connections.
|
||||
|
||||
* Prerequisites
|
||||
This module has no direct prerequisites.
|
||||
This module requires =gnutls= for secure IRC connections to work.
|
||||
|
||||
** macOS
|
||||
#+BEGIN_SRC sh
|
||||
brew install gnutls
|
||||
#+END_SRC
|
||||
|
||||
** Debian / Ubuntu
|
||||
#+BEGIN_SRC sh
|
||||
apt install gnutls-bin
|
||||
#+END_SRC
|
||||
|
||||
** Arch Linux
|
||||
#+BEGIN_SRC sh
|
||||
pacman -S gnutls
|
||||
#+END_SRC
|
||||
** NixOS
|
||||
#+BEGIN_SRC nix
|
||||
environment.systemPackages = [ pkgs.gnutls ];
|
||||
#+END_SRC
|
||||
|
||||
* Features
|
||||
** An IRC Client in Emacs
|
||||
|
@ -54,20 +73,23 @@ When in a circe buffer these keybindings will be available.
|
|||
| ~circe-reconnect~ | =SPC m R= | Reconnect the current server |
|
||||
|
||||
* Configuration
|
||||
Use ~set-irc-server!~ to configure IRC servers. Its second argument (a plist)
|
||||
Use ~set-irc-server! SERVER PLIST~ to configure IRC servers. Its second argument (a plist)
|
||||
takes the same arguments as ~circe-network-options~.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp :tangle no
|
||||
(set-irc-server! "chat.freenode.net"
|
||||
`(:tls t
|
||||
:nick "doom"
|
||||
:sasl-username "myusername"
|
||||
:sasl-password "mypassword"
|
||||
:channels ("#emacs")))
|
||||
;; if you omit =:host=, ~SERVER~ will be used instead.
|
||||
(after! circe
|
||||
(set-irc-server! "chat.freenode.net"
|
||||
`(:tls t
|
||||
:port 6697
|
||||
:nick "doom"
|
||||
:sasl-username "myusername"
|
||||
:sasl-password "mypassword"
|
||||
:channels ("#emacs"))))
|
||||
#+END_SRC
|
||||
|
||||
*It is a obviously a bad idea to store auth-details in plaintext,* so here are
|
||||
some ways to avoid that:
|
||||
However, *it is a obviously a bad idea to store your password in plaintext,* so
|
||||
here are ways to avoid that:
|
||||
|
||||
** Pass: the unix password manager
|
||||
[[https://www.passwordstore.org/][Pass]] is my tool of choice. I use it to manage my passwords. If you activate the
|
||||
|
@ -80,6 +102,7 @@ password store.
|
|||
#+BEGIN_SRC emacs-lisp :tangle no
|
||||
(set-irc-server! "chat.freenode.net"
|
||||
`(:tls t
|
||||
:port 6697
|
||||
:nick "doom"
|
||||
:sasl-username ,(+pass-get-user "irc/freenode.net")
|
||||
:sasl-password ,(+pass-get-secret "irc/freenode.net")
|
||||
|
@ -105,10 +128,10 @@ Note that =+pass-get-user= tries to find your username by looking for the fields
|
|||
listed in =+pass-user-fields= (by default =login=, =user==, =username== and
|
||||
=email=)=). An example configuration looks like
|
||||
|
||||
#+BEGIN_SRC txt :tangle no
|
||||
#+begin_example
|
||||
mysecretpassword
|
||||
username: myusername
|
||||
#+END_SRC
|
||||
#+end_example
|
||||
|
||||
** Emacs' auth-source API
|
||||
~auth-source~ is built into Emacs. As suggested [[https://github.com/jorgenschaefer/circe/wiki/Configuration#safer-password-management][in the circe wiki]], you can store
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
(defvar +irc--workspace-name "*IRC*")
|
||||
|
||||
(defun +irc-setup-wconf (&optional inhibit-workspace)
|
||||
(unless inhibit-workspace
|
||||
(+workspace-switch +irc--workspace-name t))
|
||||
(when (and (featurep! :ui workspaces)
|
||||
(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)))
|
||||
|
@ -20,17 +21,12 @@
|
|||
If INHIBIT-WORKSPACE (the universal argument) is non-nil, don't spawn a new
|
||||
workspace for it."
|
||||
(interactive "P")
|
||||
(cond ((and (featurep! :ui workspaces)
|
||||
(+workspace-exists-p +irc--workspace-name))
|
||||
(+workspace-switch +irc--workspace-name))
|
||||
((not (+irc-setup-wconf inhibit-workspace))
|
||||
(user-error "Couldn't start up a workspace for IRC")))
|
||||
(if (doom-buffers-in-mode 'circe-mode (buffer-list) t)
|
||||
(message "Circe buffers are already open")
|
||||
(if circe-network-options
|
||||
(cl-loop for network in circe-network-options
|
||||
collect (circe (car network)))
|
||||
(call-interactively #'circe))))
|
||||
(+irc-setup-wconf inhibit-workspace)
|
||||
(cond ((doom-buffers-in-mode 'circe-mode (doom-buffer-list) t)
|
||||
(message "Circe buffers are already open"))
|
||||
(circe-network-options
|
||||
(mapc #'circe (mapcar #'car circe-network-options)))
|
||||
((call-interactively #'circe))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +irc/connect (&optional inhibit-workspace)
|
||||
|
@ -52,16 +48,17 @@ workspace for it."
|
|||
(defun +irc/quit ()
|
||||
"Kill current circe session and workgroup."
|
||||
(interactive)
|
||||
(if (y-or-n-p "Really kill IRC session?")
|
||||
(let (circe-channel-killed-confirmation
|
||||
circe-server-killed-confirmation)
|
||||
(when +irc--defer-timer
|
||||
(cancel-timer +irc--defer-timer))
|
||||
(disable-circe-notifications)
|
||||
(mapc #'kill-buffer (doom-buffers-in-mode 'circe-mode (buffer-list) t))
|
||||
(when (equal (+workspace-current-name) +irc--workspace-name)
|
||||
(+workspace/delete +irc--workspace-name)))
|
||||
(message "Aborted")))
|
||||
(unless (y-or-n-p "Really kill IRC session?")
|
||||
(user-error "Aborted"))
|
||||
(let (circe-channel-killed-confirmation
|
||||
circe-server-killed-confirmation)
|
||||
(when +irc--defer-timer
|
||||
(cancel-timer +irc--defer-timer))
|
||||
(disable-circe-notifications)
|
||||
(mapc #'kill-buffer (doom-buffers-in-mode 'circe-mode (buffer-list) t))
|
||||
(when (featurep! :ui workspaces)
|
||||
(when (equal (+workspace-current-name) +irc--workspace-name)
|
||||
(+workspace/delete +irc--workspace-name)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +irc/ivy-jump-to-channel (&optional this-server)
|
||||
|
@ -93,7 +90,7 @@ argument) is non-nil only show channels in current server."
|
|||
|
||||
;;;###autoload
|
||||
(defun +irc/tracking-next-buffer ()
|
||||
"Dissables switching to an unread buffer unless in the irc workspace."
|
||||
"Disables switching to an unread buffer unless in the irc workspace."
|
||||
(interactive)
|
||||
(when (derived-mode-p 'circe-mode)
|
||||
(tracking-next-buffer)))
|
||||
|
@ -106,13 +103,12 @@ argument) is non-nil only show channels in current server."
|
|||
(defun +circe-buffer-p (buf)
|
||||
"Return non-nil if BUF is a `circe-mode' buffer."
|
||||
(with-current-buffer buf
|
||||
(and (derived-mode-p 'circe-mode)
|
||||
(eq (safe-persp-name (get-current-persp))
|
||||
+irc--workspace-name))))
|
||||
(derived-mode-p 'circe-mode)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +irc--add-circe-buffer-to-persp-h ()
|
||||
(when (bound-and-true-p persp-mode)
|
||||
(when (and (bound-and-true-p persp-mode)
|
||||
(+workspace-exists-p +irc--workspace-name))
|
||||
(let ((persp (get-current-persp))
|
||||
(buf (current-buffer)))
|
||||
;; Add a new circe buffer to irc workspace when we're in another workspace
|
||||
|
|
|
@ -1,9 +1,17 @@
|
|||
;;; app/irc/autoload/settings.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autodef
|
||||
(defun set-irc-server! (server letvars)
|
||||
(defun set-irc-server! (server plist)
|
||||
"Registers an irc SERVER for circe.
|
||||
|
||||
SERVER can either be a name for the network (in which case you must specify a
|
||||
:host), or it may be the hostname itself, in which case it will be used as the
|
||||
:host.
|
||||
|
||||
See `circe-network-options' for details."
|
||||
(after! circe
|
||||
(push (cons server letvars) circe-network-options)))
|
||||
(unless (plist-member plist :host)
|
||||
(plist-put! plist :host server))
|
||||
(setf (alist-get server circe-network-options
|
||||
nil nil #'equal)
|
||||
plist)))
|
||||
|
|
|
@ -93,6 +93,7 @@ playback.")
|
|||
(add-hook 'doom-real-buffer-functions #'+circe-buffer-p)
|
||||
(add-hook 'circe-channel-mode-hook #'turn-on-visual-line-mode)
|
||||
(add-hook 'circe-mode-hook #'+irc--add-circe-buffer-to-persp-h)
|
||||
(add-hook 'circe-mode-hook #'turn-off-smartparens-mode)
|
||||
|
||||
(defadvice! +irc--circe-run-disconnect-hook-a (&rest _)
|
||||
"Runs `+irc-disconnect-hook' after circe disconnects."
|
||||
|
@ -175,7 +176,7 @@ playback.")
|
|||
(define-key lui-mode-map "\C-u" #'lui-kill-to-beginning-of-line)
|
||||
(setq lui-fill-type nil)
|
||||
|
||||
(when (featurep! :tools flyspell)
|
||||
(when (featurep! :checkers spell)
|
||||
(setq lui-flyspell-p t))
|
||||
|
||||
(after! evil
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; app/irc/packages.el
|
||||
|
||||
(package! circe)
|
||||
(package! circe-notifications)
|
||||
(package! circe :pin "0c79138fb2")
|
||||
(package! circe-notifications :pin "291149ac12")
|
||||
|
|
|
@ -49,4 +49,3 @@ https://mediatemple.net"
|
|||
(set-popup-rules!
|
||||
'(("^\\*doom-regex\\*$" :size 4 :quit nil)
|
||||
("^\\*doom-regex-groups" :side 'left :size 28 :select nil :quit nil)))
|
||||
|
||||
|
|
|
@ -4,10 +4,6 @@
|
|||
;; by apps Reeder and Readkit. It can be invoked via `=rss'. Otherwise, if you
|
||||
;; don't care for the UI you can invoke elfeed directly with `elfeed'.
|
||||
|
||||
(defvar +rss-elfeed-files (list "elfeed.org")
|
||||
"Where to look for elfeed.org files, relative to `org-directory'. Can be
|
||||
absolute paths.")
|
||||
|
||||
(defvar +rss-split-direction 'below
|
||||
"What direction to pop up the entry buffer in elfeed.")
|
||||
|
||||
|
@ -67,8 +63,11 @@ easier to scroll through.")
|
|||
(use-package! elfeed-org
|
||||
:when (featurep! +org)
|
||||
:after elfeed
|
||||
:init
|
||||
(setq rmh-elfeed-org-files (list "elfeed.org"))
|
||||
:config
|
||||
(let ((default-directory org-directory))
|
||||
(setq rmh-elfeed-org-files
|
||||
(mapcar #'expand-file-name +rss-elfeed-files)))
|
||||
(elfeed-org))
|
||||
(and (let ((default-directory org-directory))
|
||||
(setq rmh-elfeed-org-files
|
||||
(cl-remove-if-not
|
||||
#'file-exists-p (mapcar #'expand-file-name rmh-elfeed-org-files))))
|
||||
(elfeed-org)))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; app/rss/packages.el
|
||||
|
||||
(package! elfeed)
|
||||
(package! elfeed-org)
|
||||
(package! elfeed :pin "3f0edb1737")
|
||||
(package! elfeed-org :pin "77b6bbf222")
|
||||
|
|
|
@ -83,6 +83,7 @@ that works with the feature/popup module."
|
|||
"Open a visible link, username or hashtag in a `twittering-mode' buffer."
|
||||
(interactive)
|
||||
(require 'avy)
|
||||
;; REVIEW Is this necessary anymore with `link-hint'
|
||||
(let ((pt (avy-with +twitter/ace-link
|
||||
(avy--process
|
||||
(+twitter--collect-links)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; app/twitter/packages.el
|
||||
|
||||
(package! twittering-mode)
|
||||
(package! avy)
|
||||
(package! twittering-mode :pin "114891e8fd")
|
||||
(package! avy :pin "cf95ba9582")
|
||||
|
|
|
@ -1,131 +0,0 @@
|
|||
#+TITLE: app/write
|
||||
#+DATE: October 10, 2019
|
||||
#+SINCE: v1.3
|
||||
#+STARTUP: inlineimages
|
||||
|
||||
* Table of Contents :TOC_3:noexport:
|
||||
- [[#description][Description]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#language-tool][Language Tool]]
|
||||
- [[#wordnut][Wordnut]]
|
||||
- [[#features][Features]]
|
||||
- [[#m-x-write-mode][~M-x +write-mode~]]
|
||||
- [[#language-tool-langtool][Language Tool ~+langtool~]]
|
||||
- [[#commands][Commands]]
|
||||
- [[#wordnut-wordnut][Wordnut ~+wordnut~]]
|
||||
- [[#commands-1][Commands]]
|
||||
- [[#synosaurus][Synosaurus]]
|
||||
- [[#commands-2][Commands]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#mixed-pitch-mode][mixed-pitch-mode]]
|
||||
- [[#appendix][Appendix]]
|
||||
- [[#minor-modes][Minor modes]]
|
||||
- [[#commands-3][Commands]]
|
||||
|
||||
* Description
|
||||
Adds word processing tools and the ~+write-mode~ minor mode, which converts
|
||||
Emacs into a more comfortable writing environment.
|
||||
|
||||
** Module Flags
|
||||
This module provides two module flags:
|
||||
|
||||
- ~+langtool~ Enables language tool integration.
|
||||
- ~+wordnut~ Enables wordnet integration.
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/hpdeifel/synosaurus][synosaurus]]
|
||||
+ [[https://gitlab.com/jabranham/mixed-pitch][mixed-pitch]]
|
||||
+ [[https://github.com/joostkremers/visual-fill-column][visual-fill-column]]
|
||||
+ [[https://github.com/mhayashi1120/Emacs-langtool][langtool]]* (=+langtool=)
|
||||
+ [[https://github.com/gromnitsky/wordnut][wordnut]]* (=+wordnut=)
|
||||
|
||||
* Prerequisites
|
||||
** Language Tool
|
||||
Either download and deploy it from https://languagetool.org/ or install it
|
||||
through your OS package manager:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
# MacOS/Homebrew users:
|
||||
brew install languagetool
|
||||
|
||||
# Arch Linux users:
|
||||
sudo pacman -S languagetool
|
||||
#+END_SRC
|
||||
|
||||
This module tries to guess the location of languagetool-commandline.jar. If you
|
||||
get a warning that Doom =couldn't find languagetool-commandline.jar=, you will
|
||||
need to find langaugetool-commandline.jar and set ~langtool-language-tool-jar~
|
||||
to its path.
|
||||
|
||||
** Wordnut
|
||||
This requires =wordnet= to be installed, which should be available through your
|
||||
OS package manager:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
# MacOS/Homebrew users:
|
||||
brew install wordnet
|
||||
|
||||
# Arch Linux users:
|
||||
sudo pacaur -S wordnet # on the AUR
|
||||
#+END_SRC
|
||||
|
||||
* Features
|
||||
** ~M-x +write-mode~
|
||||
Write mode makes Emacs a more comfortable writing environment by:
|
||||
|
||||
- Centering the buffer (with ~visual-fill-column-mode~), ala distraction-free
|
||||
mode from other text editors.
|
||||
- Soft-wrapping long text lines with ~visual-line-mode~.
|
||||
- Enabling ~mixed-pitch-mode~, allowing fixed-width and variable-pitch fonts to
|
||||
co-exist in one buffer. For example, a monospace font for SRC blocks and Arial
|
||||
for everything else.
|
||||
- In org-mode:
|
||||
- Turns on ~org-indent-mode~
|
||||
- Turns on ~+org-pretty-mode~
|
||||
|
||||
** Language Tool ~+langtool~
|
||||
[[https://www.languagetool.org/][Language Tool]] is a polyglot proofreader service that checks for grammar and
|
||||
stylistic issues in your writing. This requires Java 1.8+.
|
||||
|
||||
#+begin_quote
|
||||
This requires Java 1.8+
|
||||
#+end_quote
|
||||
|
||||
*** Commands
|
||||
- ~langtool-check~
|
||||
- ~langtool-correct-buffer~
|
||||
|
||||
** Wordnut ~+wordnut~
|
||||
Wordnut provides a searchable dictionary frontend for Emacs. This requires
|
||||
~wordnet~, which should be available in your OS's package manager.
|
||||
|
||||
*** Commands
|
||||
- ~wordnut-search~
|
||||
- ~wordnut-lookup-curent-word~
|
||||
|
||||
** Synosaurus
|
||||
Synosaurus provides a service for looking up synonyms. It requires an internet
|
||||
connection.
|
||||
|
||||
*** Commands
|
||||
- ~synosaurus-lookup~
|
||||
- ~synosaurus-choose-and-replace~
|
||||
|
||||
* Configuration
|
||||
** mixed-pitch-mode
|
||||
To configure which faces are displayed with fixed-pitch fonts in
|
||||
~mixed-pitch-mode~, look into ~mixed-pitch-fixed-pitch-faces~.
|
||||
|
||||
* Appendix
|
||||
** Minor modes
|
||||
- ~+write-mode~
|
||||
- ~mixed-pitch-mode~
|
||||
** Commands
|
||||
- ~langtool-check~
|
||||
- ~langtool-correct-buffer~
|
||||
- ~synosaurus-choose-and-replace~
|
||||
- ~synosaurus-lookup~
|
||||
- ~wordnut-lookup-curent-word~
|
||||
- ~wordnut-search~
|
|
@ -1,43 +0,0 @@
|
|||
;;; app/write/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defvar +write-mode-map (make-sparse-keymap)
|
||||
"TODO")
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode +write-mode
|
||||
"Turns Emacs into a more comfortable writing environment and word processor."
|
||||
:init-value nil
|
||||
:keymap +write-mode-map
|
||||
(setq-local visual-fill-column-center-text t)
|
||||
(when +write-text-scale
|
||||
(text-scale-set (if +write-mode 2 0)))
|
||||
(when +write-line-spacing
|
||||
(setq-local line-spacing +write-line-spacing)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +write|init-org-mode ()
|
||||
"Initializes `org-mode' specific settings for `+write-mode'."
|
||||
(when (eq major-mode 'org-mode)
|
||||
(+org-pretty-mode (if +write-mode +1 -1))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +write|init-line-numbers ()
|
||||
(display-line-numbers-mode (if +write-mode +1 -1)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +write|init-mixed-pitch ()
|
||||
(mixed-pitch-mode (if +write-mode +1 -1)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +write|init-visual-fill-column ()
|
||||
(visual-fill-column-mode (if +write-mode +1 -1)))
|
||||
|
||||
;;;###autoload
|
||||
(add-hook! '+write-mode-hook
|
||||
#'(flyspell-mode
|
||||
visual-line-mode
|
||||
+write|init-mixed-pitch
|
||||
+write|init-visual-fill-column
|
||||
+write|init-line-numbers
|
||||
+write|init-org-mode))
|
|
@ -1,56 +0,0 @@
|
|||
;;; app/write/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +write-text-scale nil
|
||||
"What to scale the text up to in `+write-mode'. Uses `text-scale-set'.")
|
||||
|
||||
(defvar +write-line-spacing nil
|
||||
"What to set `line-spacing' in `+write-mode'.")
|
||||
|
||||
;;
|
||||
;; Packages
|
||||
|
||||
(use-package! langtool
|
||||
:when (featurep! +langtool)
|
||||
:commands (langtool-check
|
||||
langtool-check-done
|
||||
langtool-show-message-at-point
|
||||
langtool-correct-buffer)
|
||||
:init (setq langtool-default-language "en-US")
|
||||
:config
|
||||
(unless langtool-language-tool-jar
|
||||
(setq langtool-language-tool-jar
|
||||
(cond (IS-MAC
|
||||
(locate-file "libexec/languagetool-commandline.jar"
|
||||
(doom-files-in "/usr/local/Cellar/languagetool"
|
||||
:type 'dirs
|
||||
:depth 2)))
|
||||
(IS-LINUX
|
||||
"/usr/share/java/languagetool/languagetool-commandline.jar")))))
|
||||
|
||||
|
||||
;; `synosaurus'
|
||||
(setq synosaurus-choose-method 'default)
|
||||
|
||||
|
||||
;; `mixed-pitch'
|
||||
(after! mixed-pitch
|
||||
(setq mixed-pitch-fixed-pitch-faces
|
||||
(append mixed-pitch-fixed-pitch-faces
|
||||
'(org-todo-keyword-todo
|
||||
org-todo-keyword-habt
|
||||
org-todo-keyword-done
|
||||
org-todo-keyword-wait
|
||||
org-todo-keyword-kill
|
||||
org-todo-keyword-outd
|
||||
org-todo
|
||||
org-indent
|
||||
line-number
|
||||
line-number-current-line
|
||||
org-special-keyword
|
||||
org-date
|
||||
org-property-value
|
||||
org-special-keyword
|
||||
org-property-value
|
||||
org-ref-cite-face
|
||||
org-tag
|
||||
font-lock-comment-face))))
|
|
@ -1,7 +0,0 @@
|
|||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; app/write/doctor.el
|
||||
|
||||
(when (featurep! +langtool)
|
||||
(require 'langtool)
|
||||
(unless (file-exists-p langtool-language-tool-jar)
|
||||
(warn! "Couldn't find languagetool-commandline.jar")))
|
|
@ -1,12 +0,0 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; app/write/packages.el
|
||||
|
||||
(package! synosaurus)
|
||||
(package! mixed-pitch)
|
||||
|
||||
(when (featurep! +langtool)
|
||||
(package! langtool))
|
||||
(when (featurep! +wordnut)
|
||||
(package! wordnut))
|
||||
|
||||
(package! visual-fill-column)
|
68
modules/checkers/grammar/README.org
Normal file
68
modules/checkers/grammar/README.org
Normal file
|
@ -0,0 +1,68 @@
|
|||
#+TITLE: checkers/grammar
|
||||
#+DATE: January 9, 2020
|
||||
#+SINCE: v3.0.0
|
||||
#+STARTUP: inlineimages nofold
|
||||
|
||||
* Table of Contents :TOC_3:noexport:
|
||||
- [[#description][Description]]
|
||||
- [[#maintainers][Maintainers]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#features][Features]]
|
||||
- [[#language-tool][Language Tool]]
|
||||
- [[#commands][Commands]]
|
||||
- [[#writegood-mode][writegood-mode]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#troubleshooting][Troubleshooting]]
|
||||
|
||||
* Description
|
||||
This module adds grammar checking to Emacs to aid your writing by combining
|
||||
=lang-tool= and =writegood-mode=.
|
||||
|
||||
** Maintainers
|
||||
This module has no dedicated maintainers.
|
||||
|
||||
** Module Flags
|
||||
This module provides no flags.
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/mhayashi1120/Emacs-langtool][langtool]]
|
||||
+ [[https://github.com/bnbeckwith/writegood-mode][writegood-mode]]
|
||||
|
||||
* Prerequisites
|
||||
This module requires langtool (which requires =Java 1.8+=).
|
||||
|
||||
It can be acquired either from https://languagetool.org/ or your OS's package
|
||||
manager:
|
||||
|
||||
+ macOS: ~brew install languagetool~
|
||||
+ Arch Linux: ~pacman -S languagetool~
|
||||
|
||||
This module tries to guess the location of languagetool-commandline.jar. If you
|
||||
get a warning that Doom =couldn't find languagetool-commandline.jar=, you will
|
||||
need to set ~langtool-language-tool-jar~ to its location.
|
||||
|
||||
* Features
|
||||
An in-depth list of features, how to use them, and their dependencies.
|
||||
|
||||
** Language Tool
|
||||
[[https://www.languagetool.org/][Language Tool]] is a polyglot proofreader service that checks for grammar and
|
||||
stylistic issues in your writing. This requires Java 1.8+.
|
||||
|
||||
#+begin_quote
|
||||
This requires Java 1.8+
|
||||
#+end_quote
|
||||
|
||||
*** Commands
|
||||
- ~langtool-check~
|
||||
- ~langtool-correct-buffer~
|
||||
|
||||
** writegood-mode
|
||||
This minor mode highlights weasel words, duplication and passive voice.
|
||||
|
||||
* Configuration
|
||||
How to configure this module, including common problems and how to address them.
|
||||
|
||||
* Troubleshooting
|
||||
Common issues and their solution, or places to look for help.
|
29
modules/checkers/grammar/config.el
Normal file
29
modules/checkers/grammar/config.el
Normal file
|
@ -0,0 +1,29 @@
|
|||
;;; checkers/grammar/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package! langtool
|
||||
:commands (langtool-check
|
||||
langtool-check-done
|
||||
langtool-show-message-at-point
|
||||
langtool-correct-buffer)
|
||||
:init (setq langtool-default-language "en-US")
|
||||
:config
|
||||
(unless langtool-language-tool-jar
|
||||
(setq langtool-language-tool-jar
|
||||
(cond (IS-MAC
|
||||
(locate-file "libexec/languagetool-commandline.jar"
|
||||
(doom-files-in "/usr/local/Cellar/languagetool"
|
||||
:type 'dirs
|
||||
:depth 2)))
|
||||
(IS-LINUX
|
||||
"/usr/share/java/languagetool/languagetool-commandline.jar")))))
|
||||
|
||||
|
||||
;; Detects weasel words, passive voice and duplicates. Proselint would be a
|
||||
;; better choice.
|
||||
(use-package! writegood-mode
|
||||
:hook (org-mode markdown-mode rst-mode asciidoc-mode latex-mode)
|
||||
:config
|
||||
(map! :localleader
|
||||
:map writegood-mode-map
|
||||
"g" #'writegood-grade-level
|
||||
"r" #'writegood-reading-ease))
|
5
modules/checkers/grammar/packages.el
Normal file
5
modules/checkers/grammar/packages.el
Normal file
|
@ -0,0 +1,5 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; checkers/grammar/packages.el
|
||||
|
||||
(package! langtool :pin "a71ed02ce0")
|
||||
(package! writegood-mode :pin "b71757ec33")
|
27
modules/checkers/spell/autoload.el
Normal file
27
modules/checkers/spell/autoload.el
Normal file
|
@ -0,0 +1,27 @@
|
|||
;;; checkers/spell/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autodef
|
||||
(defalias 'flyspell-mode! #'flyspell-mode)
|
||||
|
||||
(defvar +spell--flyspell-predicate-alist nil
|
||||
"TODO")
|
||||
|
||||
;;;###autodef
|
||||
(defun set-flyspell-predicate! (modes predicate)
|
||||
"TODO"
|
||||
(declare (indent defun))
|
||||
(dolist (mode (doom-enlist modes) +spell--flyspell-predicate-alist)
|
||||
(add-to-list '+spell--flyspell-predicate-alist (cons mode predicate))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +spell-init-flyspell-predicate-h ()
|
||||
"TODO"
|
||||
(when-let (pred (assq major-mode +spell--flyspell-predicate-alist))
|
||||
(setq-local flyspell-generic-check-word-predicate (cdr pred))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +spell-correction-at-point-p (&optional point)
|
||||
"TODO"
|
||||
(cl-loop for ov in (overlays-at (or point (point)))
|
||||
if (overlay-get ov 'flyspell-overlay)
|
||||
return t))
|
|
@ -1,11 +1,8 @@
|
|||
;;; tools/flyspell/config.el -*- lexical-binding: t; -*-
|
||||
;;; checkers/spell/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
(defvar ispell-dictionary "en_US")
|
||||
|
||||
(after! ispell
|
||||
(add-to-list 'ispell-extra-args "--dont-tex-check-comments")
|
||||
|
||||
;; Don't spellcheck org blocks
|
||||
(pushnew! ispell-skip-region-alist
|
||||
'(":\\(PROPERTIES\\|LOGBOOK\\):" . ":END:")
|
||||
|
@ -23,13 +20,13 @@
|
|||
((executable-find "hunspell") 'hunspell))
|
||||
(`aspell
|
||||
(setq ispell-program-name "aspell"
|
||||
ispell-extra-args '("--sug-mode=ultra" "--run-together"))
|
||||
ispell-extra-args '("--sug-mode=ultra" "--run-together" "--dont-tex-check-comments"))
|
||||
|
||||
(add-hook! 'text-mode-hook
|
||||
(defun +flyspell-remove-run-together-switch-for-aspell-h ()
|
||||
(defun +spell-remove-run-together-switch-for-aspell-h ()
|
||||
(setq-local ispell-extra-args (remove "--run-together" ispell-extra-args))))
|
||||
|
||||
(defun +flyspell-setup-ispell-extra-args-a (orig-fun &rest args)
|
||||
(defun +spell-init-ispell-extra-args-a (orig-fun &rest args)
|
||||
:around '(ispell-word flyspell-auto-correct-word)
|
||||
(let ((ispell-extra-args (remove "--run-together" ispell-extra-args)))
|
||||
(ispell-kill-ispell t)
|
||||
|
@ -49,12 +46,23 @@
|
|||
;; messages for every word when checking the entire buffer
|
||||
flyspell-issue-message-flag nil)
|
||||
|
||||
(add-hook 'text-mode-hook #'flyspell-mode)
|
||||
(when (featurep! +prog)
|
||||
(add-hook 'prog-mode-hook #'flyspell-prog-mode))
|
||||
(add-hook! '(org-mode-hook
|
||||
markdown-mode-hook
|
||||
TeX-mode-hook
|
||||
rst-mode-hook
|
||||
mu4e-compose-mode-hook
|
||||
message-mode-hook
|
||||
git-commit-mode-hook)
|
||||
#'flyspell-mode)
|
||||
|
||||
(when (featurep! +everywhere)
|
||||
(add-hook! '(yaml-mode-hook
|
||||
conf-mode-hook
|
||||
prog-mode-hook)
|
||||
#'flyspell-prog-mode))
|
||||
|
||||
(add-hook! 'flyspell-mode-hook
|
||||
(defun +flyspell-inhibit-duplicate-detection-maybe-h ()
|
||||
(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)
|
||||
|
@ -64,16 +72,21 @@ e.g. proselint and langtool."
|
|||
|
||||
;; Ensure mode-local predicates declared with `set-flyspell-predicate!' are
|
||||
;; used in their respective major modes.
|
||||
(add-hook 'flyspell-mode-hook #'+flyspell-init-predicate-h)
|
||||
(add-hook 'flyspell-mode-hook #'+spell-init-flyspell-predicate-h)
|
||||
|
||||
(map! :map flyspell-mouse-map
|
||||
"RET" #'flyspell-correct-word-generic
|
||||
[return] #'flyspell-correct-word-generic
|
||||
[mouse-1] #'flyspell-correct-word-generic))
|
||||
(let ((flyspell-correct
|
||||
(general-predicate-dispatch nil
|
||||
(and (not (or mark-active (ignore-errors (evil-insert-state-p))))
|
||||
(memq 'flyspell-incorrect (face-at-point nil t)))
|
||||
#'flyspell-correct-at-point)))
|
||||
(map! :map flyspell-mouse-map
|
||||
"RET" flyspell-correct
|
||||
[return] flyspell-correct
|
||||
[mouse-1] #'flyspell-correct-at-point)))
|
||||
|
||||
|
||||
(use-package! flyspell-correct
|
||||
:commands flyspell-correct-word-generic flyspell-correct-previous-word-generic
|
||||
:commands flyspell-correct-at-point flyspell-correct-previous
|
||||
:config
|
||||
(cond ((and (featurep! :completion helm)
|
||||
(require 'flyspell-correct-helm nil t)))
|
||||
|
@ -82,3 +95,7 @@ e.g. proselint and langtool."
|
|||
((require 'flyspell-correct-popup nil t)
|
||||
(setq flyspell-popup-correct-delay 0.8)
|
||||
(define-key popup-menu-keymap [escape] #'keyboard-quit))))
|
||||
|
||||
|
||||
(use-package! flyspell-lazy
|
||||
:after flyspell)
|
11
modules/checkers/spell/packages.el
Normal file
11
modules/checkers/spell/packages.el
Normal file
|
@ -0,0 +1,11 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; checkers/spell/packages.el
|
||||
|
||||
(package! flyspell-correct :pin "b0353a41a7")
|
||||
(cond ((featurep! :completion ivy)
|
||||
(package! flyspell-correct-ivy :pin "b0353a41a7"))
|
||||
((featurep! :completion helm)
|
||||
(package! flyspell-correct-helm :pin "b0353a41a7"))
|
||||
((package! flyspell-correct-popup :pin "b0353a41a7")))
|
||||
|
||||
(package! flyspell-lazy :pin "3ebf68cc9e")
|
25
modules/checkers/syntax/autoload.el
Normal file
25
modules/checkers/syntax/autoload.el
Normal file
|
@ -0,0 +1,25 @@
|
|||
;;; checkers/syntax/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autodef
|
||||
(defun set-next-checker! (mode checker next &optional append)
|
||||
"TODO"
|
||||
(let ((fn (intern (format "+syntax--init-checkers-for-%s-h" mode))))
|
||||
(fset fn
|
||||
(lambda ()
|
||||
(if (not (bound-and-true-p flycheck-mode))
|
||||
(add-hook 'flycheck-mode-hook fn 'append 'local)
|
||||
(flycheck-add-next-checker checker next append)
|
||||
(remove-hook 'flycheck-mode-hook fn 'local))))
|
||||
(add-hook (intern (format "%s-hook" mode)) fn)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +syntax-init-popups-h ()
|
||||
"Activate `flycheck-posframe-mode' if available and in GUI Emacs.
|
||||
Activate `flycheck-popup-tip-mode' otherwise.
|
||||
Do nothing if `lsp-ui-mode' is active and `lsp-ui-sideline-enable' is non-nil."
|
||||
(unless (and (bound-and-true-p lsp-ui-mode)
|
||||
lsp-ui-sideline-enable)
|
||||
(if (and (fboundp 'flycheck-posframe-mode)
|
||||
(display-graphic-p))
|
||||
(flycheck-posframe-mode +1)
|
||||
(flycheck-popup-tip-mode +1))))
|
|
@ -1,12 +1,7 @@
|
|||
;;; tools/flycheck/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +flycheck-lazy-idle-delay 3.0
|
||||
"The delay before flycheck checks the buffer, after a check that produces no
|
||||
errors.")
|
||||
|
||||
;;; checkers/syntax/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
;;; Flycheck
|
||||
|
||||
(use-package! flycheck
|
||||
:commands flycheck-list-errors flycheck-buffer
|
||||
|
@ -24,11 +19,10 @@ errors.")
|
|||
|
||||
;; Don't commandeer input focus if the error message pops up (happens when
|
||||
;; tooltips and childframes are disabled).
|
||||
(after! flycheck
|
||||
(set-popup-rule! flycheck-error-message-buffer :select nil))
|
||||
(set-popup-rule! "^\\*Flycheck error messages\\*" :select nil)
|
||||
|
||||
(add-hook! 'doom-escape-hook :append
|
||||
(defun +flycheck-buffer-h ()
|
||||
(defun +syntax-check-buffer-h ()
|
||||
"Flycheck buffer on ESC in normal mode."
|
||||
(when flycheck-mode
|
||||
(ignore-errors (flycheck-buffer))
|
||||
|
@ -47,7 +41,7 @@ errors.")
|
|||
|
||||
(use-package! flycheck-popup-tip
|
||||
:commands flycheck-popup-tip-show-popup flycheck-popup-tip-delete-popup
|
||||
:init (add-hook 'flycheck-mode-hook #'+flycheck-init-popups-h)
|
||||
:init (add-hook 'flycheck-mode-hook #'+syntax-init-popups-h)
|
||||
:config
|
||||
(setq flycheck-popup-tip-error-prefix "✕ ")
|
||||
(after! evil
|
||||
|
@ -55,7 +49,7 @@ errors.")
|
|||
;; the cursor's position or cause disruptive input delays.
|
||||
(add-hook! '(evil-insert-state-entry-hook evil-replace-state-entry-hook)
|
||||
#'flycheck-popup-tip-delete-popup)
|
||||
(defadvice! +flycheck--disable-popup-tip-maybe-a (&rest _)
|
||||
(defadvice! +syntax--disable-flycheck-popup-tip-maybe-a (&rest _)
|
||||
:before-while #'flycheck-popup-tip-show-popup
|
||||
(if evil-local-mode
|
||||
(eq evil-state 'normal)
|
||||
|
@ -65,7 +59,7 @@ errors.")
|
|||
(use-package! flycheck-posframe
|
||||
:when (featurep! +childframe)
|
||||
:defer t
|
||||
:init (add-hook 'flycheck-mode-hook #'+flycheck-init-popups-h)
|
||||
:init (add-hook 'flycheck-mode-hook #'+syntax-init-popups-h)
|
||||
:config
|
||||
(setq flycheck-posframe-warning-prefix "⚠ "
|
||||
flycheck-posframe-info-prefix "··· "
|
||||
|
@ -79,3 +73,7 @@ errors.")
|
|||
(add-hook! 'flycheck-posframe-inhibit-functions
|
||||
#'evil-insert-state-p
|
||||
#'evil-replace-state-p)))
|
||||
|
||||
|
||||
;;
|
||||
;;; TODO Flymake
|
9
modules/checkers/syntax/packages.el
Normal file
9
modules/checkers/syntax/packages.el
Normal file
|
@ -0,0 +1,9 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; checkers/syntax/packages.el
|
||||
|
||||
(package! flycheck :pin "74377fa9c7")
|
||||
(package! flycheck-popup-tip :pin "ef86aad907")
|
||||
(when (featurep! +childframe)
|
||||
(package! flycheck-posframe :pin "2b3e94c2e4"))
|
||||
|
||||
;; TODO flymake?
|
|
@ -26,9 +26,10 @@ https://assets.doomemacs.org/completion/company/overlay.png
|
|||
** Module Flags
|
||||
+ =+childframe= Enables displaying completion candidates in a child frame,
|
||||
rather than an overlay or tooltip (among with other UI enhancements). *This
|
||||
requires GUI Emacs 26.1+.*
|
||||
requires GUI Emacs 26.1+ and is incompatible with the =+tng= flag*
|
||||
+ =+tng= Enables completion using only ~TAB~. Pressing ~TAB~ will select the
|
||||
next completion suggestion, while ~S-TAB~ will select the previous one.
|
||||
next completion suggestion, while ~S-TAB~ will select the previous one. *This
|
||||
is incompatible with the =+childframe= flag*
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/company-mode/company-mode][company-mode]]
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
: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)
|
||||
;; 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'.
|
||||
|
@ -70,47 +71,42 @@
|
|||
company-box-max-candidates 50
|
||||
company-box-icons-alist 'company-box-icons-all-the-icons
|
||||
company-box-icons-functions
|
||||
'(+company-box-icons--yasnippet-fn
|
||||
company-box-icons--lsp
|
||||
+company-box-icons--elisp-fn
|
||||
company-box-icons--acphp)
|
||||
(cons #'+company-box-icons--elisp-fn
|
||||
(delq 'company-box-icons--elisp
|
||||
company-box-icons-functions))
|
||||
company-box-icons-all-the-icons
|
||||
`((Unknown . ,(all-the-icons-material "find_in_page" :height 0.8 :face 'all-the-icons-purple))
|
||||
(Text . ,(all-the-icons-material "text_fields" :height 0.8 :face 'all-the-icons-green))
|
||||
(Method . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
|
||||
(Function . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
|
||||
(Constructor . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
|
||||
(Field . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
|
||||
(Variable . ,(all-the-icons-material "adjust" :height 0.8 :face 'all-the-icons-blue))
|
||||
(Class . ,(all-the-icons-material "class" :height 0.8 :face 'all-the-icons-red))
|
||||
(Interface . ,(all-the-icons-material "settings_input_component" :height 0.8 :face 'all-the-icons-red))
|
||||
(Module . ,(all-the-icons-material "view_module" :height 0.8 :face 'all-the-icons-red))
|
||||
(Property . ,(all-the-icons-material "settings" :height 0.8 :face 'all-the-icons-red))
|
||||
(Unit . ,(all-the-icons-material "straighten" :height 0.8 :face 'all-the-icons-red))
|
||||
(Value . ,(all-the-icons-material "filter_1" :height 0.8 :face 'all-the-icons-red))
|
||||
(Enum . ,(all-the-icons-material "plus_one" :height 0.8 :face 'all-the-icons-red))
|
||||
(Keyword . ,(all-the-icons-material "filter_center_focus" :height 0.8 :face 'all-the-icons-red))
|
||||
(Snippet . ,(all-the-icons-material "short_text" :height 0.8 :face 'all-the-icons-red))
|
||||
(Color . ,(all-the-icons-material "color_lens" :height 0.8 :face 'all-the-icons-red))
|
||||
(File . ,(all-the-icons-material "insert_drive_file" :height 0.8 :face 'all-the-icons-red))
|
||||
(Reference . ,(all-the-icons-material "collections_bookmark" :height 0.8 :face 'all-the-icons-red))
|
||||
(Folder . ,(all-the-icons-material "folder" :height 0.8 :face 'all-the-icons-red))
|
||||
(EnumMember . ,(all-the-icons-material "people" :height 0.8 :face 'all-the-icons-red))
|
||||
(Constant . ,(all-the-icons-material "pause_circle_filled" :height 0.8 :face 'all-the-icons-red))
|
||||
(Struct . ,(all-the-icons-material "streetview" :height 0.8 :face 'all-the-icons-red))
|
||||
(Event . ,(all-the-icons-material "event" :height 0.8 :face 'all-the-icons-red))
|
||||
(Operator . ,(all-the-icons-material "control_point" :height 0.8 :face 'all-the-icons-red))
|
||||
(TypeParameter . ,(all-the-icons-material "class" :height 0.8 :face 'all-the-icons-red))
|
||||
;; (Template . ,(company-box-icons-image "Template.png"))))
|
||||
(Yasnippet . ,(all-the-icons-material "short_text" :height 0.8 :face 'all-the-icons-green))
|
||||
(ElispFunction . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
|
||||
(ElispVariable . ,(all-the-icons-material "check_circle" :height 0.8 :face 'all-the-icons-blue))
|
||||
(ElispFeature . ,(all-the-icons-material "stars" :height 0.8 :face 'all-the-icons-orange))
|
||||
(ElispFace . ,(all-the-icons-material "format_paint" :height 0.8 :face 'all-the-icons-pink))))
|
||||
|
||||
(defun +company-box-icons--yasnippet-fn (candidate)
|
||||
(when (get-text-property 0 'yas-annotation candidate)
|
||||
'Yasnippet))
|
||||
(let ((all-the-icons-scale-factor 0.8))
|
||||
`((Unknown . ,(all-the-icons-material "find_in_page" :face 'all-the-icons-purple))
|
||||
(Text . ,(all-the-icons-material "text_fields" :face 'all-the-icons-green))
|
||||
(Method . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(Function . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(Constructor . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(Field . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(Variable . ,(all-the-icons-material "adjust" :face 'all-the-icons-blue))
|
||||
(Class . ,(all-the-icons-material "class" :face 'all-the-icons-red))
|
||||
(Interface . ,(all-the-icons-material "settings_input_component" :face 'all-the-icons-red))
|
||||
(Module . ,(all-the-icons-material "view_module" :face 'all-the-icons-red))
|
||||
(Property . ,(all-the-icons-material "settings" :face 'all-the-icons-red))
|
||||
(Unit . ,(all-the-icons-material "straighten" :face 'all-the-icons-red))
|
||||
(Value . ,(all-the-icons-material "filter_1" :face 'all-the-icons-red))
|
||||
(Enum . ,(all-the-icons-material "plus_one" :face 'all-the-icons-red))
|
||||
(Keyword . ,(all-the-icons-material "filter_center_focus" :face 'all-the-icons-red))
|
||||
(Snippet . ,(all-the-icons-material "short_text" :face 'all-the-icons-red))
|
||||
(Color . ,(all-the-icons-material "color_lens" :face 'all-the-icons-red))
|
||||
(File . ,(all-the-icons-material "insert_drive_file" :face 'all-the-icons-red))
|
||||
(Reference . ,(all-the-icons-material "collections_bookmark" :face 'all-the-icons-red))
|
||||
(Folder . ,(all-the-icons-material "folder" :face 'all-the-icons-red))
|
||||
(EnumMember . ,(all-the-icons-material "people" :face 'all-the-icons-red))
|
||||
(Constant . ,(all-the-icons-material "pause_circle_filled" :face 'all-the-icons-red))
|
||||
(Struct . ,(all-the-icons-material "streetview" :face 'all-the-icons-red))
|
||||
(Event . ,(all-the-icons-material "event" :face 'all-the-icons-red))
|
||||
(Operator . ,(all-the-icons-material "control_point" :face 'all-the-icons-red))
|
||||
(TypeParameter . ,(all-the-icons-material "class" :face 'all-the-icons-red))
|
||||
(Template . ,(all-the-icons-material "short_text" :face 'all-the-icons-green))
|
||||
(ElispFunction . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(ElispVariable . ,(all-the-icons-material "check_circle" :face 'all-the-icons-blue))
|
||||
(ElispFeature . ,(all-the-icons-material "stars" :face 'all-the-icons-orange))
|
||||
(ElispFace . ,(all-the-icons-material "format_paint" :face 'all-the-icons-pink)))))
|
||||
|
||||
(defun +company-box-icons--elisp-fn (candidate)
|
||||
(when (derived-mode-p 'emacs-lisp-mode)
|
||||
|
@ -118,7 +114,15 @@
|
|||
(cond ((fboundp sym) 'ElispFunction)
|
||||
((boundp sym) 'ElispVariable)
|
||||
((featurep sym) 'ElispFeature)
|
||||
((facep sym) 'ElispFace))))))
|
||||
((facep sym) 'ElispFace)))))
|
||||
|
||||
(defadvice! +company-remove-scrollbar-a (orig-fn &rest args)
|
||||
"This disables the company-box scrollbar, because:
|
||||
https://github.com/sebastiencs/company-box/issues/44"
|
||||
:around #'company-box--update-scrollbar
|
||||
(cl-letf (((symbol-function #'display-buffer-in-side-window)
|
||||
(symbol-function #'ignore)))
|
||||
(apply orig-fn args))))
|
||||
|
||||
|
||||
(use-package! company-dict
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; completion/company/packages.el
|
||||
|
||||
(package! company)
|
||||
(package! company-dict)
|
||||
(package! company-prescient)
|
||||
(package! company :pin "9de9905ed2")
|
||||
(package! company-dict :pin "cd7b8394f6")
|
||||
(package! company-prescient :pin "7fd8c3b802")
|
||||
(when (featurep! +childframe)
|
||||
(package! company-box))
|
||||
(package! company-box :pin "8fc6168f2d"))
|
||||
|
|
|
@ -38,7 +38,7 @@ workspace."
|
|||
;;; Project search
|
||||
|
||||
;;;###autoload
|
||||
(cl-defun +helm-file-search (&key query in all-files (recursive t))
|
||||
(cl-defun +helm-file-search (&key query in all-files (recursive t) _prompt args)
|
||||
"Conduct a file search using ripgrep.
|
||||
|
||||
:query STRING
|
||||
|
@ -51,46 +51,21 @@ workspace."
|
|||
(declare (indent defun))
|
||||
(unless (executable-find "rg")
|
||||
(user-error "Couldn't find ripgrep in your PATH"))
|
||||
(require 'helm-ag)
|
||||
(helm-ag--init-state)
|
||||
(let* ((project-root (or (doom-project-root) default-directory))
|
||||
(directory (or in project-root))
|
||||
(default-directory directory)
|
||||
(helm-ag--default-directory directory)
|
||||
(helm-ag--default-target (list directory))
|
||||
(query (or query
|
||||
(when (use-region-p)
|
||||
(let ((beg (or (bound-and-true-p evil-visual-beginning) (region-beginning)))
|
||||
(end (or (bound-and-true-p evil-visual-end) (region-end))))
|
||||
(when (> (abs (- end beg)) 1)
|
||||
(rxt-quote-pcre (buffer-substring-no-properties beg end)))))
|
||||
""))
|
||||
(prompt (format "[rg %s] "
|
||||
(cond ((file-equal-p directory project-root)
|
||||
(projectile-project-name))
|
||||
((file-equal-p directory default-directory)
|
||||
"./")
|
||||
((file-relative-name directory project-root)))))
|
||||
(command
|
||||
(list "rg --no-heading --line-number --color never"
|
||||
"-S"
|
||||
(when all-files "-z -uu")
|
||||
(unless recursive "--maxdepth 1")))
|
||||
(helm-ag-base-command (string-join (delq nil command) " ")))
|
||||
;; TODO Define our own sources instead
|
||||
(helm-attrset 'name (format "[rg %s] Searching %s"
|
||||
(string-join (delq nil (cdr command)) " ")
|
||||
(abbreviate-file-name directory))
|
||||
helm-source-do-ag)
|
||||
(helm-attrset '+helm-command command helm-source-do-ag)
|
||||
(cl-letf (((symbol-function 'helm-do-ag--helm)
|
||||
(lambda () (helm :sources '(helm-source-do-ag)
|
||||
:prompt prompt
|
||||
:buffer "*helm-rg*"
|
||||
:keymap helm-do-ag-map
|
||||
:input query
|
||||
:history 'helm-ag--helm-history))))
|
||||
(helm-do-ag directory))))
|
||||
(require 'helm-rg)
|
||||
(let ((this-command 'helm-rg)
|
||||
(helm-rg-default-directory (or in (doom-project-root) default-directory))
|
||||
(helm-rg-default-extra-args
|
||||
(delq nil (append (list (when all-files "-z -uu")
|
||||
(unless recursive "--maxdepth 1"))
|
||||
args))))
|
||||
(setq deactivate-mark t)
|
||||
(helm-rg (or query
|
||||
(when (use-region-p)
|
||||
(let ((beg (or (bound-and-true-p evil-visual-beginning) (region-beginning)))
|
||||
(end (or (bound-and-true-p evil-visual-end) (region-end))))
|
||||
(when (> (abs (- end beg)) 1)
|
||||
(buffer-substring-no-properties beg end))))
|
||||
""))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +helm/project-search (&optional arg initial-query directory)
|
||||
|
|
|
@ -23,6 +23,7 @@ bottom, which is easier on the eyes on big displays."
|
|||
(setq +helm--posframe-buffer buffer)
|
||||
:position (point)
|
||||
:poshandler +helm-posframe-handler
|
||||
:respect-header-line helm-echo-input-in-header-line
|
||||
:width
|
||||
(max (cl-typecase .width
|
||||
(integer .width)
|
||||
|
|
|
@ -57,8 +57,6 @@ be negative.")
|
|||
helm-mode-line-string nil
|
||||
helm-ff-auto-update-initial-value nil
|
||||
helm-find-files-doc-header nil
|
||||
;; Don't override evil-ex's completion
|
||||
helm-mode-handle-completion-in-region nil
|
||||
;; Default helm window sizes
|
||||
helm-display-buffer-default-width nil
|
||||
helm-display-buffer-default-height 0.25
|
||||
|
@ -73,11 +71,13 @@ be negative.")
|
|||
|
||||
:init
|
||||
(when (featurep! +childframe)
|
||||
;; If this is set to 'iconify-top-level then Emacs will be minimized upon
|
||||
;; helm completion.
|
||||
(setq iconify-child-frame 'make-invisible)
|
||||
(setq helm-display-function #'+helm-posframe-display-fn))
|
||||
|
||||
(let ((fuzzy (featurep! +fuzzy)))
|
||||
(setq helm-M-x-fuzzy-match fuzzy
|
||||
helm-ag-fuzzy-match fuzzy
|
||||
helm-apropos-fuzzy-match fuzzy
|
||||
helm-apropos-fuzzy-match fuzzy
|
||||
helm-bookmark-show-location fuzzy
|
||||
|
@ -101,9 +101,9 @@ be negative.")
|
|||
;; 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/rg)
|
||||
(advice-add #'helm-projectile-ag :override #'+helm/ag)
|
||||
(advice-add #'helm-projectile-grep :override #'+helm/grep)
|
||||
(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
|
||||
(defun +helm--hide-mode-line (&rest _)
|
||||
|
@ -114,6 +114,9 @@ be negative.")
|
|||
(advice-add #'helm-display-mode-line :override #'+helm--hide-mode-line)
|
||||
(advice-add #'helm-ag-show-status-default-mode-line :override #'ignore)
|
||||
|
||||
;; Hide minibuffer if `helm-echo-input-in-header-line'
|
||||
(add-hook 'helm-minibuffer-set-up-hook #'helm-hide-minibuffer-maybe)
|
||||
|
||||
;; Use helpful instead of describe-* to display documentation
|
||||
(dolist (fn '(helm-describe-variable helm-describe-function))
|
||||
(advice-add fn :around #'doom-use-helpful-a)))
|
||||
|
@ -125,14 +128,16 @@ be negative.")
|
|||
:config (helm-flx-mode +1))
|
||||
|
||||
|
||||
(after! helm-ag
|
||||
(map! :map helm-ag-edit-map :n "RET" #'compile-goto-error)
|
||||
(define-key helm-ag-edit-map [remap quit-window] #'helm-ag--edit-abort)
|
||||
(set-popup-rule! "^\\*helm-ag-edit" :size 0.35 :ttl 0 :quit nil)
|
||||
;; Recenter after jumping to match
|
||||
(advice-add #'helm-ag--find-file-action :after-while #'doom-recenter-a)
|
||||
;; And record position before jumping
|
||||
(advice-add #'helm-ag--find-file-action :around #'doom-set-jump-maybe-a))
|
||||
(after! helm-rg
|
||||
(setq helm-rg-display-buffer-normal-method #'pop-to-buffer)
|
||||
(set-popup-rule! "^helm-rg-" :ttl nil :select t :size 0.45)
|
||||
(map! :map helm-rg-map
|
||||
"C-c C-e" #'helm-rg--bounce)
|
||||
(map! :map helm-rg--bounce-mode-map
|
||||
"q" #'kill-current-buffer
|
||||
"C-c C-c" (λ! (helm-rg--bounce-dump) (kill-current-buffer))
|
||||
"C-x C-c" #'helm-rg--bounce-dump-current-file
|
||||
"C-c C-k" #'kill-current-buffer))
|
||||
|
||||
|
||||
;;;###package helm-bookmark
|
||||
|
@ -176,6 +181,7 @@ be negative.")
|
|||
(set-keymap-parent helm-projectile-find-file-map helm-map))
|
||||
|
||||
|
||||
(setq ivy-height 20) ; for `swiper-isearch'
|
||||
(after! swiper-helm
|
||||
(setq swiper-helm-display-function
|
||||
(lambda (buf &optional _resume) (pop-to-buffer buf)))
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; completion/helm/packages.el
|
||||
|
||||
(package! helm)
|
||||
(package! helm-ag)
|
||||
(package! helm-c-yasnippet)
|
||||
(package! helm-company)
|
||||
(package! helm-describe-modes :recipe (:host github :repo "emacs-helm/helm-describe-modes"))
|
||||
(package! helm-projectile)
|
||||
(package! swiper-helm)
|
||||
(package! helm :pin "8f56312053")
|
||||
(package! helm-rg :pin "785a80fe5c")
|
||||
(package! helm-c-yasnippet :pin "65ca732b51")
|
||||
(package! helm-company :pin "6eb5c2d730")
|
||||
(package! helm-describe-modes
|
||||
:recipe (:host github :repo "emacs-helm/helm-describe-modes")
|
||||
:pin "11fb36af11")
|
||||
(package! helm-projectile :pin "5328b74ddd")
|
||||
(package! swiper-helm :pin "93fb6db87b")
|
||||
(when (featurep! +fuzzy)
|
||||
(package! helm-flx))
|
||||
(package! helm-flx :pin "6640fac5cb"))
|
||||
(when (featurep! +childframe)
|
||||
(package! posframe))
|
||||
(package! posframe :pin "087a7fc3c8"))
|
||||
(when (featurep! :lang org)
|
||||
(package! helm-org))
|
||||
(package! helm-org :pin "8457e1e462"))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; completion/ido/packages.el
|
||||
|
||||
(package! flx-ido)
|
||||
(package! ido-completing-read+)
|
||||
(package! ido-vertical-mode)
|
||||
(package! crm-custom)
|
||||
(package! flx-ido :pin "17f5c9cb2a")
|
||||
(package! ido-completing-read+ :pin "74861eabd0")
|
||||
(package! ido-vertical-mode :pin "16c4c1a112")
|
||||
(package! crm-custom :pin "f1aaccf643")
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
- [[#arch-linux][Arch Linux]]
|
||||
- [[#opensuse][openSUSE]]
|
||||
- [[#features][Features]]
|
||||
- [[#jump-to-file-project-navigation][Jump-to-file project navigation]]
|
||||
- [[#jump-to-navigation][Jump-to navigation]]
|
||||
- [[#project-search--replace][Project search & replace]]
|
||||
- [[#in-buffer-searching][In-buffer searching]]
|
||||
- [[#ivy-integration-for-various-completing-commands][Ivy integration for various completing commands]]
|
||||
|
@ -88,7 +88,7 @@ sudo zypper install ripgrep
|
|||
Ivy and its ilk are large plugins. Covering everything about them is outside of
|
||||
this documentation's scope, so only Doom-specific Ivy features are listed here:
|
||||
|
||||
** Jump-to-file project navigation
|
||||
** Jump-to navigation
|
||||
Inspired by Sublime Text's jump-to-anywhere, CtrlP/Unite in Vim, and Textmate's
|
||||
Command-T, this module provides similar functionality by bringing ~projectile~
|
||||
and ~ivy~ together.
|
||||
|
@ -99,22 +99,23 @@ https://assets.doomemacs.org/completion/ivy/projectile.png
|
|||
|----------------------+-------------------------------------|
|
||||
| =SPC p f=, =SPC SPC= | Jump to file in project |
|
||||
| =SPC f f=, =SPC .= | Jump to file from current directory |
|
||||
| =SPC s i= | Jump to symbol in file |
|
||||
|
||||
** Project search & replace
|
||||
This module provides interactive text search and replace using ripgrep.
|
||||
|
||||
| Keybind | Description |
|
||||
|-----------+---------------------------------|
|
||||
| =SPC s b= | Search the current buffer |
|
||||
| =SPC s p= | Search project |
|
||||
| =SPC s d= | Search this directory |
|
||||
| =SPC p t= | List all TODO/FIXMEs in project |
|
||||
| Keybind | Description |
|
||||
|-----------+--------------------------|
|
||||
| =SPC s p= | Search project |
|
||||
| =SPC s P= | Search another project |
|
||||
| =SPC s d= | Search this directory |
|
||||
| =SPC s D= | Search another directory |
|
||||
|
||||
https://assets.doomemacs.org/completion/ivy/search.png
|
||||
|
||||
The universal argument (=SPC u= for evil users; =C-u= otherwise) changes the
|
||||
behavior of these commands, instructing the underlying search engine to include
|
||||
ignored files.
|
||||
Prefixing these keys with the universal argument (=SPC u= for evil users; =C-u=
|
||||
otherwise) changes the behavior of these commands, instructing the underlying
|
||||
search engine to include ignored files.
|
||||
|
||||
This module also provides Ex Commands for evil users:
|
||||
|
||||
|
@ -123,15 +124,16 @@ This module also provides Ex Commands for evil users:
|
|||
| ~:pg[rep][!] [QUERY]~ | Search project (if ~!~, include hidden files) |
|
||||
| ~:pg[rep]d[!] [QUERY]~ | Search from current directory (if ~!~, don't search recursively) |
|
||||
|
||||
The optional BANG functions is equivalent to the universal argument for the
|
||||
previous commands.
|
||||
The optional `!` is equivalent to the universal argument for the previous
|
||||
commands.
|
||||
|
||||
-----
|
||||
|
||||
While in a search these extra keybindings are available to you:
|
||||
These keybindings are available while a search is active:
|
||||
|
||||
| Keybind | Description |
|
||||
|-----------+-----------------------------------------------|
|
||||
| =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 |
|
||||
|
@ -146,8 +148,9 @@ https://assets.doomemacs.org/completion/ivy/search-replace.png
|
|||
The =swiper= package provides an interactive buffer search powered by ivy. It
|
||||
can be invoked with:
|
||||
|
||||
+ =SPC s s=
|
||||
+ =SPC s S= (uses thing at point as initial input)
|
||||
+ =SPC s s= (~swiper-isearch~)
|
||||
+ =SPC s S= (~swiper-isearch-thing-at-point~)
|
||||
+ =SPC s b= (~swiper~)
|
||||
+ ~:sw[iper] [QUERY]~
|
||||
|
||||
https://assets.doomemacs.org/completion/ivy/swiper.png
|
||||
|
|
|
@ -21,16 +21,7 @@ Buffers that are considered unreal (see `doom-real-buffer-p') are dimmed with
|
|||
`+ivy-buffer-unreal-face'."
|
||||
(let ((b (get-buffer candidate)))
|
||||
(when (null uniquify-buffer-name-style)
|
||||
(when-let* ((file-path (buffer-file-name b))
|
||||
(uniquify-buffer-name-style 'forward))
|
||||
(setq candidate
|
||||
(uniquify-get-proposed-name
|
||||
(replace-regexp-in-string "<[0-9]+>$" "" (buffer-name b))
|
||||
(directory-file-name
|
||||
(if file-path
|
||||
(file-name-directory file-path)
|
||||
default-directory))
|
||||
1))))
|
||||
(setq candidate (replace-regexp-in-string "<[0-9]+>$" "" candidate)))
|
||||
(cond ((ignore-errors
|
||||
(file-remote-p
|
||||
(buffer-local-value 'default-directory b)))
|
||||
|
@ -165,10 +156,10 @@ If ARG (universal argument), open selection in other-window."
|
|||
(user-error "No completion session is active"))
|
||||
(require 'wgrep)
|
||||
(let ((caller (ivy-state-caller ivy-last)))
|
||||
(if-let* ((occur-fn (plist-get +ivy-edit-functions caller)))
|
||||
(if-let (occur-fn (plist-get +ivy-edit-functions caller))
|
||||
(ivy-exit-with-action
|
||||
(lambda (_) (funcall occur-fn)))
|
||||
(if-let* ((occur-fn (plist-get ivy--occurs-list caller)))
|
||||
(if-let (occur-fn (plist-get ivy--occurs-list caller))
|
||||
(let ((buffer (generate-new-buffer
|
||||
(format "*ivy-occur%s \"%s\"*"
|
||||
(if caller (concat " " (prin1-to-string caller)) "")
|
||||
|
@ -222,22 +213,26 @@ non-project, `projectile-find-file' if in a big project (more than
|
|||
|
||||
The point of this is to avoid Emacs locking up indexing massive file trees."
|
||||
(interactive)
|
||||
(call-interactively
|
||||
(cond ((or (file-equal-p default-directory "~")
|
||||
(when-let (proot (doom-project-root))
|
||||
(file-equal-p proot "~")))
|
||||
#'counsel-find-file)
|
||||
;; Spoof the command so that ivy/counsel will display the (well fleshed-out)
|
||||
;; actions list for `counsel-find-file' on C-o. The actions list for the other
|
||||
;; commands aren't as well configured or are empty.
|
||||
(let ((this-command 'counsel-find-file))
|
||||
(call-interactively
|
||||
(cond ((or (file-equal-p default-directory "~")
|
||||
(when-let (proot (doom-project-root))
|
||||
(file-equal-p proot "~")))
|
||||
#'counsel-find-file)
|
||||
|
||||
((doom-project-p)
|
||||
(let ((files (projectile-current-project-files)))
|
||||
(if (<= (length files) ivy-sort-max-size)
|
||||
#'counsel-projectile-find-file
|
||||
#'projectile-find-file)))
|
||||
((doom-project-p)
|
||||
(let ((files (projectile-current-project-files)))
|
||||
(if (<= (length files) ivy-sort-max-size)
|
||||
#'counsel-projectile-find-file
|
||||
#'projectile-find-file)))
|
||||
|
||||
(#'counsel-file-jump))))
|
||||
(#'counsel-file-jump)))))
|
||||
|
||||
;;;###autoload
|
||||
(cl-defun +ivy-file-search (&key query in all-files (recursive t))
|
||||
(cl-defun +ivy-file-search (&key query in all-files (recursive t) prompt args)
|
||||
"Conduct a file search using ripgrep.
|
||||
|
||||
:query STRING
|
||||
|
@ -251,36 +246,35 @@ The point of this is to avoid Emacs locking up indexing massive file trees."
|
|||
(unless (executable-find "rg")
|
||||
(user-error "Couldn't find ripgrep in your PATH"))
|
||||
(require 'counsel)
|
||||
(let* ((ivy-more-chars-alist '((t . 1)))
|
||||
(let* ((this-command 'counsel-rg)
|
||||
(project-root (or (doom-project-root) default-directory))
|
||||
(directory (or in project-root))
|
||||
(default-directory directory)
|
||||
(args (concat (if all-files " -uu")
|
||||
(unless recursive " --maxdepth 1"))))
|
||||
(unless recursive " --maxdepth 1")
|
||||
" "
|
||||
(mapconcat #'shell-quote-argument args " "))))
|
||||
(setq deactivate-mark t)
|
||||
(counsel-rg
|
||||
(or (if query query)
|
||||
(when (use-region-p)
|
||||
(let ((beg (or (bound-and-true-p evil-visual-beginning) (region-beginning)))
|
||||
(end (or (bound-and-true-p evil-visual-end) (region-end))))
|
||||
(when (> (abs (- end beg)) 1)
|
||||
(let ((query (buffer-substring-no-properties beg end)))
|
||||
;; Escape characters that are special to ivy searches
|
||||
(replace-regexp-in-string "[! |]" (lambda (substr)
|
||||
(cond ((and (string= substr " ")
|
||||
(not (featurep! +fuzzy)))
|
||||
" ")
|
||||
((string= substr "|")
|
||||
"\\\\\\\\|")
|
||||
((concat "\\\\" substr))))
|
||||
(rxt-quote-pcre query)))))))
|
||||
(or query
|
||||
(when (doom-region-active-p)
|
||||
(replace-regexp-in-string
|
||||
"[! |]" (lambda (substr)
|
||||
(cond ((and (string= substr " ")
|
||||
(not (featurep! +fuzzy)))
|
||||
" ")
|
||||
((string= substr "|")
|
||||
"\\\\\\\\|")
|
||||
((concat "\\\\" substr))))
|
||||
(rxt-quote-pcre (doom-thing-at-point-or-region)))))
|
||||
directory args
|
||||
(format "rg%s %s"
|
||||
args
|
||||
(cond ((equal directory default-directory)
|
||||
"./")
|
||||
((equal directory project-root)
|
||||
(projectile-project-name))
|
||||
((file-relative-name directory project-root)))))))
|
||||
(or prompt
|
||||
(format "rg%s [%s]: "
|
||||
args
|
||||
(cond ((equal directory default-directory)
|
||||
"./")
|
||||
((equal directory project-root)
|
||||
(projectile-project-name))
|
||||
((file-relative-name directory project-root))))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy/project-search (&optional arg initial-query directory)
|
||||
|
|
|
@ -7,16 +7,6 @@ When nil, don't preview anything.
|
|||
When non-nil, preview non-virtual buffers.
|
||||
When 'everything, also preview virtual buffers")
|
||||
|
||||
(defvar +ivy-project-search-engines '(rg ag)
|
||||
"What search tools for `+ivy/project-search' (and `+ivy-file-search' when no
|
||||
ENGINE is specified) to try, and in what order.
|
||||
|
||||
To disable a particular tool, remove it from this list. To prioritize a tool
|
||||
over others, move it to the front of the list. Later duplicates in this list are
|
||||
silently ignored.
|
||||
|
||||
If you want to already use git-grep or grep, set this to nil.")
|
||||
|
||||
(defvar +ivy-buffer-unreal-face 'font-lock-comment-face
|
||||
"The face for unreal buffers in `ivy-switch-to-buffer'.")
|
||||
|
||||
|
@ -24,18 +14,6 @@ If you want to already use git-grep or grep, set this to nil.")
|
|||
"A plist mapping ivy/counsel commands to commands that generate an editable
|
||||
results buffer.")
|
||||
|
||||
(defvar +ivy-standard-search-fn
|
||||
(if (featurep! +prescient)
|
||||
#'+ivy-prescient-non-fuzzy
|
||||
#'ivy--regex-plus)
|
||||
"Function to use for non-fuzzy search commands.")
|
||||
|
||||
(defvar +ivy-alternative-search-fn
|
||||
(cond ((featurep! +prescient) #'ivy-prescient-re-builder)
|
||||
((featurep! +fuzzy) #'ivy--regex-fuzzy)
|
||||
(#'ivy--regex-ignore-order))
|
||||
"Function to use for fuzzy search commands.")
|
||||
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
@ -43,15 +21,24 @@ results buffer.")
|
|||
(use-package! ivy
|
||||
:after-call pre-command-hook
|
||||
:init
|
||||
(setq ivy-re-builders-alist
|
||||
`(,@(cl-loop for cmd in '(counsel-ag
|
||||
counsel-rg
|
||||
counsel-grep
|
||||
swiper
|
||||
swiper-isearch)
|
||||
collect (cons cmd +ivy-standard-search-fn))
|
||||
;; Ignore order for non-fuzzy searches by default
|
||||
(t . ,+ivy-alternative-search-fn)))
|
||||
(let ((standard-search-fn
|
||||
(if (featurep! +prescient)
|
||||
#'+ivy-prescient-non-fuzzy
|
||||
#'ivy--regex-plus))
|
||||
(alt-search-fn
|
||||
(if (featurep! +fuzzy)
|
||||
#'ivy--regex-fuzzy
|
||||
;; Ignore order for non-fuzzy searches by default
|
||||
#'ivy--regex-ignore-order)))
|
||||
(setq ivy-re-builders-alist
|
||||
`((counsel-rg . ,standard-search-fn)
|
||||
(swiper . ,standard-search-fn)
|
||||
(swiper-isearch . ,standard-search-fn)
|
||||
(t . ,alt-search-fn))
|
||||
ivy-more-chars-alist
|
||||
'((counsel-rg . 1)
|
||||
(counsel-search . 2)
|
||||
(t . 3))))
|
||||
|
||||
(define-key!
|
||||
[remap switch-to-buffer] #'+ivy/switch-buffer
|
||||
|
@ -75,7 +62,7 @@ results buffer.")
|
|||
;; ...but if that ever changes, show their full path
|
||||
ivy-virtual-abbreviate 'full
|
||||
;; don't quit minibuffer on delete-error
|
||||
ivy-on-del-error-function nil
|
||||
ivy-on-del-error-function #'ignore
|
||||
;; enable ability to select prompt (alternative to `ivy-immediate-done')
|
||||
ivy-use-selectable-prompt t)
|
||||
|
||||
|
@ -110,7 +97,9 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
|
|||
(let ((completion-in-region-function #'completion--in-region))
|
||||
(apply orig-fn args)))
|
||||
|
||||
(define-key ivy-minibuffer-map (kbd "C-c C-e") #'+ivy/woccur)
|
||||
(define-key! ivy-minibuffer-map
|
||||
"C-c C-e" #'+ivy/woccur
|
||||
[remap doom/delete-backward-word] #'ivy-backward-kill-word)
|
||||
|
||||
(ivy-mode +1)
|
||||
|
||||
|
@ -128,6 +117,8 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
|
|||
(use-package! ivy-rich
|
||||
:after ivy
|
||||
:config
|
||||
(setq ivy-rich-parse-remote-buffer nil)
|
||||
|
||||
(when (featurep! +icons)
|
||||
(cl-pushnew '(+ivy-rich-buffer-icon)
|
||||
(cadr (plist-get ivy-rich-display-transformers-list
|
||||
|
@ -182,61 +173,52 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
|
|||
(define-key!
|
||||
[remap apropos] #'counsel-apropos
|
||||
[remap bookmark-jump] #'counsel-bookmark
|
||||
[remap compile] #'+ivy/compile
|
||||
[remap describe-bindings] #'counsel-descbinds
|
||||
[remap describe-face] #'counsel-faces
|
||||
[remap describe-function] #'counsel-describe-function
|
||||
[remap describe-variable] #'counsel-describe-variable
|
||||
[remap describe-bindings] #'counsel-descbinds
|
||||
[remap set-variable] #'counsel-set-variable
|
||||
[remap evil-ex-registers] #'counsel-evil-registers
|
||||
[remap evil-show-marks] #'counsel-mark-ring
|
||||
[remap execute-extended-command] #'counsel-M-x
|
||||
[remap find-file] #'counsel-find-file
|
||||
[remap find-library] #'counsel-find-library
|
||||
[remap info-lookup-symbol] #'counsel-info-lookup-symbol
|
||||
[remap imenu] #'counsel-imenu
|
||||
[remap recentf-open-files] #'counsel-recentf
|
||||
[remap swiper] #'counsel-grep-or-swiper
|
||||
[remap evil-ex-registers] #'counsel-evil-registers
|
||||
[remap evil-show-marks] #'counsel-mark-ring
|
||||
[remap yank-pop] #'counsel-yank-pop
|
||||
[remap info-lookup-symbol] #'counsel-info-lookup-symbol
|
||||
[remap load-theme] #'counsel-load-theme
|
||||
[remap locate] #'counsel-locate
|
||||
[remap org-set-tags-command] #'counsel-org-tag
|
||||
[remap projectile-compile-project] #'+ivy/project-compile
|
||||
[remap recentf-open-files] #'counsel-recentf
|
||||
[remap set-variable] #'counsel-set-variable
|
||||
[remap swiper] #'counsel-grep-or-swiper
|
||||
[remap unicode-chars-list-chars] #'counsel-unicode-char
|
||||
[remap compile] #'+ivy/compile
|
||||
[remap projectile-compile-project] #'+ivy/project-compile)
|
||||
[remap yank-pop] #'counsel-yank-pop)
|
||||
:config
|
||||
(set-popup-rule! "^\\*ivy-occur" :size 0.35 :ttl 0 :quit nil)
|
||||
|
||||
;; HACK Fix an issue where `counsel-projectile-find-file-action' would try to
|
||||
;; open a candidate in an occur buffer relative to the wrong buffer,
|
||||
;; causing it to fail to find the file we want.
|
||||
(defadvice! +ivy--run-from-ivy-directory-a (orig-fn &rest args)
|
||||
:around #'counsel-projectile-find-file-action
|
||||
(let ((default-directory (ivy-state-directory ivy-last)))
|
||||
(apply orig-fn args)))
|
||||
|
||||
;; Don't use ^ as initial input. Set this here because `counsel' defines more
|
||||
;; of its own, on top of the defaults.
|
||||
(setq ivy-initial-inputs-alist nil)
|
||||
|
||||
;; REVIEW Move this somewhere else and perhaps generalize this so both
|
||||
;; ivy/helm users can enjoy it.
|
||||
(defadvice! +ivy--counsel-file-jump-use-fd-rg-a (args)
|
||||
"Change `counsel-file-jump' to use fd or ripgrep, if they are available."
|
||||
:override #'counsel--find-return-list
|
||||
(cl-destructuring-bind (find-program . args)
|
||||
(cond ((executable-find "fd")
|
||||
(cons "fd" (list "-t" "f" "-E" ".git")))
|
||||
((executable-find "rg")
|
||||
(cons "rg" (list "--files" "--hidden" "--no-messages")))
|
||||
((cons find-program args)))
|
||||
(unless (listp args)
|
||||
(user-error "`counsel-file-jump-args' is a list now, please customize accordingly."))
|
||||
(counsel--call
|
||||
(cons find-program args)
|
||||
(lambda ()
|
||||
(goto-char (point-min))
|
||||
(let ((offset (if (member find-program '("fd" "rg")) 0 2))
|
||||
files)
|
||||
(while (< (point) (point-max))
|
||||
(push (buffer-substring
|
||||
(+ offset (line-beginning-position)) (line-end-position)) files)
|
||||
(forward-line 1))
|
||||
(nreverse files))))))
|
||||
|
||||
;; Integrate with `helpful'
|
||||
(setq counsel-describe-function-function #'helpful-callable
|
||||
counsel-describe-variable-function #'helpful-variable)
|
||||
|
||||
;; Record in jumplist when opening files via counsel-{ag,rg,pt,git-grep}
|
||||
(add-hook 'counsel-grep-post-action-hook #'better-jumper-set-jump)
|
||||
(ivy-add-actions
|
||||
'counsel-rg ; also applies to `counsel-rg'
|
||||
'(("O" +ivy-git-grep-other-window-action "open in other window")))
|
||||
|
||||
;; Make `counsel-compile' projectile-aware (if you prefer it over
|
||||
;; `+ivy/compile' and `+ivy/project-compile')
|
||||
(add-to-list 'counsel-compile-root-functions #'projectile-project-root)
|
||||
|
@ -244,51 +226,62 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
|
|||
;; Persist `counsel-compile' history
|
||||
(add-to-list 'savehist-additional-variables 'counsel-compile-history))
|
||||
|
||||
;; Use spotlight on mac for `counsel-locate' by default
|
||||
;; `counsel-imenu' -- no sorting for imenu. Sort it by appearance in page.
|
||||
(add-to-list 'ivy-sort-functions-alist '(counsel-imenu))
|
||||
|
||||
;; `counsel-locate'
|
||||
(when IS-MAC
|
||||
;; Use spotlight on mac by default since it doesn't need any additional setup
|
||||
(setq counsel-locate-cmd #'counsel-locate-cmd-mdfind))
|
||||
|
||||
;; `swiper'
|
||||
;; Don't mess with font-locking on the dashboard; it causes breakages
|
||||
(add-to-list 'swiper-font-lock-exclude #'+doom-dashboard-mode)
|
||||
|
||||
;; Record in jumplist when opening files via counsel-{ag,rg,pt,git-grep}
|
||||
(add-hook 'counsel-grep-post-action-hook #'better-jumper-set-jump)
|
||||
|
||||
;; Factories
|
||||
(defun +ivy-action-reloading (cmd)
|
||||
(lambda (x)
|
||||
(funcall cmd x)
|
||||
(ivy--reset-state ivy-last)))
|
||||
|
||||
(defun +ivy-action-given-file (cmd prompt)
|
||||
(lambda (source)
|
||||
(let* ((enable-recursive-minibuffers t)
|
||||
(target (read-file-name (format "%s %s to:" prompt source))))
|
||||
(funcall cmd source target 1))))
|
||||
|
||||
;; Configure `counsel-find-file'
|
||||
;; `counsel-find-file'
|
||||
(setq counsel-find-file-ignore-regexp "\\(?:^[#.]\\)\\|\\(?:[#~]$\\)\\|\\(?:^Icon?\\)")
|
||||
(ivy-add-actions
|
||||
'counsel-find-file
|
||||
`(("b" counsel-find-file-cd-bookmark-action "cd bookmark")
|
||||
("s" counsel-find-file-as-root "open as root")
|
||||
("m" counsel-find-file-mkdir-action "mkdir")
|
||||
("c" ,(+ivy-action-given-file #'copy-file "Copy file") "copy file")
|
||||
("d" ,(+ivy-action-reloading #'+ivy-confirm-delete-file) "delete")
|
||||
("r" (lambda (path) (rename-file path (read-string "New name: "))) "rename")
|
||||
("R" ,(+ivy-action-reloading (+ivy-action-given-file #'rename-file "Move")) "move")
|
||||
("f" find-file-other-window "other window")
|
||||
("F" find-file-other-frame "other frame")
|
||||
("p" (lambda (path) (with-ivy-window (insert (file-relative-name path default-directory)))) "insert relative path")
|
||||
("P" (lambda (path) (with-ivy-window (insert path))) "insert absolute path")
|
||||
("l" (lambda (path) "Insert org-link with relative path"
|
||||
(with-ivy-window (insert (format "[[./%s]]" (file-relative-name path default-directory))))) "insert org-link (rel. path)")
|
||||
("L" (lambda (path) "Insert org-link with absolute path"
|
||||
(with-ivy-window (insert (format "[[%s]]" path)))) "insert org-link (abs. path)")))
|
||||
(dolist (fn '(counsel-rg counsel-find-file))
|
||||
(ivy-add-actions
|
||||
fn '(("p" (lambda (path) (with-ivy-window (insert (file-relative-name path default-directory))))
|
||||
"insert relative path")
|
||||
("P" (lambda (path) (with-ivy-window (insert path)))
|
||||
"insert absolute path")
|
||||
("l" (lambda (path) (with-ivy-window (insert (format "[[./%s]]" (file-relative-name path default-directory)))))
|
||||
"insert relative org-link")
|
||||
("L" (lambda (path) (with-ivy-window (insert (format "[[%s]]" path))))
|
||||
"Insert absolute org-link"))))
|
||||
|
||||
(ivy-add-actions
|
||||
'counsel-ag ; also applies to `counsel-rg'
|
||||
'(("O" +ivy-git-grep-other-window-action "open in other window"))))
|
||||
(ivy-add-actions 'counsel-file-jump (plist-get ivy--actions-list 'counsel-find-file))
|
||||
|
||||
;; `counsel-search': use normal page for displaying results, so that we see
|
||||
;; custom ddg themes (if one is set).
|
||||
(setf (nth 1 (alist-get 'ddg counsel-search-engines-alist))
|
||||
"https://duckduckgo.com/?q=")
|
||||
|
||||
;; REVIEW Move this somewhere else and perhaps generalize this so both
|
||||
;; ivy/helm users can enjoy it.
|
||||
(defadvice! +ivy--counsel-file-jump-use-fd-rg-a (args)
|
||||
"Change `counsel-file-jump' to use fd or ripgrep, if they are available."
|
||||
:override #'counsel--find-return-list
|
||||
(cl-destructuring-bind (find-program . args)
|
||||
(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))
|
||||
((cons find-program args)))
|
||||
(unless (listp args)
|
||||
(user-error "`counsel-file-jump-args' is a list now, please customize accordingly."))
|
||||
(counsel--call
|
||||
(cons find-program args)
|
||||
(lambda ()
|
||||
(goto-char (point-min))
|
||||
(let ((offset (if (member find-program (list "rg" doom-projectile-fd-binary)) 0 2))
|
||||
files)
|
||||
(while (< (point) (point-max))
|
||||
(push (buffer-substring
|
||||
(+ offset (line-beginning-position)) (line-end-position)) files)
|
||||
(forward-line 1))
|
||||
(nreverse files)))))))
|
||||
|
||||
|
||||
(use-package! counsel-projectile
|
||||
|
@ -310,7 +303,10 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
|
|||
#'+ivy/projectile-find-file)
|
||||
|
||||
;; no highlighting visited files; slows down the filtering
|
||||
(ivy-set-display-transformer #'counsel-projectile-find-file nil))
|
||||
(ivy-set-display-transformer #'counsel-projectile-find-file nil)
|
||||
|
||||
(if (featurep! +prescient)
|
||||
(setq counsel-projectile-sort-files t)))
|
||||
|
||||
|
||||
(use-package! wgrep
|
||||
|
@ -332,8 +328,10 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
|
|||
(setf (alist-get t ivy-posframe-display-functions-alist)
|
||||
#'+ivy-display-at-frame-center-near-bottom-fn)
|
||||
|
||||
;; posframe doesn't work well with async sources
|
||||
(dolist (fn '(swiper counsel-ag counsel-grep counsel-git-grep))
|
||||
;; posframe doesn't work well with async sources (the posframe will
|
||||
;; occasionally stop responding/redrawing), and causes violent resizing of the
|
||||
;; posframe.
|
||||
(dolist (fn '(swiper counsel-rg counsel-grep counsel-git-grep))
|
||||
(setf (alist-get fn ivy-posframe-display-functions-alist)
|
||||
#'ivy-display-function-fallback)))
|
||||
|
||||
|
@ -353,7 +351,6 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
|
|||
(if (featurep! +fuzzy)
|
||||
'(literal regexp initialism fuzzy)
|
||||
'(literal regexp initialism))
|
||||
ivy-prescient-enable-filtering nil ; we do this ourselves
|
||||
ivy-prescient-retain-classic-highlighting t)
|
||||
|
||||
:config
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; completion/ivy/packages.el
|
||||
|
||||
(package! amx)
|
||||
(package! swiper :pin "7084d60312")
|
||||
(package! ivy)
|
||||
(package! counsel)
|
||||
(package! counsel-projectile)
|
||||
(package! swiper)
|
||||
(package! ivy-hydra)
|
||||
(package! ivy-rich)
|
||||
(package! wgrep)
|
||||
(package! counsel)
|
||||
|
||||
(package! amx :pin "e512e74e83")
|
||||
(package! counsel-projectile :pin "b556ed8995")
|
||||
(package! ivy-rich :pin "af43abad5c")
|
||||
(package! wgrep :pin "5977b8e000")
|
||||
|
||||
(if (featurep! +prescient)
|
||||
(package! ivy-prescient)
|
||||
(package! ivy-prescient :pin "7fd8c3b802")
|
||||
(when (featurep! +fuzzy)
|
||||
(package! flx)))
|
||||
(package! flx :pin "17f5c9cb2a")))
|
||||
|
||||
(when (featurep! +childframe)
|
||||
(package! ivy-posframe))
|
||||
(package! ivy-posframe :pin "6d697ff00a"))
|
||||
|
||||
(when (featurep! +icons)
|
||||
(package! all-the-icons-ivy))
|
||||
(package! all-the-icons-ivy :pin "a70cbfa1ef"))
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue