dev: merging from main
This commit is contained in:
commit
f94083403d
496 changed files with 5618 additions and 6088 deletions
6
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
6
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
@ -2,6 +2,7 @@
|
||||||
name: 📝 Bug Report
|
name: 📝 Bug Report
|
||||||
description: Report something that isn't working as intended
|
description: Report something that isn't working as intended
|
||||||
labels: ["is:bug", "needs-triage"]
|
labels: ["is:bug", "needs-triage"]
|
||||||
|
projects: ["doomemacs/2"]
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
|
@ -32,9 +33,8 @@ body:
|
||||||
Doom.
|
Doom.
|
||||||
required: true
|
required: true
|
||||||
- label: >
|
- label: >
|
||||||
The issue can be reproduced on a stable release of Emacs, such as 27
|
The issue can be reproduced on a stable release of Emacs, such as 27,
|
||||||
or 28. *(Doom does not support development builds like 29+ or any
|
28, or 29. *(Unstable versions end in .50, .60, or .9x)*
|
||||||
version ending in .50 or .9x)*
|
|
||||||
required: true
|
required: true
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
|
|
8
.github/workflows/add-to-project.yml
vendored
8
.github/workflows/add-to-project.yml
vendored
|
@ -1,8 +0,0 @@
|
||||||
name: Add issues to project
|
|
||||||
on:
|
|
||||||
issues:
|
|
||||||
types: [opened]
|
|
||||||
jobs:
|
|
||||||
add-to-project:
|
|
||||||
uses: doomemacs/ci/.github/workflows/add-to-project.yml@legacy
|
|
||||||
secrets: inherit
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,3 +1,6 @@
|
||||||
|
# generated by macOS
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
# machine generated doom profiles or metadata
|
# machine generated doom profiles or metadata
|
||||||
/profiles/*.el
|
/profiles/*.el
|
||||||
/.local*/
|
/.local*/
|
||||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2014-2022 Henrik Lissner.
|
Copyright (c) 2014-2024 Henrik Lissner.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
|
|
33
README.md
33
README.md
|
@ -5,7 +5,7 @@
|
||||||
[Install](#install) • [Documentation] • [FAQ] • [Screenshots] • [Contribute](#contribute)
|
[Install](#install) • [Documentation] • [FAQ] • [Screenshots] • [Contribute](#contribute)
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
[][Discord]
|
[][Discord]
|
||||||
|
@ -98,20 +98,23 @@ Check out [the FAQ][FAQ] for answers to common questions about the project.
|
||||||
|
|
||||||
|
|
||||||
# Prerequisites
|
# Prerequisites
|
||||||
+ Git 2.23+
|
- Git 2.23+
|
||||||
+ Emacs 27.1–29.1 (**Recommended: 29.1 +
|
- Emacs 27.1–29.2 (**Recommended: 29.2 +
|
||||||
[native-comp](https://www.emacswiki.org/emacs/GccEmacs)**)
|
[native-comp](https://www.emacswiki.org/emacs/GccEmacs)**)
|
||||||
> :warning: Unstable and pre-release builds of Emacs -- which end in `.50`,
|
- [ripgrep] 11.0+
|
||||||
> `.60`, or `.9X` (e.g. `28.1.91`) -- **are not officially supported**. There
|
- GNU `find`
|
||||||
> *is* some effort to support Emacs HEAD, however. [Follow this Discourse
|
- *OPTIONAL:* [fd] 7.3.0+ (improves file indexing performance for some commands)
|
||||||
> post](https://discourse.doomemacs.org/t/3241) for details.
|
|
||||||
+ [ripgrep] 11.0+
|
> [!WARNING]
|
||||||
+ GNU `find`
|
> Unstable and pre-release builds of Emacs -- which end in `.50`, `.60`, or
|
||||||
+ *OPTIONAL:* [fd] 7.3.0+ (improves file indexing performance for some commands)
|
> `.9X` (e.g. `28.1.91`) -- **are not officially supported**. There *is* some
|
||||||
|
> effort to support Emacs HEAD, however. [Follow this Discourse
|
||||||
Doom is comprised of [~150 optional modules][Modules], some of which may have
|
> post](https://discourse.doomemacs.org/t/3241) for details.
|
||||||
additional dependencies. [Visit their documentation][Modules] or run `bin/doom
|
|
||||||
doctor` to check for any that you may have missed.
|
> [!IMPORTANT]
|
||||||
|
> Doom is comprised of [~150 optional modules][Modules], some of which may have
|
||||||
|
> additional dependencies. [Visit their documentation][Modules] or run `bin/doom
|
||||||
|
> doctor` to check for any that you may have missed.
|
||||||
|
|
||||||
|
|
||||||
# Install
|
# Install
|
||||||
|
@ -135,8 +138,6 @@ commands you should know about:
|
||||||
+ `doom env` to dump a snapshot of your shell environment to a file that Doom
|
+ `doom env` to dump a snapshot of your shell environment to a file that Doom
|
||||||
will load at startup. This allows Emacs to inherit your `PATH`, among other
|
will load at startup. This allows Emacs to inherit your `PATH`, among other
|
||||||
things.
|
things.
|
||||||
+ `doom build` to recompile all installed packages (use this if you up/downgrade
|
|
||||||
Emacs).
|
|
||||||
|
|
||||||
|
|
||||||
# Roadmap
|
# Roadmap
|
||||||
|
|
12
bin/doom
12
bin/doom
|
@ -89,9 +89,9 @@
|
||||||
(user-error (message "Error: %s" (cadr e))
|
(user-error (message "Error: %s" (cadr e))
|
||||||
(kill-emacs 2)))
|
(kill-emacs 2)))
|
||||||
|
|
||||||
;; UX: Abort if the user is using 'doom' as root, unless ~/.config/emacs is
|
;; UX: Abort if the user is using 'doom' as root, unless $EMACSDIR is owned by
|
||||||
;; owned by root, in which case we assume the user genuinely wants root to be
|
;; root, in which case we can safely assume the user genuinely wants root to
|
||||||
;; their primary user account for Emacs.
|
;; be their primary user account for this session.
|
||||||
(when (equal 0 (user-real-uid))
|
(when (equal 0 (user-real-uid))
|
||||||
(unless (equal 0 (file-attribute-user-id (file-attributes doom-emacs-dir)))
|
(unless (equal 0 (file-attribute-user-id (file-attributes doom-emacs-dir)))
|
||||||
(message
|
(message
|
||||||
|
@ -271,10 +271,8 @@ SEE ALSO:
|
||||||
(defcli-autoload! ((profiles profile)))
|
(defcli-autoload! ((profiles profile)))
|
||||||
(defcli-autoload! ((upgrade up)))
|
(defcli-autoload! ((upgrade up)))
|
||||||
(defcli-autoload! (env))
|
(defcli-autoload! (env))
|
||||||
(defcli-autoload! ((build b purge p rollback)) "packages")
|
(defcli-autoload! ((build b purge p gc rollback)) "packages")
|
||||||
(defcli-autoload! ((install i)))
|
(defcli-autoload! ((install i)))
|
||||||
(defcli-autoload! ((compile c)))
|
|
||||||
(defcli-autoload! (clean) "compile")
|
|
||||||
|
|
||||||
;; TODO Post-3.0 commands
|
;; TODO Post-3.0 commands
|
||||||
;; (load! "gc" dir)
|
;; (load! "gc" dir)
|
||||||
|
@ -282,8 +280,6 @@ SEE ALSO:
|
||||||
;; (load! "nuke" dir)
|
;; (load! "nuke" dir)
|
||||||
;; (load! "package" dir)
|
;; (load! "package" dir)
|
||||||
;; (load! "profile" dir)
|
;; (load! "profile" dir)
|
||||||
;; (defcli-obsolete! ((compile c)) (sync "--compile") "v3.0.0")
|
|
||||||
;; (defcli-obsolete! ((build b)) (sync "--rebuild") "v3.0.0")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
(defcli-group! "Diagnostics"
|
(defcli-group! "Diagnostics"
|
||||||
|
|
|
@ -173,7 +173,7 @@
|
||||||
behaviour for known commands.
|
behaviour for known commands.
|
||||||
|
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
📌 Doom users with evil enabled will find the universal argument on [[kbd:][SPC u]]
|
Doom users with evil enabled will find the universal argument on [[kbd:][SPC u]]
|
||||||
instead than [[kbd:][C-u]].
|
instead than [[kbd:][C-u]].
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,12 @@
|
||||||
#+subtitle: Samples of Emacs/Doom dotfiles, concepts, and sub-projects
|
#+subtitle: Samples of Emacs/Doom dotfiles, concepts, and sub-projects
|
||||||
#+property: header-args:elisp :results pp
|
#+property: header-args:elisp :results pp
|
||||||
|
|
||||||
|
#+begin_quote
|
||||||
|
Our documentation was designed to be read in Doom Emacs ([[kbd:][M-x doom/help]]) or
|
||||||
|
online at https://docs.doomemacs.org. Avoid reading it elsewhere (like
|
||||||
|
Github), where it will be rendered incorrectly.
|
||||||
|
#+end_quote
|
||||||
|
|
||||||
* Introduction
|
* Introduction
|
||||||
Examples speak louder than technical explanations, so this file exists to house
|
Examples speak louder than technical explanations, so this file exists to house
|
||||||
examples of Doom's (and Emacs') concepts, libraries, dotfiles, and more, for
|
examples of Doom's (and Emacs') concepts, libraries, dotfiles, and more, for
|
||||||
|
@ -28,33 +34,6 @@ of our contributing guide first.
|
||||||
This section is dedicated to examples of concepts and libraries that can benefit
|
This section is dedicated to examples of concepts and libraries that can benefit
|
||||||
all Emacs users, whether or not they use Doom.
|
all Emacs users, whether or not they use Doom.
|
||||||
|
|
||||||
** TODO Emacs Lisp :demos:
|
|
||||||
**** file-name-with-extension
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 28.1
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(file-name-with-extension "some/file.cpp" "h")
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
: some/file.h
|
|
||||||
|
|
||||||
**** file-name-concat
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 28.1
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(file-name-concat user-emacs-directory "lisp" "file.el")
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(file-name-concat "foo" "bar" "baz")
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
: foo/bar/baz
|
|
||||||
|
|
||||||
** TODO Templates
|
** TODO Templates
|
||||||
*** TODO Emacs package
|
*** TODO Emacs package
|
||||||
*** TODO Dynamic module
|
*** TODO Dynamic module
|
||||||
|
@ -64,655 +43,6 @@ This section is dedicated to examples of concepts and libraries only relevant to
|
||||||
Doom and its users. These are intended to be demonstrations, not substitutes for
|
Doom and its users. These are intended to be demonstrations, not substitutes for
|
||||||
documentation.
|
documentation.
|
||||||
|
|
||||||
** TODO Emacs Lisp :demos:
|
|
||||||
*** doom-lib
|
|
||||||
**** add-hook!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
;; With only one hook and one function, this is identical to `add-hook'. In that
|
|
||||||
;; case, use that instead.
|
|
||||||
(add-hook! 'some-mode-hook #'enable-something)
|
|
||||||
|
|
||||||
;; Adding many-to-many functions to hooks
|
|
||||||
(add-hook! some-mode #'enable-something #'and-another)
|
|
||||||
(add-hook! some-mode '(enable-something and-another))
|
|
||||||
(add-hook! '(one-mode-hook second-mode-hook) #'enable-something)
|
|
||||||
(add-hook! (one-mode second-mode) #'enable-something)
|
|
||||||
|
|
||||||
;; Appending and local hooks
|
|
||||||
(add-hook! (one-mode second-mode) :append #'enable-something)
|
|
||||||
(add-hook! (one-mode second-mode) :local #'enable-something)
|
|
||||||
|
|
||||||
;; With arbitrary forms
|
|
||||||
(add-hook! (one-mode second-mode) (setq v 5) (setq a 2))
|
|
||||||
(add-hook! (one-mode second-mode) :append :local (setq v 5) (setq a 2))
|
|
||||||
|
|
||||||
;; Inline named hook functions
|
|
||||||
(add-hook! '(one-mode-hook second-mode-hook)
|
|
||||||
(defun do-something ()
|
|
||||||
...)
|
|
||||||
(defun do-another-thing ()
|
|
||||||
...))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
**** TODO add-transient-hook!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
**** after!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
;;; `after!' will take:
|
|
||||||
|
|
||||||
;; An unquoted package symbol (the name of a package)
|
|
||||||
(after! helm ...)
|
|
||||||
|
|
||||||
;; An unquoted list of package symbols (i.e. BODY is evaluated once both magit
|
|
||||||
;; and git-gutter have loaded)
|
|
||||||
(after! (magit git-gutter) ...)
|
|
||||||
|
|
||||||
;; An unquoted, nested list of compound package lists, using any combination of
|
|
||||||
;; :or/:any and :and/:all
|
|
||||||
(after! (:or package-a package-b ...) ...)
|
|
||||||
(after! (:and package-a package-b ...) ...)
|
|
||||||
(after! (:and package-a (:or package-b package-c) ...) ...)
|
|
||||||
;; (Without :or/:any/:and/:all, :and/:all are implied.)
|
|
||||||
|
|
||||||
;; A common mistake is to pass it the names of major or minor modes, e.g.
|
|
||||||
(after! rustic-mode ...)
|
|
||||||
(after! python-mode ...)
|
|
||||||
;; But the code in them will never run! rustic-mode is in the `rustic' package
|
|
||||||
;; and python-mode is in the `python' package. This is what you want:
|
|
||||||
(after! rustic ...)
|
|
||||||
(after! python ...)
|
|
||||||
#+end_src
|
|
||||||
**** appendq!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(let ((x '(a b c)))
|
|
||||||
(appendq! x '(c d e))
|
|
||||||
x)
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
: (a b c c d e)
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(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!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
(custom-set-faces!
|
|
||||||
'(outline-1 :weight normal)
|
|
||||||
'(outline-2 :weight normal)
|
|
||||||
'(outline-3 :weight normal)
|
|
||||||
'(outline-4 :weight normal)
|
|
||||||
'(outline-5 :weight normal)
|
|
||||||
'(outline-6 :weight normal)
|
|
||||||
'(default :background "red" :weight bold)
|
|
||||||
'(region :background "red" :weight bold))
|
|
||||||
|
|
||||||
(custom-set-faces!
|
|
||||||
'((outline-1 outline-2 outline-3 outline-4 outline-5 outline-6)
|
|
||||||
:weight normal)
|
|
||||||
'((default region)
|
|
||||||
:background "red" :weight bold))
|
|
||||||
|
|
||||||
(let ((red-bg-faces '(default region)))
|
|
||||||
(custom-set-faces!
|
|
||||||
`(,(cl-loop for i from 0 to 6 collect (intern (format "outline-%d" i)))
|
|
||||||
:weight normal)
|
|
||||||
`(,red-bg-faces
|
|
||||||
:background "red" :weight bold)))
|
|
||||||
|
|
||||||
;; You may utilise `doom-themes's theme API to fetch or tweak colors from their
|
|
||||||
;; palettes. No need to wait until the theme or package is loaded. e.g.
|
|
||||||
(custom-set-faces!
|
|
||||||
`(outline-1 :foreground ,(doom-color 'red))
|
|
||||||
`(outline-2 :background ,(doom-color 'blue)))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
**** custom-theme-set-faces!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
(custom-theme-set-faces! 'doom-one
|
|
||||||
'(outline-1 :weight normal)
|
|
||||||
'(outline-2 :weight normal)
|
|
||||||
'(outline-3 :weight normal)
|
|
||||||
'(outline-4 :weight normal)
|
|
||||||
'(outline-5 :weight normal)
|
|
||||||
'(outline-6 :weight normal)
|
|
||||||
'(default :background "red" :weight bold)
|
|
||||||
'(region :background "red" :weight bold))
|
|
||||||
|
|
||||||
(custom-theme-set-faces! '(doom-one-theme doom-one-light-theme)
|
|
||||||
'((outline-1 outline-2 outline-3 outline-4 outline-5 outline-6)
|
|
||||||
:weight normal)
|
|
||||||
'((default region)
|
|
||||||
:background "red" :weight bold))
|
|
||||||
|
|
||||||
(let ((red-bg-faces '(default region)))
|
|
||||||
(custom-theme-set-faces! '(doom-one-theme doom-one-light-theme)
|
|
||||||
`(,(cl-loop for i from 0 to 6 collect (intern (format "outline-%d" i)))
|
|
||||||
:weight normal)
|
|
||||||
`(,red-bg-faces
|
|
||||||
:background "red" :weight bold)))
|
|
||||||
|
|
||||||
;; You may utilise `doom-themes's theme API to fetch or tweak colors from their
|
|
||||||
;; palettes. No need to wait until the theme or package is loaded. e.g.
|
|
||||||
(custom-theme-set-faces! 'doom-one
|
|
||||||
`(outline-1 :foreground ,(doom-color 'red))
|
|
||||||
`(outline-2 :background ,(doom-color 'blue)))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
**** TODO defer-feature!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
**** TODO defer-until!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
**** disable-packages!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
;; Disable packages enabled by DOOM
|
|
||||||
(disable-packages! some-package second-package)
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
**** file-exists-p!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(file-exists-p! "init.el" doom-emacs-dir)
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
: /home/hlissner/.emacs.d/init.el
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(file-exists-p! (and (or "doesnotexist" "init.el")
|
|
||||||
"LICENSE")
|
|
||||||
doom-emacs-dir)
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
: /home/hlissner/.emacs.d/LICENSE
|
|
||||||
|
|
||||||
**** cmd!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
(map! "C-j" (cmd! (newline) (indent-according-to-mode)))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
**** cmd!!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
When ~newline~ is passed a numerical prefix argument (=C-u 5 M-x newline=), it
|
|
||||||
inserts N newlines. We can use ~cmd!!~ to easily create a keybinds that bakes in
|
|
||||||
the prefix arg into the command call:
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
(map! "C-j" (cmd!! #'newline 5))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
Or to create aliases for functions that behave differently:
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
(fset 'insert-5-newlines (cmd!! #'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 (cmd!! #'org-global-cycle '(4))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
**** cmds!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
(map! :i [tab] (cmds! (and (modulep! :editor snippets)
|
|
||||||
(bound-and-true-p yas-minor-mode)
|
|
||||||
(yas-maybe-expand-abbrev-key-filter 'yas-expand))
|
|
||||||
#'yas-expand
|
|
||||||
(modulep! :completion company +tng)
|
|
||||||
#'company-indent-or-complete-common)
|
|
||||||
:m [tab] (cmds! (and (bound-and-true-p yas-minor-mode)
|
|
||||||
(evil-visual-state-p)
|
|
||||||
(or (eq evil-visual-selection 'line)
|
|
||||||
(not (memq (char-after) (list ?\( ?\[ ?\{ ?\} ?\] ?\))))))
|
|
||||||
#'yas-insert-snippet
|
|
||||||
(and (modulep! :editor fold)
|
|
||||||
(save-excursion (end-of-line) (invisible-p (point))))
|
|
||||||
#'+fold/toggle
|
|
||||||
(fboundp 'evil-jump-item)
|
|
||||||
#'evil-jump-item))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
**** kbd!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
(map! "," (kbd! "SPC")
|
|
||||||
";" (kbd! ":"))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
**** lambda!
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(mapcar (lambda! ((&key foo bar baz))
|
|
||||||
(list foo bar baz))
|
|
||||||
'((:foo 10 :bar 25)
|
|
||||||
(:baz hello :boop nil)
|
|
||||||
(:bar 42)))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
**** fn!
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(mapcar (fn! (symbol-name %)) '(hello world))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(seq-sort (fn! (string-lessp (symbol-name %1)
|
|
||||||
(symbol-name %2)))
|
|
||||||
'(bonzo foo bar buddy doomguy baz zombies))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(format "You passed %d arguments to this function"
|
|
||||||
(funcall (fn! (length %*)) :foo :bar :baz "hello" 123 t))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
**** load!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
;;; Lets say we're in ~/.doom.d/config.el
|
|
||||||
(load! "lisp/module") ; loads ~/.doom.d/lisp/module.el
|
|
||||||
(load! "somefile" doom-emacs-dir) ; loads ~/.emacs.d/somefile.el
|
|
||||||
(load! "anotherfile" doom-user-dir) ; loads ~/.doom.d/anotherfile.el
|
|
||||||
|
|
||||||
;; If you don't want a `load!' call to throw an error if the file doesn't exist:
|
|
||||||
(load! "~/.maynotexist" nil t)
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
**** map!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
(map! :map magit-mode-map
|
|
||||||
:m "C-r" 'do-something ; C-r in motion state
|
|
||||||
:nv "q" 'magit-mode-quit-window ; q in normal+visual states
|
|
||||||
"C-x C-r" 'a-global-keybind
|
|
||||||
:g "C-x C-r" 'another-global-keybind ; same as above
|
|
||||||
|
|
||||||
(:when IS-MAC
|
|
||||||
:n "M-s" 'some-fn
|
|
||||||
:i "M-o" (cmd! (message "Hi"))))
|
|
||||||
|
|
||||||
(map! (:when (modulep! :completion company) ; Conditional loading
|
|
||||||
:i "C-@" #'+company/complete
|
|
||||||
(:prefix "C-x" ; Use a prefix key
|
|
||||||
:i "C-l" #'+company/whole-lines)))
|
|
||||||
|
|
||||||
(map! (:when (modulep! :lang latex) ; local conditional
|
|
||||||
(:map LaTeX-mode-map
|
|
||||||
:localleader ; Use local leader
|
|
||||||
:desc "View" "v" #'TeX-view)) ; Add which-key description
|
|
||||||
:leader ; Use leader key from now on
|
|
||||||
:desc "Eval expression" ";" #'eval-expression)
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
These are side-by-side comparisons, showing how to bind keys with and without
|
|
||||||
~map!~:
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
;; bind a global key
|
|
||||||
(global-set-key (kbd "C-x y") #'do-something)
|
|
||||||
(map! "C-x y" #'do-something)
|
|
||||||
|
|
||||||
;; bind a key on a keymap
|
|
||||||
(define-key emacs-lisp-mode-map (kbd "C-c p") #'do-something)
|
|
||||||
(map! :map emacs-lisp-mode-map "C-c p" #'do-something)
|
|
||||||
|
|
||||||
;; unbind a key defined elsewhere
|
|
||||||
(define-key lua-mode-map (kbd "SPC m b") nil)
|
|
||||||
(map! :map lua-mode-map "SPC m b" nil)
|
|
||||||
|
|
||||||
;; bind multiple keys
|
|
||||||
(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)
|
|
||||||
|
|
||||||
;; bind global keys in normal mode
|
|
||||||
(evil-define-key* 'normal 'global
|
|
||||||
(kbd "C-x x") #'do-something
|
|
||||||
(kbd "C-x y") #'do-something-else
|
|
||||||
(kbd "C-x z") #'do-another-thing)
|
|
||||||
(map! :n "C-x x" #'do-something
|
|
||||||
:n "C-x y" #'do-something-else
|
|
||||||
:n "C-x z" #'do-another-thing)
|
|
||||||
|
|
||||||
;; or on a deferred keymap
|
|
||||||
(evil-define-key 'normal emacs-lisp-mode-map
|
|
||||||
(kbd "C-x x") #'do-something
|
|
||||||
(kbd "C-x y") #'do-something-else
|
|
||||||
(kbd "C-x z") #'do-another-thing)
|
|
||||||
(map! :map emacs-lisp-mode-map
|
|
||||||
:n "C-x x" #'do-something
|
|
||||||
:n "C-x y" #'do-something-else
|
|
||||||
:n "C-x z" #'do-another-thing)
|
|
||||||
|
|
||||||
;; or multiple maps
|
|
||||||
(dolist (map (list emacs-lisp-mode go-mode-map ivy-minibuffer-map))
|
|
||||||
(evil-define-key '(normal insert) map
|
|
||||||
"a" #'a
|
|
||||||
"b" #'b
|
|
||||||
"c" #'c))
|
|
||||||
(map! :map (emacs-lisp-mode go-mode-map ivy-minibuffer-map)
|
|
||||||
:ni "a" #'a
|
|
||||||
:ni "b" #'b
|
|
||||||
:ni "c" #'c)
|
|
||||||
|
|
||||||
;; or in multiple states (order of states doesn't matter)
|
|
||||||
(evil-define-key* '(normal visual) emacs-lisp-mode-map (kbd "C-x x") #'do-something)
|
|
||||||
(evil-define-key* 'insert emacs-lisp-mode-map (kbd "C-x x") #'do-something-else)
|
|
||||||
(evil-define-key* '(visual normal insert emacs) emacs-lisp-mode-map (kbd "C-x z") #'do-another-thing)
|
|
||||||
(map! :map emacs-lisp-mode
|
|
||||||
:nv "C-x x" #'do-something ; normal+visual
|
|
||||||
:i "C-x y" #'do-something-else ; insert
|
|
||||||
:vnie "C-x z" #'do-another-thing) ; visual+normal+insert+emacs
|
|
||||||
|
|
||||||
;; You can nest map! calls:
|
|
||||||
(evil-define-key* '(normal visual) emacs-lisp-mode-map (kbd "C-x x") #'do-something)
|
|
||||||
(evil-define-key* 'normal go-lisp-mode-map (kbd "C-x x") #'do-something-else)
|
|
||||||
(map! (:map emacs-lisp-mode :nv "C-x x" #'do-something)
|
|
||||||
(:map go-lisp-mode :n "C-x x" #'do-something-else))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
**** pushnew!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(let ((list '(a b c)))
|
|
||||||
(pushnew! list 'c 'd 'e)
|
|
||||||
list)
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
: (e d a b c)
|
|
||||||
|
|
||||||
**** prependq!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(let ((x '(a b c)))
|
|
||||||
(prependq! x '(c d e))
|
|
||||||
x)
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
: (c d e a b c)
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(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!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
;; Enters recentf-mode without extra output
|
|
||||||
(quiet! (recentf-mode +1))
|
|
||||||
#+end_src
|
|
||||||
**** remove-hook!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
;; With only one hook and one function, this is identical to `remove-hook'. In
|
|
||||||
;; that case, use that instead.
|
|
||||||
(remove-hook! 'some-mode-hook #'enable-something)
|
|
||||||
|
|
||||||
;; Removing N functions from M hooks
|
|
||||||
(remove-hook! some-mode #'enable-something #'and-another)
|
|
||||||
(remove-hook! some-mode #'(enable-something and-another))
|
|
||||||
(remove-hook! '(one-mode-hook second-mode-hook) #'enable-something)
|
|
||||||
(remove-hook! (one-mode second-mode) #'enable-something)
|
|
||||||
|
|
||||||
;; Removing buffer-local hooks
|
|
||||||
(remove-hook! (one-mode second-mode) :local #'enable-something)
|
|
||||||
|
|
||||||
;; 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!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
;; 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!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
;; Set multiple variables after a hook
|
|
||||||
(setq-hook! 'markdown-mode-hook
|
|
||||||
line-spacing 2
|
|
||||||
fill-column 80)
|
|
||||||
|
|
||||||
;; Set variables after multiple hooks
|
|
||||||
(setq-hook! '(eshell-mode-hook term-mode-hook)
|
|
||||||
hscroll-margin 0)
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
**** unsetq-hook!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
(unsetq-hook! 'markdown-mode-hook line-spacing)
|
|
||||||
|
|
||||||
;; Removes the following variable hook
|
|
||||||
(setq-hook! 'markdown-mode-hook line-spacing 2)
|
|
||||||
|
|
||||||
;; Removing N variables from M hooks
|
|
||||||
(unsetq-hook! some-mode enable-something and-another)
|
|
||||||
(unsetq-hook! some-mode (enable-something and-another))
|
|
||||||
(unsetq-hook! '(one-mode-hook second-mode-hook) enable-something)
|
|
||||||
(unsetq-hook! (one-mode second-mode) enable-something)
|
|
||||||
#+end_src
|
|
||||||
**** versionp!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(versionp! "25.3" > "27.1")
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
: nil
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(versionp! "28.0" <= emacs-version <= "28.1")
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
: t
|
|
||||||
|
|
||||||
*** doom-modules
|
|
||||||
**** doom!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
(doom! :completion
|
|
||||||
company
|
|
||||||
ivy
|
|
||||||
;;helm
|
|
||||||
|
|
||||||
:tools
|
|
||||||
(:if IS-MAC macos)
|
|
||||||
docker
|
|
||||||
lsp
|
|
||||||
|
|
||||||
:lang
|
|
||||||
(cc +lsp)
|
|
||||||
(:cond ((string= system-name "work-pc")
|
|
||||||
python
|
|
||||||
rust
|
|
||||||
web)
|
|
||||||
((string= system-name "writing-pc")
|
|
||||||
(org +dragndrop)
|
|
||||||
ruby))
|
|
||||||
(:if IS-LINUX
|
|
||||||
(web +lsp)
|
|
||||||
web)
|
|
||||||
|
|
||||||
:config
|
|
||||||
literate
|
|
||||||
(default +bindings +smartparens))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
**** use-package!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
;; Use after-call to load package before hook
|
|
||||||
(use-package! projectile
|
|
||||||
:after-call (pre-command-hook after-find-file dired-before-readin-hook))
|
|
||||||
|
|
||||||
;; defer recentf packages one by one
|
|
||||||
(use-package! recentf
|
|
||||||
:defer-incrementally easymenu tree-widget timer
|
|
||||||
:after-call after-find-file)
|
|
||||||
|
|
||||||
;; This is equivalent to :defer-incrementally (abc)
|
|
||||||
(use-package! abc
|
|
||||||
:defer-incrementally t)
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
**** package!
|
|
||||||
:PROPERTIES:
|
|
||||||
:added: 3.0.0-pre
|
|
||||||
:END:
|
|
||||||
#+begin_src emacs-lisp :eval no
|
|
||||||
;; To install a package that can be found on ELPA or any of the sources
|
|
||||||
;; specified in `straight-recipe-repositories':
|
|
||||||
(package! evil)
|
|
||||||
(package! js2-mode)
|
|
||||||
(package! rainbow-delimiters)
|
|
||||||
|
|
||||||
;; To disable a package included with Doom (which will no-op all its `after!'
|
|
||||||
;; and `use-package!' blocks):
|
|
||||||
(package! evil :disable t)
|
|
||||||
(package! rainbow-delimiters :disable t)
|
|
||||||
|
|
||||||
;; To install a package from a github repo
|
|
||||||
(package! so-long :recipe (:host github :repo "hlissner/emacs-so-long"))
|
|
||||||
|
|
||||||
;; If a package is particularly big and comes with submodules you don't need,
|
|
||||||
;; you can tell the package manager not to clone the repo recursively:
|
|
||||||
(package! ansible :recipe (:nonrecursive t))
|
|
||||||
|
|
||||||
;; To pin a package to a specific commit:
|
|
||||||
(package! evil :pin "e7bc39de2f9")
|
|
||||||
;; ...or branch:
|
|
||||||
(package! evil :recipe (:branch "stable"))
|
|
||||||
;; 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
|
|
||||||
|
|
||||||
*** doom-cli
|
|
||||||
**** TODO defcli!
|
|
||||||
**** TODO defcli-alias!
|
|
||||||
**** TODO defcli-obsolete!
|
|
||||||
**** TODO defcli-stub!
|
|
||||||
**** TODO defcli-autoload!
|
|
||||||
**** TODO defcli-group!
|
|
||||||
**** TODO exit!
|
|
||||||
**** TODO call!
|
|
||||||
**** TODO run!
|
|
||||||
**** TODO sh!
|
|
||||||
**** TODO sh!!
|
|
||||||
**** TODO git!
|
|
||||||
**** TODO def-cli-context-get
|
|
||||||
**** TODO def-cli-context-put
|
|
||||||
**** TODO def-cli-context-find-option
|
|
||||||
**** TODO def-cli-call
|
|
||||||
**** TODO def-cli-exit
|
|
||||||
**** TODO def-cli-load
|
|
||||||
**** TODO def-cli-load-all
|
|
||||||
**** TODO doom-cli-find
|
|
||||||
**** TODO doom-cli-get
|
|
||||||
**** TODO doom-cli-prop
|
|
||||||
**** TODO doom-cli-subcommands
|
|
||||||
**** TODO doom-cli-aliases
|
|
||||||
*** TODO lib/files.el
|
|
||||||
**** TODO doom-path
|
|
||||||
**** TODO doom-glob
|
|
||||||
**** TODO doom-dir
|
|
||||||
**** TODO doom-files-in
|
|
||||||
**** TODO doom-file-cookie-p
|
|
||||||
**** TODO file-exists-p!
|
|
||||||
**** TODO doom-file-size
|
|
||||||
**** TODO doom-file-line-count
|
|
||||||
**** TODO doom-directory-size
|
|
||||||
**** TODO doom-file-read
|
|
||||||
**** TODO doom-file-write
|
|
||||||
**** TODO with-file-contents!
|
|
||||||
|
|
||||||
** TODO Configuration files
|
** TODO Configuration files
|
||||||
*** =profiles.el=
|
*** =profiles.el=
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
|
@ -779,7 +109,7 @@ Here is an exhaustive example of all its syntax and capabilities:
|
||||||
(profile3
|
(profile3
|
||||||
...))
|
...))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
*** =.doomprofile=
|
*** =.doomprofile=
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:ID: ac37ac6f-6082-4c34-b98c-962bc1e528c9
|
:ID: ac37ac6f-6082-4c34-b98c-962bc1e528c9
|
||||||
|
|
34
docs/faq.org
34
docs/faq.org
|
@ -5,6 +5,12 @@
|
||||||
#+subtitle: Answers to common issues and questions
|
#+subtitle: Answers to common issues and questions
|
||||||
#+startup: nonum show2levels*
|
#+startup: nonum show2levels*
|
||||||
|
|
||||||
|
#+begin_quote
|
||||||
|
Our documentation was designed to be read in Doom Emacs ([[kbd:][M-x doom/help]]) or
|
||||||
|
online at https://docs.doomemacs.org. Avoid reading it elsewhere (like
|
||||||
|
Github) where it will be rendered incorrectly.
|
||||||
|
#+end_quote
|
||||||
|
|
||||||
* General
|
* General
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:ID: 3c17177d-8ba9-4d1a-a279-b6dea21c8a9a
|
:ID: 3c17177d-8ba9-4d1a-a279-b6dea21c8a9a
|
||||||
|
@ -242,8 +248,9 @@ Doom exposes a couple variables for setting fonts. They are:
|
||||||
- [[var:doom-variable-pitch-font]]: used for non-monospace fonts (e.g. when using
|
- [[var:doom-variable-pitch-font]]: used for non-monospace fonts (e.g. when using
|
||||||
variable-pitch-mode or mixed-pitch-mode). Popular for text modes, like Org or
|
variable-pitch-mode or mixed-pitch-mode). Popular for text modes, like Org or
|
||||||
Markdown.
|
Markdown.
|
||||||
- [[var:doom-unicode-font]]: used for rendering unicode glyphs. This is ~Symbola~ by
|
- [[var:doom-emoji-font]]: used for rendering emoji. Only needed if you want to use
|
||||||
default. It is ignored if the [[doom-module::ui unicode]] module is enabled.
|
a font other than your operating system’s default.
|
||||||
|
- [[var:doom-symbol-font]]: used for rendering symbols.
|
||||||
- [[var:doom-serif-font]]: the sans-serif font to use wherever the [[face:fixed-pitch-serif]]
|
- [[var:doom-serif-font]]: the sans-serif font to use wherever the [[face:fixed-pitch-serif]]
|
||||||
face is used.
|
face is used.
|
||||||
- [[var:doom-big-font]]: the large font to use when [[fn:doom-big-font-mode]] is active.
|
- [[var:doom-big-font]]: the large font to use when [[fn:doom-big-font-mode]] is active.
|
||||||
|
@ -261,12 +268,12 @@ For example:
|
||||||
;; in $DOOMDIR/config.el
|
;; in $DOOMDIR/config.el
|
||||||
(setq doom-font (font-spec :family "JetBrainsMono" :size 12 :weight 'light)
|
(setq doom-font (font-spec :family "JetBrainsMono" :size 12 :weight 'light)
|
||||||
doom-variable-pitch-font (font-spec :family "DejaVu Sans" :size 13)
|
doom-variable-pitch-font (font-spec :family "DejaVu Sans" :size 13)
|
||||||
doom-unicode-font (font-spec :family "Symbola")
|
doom-symbol-font (font-spec :family "JuliaMono")
|
||||||
doom-big-font (font-spec :family "JetBrainsMono" :size 24))
|
doom-big-font (font-spec :family "JetBrainsMono" :size 24))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🚧 If you or Emacs can't find your font, use ~M-x describe-font~ to look them
|
If you or Emacs can't find your font, use ~M-x describe-font~ to look them
|
||||||
up, or run ~$ fc-list~ to see all the available fonts on your system. *Font
|
up, or run ~$ fc-list~ to see all the available fonts on your system. *Font
|
||||||
issues are /rarely/ Doom issues!*
|
issues are /rarely/ Doom issues!*
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
@ -395,14 +402,13 @@ This command is never needed for changes to =$DOOMDIR/config.el=.
|
||||||
|
|
||||||
** Copy or sync my config to another system?
|
** Copy or sync my config to another system?
|
||||||
*Short answer:* it is safe to sync =$DOOMDIR= across systems, but not
|
*Short answer:* it is safe to sync =$DOOMDIR= across systems, but not
|
||||||
=$EMACSDIR=. Once moved, use ~$ doom sync && doom build~ to ensure everything is
|
=$EMACSDIR=. Once moved, use ~$ doom sync~ to ensure everything is set up
|
||||||
set up correctly.
|
correctly.
|
||||||
|
|
||||||
*Long answer:* packages can contain baked-in absolute paths and non-portable
|
*Long answer:* packages can contain baked-in absolute paths and non-portable
|
||||||
byte-code. It is never a good idea to mirror it across multiple systems, unless
|
byte-code. It is never a good idea to mirror it across multiple systems, unless
|
||||||
they are all the same (same OS, same version of Emacs, same paths). Most issues
|
they are all the same (same OS, same version of Emacs, same paths). Most issues
|
||||||
should be solved by running ~$ doom sync && doom build~ on the other end, once
|
should be solved by running ~$ doom sync~ on the other end, once moved.
|
||||||
moved.
|
|
||||||
|
|
||||||
** Start over, in case something went terribly wrong?
|
** Start over, in case something went terribly wrong?
|
||||||
Delete =$EMACSDIR/.local/straight= and run ~$ doom sync~.
|
Delete =$EMACSDIR/.local/straight= and run ~$ doom sync~.
|
||||||
|
@ -518,7 +524,7 @@ Here are a few common causes for random crashes:
|
||||||
|
|
||||||
- Some fonts cause Emacs to crash when they lack support for a particular glyph
|
- Some fonts cause Emacs to crash when they lack support for a particular glyph
|
||||||
(typically symbols). Try changing your font by changing ~doom-font~ or
|
(typically symbols). Try changing your font by changing ~doom-font~ or
|
||||||
~doom-unicode-font~.
|
~doom-symbol-font~.
|
||||||
|
|
||||||
- Ligatures can cause Emacs to crash. Try a different [[doom-module::ui ligatures +fira][ligature font]] or disable
|
- Ligatures can cause Emacs to crash. Try a different [[doom-module::ui ligatures +fira][ligature font]] or disable
|
||||||
the [[doom-module::ui ligatures]] module altogether.
|
the [[doom-module::ui ligatures]] module altogether.
|
||||||
|
@ -618,7 +624,7 @@ keybinds to work:
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
📌 I use [C-left] because it is easier to type than "<C-left>", but they are
|
I use [C-left] because it is easier to type than "<C-left>", but they are
|
||||||
equivalent; two different ways to refer to the same key.
|
equivalent; two different ways to refer to the same key.
|
||||||
#+end_quote
|
#+end_quote
|
||||||
** Recursive load error on startup
|
** Recursive load error on startup
|
||||||
|
@ -638,7 +644,7 @@ Then these are the three most common explanations:
|
||||||
- *GNU* =tar= and/or =gzip= are not installed on your system.
|
- *GNU* =tar= and/or =gzip= are not installed on your system.
|
||||||
|
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🚧 *Warning macOS and *BSD distro users:* you likely have BSD variants of
|
*Warning macOS and *BSD distro users:* you likely have BSD variants of
|
||||||
=tar= and =gzip= installed by default. Emacs requires the GNU variants!
|
=tar= and =gzip= installed by default. Emacs requires the GNU variants!
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
|
@ -833,13 +839,13 @@ There's more about quoting [[https://emacsdocs.org/docs/elisp/Quoting][in the Em
|
||||||
|
|
||||||
** TODO How does Doom Emacs start up so quickly?
|
** TODO How does Doom Emacs start up so quickly?
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 *This post is a work in progress!* However, there's a post on our Discourse
|
*This post is a work in progress!* However, there's a post on our Discourse
|
||||||
that outlines [[https://discourse.doomemacs.org/t/how-does-doom-start-up-so-quickly/163/1][some of our older techniques]].
|
that outlines [[https://discourse.doomemacs.org/t/how-does-doom-start-up-so-quickly/163/1][some of our older techniques]].
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
** TODO How does Doom Emacs improve runtime performance?
|
** TODO How does Doom Emacs improve runtime performance?
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 *This post is a work in progress!*
|
*This post is a work in progress!*
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
** Why does Doom not use dash, f, s, or similar libraries?
|
** Why does Doom not use dash, f, s, or similar libraries?
|
||||||
|
@ -911,7 +917,7 @@ you, a combination of [[kbd:][o]] (swaps your cursor between the two ends of the
|
||||||
and motion keys can adjust the ends of your selection.
|
and motion keys can adjust the ends of your selection.
|
||||||
|
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
📌 There are also text objects for xml tags ([[kbd:][x]]), C-style function arguments
|
There are also text objects for xml tags ([[kbd:][x]]), C-style function arguments
|
||||||
([[kbd:][a]]), angle brackets, and single/double quotes.
|
([[kbd:][a]]), angle brackets, and single/double quotes.
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
|
|
|
@ -551,9 +551,7 @@ doom sync
|
||||||
doom env
|
doom env
|
||||||
|
|
||||||
# Lastly, install the icon fonts Doom uses:
|
# Lastly, install the icon fonts Doom uses:
|
||||||
emacs --batch -f all-the-icons-install-fonts
|
emacs --batch -f nerd-icons-install-fonts
|
||||||
# On Windows, `all-the-icons-install-fonts` will only download the fonts, you'll
|
|
||||||
# have to install them by hand afterwards!
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
To understand the purpose of the =~/.doom.d= directory and =~/.doom.d/init.el=
|
To understand the purpose of the =~/.doom.d= directory and =~/.doom.d/init.el=
|
||||||
|
|
|
@ -27,16 +27,17 @@
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
;; PERF: Garbage collection is a big contributor to startup times. This fends it
|
;; PERF: Garbage collection is a big contributor to startup times. This fends it
|
||||||
;; off, but will be reset later by `gcmh-mode'. Not resetting it later will
|
;; off, but will be reset later by `gcmh-mode' (or in doom-cli.el, if in a
|
||||||
;; cause stuttering/freezes.
|
;; noninteractive session). Not resetting it later causes stuttering/freezes.
|
||||||
(setq gc-cons-threshold most-positive-fixnum)
|
(setq gc-cons-threshold most-positive-fixnum)
|
||||||
|
|
||||||
;; PERF: Don't use precious startup time checking mtime on elisp bytecode.
|
;; PERF: Don't use precious startup time checking mtime on elisp bytecode.
|
||||||
;; Ensuring correctness is 'doom sync's job, not the interactive session's.
|
;; Ensuring correctness is 'doom sync's job, not the interactive session's.
|
||||||
;; Still, stale byte-code will cause *heavy* losses in startup efficiency.
|
;; Still, stale byte-code will cause *heavy* losses in startup efficiency, but
|
||||||
|
;; performance is unimportant when Emacs is in an error state.
|
||||||
(setq load-prefer-newer noninteractive)
|
(setq load-prefer-newer noninteractive)
|
||||||
|
|
||||||
;; UX: Respect DEBUG envvar as an alternative to --debug-init, and to make are
|
;; UX: Respect DEBUG envvar as an alternative to --debug-init, and to make
|
||||||
;; startup sufficiently verbose from this point on.
|
;; startup sufficiently verbose from this point on.
|
||||||
(when (getenv-internal "DEBUG")
|
(when (getenv-internal "DEBUG")
|
||||||
(setq init-file-debug t
|
(setq init-file-debug t
|
||||||
|
@ -48,17 +49,17 @@
|
||||||
|
|
||||||
(or
|
(or
|
||||||
;; PERF: `file-name-handler-alist' is consulted often. Unsetting it offers a
|
;; PERF: `file-name-handler-alist' is consulted often. Unsetting it offers a
|
||||||
;; notable saving in startup time. This let-binding is just a stopgap though,
|
;; notable saving in startup time. This is just a stopgap though; this
|
||||||
;; a more complete version of this optimization can be found in lisp/doom.el.
|
;; optimization is continued more comprehensively in lisp/doom.el.
|
||||||
(let (file-name-handler-alist)
|
(let (file-name-handler-alist)
|
||||||
(let* (;; FIX: Unset `command-line-args' in noninteractive sessions, to
|
(let (;; FIX: Unset `command-line-args' in noninteractive sessions, to
|
||||||
;; ensure upstream switches aren't misinterpreted.
|
;; ensure upstream switches aren't misinterpreted.
|
||||||
(command-line-args (unless noninteractive command-line-args))
|
(command-line-args (unless noninteractive command-line-args))
|
||||||
;; I avoid using `command-switch-alist' to process --profile (and
|
;; I avoid using `command-switch-alist' to process --profile (and
|
||||||
;; --init-directory) because it is processed too late to change
|
;; --init-directory) because it is processed too late to change
|
||||||
;; `user-emacs-directory' in time.
|
;; `user-emacs-directory' in time.
|
||||||
(profile (or (cadr (member "--profile" command-line-args))
|
(profile (or (cadr (member "--profile" command-line-args))
|
||||||
(getenv-internal "DOOMPROFILE"))))
|
(getenv-internal "DOOMPROFILE"))))
|
||||||
(if (null profile)
|
(if (null profile)
|
||||||
;; REVIEW: Backported from Emacs 29. Remove when 28 support is dropped.
|
;; REVIEW: Backported from Emacs 29. Remove when 28 support is dropped.
|
||||||
(let ((init-dir (or (cadr (member "--init-directory" command-line-args))
|
(let ((init-dir (or (cadr (member "--init-directory" command-line-args))
|
||||||
|
@ -84,7 +85,10 @@
|
||||||
(or (load (expand-file-name
|
(or (load (expand-file-name
|
||||||
(format (let ((lfile (getenv-internal "DOOMPROFILELOADFILE")))
|
(format (let ((lfile (getenv-internal "DOOMPROFILELOADFILE")))
|
||||||
(if lfile
|
(if lfile
|
||||||
(concat (string-remove-suffix ".el" lfile)
|
(concat (let ((suffix ".el"))
|
||||||
|
(if (string-suffix-p suffix lfile)
|
||||||
|
(substring lfile 0 (- (length lfile) (length suffix)))
|
||||||
|
lfile))
|
||||||
".%d.elc")
|
".%d.elc")
|
||||||
"profiles/load.%d.elc"))
|
"profiles/load.%d.elc"))
|
||||||
emacs-major-version)
|
emacs-major-version)
|
||||||
|
@ -94,33 +98,33 @@
|
||||||
|
|
||||||
;; PERF: When `load'ing or `require'ing files, each permutation of
|
;; PERF: When `load'ing or `require'ing files, each permutation of
|
||||||
;; `load-suffixes' and `load-file-rep-suffixes' (then `load-suffixes' +
|
;; `load-suffixes' and `load-file-rep-suffixes' (then `load-suffixes' +
|
||||||
;; `load-file-rep-suffixes') is used to locate the file. Each permutation
|
;; `load-file-rep-suffixes') is used to locate the file. Each permutation
|
||||||
;; is a file op, which is normally very fast, but they can add up over the
|
;; amounts to at least one file op, which is normally very fast, but can
|
||||||
;; hundreds/thousands of files Emacs needs to load.
|
;; add up over the hundreds/thousands of files Emacs loads.
|
||||||
;;
|
;;
|
||||||
;; To reduce that burden -- and since Doom doesn't load any dynamic modules
|
;; To reduce that burden -- and since Doom doesn't load any dynamic modules
|
||||||
;; -- I remove `.so' from `load-suffixes' and pass the `must-suffix' arg to
|
;; this early -- I remove `.so' from `load-suffixes' and pass the
|
||||||
;; `load'. See the docs of `load' for details.
|
;; `must-suffix' arg to `load'. See the docs of `load' for details.
|
||||||
(if (let ((load-suffixes '(".elc" ".el")))
|
(if (let ((load-suffixes '(".elc" ".el")))
|
||||||
;; I avoid `load's NOERROR argument because other, legitimate errors
|
;; I avoid `load's NOERROR argument because it suppresses other,
|
||||||
;; (like permission or IO errors) should not be suppressed or
|
;; legitimate errors (like permission or IO errors), which gets
|
||||||
;; interpreted as "this is not a Doom config".
|
;; incorrectly interpreted as "this is not a Doom config".
|
||||||
(condition-case _
|
(condition-case-unless-debug _
|
||||||
;; Load the heart of Doom Emacs.
|
;; Load the heart of Doom Emacs.
|
||||||
(load (expand-file-name "lisp/doom" user-emacs-directory)
|
(load (expand-file-name "lisp/doom" user-emacs-directory)
|
||||||
nil (not init-file-debug) nil 'must-suffix)
|
nil (not init-file-debug) nil 'must-suffix)
|
||||||
;; Failing that, assume that we're loading a non-Doom config.
|
;; Failing that, assume that we're loading a non-Doom config.
|
||||||
(file-missing
|
(file-missing
|
||||||
;; HACK: `startup--load-user-init-file' resolves $EMACSDIR from a
|
;; HACK: `startup--load-user-init-file' resolves $EMACSDIR from a
|
||||||
;; lexically bound `startup-init-directory', which means changes
|
;; lexical (and so, not-trivially-modifiable)
|
||||||
;; to `user-emacs-directory' won't be respected when loading
|
;; `startup-init-directory', so Emacs will fail to locate the
|
||||||
;; $EMACSDIR/init.el, so I force it to:
|
;; correct $EMACSDIR/init.el without help.
|
||||||
(define-advice startup--load-user-init-file (:filter-args (args) reroute-to-profile)
|
(define-advice startup--load-user-init-file (:filter-args (args) reroute-to-profile)
|
||||||
(list (lambda () (expand-file-name "init.el" user-emacs-directory))
|
(list (lambda () (expand-file-name "init.el" user-emacs-directory))
|
||||||
nil (nth 2 args)))
|
nil (nth 2 args)))
|
||||||
;; Set `user-init-file' for the `load' call further below, and do so
|
;; (Re)set `user-init-file' for the `load' call further below, and
|
||||||
;; here while our `file-name-handler-alist' optimization is still
|
;; do so here while our `file-name-handler-alist' optimization is
|
||||||
;; effective (benefits `expand-file-name'). BTW: Emacs resets
|
;; still effective (benefits `expand-file-name'). BTW: Emacs resets
|
||||||
;; `user-init-file' and `early-init-file' after this file is loaded.
|
;; `user-init-file' and `early-init-file' after this file is loaded.
|
||||||
(setq user-init-file (expand-file-name "early-init" user-emacs-directory))
|
(setq user-init-file (expand-file-name "early-init" user-emacs-directory))
|
||||||
;; COMPAT: I make no assumptions about the config we're going to
|
;; COMPAT: I make no assumptions about the config we're going to
|
||||||
|
@ -133,7 +137,7 @@
|
||||||
;; as a best fit guess. It's better than Emacs' 80kb default.
|
;; as a best fit guess. It's better than Emacs' 80kb default.
|
||||||
(setq gc-cons-threshold (* 16 1024 1024))
|
(setq gc-cons-threshold (* 16 1024 1024))
|
||||||
nil)))
|
nil)))
|
||||||
;; ...But if Doom loaded then continue as normal.
|
;; ...Otherwise, we're loading a Doom config, so continue as normal.
|
||||||
(doom-require (if noninteractive 'doom-cli 'doom-start))))
|
(doom-require (if noninteractive 'doom-cli 'doom-start))))
|
||||||
|
|
||||||
;; Then continue on to the config/profile we want to load.
|
;; Then continue on to the config/profile we want to load.
|
||||||
|
|
|
@ -1,214 +0,0 @@
|
||||||
;;; lisp/cli/commands/byte-compile.el -*- lexical-binding: t; -*-
|
|
||||||
|
|
||||||
;;
|
|
||||||
;;; Variables
|
|
||||||
|
|
||||||
;; None yet!
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;;; Commands
|
|
||||||
|
|
||||||
(defcli! ((compile c))
|
|
||||||
((recompile-p ("-r" "--recompile"))
|
|
||||||
(core-p ("-c" "--core"))
|
|
||||||
(private-p ("-p" "--private"))
|
|
||||||
(verbose-p ("-v" "--verbose")))
|
|
||||||
"Byte-compiles your config or selected modules.
|
|
||||||
|
|
||||||
compile [TARGETS...]
|
|
||||||
compile :core :user lang/python
|
|
||||||
compile feature lang
|
|
||||||
|
|
||||||
Accepts :core and :user as special arguments, which target Doom's core files
|
|
||||||
and your private config files, respectively. To recompile your packages, use
|
|
||||||
'doom build' instead."
|
|
||||||
(doom-cli-compile
|
|
||||||
(if (or core-p private-p)
|
|
||||||
(append (if core-p (doom-glob doom-emacs-dir "init.el"))
|
|
||||||
(if core-p (list doom-core-dir))
|
|
||||||
(if private-p (list doom-user-dir)))
|
|
||||||
(or (y-or-n-p
|
|
||||||
(concat "WARNING: Changes made to your config after compiling it won't take effect until\n"
|
|
||||||
"this command is rerun or you run 'doom clean'! It will also make error backtraces\n"
|
|
||||||
"much more difficult to decipher.\n\n"
|
|
||||||
"If you intend to use it anyway, remember this or it will come back to bite you!\n\n"
|
|
||||||
"Continue anyway?"))
|
|
||||||
(user-error "Aborted"))
|
|
||||||
(append (doom-glob doom-emacs-dir "init.el")
|
|
||||||
(list doom-core-dir)
|
|
||||||
(seq-filter
|
|
||||||
;; Only compile Doom's modules
|
|
||||||
(doom-rpartial #'file-in-directory-p doom-emacs-dir)
|
|
||||||
;; Omit `doom-user-dir', which is always first
|
|
||||||
(doom-module-load-path))))
|
|
||||||
recompile-p
|
|
||||||
verbose-p))
|
|
||||||
|
|
||||||
(defcli! clean ()
|
|
||||||
"Delete all *.elc files."
|
|
||||||
(doom-compile-clean))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;;; Helpers
|
|
||||||
|
|
||||||
(cl-defun doom-cli-compile (&optional targets recompile-p verbose-p)
|
|
||||||
"Byte compiles your emacs configuration.
|
|
||||||
|
|
||||||
init.el is always byte-compiled by this.
|
|
||||||
|
|
||||||
If TARGETS is specified, as a list of direcotries
|
|
||||||
|
|
||||||
If MODULES is specified (a list of module strings, e.g. \"lang/php\"), those are
|
|
||||||
byte-compiled. Otherwise, all enabled modules are byte-compiled, including Doom
|
|
||||||
core. It always ignores unit tests and files with `no-byte-compile' enabled.
|
|
||||||
|
|
||||||
WARNING: byte-compilation yields marginal gains and makes debugging new issues
|
|
||||||
difficult. It is recommended you don't use it unless you understand the
|
|
||||||
reprecussions.
|
|
||||||
|
|
||||||
Use `doom-compile-clean' or `make clean' to reverse
|
|
||||||
byte-compilation.
|
|
||||||
|
|
||||||
If RECOMPILE-P is non-nil, only recompile out-of-date files."
|
|
||||||
(let* ((default-directory doom-emacs-dir)
|
|
||||||
(targets (nreverse (delete-dups targets)))
|
|
||||||
;; In case it is changed during compile-time
|
|
||||||
(auto-mode-alist auto-mode-alist)
|
|
||||||
kill-emacs-hook kill-buffer-query-functions)
|
|
||||||
|
|
||||||
(let ((after-load-functions
|
|
||||||
(if (null targets)
|
|
||||||
after-load-functions
|
|
||||||
;; Assemble el files we want to compile, and preserve in the order
|
|
||||||
;; they are loaded in, so we don't run into any scary catch-22s
|
|
||||||
;; while byte-compiling, like missing macros.
|
|
||||||
(cons (let ((target-dirs (seq-filter #'file-directory-p targets)))
|
|
||||||
(lambda (path)
|
|
||||||
(and (not (doom-compile--ignore-file-p path))
|
|
||||||
(seq-find (doom-partial #'file-in-directory-p path)
|
|
||||||
target-dirs)
|
|
||||||
(cl-pushnew path targets))))
|
|
||||||
after-load-functions))))
|
|
||||||
(doom-log "Reloading Doom in preparation for byte-compilation")
|
|
||||||
;; 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 ((load-prefer-newer t))
|
|
||||||
(require 'doom-start)))
|
|
||||||
|
|
||||||
(if (null targets)
|
|
||||||
(print! (item "No targets to %scompile" (if recompile-p "re" "")))
|
|
||||||
(print! (start "%scompiling your config...")
|
|
||||||
(if recompile-p "Re" "Byte-"))
|
|
||||||
|
|
||||||
(dolist (dir
|
|
||||||
(cl-remove-if-not #'file-directory-p targets)
|
|
||||||
(setq targets (cl-remove-if #'file-directory-p targets)))
|
|
||||||
(prependq! targets
|
|
||||||
(doom-files-in
|
|
||||||
dir :match "\\.el" :filter #'doom-compile--ignore-file-p)))
|
|
||||||
|
|
||||||
(print-group!
|
|
||||||
(require 'use-package)
|
|
||||||
(condition-case-unless-debug e
|
|
||||||
(let* ((total-ok 0)
|
|
||||||
(total-fail 0)
|
|
||||||
(total-noop 0)
|
|
||||||
(byte-compile-verbose nil)
|
|
||||||
(byte-compile-warnings '(not free-vars unresolved noruntime lexical make-local))
|
|
||||||
(byte-compile-dynamic-docstrings t)
|
|
||||||
(use-package-compute-statistics nil)
|
|
||||||
(use-package-defaults use-package-defaults)
|
|
||||||
(use-package-expand-minimally t)
|
|
||||||
(targets (delete-dups targets))
|
|
||||||
(modules (seq-group-by #'doom-module-from-path targets))
|
|
||||||
(total-files (length targets))
|
|
||||||
(total-modules (length modules))
|
|
||||||
(i 0)
|
|
||||||
last-module)
|
|
||||||
;; Prevent packages from being loaded at compile time if they
|
|
||||||
;; don't meet their own predicates.
|
|
||||||
(push (list :no-require t
|
|
||||||
(lambda (_name args)
|
|
||||||
(or (when-let (pred (or (plist-get args :if)
|
|
||||||
(plist-get args :when)))
|
|
||||||
(not (eval pred t)))
|
|
||||||
(when-let (pred (plist-get args :unless))
|
|
||||||
(eval pred t)))))
|
|
||||||
use-package-defaults)
|
|
||||||
(dolist (module-files modules)
|
|
||||||
(cl-incf i)
|
|
||||||
(dolist (target (cdr module-files))
|
|
||||||
(let ((elc-file (byte-compile-dest-file target)))
|
|
||||||
(cl-incf
|
|
||||||
(if (and recompile-p (not (file-newer-than-file-p target elc-file)))
|
|
||||||
total-noop
|
|
||||||
(pcase (if (not (doom-file-cookie-p target "if" t))
|
|
||||||
'no-byte-compile
|
|
||||||
(unless (equal last-module (car module-files))
|
|
||||||
(print! (success "(% 3d/%d) Compiling %s")
|
|
||||||
i total-modules
|
|
||||||
(if-let (m (caar module-files))
|
|
||||||
(format "%s %s module..." m (cdar module-files))
|
|
||||||
(format "%d stand alone elisp files..."
|
|
||||||
(length (cdr module-files))))
|
|
||||||
(caar module-files) (cdar module-files))
|
|
||||||
(setq last-module (car module-files)))
|
|
||||||
(if verbose-p
|
|
||||||
(byte-compile-file target)
|
|
||||||
(quiet! (byte-compile-file target))))
|
|
||||||
(`no-byte-compile
|
|
||||||
(doom-log "(% 3d/%d) Ignored %s" i total-modules target)
|
|
||||||
total-noop)
|
|
||||||
(`nil
|
|
||||||
(print! (error "(% 3d/%d) Failed to compile %s")
|
|
||||||
i total-modules (relpath target))
|
|
||||||
total-fail)
|
|
||||||
(_ total-ok)))))))
|
|
||||||
(print! (class (if (= total-fail 0) 'success 'warn)
|
|
||||||
"%s %d/%d file(s) (%d ignored)")
|
|
||||||
(if recompile-p "Recompiled" "Byte-compiled")
|
|
||||||
total-ok total-files
|
|
||||||
total-noop)
|
|
||||||
(= total-fail 0))
|
|
||||||
((debug error)
|
|
||||||
(print! (error "There were breaking errors.\n\n%s")
|
|
||||||
"Reverting changes...")
|
|
||||||
(signal 'doom-error (list 'byte-compile e))))))))
|
|
||||||
|
|
||||||
(defun doom-compile--ignore-file-p (path)
|
|
||||||
(let ((filename (file-name-nondirectory path)))
|
|
||||||
(or (not (equal (file-name-extension path) "el"))
|
|
||||||
(member filename (list doom-module-packages-file "doctor.el"))
|
|
||||||
(string-prefix-p "." filename)
|
|
||||||
(string-prefix-p "test-" filename)
|
|
||||||
(string-prefix-p "flycheck_" filename)
|
|
||||||
(string-suffix-p ".example.el" filename))))
|
|
||||||
|
|
||||||
(defun doom-compile-clean ()
|
|
||||||
"Delete all the compiled elc files in your Emacs configuration and private
|
|
||||||
module. This does not include your byte-compiled, third party packages.'"
|
|
||||||
(require 'doom-modules)
|
|
||||||
(print! (start "Cleaning .elc files"))
|
|
||||||
(print-group!
|
|
||||||
(cl-loop with default-directory = doom-emacs-dir
|
|
||||||
with success = 0
|
|
||||||
with esc = (if init-file-debug "" "\033[1A")
|
|
||||||
for path
|
|
||||||
in (append (doom-glob doom-emacs-dir "*.elc")
|
|
||||||
(doom-files-in doom-user-dir :match "\\.elc$" :depth 1)
|
|
||||||
(doom-files-in doom-core-dir :match "\\.elc$")
|
|
||||||
(doom-files-in doom-modules-dirs :match "\\.elc$" :depth 4))
|
|
||||||
if (file-exists-p path)
|
|
||||||
do (delete-file path)
|
|
||||||
and do (print! (success "\033[KDeleted %s%s") (relpath path) esc)
|
|
||||||
and do (cl-incf success)
|
|
||||||
finally do
|
|
||||||
(print! (if (> success 0)
|
|
||||||
(success "\033[K%d elc files deleted" success)
|
|
||||||
(item "\033[KNo elc files to clean"))))
|
|
||||||
t))
|
|
||||||
|
|
||||||
(provide 'doom-cli-compile)
|
|
||||||
;;; compile.el ends here
|
|
|
@ -96,48 +96,86 @@ in."
|
||||||
(error! "Couldn't find the `rg' binary; this a hard dependecy for Doom, file searches may not work at all")))
|
(error! "Couldn't find the `rg' binary; this a hard dependecy for Doom, file searches may not work at all")))
|
||||||
|
|
||||||
(print! (start "Checking for Emacs config conflicts..."))
|
(print! (start "Checking for Emacs config conflicts..."))
|
||||||
(when (file-exists-p "~/.emacs")
|
(print-group!
|
||||||
(warn! "Detected an ~/.emacs file, which may prevent Doom from loading")
|
(unless (or (file-equal-p doom-emacs-dir "~/.emacs.d")
|
||||||
(explain! "If Emacs finds an ~/.emacs file, it will ignore ~/.emacs.d, where Doom is "
|
(file-equal-p doom-emacs-dir "~/.config/emacs"))
|
||||||
"typically installed. If you're seeing a vanilla Emacs splash screen, this "
|
(print! (warn "Doom is installed in a non-standard location"))
|
||||||
"may explain why. If you use Chemacs, you may ignore this warning."))
|
(explain! "The standard locations are ~/.config/emacs or ~/.emacs.d. Emacs will fail "
|
||||||
|
"to load Doom if it is not explicitly told where to look for it. In Emacs 29+, "
|
||||||
|
"this is possible with the --init-directory option:\n\n"
|
||||||
|
" $ emacs --init-directory '" (abbreviate-file-name doom-emacs-dir) "'\n\n"
|
||||||
|
"However, Emacs 27-28 users have no choice but to move Doom to a standard "
|
||||||
|
"location.\n\n"
|
||||||
|
"Chemacs users may ignore this warning, however."))
|
||||||
|
(let (found?)
|
||||||
|
(dolist (file '("~/_emacs" "~/.emacs" "~/.emacs.el" "~/.emacs.d" "~/.config/emacs"))
|
||||||
|
(when (and (file-exists-p file)
|
||||||
|
(not (file-equal-p file doom-emacs-dir)))
|
||||||
|
(setq found? t)
|
||||||
|
(print! (warn "Found another Emacs config: %s (%s)")
|
||||||
|
file (if (file-directory-p file) "directory" "file"))))
|
||||||
|
(when found?
|
||||||
|
(explain! "Having multiple Emacs configs may prevent Doom from loading properly. Emacs "
|
||||||
|
"will load the first it finds and ignore the rest. If Doom isn't starting up "
|
||||||
|
"correctly (e.g. you get a vanilla splash screen), make sure that only one of "
|
||||||
|
"these exist.\n\n"
|
||||||
|
"Chemacs users may ignore this warning."))))
|
||||||
|
|
||||||
(print! (start "Checking for great Emacs features..."))
|
(print! (start "Checking for missing Emacs features..."))
|
||||||
(unless (functionp 'json-serialize)
|
(print-group!
|
||||||
(warn! "Emacs was not built with native JSON support")
|
(unless (functionp 'json-serialize)
|
||||||
(explain! "Users will see a substantial performance gain by building Emacs with "
|
(warn! "Emacs was not built with native JSON support")
|
||||||
"jansson support (i.e. a native JSON library), particularly LSP users. "
|
(explain! "Users will see a substantial performance gain by building Emacs with "
|
||||||
"You must install a prebuilt Emacs binary with this included, or compile "
|
"jansson support (i.e. a native JSON library), particularly LSP users. "
|
||||||
"Emacs with the --with-json option."))
|
"You must install a prebuilt Emacs binary with this included, or compile "
|
||||||
(unless (featurep 'native-compile)
|
"Emacs with the --with-json option."))
|
||||||
(warn! "Emacs was not built with native compilation support")
|
(unless (featurep 'native-compile)
|
||||||
(explain! "Users will see a substantial performance gain by building Emacs with "
|
(warn! "Emacs was not built with native compilation support")
|
||||||
"native compilation support, availible in emacs 28+."
|
(explain! "Users will see a substantial performance gain by building Emacs with "
|
||||||
"You must install a prebuilt Emacs binary with this included, or compile "
|
"native compilation support, availible in emacs 28+."
|
||||||
"Emacs with the --with-native-compilation option."))
|
"You must install a prebuilt Emacs binary with this included, or compile "
|
||||||
|
"Emacs with the --with-native-compilation option.")))
|
||||||
|
|
||||||
(print! (start "Checking for private config conflicts..."))
|
(print! (start "Checking for private config conflicts..."))
|
||||||
(let* ((xdg-dir (concat (or (getenv "XDG_CONFIG_HOME")
|
(print-group!
|
||||||
"~/.config")
|
(let* ((xdg-dir (concat (or (getenv "XDG_CONFIG_HOME")
|
||||||
"/doom/"))
|
"~/.config")
|
||||||
(doom-dir (or (getenv "DOOMDIR")
|
"/doom/"))
|
||||||
"~/.doom.d/"))
|
(doom-dir (or (getenv "DOOMDIR")
|
||||||
(dir (if (file-directory-p xdg-dir)
|
"~/.doom.d/"))
|
||||||
xdg-dir
|
(dir (if (file-directory-p xdg-dir)
|
||||||
doom-dir)))
|
xdg-dir
|
||||||
(when (file-equal-p dir doom-emacs-dir)
|
doom-dir)))
|
||||||
(print! (error "Doom was cloned to %S, not ~/.emacs.d or ~/.config/emacs"
|
(when (file-equal-p dir doom-emacs-dir)
|
||||||
(path dir)))
|
(print! (error "Doom was cloned to %S, not ~/.emacs.d or ~/.config/emacs"
|
||||||
(explain! "Doom's source and your private Doom config have to live in separate directories. "
|
(path dir)))
|
||||||
"Putting them in the same directory (without changing the DOOMDIR environment "
|
(explain! "Doom's source and your private Doom config have to live in separate directories. "
|
||||||
"variable) will cause errors on startup."))
|
"Putting them in the same directory (without changing the DOOMDIR environment "
|
||||||
(when (and (not (file-equal-p xdg-dir doom-dir))
|
"variable) will cause errors on startup."))
|
||||||
(file-directory-p xdg-dir)
|
(when (and (not (file-equal-p xdg-dir doom-dir))
|
||||||
(file-directory-p doom-dir))
|
(file-directory-p xdg-dir)
|
||||||
(print! (warn "Detected two private configs, in %s and %s")
|
(file-directory-p doom-dir))
|
||||||
(abbreviate-file-name xdg-dir)
|
(print! (warn "Detected two private configs, in %s and %s")
|
||||||
doom-dir)
|
(abbreviate-file-name xdg-dir)
|
||||||
(explain! "The second directory will be ignored, as it has lower precedence.")))
|
doom-dir)
|
||||||
|
(explain! "The second directory will be ignored, as it has lower precedence."))))
|
||||||
|
|
||||||
|
(print! (start "Checking for common environmental issues..."))
|
||||||
|
(when (string-match-p "/fish$" shell-file-name)
|
||||||
|
(print! (warn "Detected Fish as your $SHELL"))
|
||||||
|
(explain! "Fish (and possibly other non-POSIX shells) is known to inject garbage "
|
||||||
|
"output into some of the child processes that Emacs spawns. Many Emacs "
|
||||||
|
"packages/utilities will choke on this output, causing unpredictable issues. "
|
||||||
|
"To get around this, either:\n\n"
|
||||||
|
" - Add the following to $DOOMDIR/config.el:\n\n"
|
||||||
|
" (setq shell-file-name (executable-find \"bash\"))\n\n"
|
||||||
|
" - Or change your default shell to a POSIX shell (like bash or zsh) "
|
||||||
|
" and explicitly configure your terminal apps to use the shell you "
|
||||||
|
" want.\n\n"
|
||||||
|
"If you opt for option 1 and use one of Emacs' terminal emulators, you "
|
||||||
|
"will also need to configure them to use Fish, e.g.\n\n"
|
||||||
|
" (setq-default vterm-shell (executable-find \"fish\"))\n\n"
|
||||||
|
" (setq-default explicit-shell-file-name (executable-find \"fish\"))\n"))
|
||||||
|
|
||||||
(print! (start "Checking for stale elc files..."))
|
(print! (start "Checking for stale elc files..."))
|
||||||
(elc-check-dir doom-core-dir)
|
(elc-check-dir doom-core-dir)
|
||||||
|
@ -205,13 +243,13 @@ in."
|
||||||
;; Check for fonts
|
;; Check for fonts
|
||||||
(if (not (executable-find "fc-list"))
|
(if (not (executable-find "fc-list"))
|
||||||
(warn! "Warning: unable to detect fonts because fontconfig isn't installed")
|
(warn! "Warning: unable to detect fonts because fontconfig isn't installed")
|
||||||
;; all-the-icons fonts
|
;; nerd-icons fonts
|
||||||
(when (and (pcase system-type
|
(when (and (pcase system-type
|
||||||
(`gnu/linux (concat (or (getenv "XDG_DATA_HOME")
|
(`gnu/linux (concat (or (getenv "XDG_DATA_HOME")
|
||||||
"~/.local/share")
|
"~/.local/share")
|
||||||
"/fonts/"))
|
"/fonts/"))
|
||||||
(`darwin "~/Library/Fonts/"))
|
(`darwin "~/Library/Fonts/"))
|
||||||
(require 'all-the-icons nil t))
|
(require 'nerd-icons nil t))
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(let ((errors 0))
|
(let ((errors 0))
|
||||||
(cl-destructuring-bind (status . output)
|
(cl-destructuring-bind (status . output)
|
||||||
|
@ -219,15 +257,16 @@ in."
|
||||||
(if (not (zerop status))
|
(if (not (zerop status))
|
||||||
(print! (error "There was an error running `fc-list'. Is fontconfig installed correctly?"))
|
(print! (error "There was an error running `fc-list'. Is fontconfig installed correctly?"))
|
||||||
(insert (cdr (doom-call-process "fc-list" "" "file")))
|
(insert (cdr (doom-call-process "fc-list" "" "file")))
|
||||||
(dolist (font all-the-icons-font-names)
|
(dolist (font nerd-icons-font-names)
|
||||||
(if (save-excursion (re-search-backward font nil t))
|
(if (save-excursion (re-search-backward font nil t))
|
||||||
(success! "Found font %s" font)
|
(success! "Found font %s" font)
|
||||||
(print! (warn "Warning: couldn't find %S font") font)))
|
(print! (warn "%S font is not installed on your system") font)
|
||||||
|
(cl-incf errors)))
|
||||||
(when (> errors 0)
|
(when (> errors 0)
|
||||||
(explain! "Some all-the-icons fonts were missing.\n\n"
|
(explain! "Some needed fonts are not properly installed on your system. To download and "
|
||||||
"You can install them by running `M-x all-the-icons-install-fonts' within Emacs.\n"
|
"install them, run `M-x nerd-icons-install-fonts' from within Doom Emacs. "
|
||||||
"This could also mean you've installed them in non-standard locations, in which "
|
"However, on Windows this command will only download them; the fonts must "
|
||||||
"case feel free to ignore this warning.")))))))))
|
"be installed manually afterwards.")))))))))
|
||||||
|
|
||||||
(print! (start "Checking for stale elc files in your DOOMDIR..."))
|
(print! (start "Checking for stale elc files in your DOOMDIR..."))
|
||||||
(when (file-directory-p doom-user-dir)
|
(when (file-directory-p doom-user-dir)
|
||||||
|
|
|
@ -33,7 +33,8 @@
|
||||||
"^SSH_\\(AUTH_SOCK\\|AGENT_PID\\)$" "^\\(SSH\\|GPG\\)_TTY$"
|
"^SSH_\\(AUTH_SOCK\\|AGENT_PID\\)$" "^\\(SSH\\|GPG\\)_TTY$"
|
||||||
"^GPG_AGENT_INFO$"
|
"^GPG_AGENT_INFO$"
|
||||||
;; Internal Doom envvars
|
;; Internal Doom envvars
|
||||||
"^DEBUG$" "^INSECURE$" "^\\(EMACS\\|DOOM\\)DIR$" "^DOOMPROFILE$" "^__")
|
"^DEBUG$" "^INSECURE$" "^\\(EMACS\\|DOOM\\)DIR$"
|
||||||
|
"^DOOM\\(PATH\\|PROFILE\\)$" "^__")
|
||||||
"Environment variables to omit from envvar files.
|
"Environment variables to omit from envvar files.
|
||||||
|
|
||||||
Each string is a regexp, matched against variable names to omit from
|
Each string is a regexp, matched against variable names to omit from
|
||||||
|
|
466
lisp/cli/help.el
466
lisp/cli/help.el
|
@ -1,466 +0,0 @@
|
||||||
;;; lisp/cli/help.el -*- lexical-binding: t; -*-
|
|
||||||
;;; Commentary:
|
|
||||||
;;
|
|
||||||
;; This file defines special commands that the Doom CLI will invoke when a
|
|
||||||
;; command is passed with -?, --help, or --version. They can also be aliased to
|
|
||||||
;; a sub-command to make more of its capabilities accessible to users, with:
|
|
||||||
;;
|
|
||||||
;; (defcli-alias! (myscript (help h)) (:help))
|
|
||||||
;;
|
|
||||||
;; You can define your own command-specific help handlers, e.g.
|
|
||||||
;;
|
|
||||||
;; (defcli! (:help myscript subcommand) () ...)
|
|
||||||
;;
|
|
||||||
;; And it will be invoked instead of the generic one.
|
|
||||||
;;
|
|
||||||
;;; Code:
|
|
||||||
|
|
||||||
;;
|
|
||||||
;;; Variables
|
|
||||||
|
|
||||||
(defvar doom-help-commands '("%p %c {-?,--help}")
|
|
||||||
"A list of help commands recognized for the running script.
|
|
||||||
|
|
||||||
Recognizes %p (for the prefix) and %c (for the active command).")
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;;; Commands
|
|
||||||
|
|
||||||
(defcli! (:root :help)
|
|
||||||
((localonly? ("-g" "--no-global") "Hide global options")
|
|
||||||
(manpage? ("--manpage") "Generate in manpage format")
|
|
||||||
(commands? ("--commands") "List all known commands")
|
|
||||||
&multiple
|
|
||||||
(sections ("--synopsis" "--subcommands" "--similar" "--envvars"
|
|
||||||
"--postamble")
|
|
||||||
"Show only the specified sections.")
|
|
||||||
&context context
|
|
||||||
&args command)
|
|
||||||
"Show documentation for a Doom CLI command.
|
|
||||||
|
|
||||||
OPTIONS:
|
|
||||||
--synopsis, --subcommands, --similar, --envvars, --postamble
|
|
||||||
TODO"
|
|
||||||
(doom-cli-load-all)
|
|
||||||
(when (doom-cli-context-error context)
|
|
||||||
(terpri))
|
|
||||||
(let* ((command (cons (doom-cli-context-prefix context) command))
|
|
||||||
(cli (doom-cli-get command t))
|
|
||||||
(rcli (doom-cli-get cli))
|
|
||||||
(fallbackcli (cl-loop with targets = (doom-cli--command-expand (butlast command) t)
|
|
||||||
for cmd in (cons command targets)
|
|
||||||
if (doom-cli-get cmd t)
|
|
||||||
return it)))
|
|
||||||
(cond (commands?
|
|
||||||
(let ((cli (or cli (doom-cli-get (doom-cli-context-prefix context)))))
|
|
||||||
(print! "Commands under '%s':\n%s"
|
|
||||||
(doom-cli-command-string cli)
|
|
||||||
(indent (doom-cli-help--render-commands
|
|
||||||
(or (doom-cli-subcommands cli)
|
|
||||||
(user-error "No commands found"))
|
|
||||||
:prefix (doom-cli-command cli)
|
|
||||||
:inline? t
|
|
||||||
:docs? t)))))
|
|
||||||
((null sections)
|
|
||||||
(if (null cli)
|
|
||||||
(signal 'doom-cli-command-not-found-error command)
|
|
||||||
(doom-cli-help--print cli context manpage? localonly?)
|
|
||||||
(exit! :pager?)))
|
|
||||||
((dolist (section sections)
|
|
||||||
(unless (equal section (car sections)) (terpri))
|
|
||||||
(pcase section
|
|
||||||
("--synopsis"
|
|
||||||
(print! "%s" (doom-cli-help--render-synopsis
|
|
||||||
(doom-cli-help--synopsis cli)
|
|
||||||
"Usage: ")))
|
|
||||||
("--subcommands"
|
|
||||||
(print! "%s\n%s" (bold "Available commands:")
|
|
||||||
(indent (doom-cli-help--render-commands
|
|
||||||
(doom-cli-subcommands rcli 1)
|
|
||||||
:prefix command
|
|
||||||
:grouped? t
|
|
||||||
:docs? t)
|
|
||||||
doom-print-indent-increment)))
|
|
||||||
("--similar"
|
|
||||||
(unless command
|
|
||||||
(user-error "No command specified"))
|
|
||||||
(let ((similar (doom-cli-help-similar-commands command 0.4)))
|
|
||||||
(print! "Similar commands:")
|
|
||||||
(if (not similar)
|
|
||||||
(print! (indent (warn "Can't find any!")))
|
|
||||||
(dolist (command (seq-take similar 10))
|
|
||||||
(print! (indent (item "(%d%%) %s"))
|
|
||||||
(* (car command) 100)
|
|
||||||
(doom-cli-command-string (cdr command)))))))
|
|
||||||
("--envvars"
|
|
||||||
(let* ((key "ENVIRONMENT VARIABLES")
|
|
||||||
(clis (if command (doom-cli-find command) (hash-table-values doom-cli--table)))
|
|
||||||
(clis (seq-remove #'doom-cli-alias clis))
|
|
||||||
(clis (seq-filter (fn! (cdr (assoc key (doom-cli-docs %)))) clis))
|
|
||||||
(clis (seq-group-by #'doom-cli-command clis)))
|
|
||||||
(print! "List of environment variables for %s:\n" command)
|
|
||||||
(if (null clis)
|
|
||||||
(print! (indent "None!"))
|
|
||||||
(dolist (group clis)
|
|
||||||
(print! (bold "%s%s:"
|
|
||||||
(doom-cli-command-string (car group))
|
|
||||||
(if (doom-cli-fn (doom-cli-get (car group)))
|
|
||||||
"" " *")))
|
|
||||||
(dolist (cli (cdr group))
|
|
||||||
(print! (indent "%s") (markup (cdr (assoc key (doom-cli-docs cli))))))))))
|
|
||||||
("--postamble"
|
|
||||||
(print! "See %s for documentation."
|
|
||||||
(join (cl-loop with spec =
|
|
||||||
`((?p . ,(doom-cli-context-prefix context))
|
|
||||||
(?c . ,(doom-cli-command-string (cdr (doom-cli-command (or cli fallbackcli))))))
|
|
||||||
for cmd in doom-help-commands
|
|
||||||
for formatted = (trim (format-spec cmd spec))
|
|
||||||
collect (replace-regexp-in-string
|
|
||||||
" +" " " (format "'%s'" formatted)))
|
|
||||||
" or ")))))))))
|
|
||||||
|
|
||||||
(defcli! (:root :version)
|
|
||||||
((simple? ("--simple"))
|
|
||||||
&context context)
|
|
||||||
"Show installed versions of Doom, Doom modules, and Emacs."
|
|
||||||
(doom/version)
|
|
||||||
(unless simple?
|
|
||||||
(terpri)
|
|
||||||
(with-temp-buffer
|
|
||||||
(insert-file-contents (doom-path doom-emacs-dir "LICENSE"))
|
|
||||||
(re-search-forward "^Copyright (c) ")
|
|
||||||
(print! "%s\n" (trim (thing-at-point 'line t)))
|
|
||||||
(print! (p "Doom Emacs uses the MIT license and is provided without warranty "
|
|
||||||
"of any kind. You may redistribute and modify copies if "
|
|
||||||
"given proper attribution. See the LICENSE file for details.")))))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;;; Helpers
|
|
||||||
|
|
||||||
(defun doom-cli-help (cli)
|
|
||||||
"Return an alist of documentation summarizing CLI (a `doom-cli')."
|
|
||||||
(let* ((rcli (doom-cli-get cli))
|
|
||||||
(docs (doom-cli-docs rcli)))
|
|
||||||
`((command . ,(doom-cli-command-string cli))
|
|
||||||
(summary . ,(or (cdr (assoc "SUMMARY" docs)) "TODO"))
|
|
||||||
(description . ,(or (cdr (assoc "MAIN" docs)) "TODO"))
|
|
||||||
(synopsis . ,(doom-cli-help--synopsis cli))
|
|
||||||
(arguments . ,(doom-cli-help--arguments rcli))
|
|
||||||
(options . ,(doom-cli-help--options rcli))
|
|
||||||
(commands . ,(doom-cli-subcommands cli 1))
|
|
||||||
(sections . ,(seq-filter #'cdr (cddr docs))))))
|
|
||||||
|
|
||||||
(defun doom-cli-help-similar-commands (command &optional maxscore)
|
|
||||||
"Return N commands that are similar to COMMAND."
|
|
||||||
(seq-take-while
|
|
||||||
(fn! (>= (car %) (or maxscore 0.0)))
|
|
||||||
(seq-sort-by
|
|
||||||
#'car #'>
|
|
||||||
(cl-loop with prefix = (seq-find #'doom-cli-get (nreverse (doom-cli--command-expand command t)))
|
|
||||||
with input = (doom-cli-command-string (cdr (doom-cli--command command t)))
|
|
||||||
for command in (hash-table-keys doom-cli--table)
|
|
||||||
if (doom-cli-fn (doom-cli-get command))
|
|
||||||
if (equal prefix (seq-take command (length prefix)))
|
|
||||||
collect (cons (doom-cli-help--similarity
|
|
||||||
input (doom-cli-command-string (cdr command)))
|
|
||||||
command)))))
|
|
||||||
|
|
||||||
(defun doom-cli-help--similarity (s1 s2)
|
|
||||||
;; Ratcliff-Obershelp similarity
|
|
||||||
(let* ((s1 (downcase s1))
|
|
||||||
(s2 (downcase s2))
|
|
||||||
(s1len (length s1))
|
|
||||||
(s2len (length s2)))
|
|
||||||
(if (or (zerop s1len)
|
|
||||||
(zerop s2len))
|
|
||||||
0.0
|
|
||||||
(/ (let ((i 0) (j 0) (score 0) jlast)
|
|
||||||
(while (< i s1len)
|
|
||||||
(unless jlast (setq jlast j))
|
|
||||||
(if (and (< j s2len)
|
|
||||||
(= (aref s1 i) (aref s2 j)))
|
|
||||||
(progn (cl-incf score)
|
|
||||||
(cl-incf i)
|
|
||||||
(cl-incf j))
|
|
||||||
(setq m 0)
|
|
||||||
(cl-incf j)
|
|
||||||
(when (>= j s2len)
|
|
||||||
(setq j (or jlast j)
|
|
||||||
jlast nil)
|
|
||||||
(cl-incf i))))
|
|
||||||
(* 2.0 score))
|
|
||||||
(+ (length s1)
|
|
||||||
(length s2))))))
|
|
||||||
|
|
||||||
;;; Help: printers
|
|
||||||
;; TODO Parameterize optional args with `cl-defun'
|
|
||||||
(defun doom-cli-help--print (cli context &optional manpage? noglobal?)
|
|
||||||
"Write CLI's documentation in a manpage-esque format to stdout."
|
|
||||||
(let-alist (doom-cli-help cli)
|
|
||||||
(let* ((alist
|
|
||||||
`(,@(if manpage?
|
|
||||||
`((nil . ,(let* ((title (cadr (member "--load" command-line-args)))
|
|
||||||
(width (floor (/ (- (doom-cli-context-width context)
|
|
||||||
(length title))
|
|
||||||
2.0))))
|
|
||||||
;; FIXME Who am I fooling?
|
|
||||||
(format (format "%%-%ds%%s%%%ds" width width)
|
|
||||||
"DOOM(1)" title "DOOM(1)")))
|
|
||||||
("NAME" . ,(concat .command " - " .summary))
|
|
||||||
("SYNOPSIS" . ,(doom-cli-help--render-synopsis .synopsis nil t))
|
|
||||||
("DESCRIPTION" . ,.description))
|
|
||||||
`((nil . ,(doom-cli-help--render-synopsis .synopsis "Usage: "))
|
|
||||||
(nil . ,(string-join (seq-remove #'string-empty-p (list .summary .description))
|
|
||||||
"\n\n"))))
|
|
||||||
("ARGUMENTS" . ,(doom-cli-help--render-arguments .arguments))
|
|
||||||
("COMMANDS"
|
|
||||||
. ,(doom-cli-help--render-commands
|
|
||||||
.commands :prefix (doom-cli-command cli) :grouped? t :docs? t))
|
|
||||||
("OPTIONS"
|
|
||||||
. ,(doom-cli-help--render-options
|
|
||||||
(if (or (not (doom-cli-fn cli)) noglobal?)
|
|
||||||
`(,(assq 'local .options))
|
|
||||||
.options)
|
|
||||||
cli))))
|
|
||||||
(command (doom-cli-command cli)))
|
|
||||||
(letf! (defun printsection (section)
|
|
||||||
(print! "%s\n"
|
|
||||||
(if (null section)
|
|
||||||
(dark "TODO")
|
|
||||||
(markup
|
|
||||||
(format-spec
|
|
||||||
section `((?p . ,(car command))
|
|
||||||
(?c . ,(doom-cli-command-string (cdr command))))
|
|
||||||
'ignore)))))
|
|
||||||
(pcase-dolist (`(,label . ,contents) alist)
|
|
||||||
(when (and contents (not (string-blank-p contents)))
|
|
||||||
(when label
|
|
||||||
(print! (bold "%s%s") label (if manpage? "" ":")))
|
|
||||||
(print-group! :if label (printsection contents))))
|
|
||||||
(pcase-dolist (`(,label . ,contents) .sections)
|
|
||||||
(when (and contents (not (assoc label alist)))
|
|
||||||
(print! (bold "%s:") label)
|
|
||||||
(print-group! (printsection contents))))))))
|
|
||||||
|
|
||||||
;;; Help: synopsis
|
|
||||||
(defun doom-cli-help--synopsis (cli &optional all-options?)
|
|
||||||
(let* ((rcli (doom-cli-get cli))
|
|
||||||
(opts (doom-cli-help--options rcli))
|
|
||||||
(opts (mapcar #'car (if all-options? (mapcan #'cdr opts) (alist-get 'local opts))))
|
|
||||||
(opts (cl-loop for opt in opts
|
|
||||||
for args = (cdar opt)
|
|
||||||
for switches = (mapcar #'car opt)
|
|
||||||
for multi? = (member "..." args)
|
|
||||||
if args
|
|
||||||
collect (format (if multi? "[%s %s]..." "[%s %s]")
|
|
||||||
(string-join switches "|")
|
|
||||||
(string-join (remove "..." args) "|"))
|
|
||||||
else collect (format "[%s]" (string-join switches "|"))))
|
|
||||||
(args (doom-cli-arguments rcli))
|
|
||||||
(subcommands? (doom-cli-subcommands rcli 1 :predicate? t)))
|
|
||||||
`((command . ,(doom-cli-command cli))
|
|
||||||
(options ,@opts)
|
|
||||||
(required ,@(mapcar (fn! (upcase (format "`%s'" %))) (if subcommands? '(command) (alist-get '&required args))))
|
|
||||||
(optional ,@(mapcar (fn! (upcase (format "[`%s']" %)))(alist-get '&optional args)))
|
|
||||||
(rest ,@(mapcar (fn! (upcase (format "[`%s'...]" %))) (if subcommands? '(args) (alist-get '&args args)))))))
|
|
||||||
|
|
||||||
(defun doom-cli-help--render-synopsis (synopsis &optional prefix)
|
|
||||||
(let-alist synopsis
|
|
||||||
(let ((doom-print-indent 0)
|
|
||||||
(prefix (or prefix ""))
|
|
||||||
(command (doom-cli-command-string .command)))
|
|
||||||
(string-trim-right
|
|
||||||
(format! "%s\n\n"
|
|
||||||
(fill (concat (bold prefix)
|
|
||||||
(format "%s " command)
|
|
||||||
(markup
|
|
||||||
(join (append .options
|
|
||||||
(and .options
|
|
||||||
(or .required
|
|
||||||
.optional
|
|
||||||
.rest)
|
|
||||||
(list (dark "[--]")))
|
|
||||||
.required
|
|
||||||
.optional
|
|
||||||
.rest))))
|
|
||||||
80 (1+ (length (concat prefix command)))))))))
|
|
||||||
|
|
||||||
;;; Help: arguments
|
|
||||||
(defun doom-cli-help--arguments (cli &optional all?)
|
|
||||||
(doom-cli-help--parse-docs (doom-cli-find cli t) "ARGUMENTS"))
|
|
||||||
|
|
||||||
(defun doom-cli-help--render-arguments (arguments)
|
|
||||||
(mapconcat (lambda (arg)
|
|
||||||
(format! "%-20s\n%s"
|
|
||||||
(underscore (car arg))
|
|
||||||
(indent (if (equal (cdr arg) "TODO")
|
|
||||||
(dark (cdr arg))
|
|
||||||
(cdr arg))
|
|
||||||
doom-print-indent-increment)))
|
|
||||||
arguments
|
|
||||||
"\n"))
|
|
||||||
|
|
||||||
;;; Help: commands
|
|
||||||
(cl-defun doom-cli-help--render-commands (commands &key prefix grouped? docs? (inline? t))
|
|
||||||
(with-temp-buffer
|
|
||||||
(let* ((doom-print-indent 0)
|
|
||||||
(commands (seq-group-by (fn! (if grouped? (doom-cli-prop (doom-cli-get % t) :group)))
|
|
||||||
(nreverse commands)))
|
|
||||||
(toplevel (assq nil commands))
|
|
||||||
(rest (remove toplevel commands))
|
|
||||||
(drop (if prefix (length prefix) 0))
|
|
||||||
(minwidth
|
|
||||||
(apply
|
|
||||||
#'max (or (cl-loop for cmd in (apply #'append (mapcar #'cdr commands))
|
|
||||||
for cmd = (seq-drop cmd drop)
|
|
||||||
collect (length (doom-cli-command-string cmd)))
|
|
||||||
(list 15))))
|
|
||||||
(ellipsis (doom-print--style 'dark " […]"))
|
|
||||||
(ellipsislen (- (length ellipsis) (if (eq doom-print-backend 'ansi) 2 4))))
|
|
||||||
(dolist (group (cons toplevel rest))
|
|
||||||
(let ((label (if (car-safe group) (cdr commands))))
|
|
||||||
(when label
|
|
||||||
(insert! ((bold "%s:") (car group)) "\n"))
|
|
||||||
(print-group! :if label
|
|
||||||
(dolist (command (cdr group))
|
|
||||||
(let* ((cli (doom-cli-get command t))
|
|
||||||
(rcli (doom-cli-get command))
|
|
||||||
(summary (doom-cli-short-docs rcli))
|
|
||||||
(subcommands? (doom-cli-subcommands cli 1 :predicate? t)))
|
|
||||||
(insert! ((format "%%-%ds%%s%%s"
|
|
||||||
(+ (- minwidth doom-print-indent)
|
|
||||||
doom-print-indent-increment
|
|
||||||
(if subcommands? ellipsislen 0)))
|
|
||||||
(concat (doom-cli-command-string (seq-drop command drop))
|
|
||||||
(if subcommands? ellipsis))
|
|
||||||
(if inline? " " "\n")
|
|
||||||
(indent (if (and (doom-cli-alias cli)
|
|
||||||
(not (doom-cli-type rcli)))
|
|
||||||
(dark "-> %s" (doom-cli-command-string cli))
|
|
||||||
(when docs?
|
|
||||||
(if summary (markup summary) (dark "TODO"))))))
|
|
||||||
"\n")))
|
|
||||||
(when (cdr rest)
|
|
||||||
(insert "\n")))))
|
|
||||||
(string-trim-right (buffer-string)))))
|
|
||||||
|
|
||||||
;;; Help: options
|
|
||||||
(defun doom-cli-help--options (cli &optional noformatting?)
|
|
||||||
"Return an alist summarizing CLI's options.
|
|
||||||
|
|
||||||
The alist's CAR are lists of formatted switches plus their arguments, e.g.
|
|
||||||
'((\"`--foo'\" \"`BAR'\") ...). Their CDR is their formatted documentation."
|
|
||||||
(let* ((docs (doom-cli-help--parse-docs (doom-cli-find cli t) "OPTIONS"))
|
|
||||||
(docs (mapcar (fn! (cons (split-string (car %) ", ")
|
|
||||||
(cdr %)))
|
|
||||||
docs))
|
|
||||||
(strfmt (if noformatting? "%s" "`%s'"))
|
|
||||||
local-options
|
|
||||||
global-options
|
|
||||||
seen)
|
|
||||||
(dolist (neighbor (nreverse (doom-cli-find cli)))
|
|
||||||
(dolist (option (doom-cli-options neighbor))
|
|
||||||
(when-let* ((switches (cl-loop for sw in (doom-cli-option-switches option)
|
|
||||||
if (and (doom-cli-option-flag-p option)
|
|
||||||
(string-prefix-p "--" sw))
|
|
||||||
collect (format "--[no-]%s" (substring sw 2))
|
|
||||||
else collect sw))
|
|
||||||
(switches (seq-difference switches seen)))
|
|
||||||
(dolist (switch switches) (push switch seen))
|
|
||||||
(push (cons (cl-loop for switch in switches
|
|
||||||
if (doom-cli-option-arguments option)
|
|
||||||
collect (cons (format strfmt switch)
|
|
||||||
(append (doom-cli-help--parse-args it noformatting?)
|
|
||||||
(when (doom-cli-option-multiple-p option)
|
|
||||||
(list "..."))))
|
|
||||||
else collect (list (format strfmt switch)))
|
|
||||||
(string-join
|
|
||||||
(or (delq
|
|
||||||
nil (cons (when-let (docs (doom-cli-option-docs option))
|
|
||||||
(concat docs "."))
|
|
||||||
(cl-loop for (flags . docs) in docs
|
|
||||||
unless (equal (seq-difference flags switches) flags)
|
|
||||||
collect docs)))
|
|
||||||
'("TODO"))
|
|
||||||
"\n\n"))
|
|
||||||
(if (equal (doom-cli-command neighbor)
|
|
||||||
(doom-cli-command cli))
|
|
||||||
local-options
|
|
||||||
global-options)))))
|
|
||||||
`((local . ,(nreverse local-options))
|
|
||||||
(global . ,(nreverse global-options)))))
|
|
||||||
|
|
||||||
(defun doom-cli-help--render-options (options &optional cli)
|
|
||||||
(let ((doom-print-indent 0)
|
|
||||||
(local (assq 'local options))
|
|
||||||
(global (assq 'global options)))
|
|
||||||
(when (or (cdr local) (cdr global))
|
|
||||||
(letf! (defun printopts (opts)
|
|
||||||
(pcase-dolist (`(,switches . ,docs) (cdr opts))
|
|
||||||
(let (multiple?)
|
|
||||||
(insert!
|
|
||||||
("%s%s\n%s"
|
|
||||||
(mapconcat
|
|
||||||
(fn! (when (member "..." (cdr %))
|
|
||||||
(setq multiple? t))
|
|
||||||
(string-trim-right
|
|
||||||
(format "%s %s"
|
|
||||||
(doom-print--cli-markup (car %))
|
|
||||||
(doom-print--cli-markup
|
|
||||||
(string-join (remove "..." (cdr %)) "|")))))
|
|
||||||
switches
|
|
||||||
", ")
|
|
||||||
(if multiple? ", ..." "")
|
|
||||||
(indent (fill (markup docs)) doom-print-indent-increment))
|
|
||||||
"\n\n"))))
|
|
||||||
(with-temp-buffer
|
|
||||||
(if (null (cdr local))
|
|
||||||
(insert (if global "This command has no local options.\n" "") "\n")
|
|
||||||
(printopts local))
|
|
||||||
(when (cdr global)
|
|
||||||
(insert! ((bold "Global options:\n")))
|
|
||||||
(print-group! (printopts global)))
|
|
||||||
(string-trim-right (buffer-string)))))))
|
|
||||||
|
|
||||||
;;; Help: internal
|
|
||||||
(defun doom-cli-help--parse-args (args &optional noformatting?)
|
|
||||||
(cl-loop for arg in args
|
|
||||||
if (listp arg)
|
|
||||||
collect (string-join (doom-cli-help--parse-args arg noformatting?) "|")
|
|
||||||
else if (symbolp arg)
|
|
||||||
collect (format (if noformatting? "%s" "`%s'") (upcase (symbol-name arg)))
|
|
||||||
else collect arg))
|
|
||||||
|
|
||||||
(defun doom-cli-help--parse-docs (cli-list section-name)
|
|
||||||
(cl-check-type section-name string)
|
|
||||||
(let (alist)
|
|
||||||
(dolist (cli cli-list (nreverse alist))
|
|
||||||
(when-let (section (cdr (assoc section-name (doom-cli-docs cli))))
|
|
||||||
(with-temp-buffer
|
|
||||||
(save-excursion (insert section))
|
|
||||||
(let ((lead (current-indentation))
|
|
||||||
(buffer (current-buffer)))
|
|
||||||
(while (not (eobp))
|
|
||||||
(let ((heading (string-trim (buffer-substring (point-at-bol) (point-at-eol))))
|
|
||||||
(beg (point-at-bol 2))
|
|
||||||
end)
|
|
||||||
(forward-line 1)
|
|
||||||
(while (and (not (eobp))
|
|
||||||
(/= (current-indentation) lead)
|
|
||||||
(forward-line 1)))
|
|
||||||
(setf (alist-get heading alist nil nil #'equal)
|
|
||||||
(string-join
|
|
||||||
(delq
|
|
||||||
nil (list (alist-get heading alist nil nil #'equal)
|
|
||||||
(let ((end (point)))
|
|
||||||
(with-temp-buffer
|
|
||||||
(insert-buffer-substring buffer beg end)
|
|
||||||
(goto-char (point-min))
|
|
||||||
(indent-rigidly (point-min) (point-max) (- (current-indentation)))
|
|
||||||
(string-trim-right (buffer-string))))))
|
|
||||||
"\n\n"))))))))))
|
|
||||||
|
|
||||||
(provide 'doom-cli-help)
|
|
||||||
;;; help.el ends here
|
|
|
@ -19,7 +19,7 @@
|
||||||
(config? ("--config" :yes) "Create `$DOOMDIR' or dummy files therein?")
|
(config? ("--config" :yes) "Create `$DOOMDIR' or dummy files therein?")
|
||||||
(envfile? ("--env" :yes) "(Re)generate an envvars file? (see `$ doom help env`)")
|
(envfile? ("--env" :yes) "(Re)generate an envvars file? (see `$ doom help env`)")
|
||||||
(install? ("--install" :yes) "Auto-install packages?")
|
(install? ("--install" :yes) "Auto-install packages?")
|
||||||
(fonts? ("--fonts" :yes) "Install (or prompt to install) all-the-icons fonts?")
|
(fonts? ("--fonts" :yes) "Install (or prompt to install) nerd-icons fonts?")
|
||||||
(hooks? ("--hooks" :yes) "Deploy Doom's git hooks to itself?")
|
(hooks? ("--hooks" :yes) "Deploy Doom's git hooks to itself?")
|
||||||
&context context)
|
&context context)
|
||||||
"Installs and sets up Doom Emacs for the first time.
|
"Installs and sets up Doom Emacs for the first time.
|
||||||
|
@ -32,7 +32,7 @@ This command does the following:
|
||||||
3. Creates dummy files for `$DOOMDIR'/{config,packages}.el,
|
3. Creates dummy files for `$DOOMDIR'/{config,packages}.el,
|
||||||
4. Prompts you to generate an envvar file (same as `$ doom env`),
|
4. Prompts you to generate an envvar file (same as `$ doom env`),
|
||||||
5. Installs any dependencies of enabled modules (specified by `$DOOMDIR'/init.el),
|
5. Installs any dependencies of enabled modules (specified by `$DOOMDIR'/init.el),
|
||||||
6. And prompts to install all-the-icons' fonts
|
6. And prompts to install nerd-icons' fonts
|
||||||
|
|
||||||
This command is idempotent and safe to reuse.
|
This command is idempotent and safe to reuse.
|
||||||
|
|
||||||
|
@ -55,20 +55,19 @@ Change `$DOOMDIR' with the `--doomdir' option, e.g.
|
||||||
(setq doom-user-dir (expand-file-name "doom/" xdg-config-dir)))))
|
(setq doom-user-dir (expand-file-name "doom/" xdg-config-dir)))))
|
||||||
|
|
||||||
(if (file-directory-p doom-user-dir)
|
(if (file-directory-p doom-user-dir)
|
||||||
(print! (item "Skipping %s (already exists)") (relpath doom-user-dir))
|
(print! (item "Skipping %s (already exists)") (path doom-user-dir))
|
||||||
(make-directory doom-user-dir 'parents)
|
(make-directory doom-user-dir 'parents)
|
||||||
(print! (success "Created %s") (relpath doom-user-dir)))
|
(print! (success "Created %s") (path doom-user-dir)))
|
||||||
|
|
||||||
;; Create init.el, config.el & packages.el
|
;; Create init.el, config.el & packages.el
|
||||||
(print-group!
|
(print-group!
|
||||||
(mapc (lambda (file)
|
(mapc (lambda (file)
|
||||||
(cl-destructuring-bind (filename . template) file
|
(cl-destructuring-bind (filename . template) file
|
||||||
(if (file-exists-p! filename doom-user-dir)
|
(setq filename (doom-path doom-user-dir filename))
|
||||||
(print! (item "Skipping %s (already exists)")
|
(if (file-exists-p filename)
|
||||||
(path filename))
|
(print! (item "Skipping %s (already exists)...") (path filename))
|
||||||
(print! (item "Creating %s%s") (relpath doom-user-dir) filename)
|
(print! (item "Creating %s...") (path filename))
|
||||||
(with-temp-file (doom-path doom-user-dir filename)
|
(with-temp-file filename (insert-file-contents template))
|
||||||
(insert-file-contents template))
|
|
||||||
(print! (success "Done!")))))
|
(print! (success "Done!")))))
|
||||||
(let ((template-dir (doom-path doom-emacs-dir "templates")))
|
(let ((template-dir (doom-path doom-emacs-dir "templates")))
|
||||||
`((,doom-module-init-file
|
`((,doom-module-init-file
|
||||||
|
@ -96,7 +95,7 @@ Change `$DOOMDIR' with the `--doomdir' option, e.g.
|
||||||
(if (eq install? :no)
|
(if (eq install? :no)
|
||||||
(print! (warn "Not installing plugins, as requested"))
|
(print! (warn "Not installing plugins, as requested"))
|
||||||
(print! "Installing plugins")
|
(print! "Installing plugins")
|
||||||
(doom-packages-install))
|
(doom-packages-ensure))
|
||||||
|
|
||||||
(print! "Regenerating autoloads files")
|
(print! "Regenerating autoloads files")
|
||||||
(doom-profile-generate)
|
(doom-profile-generate)
|
||||||
|
@ -110,22 +109,6 @@ Change `$DOOMDIR' with the `--doomdir' option, e.g.
|
||||||
('user-error
|
('user-error
|
||||||
(print! (warn "%s") (error-message-string e))))))
|
(print! (warn "%s") (error-message-string e))))))
|
||||||
|
|
||||||
(cond ((eq fonts? :no))
|
|
||||||
(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 yes? (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")
|
(when (file-exists-p "~/.emacs")
|
||||||
(print! (warn "A ~/.emacs file was detected. This conflicts with Doom and should be deleted!")))
|
(print! (warn "A ~/.emacs file was detected. This conflicts with Doom and should be deleted!")))
|
||||||
|
|
||||||
|
|
|
@ -183,32 +183,69 @@ OPTIONS:
|
||||||
input (doom-cli-command-string (cdr command)))
|
input (doom-cli-command-string (cdr command)))
|
||||||
command)))))
|
command)))))
|
||||||
|
|
||||||
(defun doom-cli-help--similarity (s1 s2)
|
(defun doom-cli-help--similarity (a b)
|
||||||
;; Ratcliff-Obershelp similarity
|
(- 1 (/ (float (doom-cli-help--string-distance a b))
|
||||||
(let* ((s1 (downcase s1))
|
(max (length a) (length b)))))
|
||||||
(s2 (downcase s2))
|
|
||||||
(s1len (length s1))
|
(defun doom-cli-help--string-distance (a b)
|
||||||
(s2len (length s2)))
|
"Calculate the Restricted Damerau-Levenshtein distance between A and B.
|
||||||
(if (or (zerop s1len)
|
This is also known as the Optimal String Alignment algorithm.
|
||||||
(zerop s2len))
|
|
||||||
0.0
|
It is assumed that A and B are both strings, and before processing both are
|
||||||
(/ (let ((i 0) (j 0) (score 0) jlast)
|
converted to lowercase.
|
||||||
(while (< i s1len)
|
|
||||||
(unless jlast (setq jlast j))
|
This returns the minimum number of edits required to transform A
|
||||||
(if (and (< j s2len)
|
to B, where each edit is a deletion, insertion, substitution, or
|
||||||
(= (aref s1 i) (aref s2 j)))
|
transposition of a character, with the restriction that no
|
||||||
(progn (cl-incf score)
|
substring is edited more than once."
|
||||||
(cl-incf i)
|
(let ((a (downcase a))
|
||||||
(cl-incf j))
|
(b (downcase b))
|
||||||
(setq m 0)
|
(alen (length a))
|
||||||
(cl-incf j)
|
(blen (length b))
|
||||||
(when (>= j s2len)
|
(start 0))
|
||||||
(setq j (or jlast j)
|
(when (> alen blen)
|
||||||
jlast nil)
|
(let ((c a)
|
||||||
(cl-incf i))))
|
(clen alen))
|
||||||
(* 2.0 score))
|
(setq a b alen blen
|
||||||
(+ (length s1)
|
b c blen clen)))
|
||||||
(length s2))))))
|
(while (and (< start (min alen blen))
|
||||||
|
(= (aref a start) (aref b start)))
|
||||||
|
(cl-incf start))
|
||||||
|
(cl-decf start)
|
||||||
|
(if (= (1+ start) alen)
|
||||||
|
(- blen start)
|
||||||
|
(let ((v0 (make-vector (- blen start) 0))
|
||||||
|
(v1 (make-vector (- blen start) 0))
|
||||||
|
(a_i (aref a (max 0 start)))
|
||||||
|
(current 0)
|
||||||
|
a_i-1 b_j b_j-1
|
||||||
|
left transition-next
|
||||||
|
above this-transition)
|
||||||
|
(dotimes (vi (length v0))
|
||||||
|
(aset v0 vi (1+ vi)))
|
||||||
|
(dolist (i (number-sequence (1+ start) (1- alen)))
|
||||||
|
(setq a_i-1 a_i
|
||||||
|
a_i (aref a i)
|
||||||
|
b_j (aref b (max 0 start))
|
||||||
|
left (- i start 1)
|
||||||
|
current (- i start)
|
||||||
|
transition-next 0)
|
||||||
|
(dolist (j (number-sequence (1+ start) (1- blen)))
|
||||||
|
(setq b_j-1 b_j
|
||||||
|
b_j (aref b j)
|
||||||
|
above current
|
||||||
|
current left
|
||||||
|
this-transition transition-next
|
||||||
|
transition-next (aref v1 (- j start)))
|
||||||
|
(aset v1 (- j start) current)
|
||||||
|
(setq left (aref v0 (- j start)))
|
||||||
|
(unless (= a_i b_j)
|
||||||
|
;; Minimum between substitution, deletion, and insertion
|
||||||
|
(setq current (min (1+ current) (1+ above) (1+ left)))
|
||||||
|
(when (and (> i (1+ start)) (> j (1+ start)) (= a_i b_j-1) (= a_i-1 b_j))
|
||||||
|
(setq current (min current (cl-incf this-transition)))))
|
||||||
|
(aset v0 (- j start) current)))
|
||||||
|
current))))
|
||||||
|
|
||||||
;;; Help: printers
|
;;; Help: printers
|
||||||
;; TODO Parameterize optional args with `cl-defun'
|
;; TODO Parameterize optional args with `cl-defun'
|
||||||
|
|
|
@ -13,28 +13,12 @@
|
||||||
;;
|
;;
|
||||||
;;; Commands
|
;;; Commands
|
||||||
|
|
||||||
(defcli! (:before (build b purge p)) (&context context)
|
(defcli-obsolete! ((build b)) (sync "--rebuild") "v3.0.0")
|
||||||
(require 'comp nil t)
|
|
||||||
(doom-initialize-core-packages))
|
|
||||||
|
|
||||||
;; DEPRECATED Replace with "doom sync --rebuild"
|
(defcli-obsolete! ((purge p)) (gc) "v3.0.0")
|
||||||
(defcli! ((build b))
|
|
||||||
((rebuild-p ("-r") "Only rebuild packages that need rebuilding")
|
|
||||||
(jobs ("-j" "--jobs" num) "How many CPUs to use for native compilation"))
|
|
||||||
"Byte-compiles & symlinks installed packages.
|
|
||||||
|
|
||||||
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)."
|
|
||||||
:benchmark t
|
|
||||||
(when jobs
|
|
||||||
(setq native-comp-async-jobs-number (truncate jobs)))
|
|
||||||
(when (doom-packages-build (not rebuild-p))
|
|
||||||
(doom-profile-generate))
|
|
||||||
t)
|
|
||||||
|
|
||||||
;; TODO Rename to "doom gc" and move to its own file
|
;; TODO Rename to "doom gc" and move to its own file
|
||||||
(defcli! ((purge p))
|
(defcli! (gc)
|
||||||
((nobuilds-p ("-b" "--no-builds") "Don't purge unneeded (built) packages")
|
((nobuilds-p ("-b" "--no-builds") "Don't purge unneeded (built) packages")
|
||||||
(noelpa-p ("-p" "--no-elpa") "Don't purge ELPA packages")
|
(noelpa-p ("-p" "--no-elpa") "Don't purge ELPA packages")
|
||||||
(norepos-p ("-r" "--no-repos") "Don't purge unused straight repos")
|
(norepos-p ("-r" "--no-repos") "Don't purge unused straight repos")
|
||||||
|
@ -50,6 +34,8 @@ possible.
|
||||||
It is a good idea to occasionally run this doom purge -g to ensure your package
|
It is a good idea to occasionally run this doom purge -g to ensure your package
|
||||||
list remains lean."
|
list remains lean."
|
||||||
:benchmark t
|
:benchmark t
|
||||||
|
(require 'comp nil t)
|
||||||
|
(doom-initialize-core-packages)
|
||||||
(straight-check-all)
|
(straight-check-all)
|
||||||
(when (doom-packages-purge
|
(when (doom-packages-purge
|
||||||
(not noelpa-p)
|
(not noelpa-p)
|
||||||
|
@ -242,154 +228,149 @@ list remains lean."
|
||||||
|
|
||||||
(defun doom-packages--write-missing-eln-errors ()
|
(defun doom-packages--write-missing-eln-errors ()
|
||||||
"Write .error files for any expected .eln files that are missing."
|
"Write .error files for any expected .eln files that are missing."
|
||||||
(when (featurep 'native-compile)
|
(cl-loop for file in doom-packages--eln-output-expected
|
||||||
(cl-loop for file in doom-packages--eln-output-expected
|
for eln-name = (doom-packages--eln-file-name file)
|
||||||
for eln-name = (doom-packages--eln-file-name file)
|
for eln-file = (doom-packages--eln-output-file eln-name)
|
||||||
for eln-file = (doom-packages--eln-output-file eln-name)
|
for error-file = (doom-packages--eln-error-file eln-name)
|
||||||
for error-file = (doom-packages--eln-error-file eln-name)
|
for error-dir = (file-name-directory error-file)
|
||||||
for error-dir = (file-name-directory error-file)
|
unless (or (file-exists-p eln-file)
|
||||||
unless (or (file-exists-p eln-file)
|
(file-newer-than-file-p error-file file)
|
||||||
(file-newer-than-file-p error-file file)
|
(not (file-writable-p error-dir)))
|
||||||
(not (file-writable-p error-dir)))
|
do (make-directory error-dir 'parents)
|
||||||
do (make-directory error-dir 'parents)
|
(write-region "" nil error-file)
|
||||||
(write-region "" nil error-file)
|
(doom-log "Wrote %s" error-file))
|
||||||
(doom-log "Wrote %s" error-file))
|
(setq doom-packages--eln-output-expected nil))
|
||||||
(setq doom-packages--eln-output-expected nil)))
|
|
||||||
|
|
||||||
(defun doom-packages--compile-site-files ()
|
(defun doom-packages--compile-site-files ()
|
||||||
"Queue async compilation for all non-doom Elisp files."
|
"Queue async compilation for all non-doom Elisp files."
|
||||||
(when (featurep 'native-compile)
|
(cl-loop with paths = (cl-loop for path in load-path
|
||||||
(cl-loop with paths = (cl-loop for path in load-path
|
unless (file-in-directory-p path doom-local-dir)
|
||||||
unless (file-in-directory-p path doom-local-dir)
|
collect path)
|
||||||
collect path)
|
for file in (doom-files-in paths :match "\\.el\\(?:\\.gz\\)?$")
|
||||||
for file in (doom-files-in paths :match "\\.el\\(?:\\.gz\\)?$")
|
if (and (file-exists-p (byte-compile-dest-file file))
|
||||||
if (and (file-exists-p (byte-compile-dest-file file))
|
(not (doom-packages--find-eln-file (doom-packages--eln-file-name file)))
|
||||||
(not (doom-packages--find-eln-file (doom-packages--eln-file-name file)))
|
(not (cl-some (fn! (string-match-p % file))
|
||||||
(not (cl-some (fn! (string-match-p % file))
|
native-comp-deferred-compilation-deny-list))) do
|
||||||
native-comp-deferred-compilation-deny-list))) do
|
(doom-log "Compiling %s" file)
|
||||||
(doom-log "Compiling %s" file)
|
(native-compile-async file)))
|
||||||
(native-compile-async file))))
|
|
||||||
|
|
||||||
(defun doom-packages-install ()
|
(defun doom-packages-ensure (&optional force-p)
|
||||||
"Installs missing packages.
|
"Ensure packages are installed, built"
|
||||||
|
|
||||||
This function will install any primary package (i.e. a package with a `package!'
|
|
||||||
declaration) or dependency thereof that hasn't already been."
|
|
||||||
(doom-initialize-packages)
|
(doom-initialize-packages)
|
||||||
(print! (start "Installing packages..."))
|
(if (not (file-directory-p (straight--repos-dir)))
|
||||||
(let ((pinned (doom-package-pinned-list)))
|
(print! (start "Installing all packages for the first time (this may take a while)..."))
|
||||||
(print-group!
|
(if force-p
|
||||||
(add-hook 'native-comp-async-cu-done-functions #'doom-packages--native-compile-done-h)
|
(print! (start "Rebuilding all packages (this may take a while)..."))
|
||||||
(if-let (built
|
(print! (start "Ensuring packages are installed and built..."))))
|
||||||
(doom-packages--with-recipes (doom-package-recipe-list)
|
|
||||||
(recipe package type local-repo)
|
|
||||||
(unless (file-directory-p (straight--repos-dir local-repo))
|
|
||||||
(doom-packages--cli-recipes-update))
|
|
||||||
(condition-case-unless-debug e
|
|
||||||
(let ((straight-use-package-pre-build-functions
|
|
||||||
(cons (lambda (pkg &rest _)
|
|
||||||
(when-let (commit (cdr (assoc pkg pinned)))
|
|
||||||
(print! (item "Checked out %s: %s") pkg commit)))
|
|
||||||
straight-use-package-pre-build-functions)))
|
|
||||||
(straight-use-package (intern package))
|
|
||||||
;; HACK Line encoding issues can plague repos with dirty
|
|
||||||
;; worktree prompts when updating packages or "Local
|
|
||||||
;; variables entry is missing the suffix" errors when
|
|
||||||
;; installing them (see hlissner/doom-emacs#2637), so
|
|
||||||
;; have git handle conversion by force.
|
|
||||||
(when (and IS-WINDOWS (stringp local-repo))
|
|
||||||
(let ((default-directory (straight--repos-dir local-repo)))
|
|
||||||
(when (file-in-directory-p default-directory straight-base-dir)
|
|
||||||
(straight--process-run "git" "config" "core.autocrlf" "true")))))
|
|
||||||
(error
|
|
||||||
(signal 'doom-package-error (list package e))))))
|
|
||||||
(progn
|
|
||||||
(when (featurep 'native-compile)
|
|
||||||
(doom-packages--compile-site-files)
|
|
||||||
(doom-packages--wait-for-native-compile-jobs)
|
|
||||||
(doom-packages--write-missing-eln-errors))
|
|
||||||
(print! (success "\033[KInstalled %d packages") (length built)))
|
|
||||||
(print! (item "No packages need to be installed"))
|
|
||||||
nil))))
|
|
||||||
|
|
||||||
|
|
||||||
(defun doom-packages-build (&optional force-p)
|
|
||||||
"(Re)build all packages."
|
|
||||||
(doom-initialize-packages)
|
|
||||||
(print! (start "(Re)building %spackages...") (if force-p "all " ""))
|
|
||||||
(print-group!
|
(print-group!
|
||||||
(let ((straight-check-for-modifications
|
(let ((straight-check-for-modifications
|
||||||
(when (file-directory-p (straight--modified-dir))
|
(when (file-directory-p (straight--modified-dir))
|
||||||
'(find-when-checking)))
|
'(find-when-checking)))
|
||||||
(straight--allow-find
|
(straight--allow-find
|
||||||
(and straight-check-for-modifications
|
(and straight-check-for-modifications
|
||||||
(executable-find straight-find-executable)
|
(executable-find straight-find-executable)
|
||||||
t))
|
t))
|
||||||
(straight--packages-not-to-rebuild
|
(straight--packages-not-to-rebuild
|
||||||
(or straight--packages-not-to-rebuild (make-hash-table :test #'equal)))
|
(or straight--packages-not-to-rebuild (make-hash-table :test #'equal)))
|
||||||
(straight--packages-to-rebuild
|
(straight--packages-to-rebuild
|
||||||
(or (if force-p :all straight--packages-to-rebuild)
|
(or (if force-p :all straight--packages-to-rebuild)
|
||||||
(make-hash-table :test #'equal)))
|
(make-hash-table :test #'equal)))
|
||||||
(recipes (doom-package-recipe-list)))
|
(recipes (doom-package-recipe-list))
|
||||||
(add-hook 'native-comp-async-cu-done-functions #'doom-packages--native-compile-done-h)
|
(pinned (doom-package-pinned-list)))
|
||||||
(unless force-p
|
(add-hook 'native-comp-async-cu-done-functions #'doom-packages--native-compile-done-h)
|
||||||
(straight--make-build-cache-available))
|
(straight--make-build-cache-available)
|
||||||
(if-let (built
|
(if-let (built
|
||||||
(doom-packages--with-recipes recipes (package local-repo recipe)
|
(doom-packages--with-recipes recipes (package local-repo recipe)
|
||||||
(unless force-p
|
(let ((repo-dir (straight--repos-dir (or local-repo package)))
|
||||||
;; Ensure packages with outdated files/bytecode are rebuilt
|
(build-dir (straight--build-dir package)))
|
||||||
(let* ((build-dir (straight--build-dir package))
|
(unless force-p
|
||||||
(repo-dir (straight--repos-dir local-repo))
|
;; Ensure packages with outdated files/bytecode are rebuilt
|
||||||
(build (if (plist-member recipe :build)
|
(let* ((build (if (plist-member recipe :build)
|
||||||
(plist-get recipe :build)
|
(plist-get recipe :build)
|
||||||
t))
|
t))
|
||||||
(want-byte-compile
|
(want-byte-compile
|
||||||
(or (eq build t)
|
(or (eq build t)
|
||||||
(memq 'compile build)))
|
(memq 'compile build)))
|
||||||
(want-native-compile
|
(want-native-compile
|
||||||
(or (eq build t)
|
(or (eq build t)
|
||||||
(memq 'native-compile build))))
|
(memq 'native-compile build))))
|
||||||
(and (eq (car-safe build) :not)
|
(and (eq (car-safe build) :not)
|
||||||
(setq want-byte-compile (not want-byte-compile)
|
(setq want-byte-compile (not want-byte-compile)
|
||||||
want-native-compile (not want-native-compile)))
|
want-native-compile (not want-native-compile)))
|
||||||
(unless (featurep 'native-compile)
|
(unless (featurep 'native-compile)
|
||||||
(setq want-native-compile nil))
|
(setq want-native-compile nil))
|
||||||
(and (or want-byte-compile want-native-compile)
|
(and (or want-byte-compile want-native-compile)
|
||||||
(or (file-newer-than-file-p repo-dir build-dir)
|
(or (file-newer-than-file-p repo-dir build-dir)
|
||||||
(file-exists-p (straight--modified-dir (or local-repo package)))
|
(file-exists-p (straight--modified-dir (or local-repo package)))
|
||||||
(cl-loop with outdated = nil
|
(cl-loop with outdated = nil
|
||||||
for file in (doom-files-in build-dir :match "\\.el$" :full t)
|
for file in (doom-files-in build-dir :match "\\.el$" :full t)
|
||||||
if (or (if want-byte-compile (doom-packages--elc-file-outdated-p file))
|
if (or (if want-byte-compile (doom-packages--elc-file-outdated-p file))
|
||||||
(if want-native-compile (doom-packages--eln-file-outdated-p file)))
|
(if want-native-compile (doom-packages--eln-file-outdated-p file)))
|
||||||
do (setq outdated t)
|
do (setq outdated t)
|
||||||
(when want-native-compile
|
(when want-native-compile
|
||||||
(push file doom-packages--eln-output-expected))
|
(push file doom-packages--eln-output-expected))
|
||||||
finally return outdated))
|
finally return outdated))
|
||||||
(puthash package t straight--packages-to-rebuild))))
|
(puthash package t straight--packages-to-rebuild))))
|
||||||
(straight-use-package (intern package))))
|
(unless (file-directory-p repo-dir)
|
||||||
(progn
|
(doom-packages--cli-recipes-update))
|
||||||
(when (featurep 'native-compile)
|
(condition-case-unless-debug e
|
||||||
(doom-packages--compile-site-files)
|
(let ((straight-vc-git-post-clone-hook
|
||||||
(doom-packages--wait-for-native-compile-jobs)
|
(cons (lambda! (&key repo-dir commit)
|
||||||
(doom-packages--write-missing-eln-errors))
|
(print-group!
|
||||||
;; HACK Every time you save a file in a package that straight tracks,
|
(if-let (pin (cdr (assoc package pinned)))
|
||||||
;; it is recorded in ~/.emacs.d/.local/straight/modified/.
|
(print! (item "Pinned to %s") pin)
|
||||||
;; Typically, straight will clean these up after rebuilding, but
|
(print! (item "Checked out %s") commit)))
|
||||||
;; Doom's use-case circumnavigates that, leaving these files
|
;; HACK: Line encoding issues can plague
|
||||||
;; there and causing a rebuild of those packages each time `doom
|
;; repos with dirty worktree prompts
|
||||||
;; sync' or similar is run, so we clean it up ourselves:
|
;; when updating packages or "Local
|
||||||
(delete-directory (straight--modified-dir) 'recursive)
|
;; variables entry is missing the
|
||||||
(print! (success "\033[KRebuilt %d package(s)") (length built)))
|
;; suffix" errors when installing them
|
||||||
(print! (item "No packages need rebuilding"))
|
;; (see #2637), so have git handle
|
||||||
nil))))
|
;; conversion by force.
|
||||||
|
(when (and doom--system-windows-p (stringp repo-dir))
|
||||||
|
(let ((default-directory repo-dir))
|
||||||
|
(when (file-in-directory-p default-directory straight-base-dir)
|
||||||
|
(straight--process-run "git" "config" "core.autocrlf" "true")))))
|
||||||
|
straight-vc-git-post-clone-hook)))
|
||||||
|
(straight-use-package (intern package))
|
||||||
|
;; HACK: Straight can sometimes fail to clone a repo,
|
||||||
|
;; leaving behind an empty directory which, in future
|
||||||
|
;; invocations, it will assume indicates a successful
|
||||||
|
;; clone (causing load errors later).
|
||||||
|
(let ((try 0))
|
||||||
|
(while (or (not (file-directory-p repo-dir))
|
||||||
|
(directory-empty-p repo-dir))
|
||||||
|
(when (= try 3)
|
||||||
|
(error "Failed to clone package"))
|
||||||
|
(print! "Failed to clone %S, trying again (attempt #%d)..." package (1+ try))
|
||||||
|
(delete-directory repo-dir t)
|
||||||
|
(delete-directory build-dir t)
|
||||||
|
(straight-use-package (intern package))
|
||||||
|
(cl-incf try))))
|
||||||
|
(error
|
||||||
|
(signal 'doom-package-error (list package e)))))))
|
||||||
|
(progn
|
||||||
|
(when (featurep 'native-compile)
|
||||||
|
(doom-packages--compile-site-files)
|
||||||
|
(doom-packages--wait-for-native-compile-jobs)
|
||||||
|
(doom-packages--write-missing-eln-errors))
|
||||||
|
;; HACK: Every time you save a file in a package that straight
|
||||||
|
;; tracks, it is recorded in ~/.emacs.d/.local/straight/modified/.
|
||||||
|
;; Typically, straight will clean these up after rebuilding, but
|
||||||
|
;; Doom's use-case circumnavigates that, leaving these files there
|
||||||
|
;; and causing a rebuild of those packages each time `doom sync'
|
||||||
|
;; or similar is run, so we clean it up ourselves:
|
||||||
|
(delete-directory (straight--modified-dir) 'recursive)
|
||||||
|
(print! (success "\033[KBuilt %d package(s)") (length built)))
|
||||||
|
(print! (item "No packages need attention"))
|
||||||
|
nil))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defun doom-packages-update ()
|
(defun doom-packages-update (&optional pinned-only-p)
|
||||||
"Updates packages."
|
"Updates packages."
|
||||||
(doom-initialize-packages)
|
(doom-initialize-packages)
|
||||||
(doom-packages--barf-if-incomplete)
|
(doom-packages--barf-if-incomplete)
|
||||||
(doom-packages--cli-recipes-update)
|
|
||||||
(let* ((repo-dir (straight--repos-dir))
|
(let* ((repo-dir (straight--repos-dir))
|
||||||
(pinned (doom-package-pinned-list))
|
(pinned (doom-package-pinned-list))
|
||||||
(recipes (doom-package-recipe-list))
|
(recipes (doom-package-recipe-list))
|
||||||
|
@ -397,9 +378,10 @@ declaration) or dependency thereof that hasn't already been."
|
||||||
(repos-to-rebuild (make-hash-table :test 'equal))
|
(repos-to-rebuild (make-hash-table :test 'equal))
|
||||||
(total (length recipes))
|
(total (length recipes))
|
||||||
(esc (unless init-file-debug "\033[1A"))
|
(esc (unless init-file-debug "\033[1A"))
|
||||||
(i 0)
|
(i 0))
|
||||||
errors)
|
(if pinned-only-p
|
||||||
(print! (start "Updating packages (this may take a while)..."))
|
(print! (start "Updating pinned packages..."))
|
||||||
|
(print! (start "Updating all packages (this may take a while)...")))
|
||||||
(doom-packages--with-recipes recipes (recipe package type local-repo)
|
(doom-packages--with-recipes recipes (recipe package type local-repo)
|
||||||
(cl-incf i)
|
(cl-incf i)
|
||||||
(print-group!
|
(print-group!
|
||||||
|
@ -412,11 +394,13 @@ declaration) or dependency thereof that hasn't already been."
|
||||||
(cl-return))
|
(cl-return))
|
||||||
(let ((default-directory (straight--repos-dir local-repo)))
|
(let ((default-directory (straight--repos-dir local-repo)))
|
||||||
(unless (file-in-directory-p default-directory repo-dir)
|
(unless (file-in-directory-p default-directory repo-dir)
|
||||||
(print! (warn "(%d/%d) Skipping %s because it is local") i total package)
|
(print! (warn "(%d/%d) Skipping %s because it is out-of-tree...") i total package)
|
||||||
(cl-return))
|
(cl-return))
|
||||||
(when (eq type 'git)
|
(when (eq type 'git)
|
||||||
(unless (file-exists-p ".git")
|
(unless (file-exists-p ".git")
|
||||||
(error "%S is not a valid repository" package)))
|
(error "%S is not a valid repository" package)))
|
||||||
|
(when (and pinned-only-p (not (assoc local-repo pinned)))
|
||||||
|
(cl-return))
|
||||||
(condition-case-unless-debug e
|
(condition-case-unless-debug e
|
||||||
(let ((ref (straight-vc-get-commit type local-repo))
|
(let ((ref (straight-vc-get-commit type local-repo))
|
||||||
(target-ref
|
(target-ref
|
||||||
|
@ -430,13 +414,6 @@ declaration) or dependency thereof that hasn't already been."
|
||||||
(doom-packages--straight-with (straight-vc-fetch-from-remote recipe)
|
(doom-packages--straight-with (straight-vc-fetch-from-remote recipe)
|
||||||
(when .it
|
(when .it
|
||||||
(straight-merge-package package)
|
(straight-merge-package package)
|
||||||
;; (condition-case e
|
|
||||||
;; (straight-merge-package package)
|
|
||||||
;; (wrong-type-argument
|
|
||||||
;; (if (not (equal (cdr e) '(arrayp nil)))
|
|
||||||
;; (signal (car e) (cdr e))
|
|
||||||
;; (delete-directory (straight--build-dir local-repo) t)
|
|
||||||
;; (straight-use-package (intern package)))))
|
|
||||||
(setq target-ref (straight-vc-get-commit type local-repo))
|
(setq target-ref (straight-vc-get-commit type local-repo))
|
||||||
(setq output (doom-packages--commit-log-between ref target-ref)
|
(setq output (doom-packages--commit-log-between ref target-ref)
|
||||||
commits (length (split-string output "\n" t)))
|
commits (length (split-string output "\n" t)))
|
||||||
|
@ -464,7 +441,7 @@ declaration) or dependency thereof that hasn't already been."
|
||||||
(straight-vc-git-default-clone-depth 'full))
|
(straight-vc-git-default-clone-depth 'full))
|
||||||
(delete-directory repo 'recursive)
|
(delete-directory repo 'recursive)
|
||||||
(print-group!
|
(print-group!
|
||||||
(straight-use-package (intern package) nil 'no-build))
|
(straight-use-package (intern package) nil 'no-build))
|
||||||
(prog1 (file-directory-p repo)
|
(prog1 (file-directory-p repo)
|
||||||
(or (not (eq type 'git))
|
(or (not (eq type 'git))
|
||||||
(setq output (doom-packages--commit-log-between ref target-ref)
|
(setq output (doom-packages--commit-log-between ref target-ref)
|
||||||
|
@ -520,13 +497,14 @@ declaration) or dependency thereof that hasn't already been."
|
||||||
(princ "\033[K")
|
(princ "\033[K")
|
||||||
(if (hash-table-empty-p packages-to-rebuild)
|
(if (hash-table-empty-p packages-to-rebuild)
|
||||||
(ignore (print! (success "All %d packages are up-to-date") total))
|
(ignore (print! (success "All %d packages are up-to-date") total))
|
||||||
|
(doom-packages--cli-recipes-update)
|
||||||
(straight--transaction-finalize)
|
(straight--transaction-finalize)
|
||||||
(let ((default-directory (straight--build-dir)))
|
(let ((default-directory (straight--build-dir)))
|
||||||
(mapc (doom-rpartial #'delete-directory 'recursive)
|
(mapc (doom-rpartial #'delete-directory 'recursive)
|
||||||
(hash-table-keys packages-to-rebuild)))
|
(hash-table-keys packages-to-rebuild)))
|
||||||
(print! (success "Updated %d package(s)")
|
(print! (success "Updated %d package(s)")
|
||||||
(hash-table-count packages-to-rebuild))
|
(hash-table-count packages-to-rebuild))
|
||||||
(doom-packages-build)
|
(doom-packages-ensure)
|
||||||
t))))
|
t))))
|
||||||
|
|
||||||
|
|
||||||
|
@ -652,6 +630,7 @@ If ELPA-P, include packages installed with package.el (M-x package-install)."
|
||||||
(doom-initialize-packages)
|
(doom-initialize-packages)
|
||||||
(doom-packages--barf-if-incomplete)
|
(doom-packages--barf-if-incomplete)
|
||||||
(print! (start "Purging orphaned packages (for the emperor)..."))
|
(print! (start "Purging orphaned packages (for the emperor)..."))
|
||||||
|
(quiet! (straight-prune-build-cache))
|
||||||
(cl-destructuring-bind (&optional builds-to-purge repos-to-purge repos-to-regraft)
|
(cl-destructuring-bind (&optional builds-to-purge repos-to-purge repos-to-regraft)
|
||||||
(let ((rdirs
|
(let ((rdirs
|
||||||
(and (or repos-p regraft-repos-p)
|
(and (or repos-p regraft-repos-p)
|
||||||
|
@ -672,8 +651,7 @@ If ELPA-P, include packages installed with package.el (M-x package-install)."
|
||||||
nil (list
|
nil (list
|
||||||
(if (not builds-p)
|
(if (not builds-p)
|
||||||
(ignore (print! (item "Skipping builds")))
|
(ignore (print! (item "Skipping builds")))
|
||||||
(and (/= 0 (doom-packages--purge-builds builds-to-purge))
|
(/= 0 (doom-packages--purge-builds builds-to-purge)))
|
||||||
(quiet! (straight-prune-build-cache))))
|
|
||||||
(if (not elpa-p)
|
(if (not elpa-p)
|
||||||
(ignore (print! (item "Skipping elpa packages")))
|
(ignore (print! (item "Skipping elpa packages")))
|
||||||
(/= 0 (doom-packages--purge-elpa)))
|
(/= 0 (doom-packages--purge-elpa)))
|
||||||
|
@ -821,5 +799,31 @@ However, in batch mode, print to stdout instead of stderr."
|
||||||
"/dev/null")))
|
"/dev/null")))
|
||||||
(apply fn args)))
|
(apply fn args)))
|
||||||
|
|
||||||
|
;; If the repo failed to clone correctly (usually due to a connection failure),
|
||||||
|
;; straight proceeds as normal until a later call produces a garbage result
|
||||||
|
;; (typically, when it fails to fetch the remote branch of the empty directory).
|
||||||
|
;; This causes Straight to throw an otherwise cryptic type error when it tries
|
||||||
|
;; to sanitize the result for its log buffer.
|
||||||
|
;;
|
||||||
|
;; This error is a common source of user confusion and false positive bug
|
||||||
|
;; reports, so this advice catches them to regurgitates a more cogent
|
||||||
|
;; explanation.
|
||||||
|
(defadvice! doom-cli--straight-throw-error-on-no-branch-a (fn &rest args)
|
||||||
|
:around #'straight--process-log
|
||||||
|
(letf! ((defun shell-quote-argument (&rest args)
|
||||||
|
(unless (car args)
|
||||||
|
(error "Package was not properly cloned due to a connection failure, please try again later"))
|
||||||
|
(apply shell-quote-argument args)))
|
||||||
|
(apply fn args)))
|
||||||
|
|
||||||
|
(defadvice! doom-cli--straight-regurgitate-empty-string-error-a (fn &rest args)
|
||||||
|
:around #'straight-vc-git-local-repo-name
|
||||||
|
(condition-case-unless-debug e
|
||||||
|
(apply fn args)
|
||||||
|
(wrong-type-argument
|
||||||
|
(if (eq (cadr e) 'stringp)
|
||||||
|
(error "Package was not properly cloned due to a connection failure, please try again later")
|
||||||
|
(signal (car e) (cdr e))))))
|
||||||
|
|
||||||
(provide 'doom-cli-packages)
|
(provide 'doom-cli-packages)
|
||||||
;;; packages.el ends here
|
;;; packages.el ends here
|
||||||
|
|
|
@ -14,18 +14,21 @@
|
||||||
(defvar doom-before-sync-hook ()
|
(defvar doom-before-sync-hook ()
|
||||||
"Hooks run before 'doom sync' synchronizes the user's config with Doom.")
|
"Hooks run before 'doom sync' synchronizes the user's config with Doom.")
|
||||||
|
|
||||||
|
(defvar doom-cli-sync-info-file (file-name-concat doom-profile-data-dir "sync"))
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;;; Commands
|
;;; Commands
|
||||||
|
|
||||||
(defcli-alias! (:before (sync s)) (:before build))
|
|
||||||
|
|
||||||
(defcli! ((sync s))
|
(defcli! ((sync s))
|
||||||
((noenvvar? ("-e") "Don't regenerate the envvar file")
|
((noenvvar? ("-e") "Don't regenerate the envvar file")
|
||||||
(noelc? ("-c") "Don't recompile config")
|
(update? ("-u") "Update all installed packages after syncing")
|
||||||
(update? ("-u") "Update installed packages after syncing")
|
(noupdate? ("-U") "Don't update any packages")
|
||||||
(purge? ("-p") "Purge orphaned package repos & regraft them")
|
(purge? ("--gc") "Purge orphaned package repos & regraft them")
|
||||||
(jobs ("-j" "--jobs" num) "How many CPUs to use for native compilation"))
|
(jobs ("-j" "--jobs" num) "How many threads to use for native compilation")
|
||||||
|
(rebuild? ("-b" "--rebuild") "Rebuild all installed packages, unconditionally")
|
||||||
|
(nobuild? ("-B") "Don't rebuild packages when hostname or Emacs version has changed")
|
||||||
|
&context context)
|
||||||
"Synchronize your config with Doom Emacs.
|
"Synchronize your config with Doom Emacs.
|
||||||
|
|
||||||
This is the equivalent of running autoremove, install, autoloads, then
|
This is the equivalent of running autoremove, install, autoloads, then
|
||||||
|
@ -33,8 +36,10 @@ recompile. Run this whenever you:
|
||||||
|
|
||||||
1. Modify your `doom!' block,
|
1. Modify your `doom!' block,
|
||||||
2. Add or remove `package!' blocks to your config,
|
2. Add or remove `package!' blocks to your config,
|
||||||
3. Add or remove autoloaded functions in module autoloaded files.
|
3. Add or remove autoloaded functions in module autoloaded files,
|
||||||
4. Update Doom outside of Doom (e.g. with git)
|
4. Update Doom outside of Doom (e.g. with git),
|
||||||
|
5. Move your Doom config (either $EMACSDIR or $DOOMDIR) to a new location.
|
||||||
|
6. When you up (or down) grade Emacs itself.
|
||||||
|
|
||||||
It will ensure that unneeded packages are removed, all needed packages are
|
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
|
installed, autoloads files are up-to-date and no byte-compiled files have gone
|
||||||
|
@ -47,26 +52,49 @@ OPTIONS:
|
||||||
:benchmark t
|
:benchmark t
|
||||||
(when (doom-profiles-bootloadable-p)
|
(when (doom-profiles-bootloadable-p)
|
||||||
(call! '(profiles sync "--reload")))
|
(call! '(profiles sync "--reload")))
|
||||||
(run-hooks 'doom-before-sync-hook)
|
|
||||||
(add-hook 'kill-emacs-hook #'doom-sync--abort-warning-h)
|
|
||||||
(when jobs
|
(when jobs
|
||||||
(setq native-comp-async-jobs-number (truncate jobs)))
|
(setq native-comp-async-jobs-number (truncate jobs)))
|
||||||
(print! (start "Synchronizing %S profile..." )
|
(run-hooks 'doom-before-sync-hook)
|
||||||
(or (car doom-profile) "default"))
|
(add-hook 'kill-emacs-hook #'doom-sync--abort-warning-h)
|
||||||
|
(print! (item "Using Emacs %s @ %s") emacs-version (path invocation-directory invocation-name))
|
||||||
|
(print! (start "Synchronizing %S profile..." ) (or (car doom-profile) "default"))
|
||||||
(unwind-protect
|
(unwind-protect
|
||||||
(print-group!
|
(print-group!
|
||||||
(when (and (not noenvvar?)
|
;; If the user has up/downgraded Emacs since last sync, or copied their
|
||||||
(file-exists-p doom-env-file))
|
;; config to a different system, then their packages need to be
|
||||||
(call! '(env)))
|
;; recompiled. This is necessary because Emacs byte-code is not
|
||||||
(doom-packages-install)
|
;; necessarily back/forward compatible across major versions, and many
|
||||||
(doom-packages-build)
|
;; packages bake in hardcoded data at compile-time.
|
||||||
(when update?
|
(pcase-let ((`(,old-version . ,old-host) (doom-file-read doom-cli-sync-info-file :by 'read :noerror t))
|
||||||
(doom-packages-update))
|
(to-rebuild nil))
|
||||||
(doom-packages-purge purge? purge? purge? purge? purge?)
|
(when (and old-version (not (equal old-version emacs-version)))
|
||||||
(when (doom-profile-generate)
|
(print! (warn "Emacs version has changed since last sync (from %s to %s)") old-version emacs-version)
|
||||||
(print! (item "Restart Emacs or use 'M-x doom/reload' for changes to take effect"))
|
(setq to-rebuild t))
|
||||||
(run-hooks 'doom-after-sync-hook))
|
(when (and old-host (not (equal old-host (system-name))))
|
||||||
t)
|
(print! (warn "Your system has changed since last sync"))
|
||||||
|
(setq to-rebuild t))
|
||||||
|
(when (and to-rebuild (not (doom-cli-context-suppress-prompts-p context)))
|
||||||
|
(cond (nobuild?
|
||||||
|
(print! (warn "Packages must be rebuilt, but -B has prevented it. Skipping...")))
|
||||||
|
((doom-cli-context-get context 'upgrading)
|
||||||
|
(print! (warn "Packages will be rebuilt"))
|
||||||
|
(setq rebuild? t))
|
||||||
|
((y-or-n-p (format! " %s" "Installed packages must be rebuilt. Do so now?"))
|
||||||
|
(setq rebuild? t))
|
||||||
|
((exit! 0)))))
|
||||||
|
(when (and (not noenvvar?)
|
||||||
|
(file-exists-p doom-env-file))
|
||||||
|
(call! '(env)))
|
||||||
|
(doom-packages-ensure rebuild?)
|
||||||
|
(unless noupdate? (doom-packages-update (not update?)))
|
||||||
|
(doom-packages-purge purge? purge? purge? purge? purge?)
|
||||||
|
(when (doom-profile-generate)
|
||||||
|
(print! (item "Restart Emacs or use 'M-x doom/reload' for changes to take effect"))
|
||||||
|
(run-hooks 'doom-after-sync-hook))
|
||||||
|
(when (and (not rebuild?) (not nobuild?))
|
||||||
|
(with-temp-file doom-cli-sync-info-file
|
||||||
|
(prin1 (cons emacs-version (system-name)) (current-buffer))))
|
||||||
|
t)
|
||||||
(remove-hook 'kill-emacs-hook #'doom-sync--abort-warning-h)))
|
(remove-hook 'kill-emacs-hook #'doom-sync--abort-warning-h)))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(load! "packages")
|
(load! "packages")
|
||||||
(load! "compile")
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
@ -22,6 +21,7 @@
|
||||||
(defcli! ((upgrade up))
|
(defcli! ((upgrade up))
|
||||||
((packages? ("-p" "--packages") "Only upgrade packages, not Doom")
|
((packages? ("-p" "--packages") "Only upgrade packages, not Doom")
|
||||||
(jobs ("-j" "--jobs" num) "How many CPUs to use for native compilation")
|
(jobs ("-j" "--jobs" num) "How many CPUs to use for native compilation")
|
||||||
|
(nobuild? ("-B") "Don't rebuild packages when hostname or Emacs version has changed")
|
||||||
&context context)
|
&context context)
|
||||||
"Updates Doom and packages.
|
"Updates Doom and packages.
|
||||||
|
|
||||||
|
@ -30,10 +30,11 @@ following shell commands:
|
||||||
|
|
||||||
cd ~/.emacs.d
|
cd ~/.emacs.d
|
||||||
git pull --rebase
|
git pull --rebase
|
||||||
doom clean
|
|
||||||
doom sync -u"
|
doom sync -u"
|
||||||
(let* ((force? (doom-cli-context-suppress-prompts-p context))
|
(let* ((force? (doom-cli-context-suppress-prompts-p context))
|
||||||
(sync-cmd (append '("sync" "-u") (if jobs `("-j" ,num)))))
|
(sync-cmd (append '("sync" "-u")
|
||||||
|
(if nobuild? '("-B"))
|
||||||
|
(if jobs `("-j" ,num)))))
|
||||||
(cond
|
(cond
|
||||||
(packages?
|
(packages?
|
||||||
;; HACK It's messy to use straight to upgrade straight, due to the
|
;; HACK It's messy to use straight to upgrade straight, due to the
|
||||||
|
@ -54,7 +55,9 @@ following shell commands:
|
||||||
;; Reload Doom's CLI & libraries, in case there were any upstream changes.
|
;; Reload Doom's CLI & libraries, in case there were any upstream changes.
|
||||||
;; Major changes will still break, however
|
;; Major changes will still break, however
|
||||||
(print! (item "Reloading Doom Emacs"))
|
(print! (item "Reloading Doom Emacs"))
|
||||||
|
(doom-cli-context-put context 'upgrading t)
|
||||||
(exit! "doom" "upgrade" "-p"
|
(exit! "doom" "upgrade" "-p"
|
||||||
|
(if nobuild? "-B")
|
||||||
(if force? "--force")
|
(if force? "--force")
|
||||||
(if jobs (format "--jobs=%d" jobs))))
|
(if jobs (format "--jobs=%d" jobs))))
|
||||||
|
|
||||||
|
@ -96,6 +99,8 @@ following shell commands:
|
||||||
(sh! "git" "reset" "--hard" (format "origin/%s" branch))
|
(sh! "git" "reset" "--hard" (format "origin/%s" branch))
|
||||||
(sh! "git" "clean" "-ffd")))
|
(sh! "git" "clean" "-ffd")))
|
||||||
|
|
||||||
|
;; In case of leftover state from a partial/incomplete 'doom upgrade'
|
||||||
|
(sh! "git" "branch" "-D" target-remote)
|
||||||
(sh! "git" "remote" "remove" doom-upgrade-remote)
|
(sh! "git" "remote" "remove" doom-upgrade-remote)
|
||||||
(unwind-protect
|
(unwind-protect
|
||||||
(let (result)
|
(let (result)
|
||||||
|
@ -136,7 +141,6 @@ following shell commands:
|
||||||
(ignore (print! (error "Aborted")))
|
(ignore (print! (error "Aborted")))
|
||||||
(print! (start "Upgrading Doom Emacs..."))
|
(print! (start "Upgrading Doom Emacs..."))
|
||||||
(print-group!
|
(print-group!
|
||||||
(doom-compile-clean)
|
|
||||||
(doom-cli-context-put context 'straight-recipe (doom-upgrade--get-straight-recipe))
|
(doom-cli-context-put context 'straight-recipe (doom-upgrade--get-straight-recipe))
|
||||||
(or (and (zerop (car (sh! "git" "reset" "--hard" target-remote)))
|
(or (and (zerop (car (sh! "git" "reset" "--hard" target-remote)))
|
||||||
(equal (cdr (sh! "git" "rev-parse" "HEAD")) new-rev))
|
(equal (cdr (sh! "git" "rev-parse" "HEAD")) new-rev))
|
||||||
|
|
654
lisp/demos.org
Normal file
654
lisp/demos.org
Normal file
|
@ -0,0 +1,654 @@
|
||||||
|
#+title: Doom Emacs API Demos
|
||||||
|
#+property: header-args:elisp :results pp :exports both :eval never-export
|
||||||
|
|
||||||
|
This module installs the elisp-demos package, which adds code examples to
|
||||||
|
documentation buffers (the ones help.el or helpful produces). The built-in demos
|
||||||
|
are great, but this file exists to add demos for Doom's API and beyond.
|
||||||
|
|
||||||
|
#+begin_quote
|
||||||
|
Please make sure new additions to this file are arranged alphabetically and
|
||||||
|
has a :PROPERTIES: drawer that includes in what version of Doom that the
|
||||||
|
symbol/function was added.
|
||||||
|
#+end_quote
|
||||||
|
|
||||||
|
#+begin_quote
|
||||||
|
Please don't add demos for code outside of Doom Emacs. PR those to the parent
|
||||||
|
project: https://github.com/xuchunyang/elisp-demos. And please don't add
|
||||||
|
functions from modules, put those in that module's demo.org file, or your
|
||||||
|
own in $DOOMDIR/demos.org.
|
||||||
|
#+end_quote
|
||||||
|
|
||||||
|
* add-hook!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
;; With only one hook and one function, this is identical to `add-hook'. In that
|
||||||
|
;; case, use that instead.
|
||||||
|
(add-hook! 'some-mode-hook #'enable-something)
|
||||||
|
|
||||||
|
;; Adding many-to-many functions to hooks
|
||||||
|
(add-hook! some-mode #'enable-something #'and-another)
|
||||||
|
(add-hook! some-mode '(enable-something and-another))
|
||||||
|
(add-hook! '(one-mode-hook second-mode-hook) #'enable-something)
|
||||||
|
(add-hook! (one-mode second-mode) #'enable-something)
|
||||||
|
|
||||||
|
;; Appending and local hooks
|
||||||
|
(add-hook! (one-mode second-mode) :append #'enable-something)
|
||||||
|
(add-hook! (one-mode second-mode) :local #'enable-something)
|
||||||
|
|
||||||
|
;; With arbitrary forms
|
||||||
|
(add-hook! (one-mode second-mode) (setq v 5) (setq a 2))
|
||||||
|
(add-hook! (one-mode second-mode) :append :local (setq v 5) (setq a 2))
|
||||||
|
|
||||||
|
;; Inline named hook functions
|
||||||
|
(add-hook! '(one-mode-hook second-mode-hook)
|
||||||
|
(defun do-something ()
|
||||||
|
...)
|
||||||
|
(defun do-another-thing ()
|
||||||
|
...))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* TODO add-transient-hook!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
* after!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
;;; `after!' will take:
|
||||||
|
|
||||||
|
;; An unquoted package symbol (the name of a package)
|
||||||
|
(after! helm ...)
|
||||||
|
|
||||||
|
;; An unquoted list of package symbols (i.e. BODY is evaluated once both magit
|
||||||
|
;; and git-gutter have loaded)
|
||||||
|
(after! (magit git-gutter) ...)
|
||||||
|
|
||||||
|
;; An unquoted, nested list of compound package lists, using any combination of
|
||||||
|
;; :or/:any and :and/:all
|
||||||
|
(after! (:or package-a package-b ...) ...)
|
||||||
|
(after! (:and package-a package-b ...) ...)
|
||||||
|
(after! (:and package-a (:or package-b package-c) ...) ...)
|
||||||
|
;; (Without :or/:any/:and/:all, :and/:all are implied.)
|
||||||
|
|
||||||
|
;; A common mistake is to pass it the names of major or minor modes, e.g.
|
||||||
|
(after! rustic-mode ...)
|
||||||
|
(after! python-mode ...)
|
||||||
|
;; But the code in them will never run! rustic-mode is in the `rustic' package
|
||||||
|
;; and python-mode is in the `python' package. This is what you want:
|
||||||
|
(after! rustic ...)
|
||||||
|
(after! python ...)
|
||||||
|
#+end_src
|
||||||
|
* appendq!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(let ((x '(a b c)))
|
||||||
|
(appendq! x '(c d e))
|
||||||
|
x)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: (a b c c d e)
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(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)
|
||||||
|
|
||||||
|
* cmd!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
(map! "C-j" (cmd! (newline) (indent-according-to-mode)))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* cmd!!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
When ~newline~ is passed a numerical prefix argument (=C-u 5 M-x newline=), it
|
||||||
|
inserts N newlines. We can use ~cmd!!~ to easily create a keybinds that bakes in
|
||||||
|
the prefix arg into the command call:
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
(map! "C-j" (cmd!! #'newline 5))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Or to create aliases for functions that behave differently:
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
(fset 'insert-5-newlines (cmd!! #'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 (cmd!! #'org-global-cycle '(4))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* cmds!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
(map! :i [tab] (cmds! (and (modulep! :editor snippets)
|
||||||
|
(bound-and-true-p yas-minor-mode)
|
||||||
|
(yas-maybe-expand-abbrev-key-filter 'yas-expand))
|
||||||
|
#'yas-expand
|
||||||
|
(modulep! :completion company +tng)
|
||||||
|
#'company-indent-or-complete-common)
|
||||||
|
:m [tab] (cmds! (and (bound-and-true-p yas-minor-mode)
|
||||||
|
(evil-visual-state-p)
|
||||||
|
(or (eq evil-visual-selection 'line)
|
||||||
|
(not (memq (char-after) (list ?\( ?\[ ?\{ ?\} ?\] ?\))))))
|
||||||
|
#'yas-insert-snippet
|
||||||
|
(and (modulep! :editor fold)
|
||||||
|
(save-excursion (end-of-line) (invisible-p (point))))
|
||||||
|
#'+fold/toggle
|
||||||
|
(fboundp 'evil-jump-item)
|
||||||
|
#'evil-jump-item))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* custom-set-faces!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
(custom-set-faces!
|
||||||
|
'(outline-1 :weight normal)
|
||||||
|
'(outline-2 :weight normal)
|
||||||
|
'(outline-3 :weight normal)
|
||||||
|
'(outline-4 :weight normal)
|
||||||
|
'(outline-5 :weight normal)
|
||||||
|
'(outline-6 :weight normal)
|
||||||
|
'(default :background "red" :weight bold)
|
||||||
|
'(region :background "red" :weight bold))
|
||||||
|
|
||||||
|
(custom-set-faces!
|
||||||
|
'((outline-1 outline-2 outline-3 outline-4 outline-5 outline-6)
|
||||||
|
:weight normal)
|
||||||
|
'((default region)
|
||||||
|
:background "red" :weight bold))
|
||||||
|
|
||||||
|
(let ((red-bg-faces '(default region)))
|
||||||
|
(custom-set-faces!
|
||||||
|
`(,(cl-loop for i from 0 to 6 collect (intern (format "outline-%d" i)))
|
||||||
|
:weight normal)
|
||||||
|
`(,red-bg-faces
|
||||||
|
:background "red" :weight bold)))
|
||||||
|
|
||||||
|
;; You may utilise `doom-themes's theme API to fetch or tweak colors from their
|
||||||
|
;; palettes. No need to wait until the theme or package is loaded. e.g.
|
||||||
|
(custom-set-faces!
|
||||||
|
`(outline-1 :foreground ,(doom-color 'red))
|
||||||
|
`(outline-2 :background ,(doom-color 'blue)))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* custom-theme-set-faces!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
(custom-theme-set-faces! 'doom-one
|
||||||
|
'(outline-1 :weight normal)
|
||||||
|
'(outline-2 :weight normal)
|
||||||
|
'(outline-3 :weight normal)
|
||||||
|
'(outline-4 :weight normal)
|
||||||
|
'(outline-5 :weight normal)
|
||||||
|
'(outline-6 :weight normal)
|
||||||
|
'(default :background "red" :weight bold)
|
||||||
|
'(region :background "red" :weight bold))
|
||||||
|
|
||||||
|
(custom-theme-set-faces! '(doom-one-theme doom-one-light-theme)
|
||||||
|
'((outline-1 outline-2 outline-3 outline-4 outline-5 outline-6)
|
||||||
|
:weight normal)
|
||||||
|
'((default region)
|
||||||
|
:background "red" :weight bold))
|
||||||
|
|
||||||
|
(let ((red-bg-faces '(default region)))
|
||||||
|
(custom-theme-set-faces! '(doom-one-theme doom-one-light-theme)
|
||||||
|
`(,(cl-loop for i from 0 to 6 collect (intern (format "outline-%d" i)))
|
||||||
|
:weight normal)
|
||||||
|
`(,red-bg-faces
|
||||||
|
:background "red" :weight bold)))
|
||||||
|
|
||||||
|
;; You may utilise `doom-themes's theme API to fetch or tweak colors from their
|
||||||
|
;; palettes. No need to wait until the theme or package is loaded. e.g.
|
||||||
|
(custom-theme-set-faces! 'doom-one
|
||||||
|
`(outline-1 :foreground ,(doom-color 'red))
|
||||||
|
`(outline-2 :background ,(doom-color 'blue)))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* TODO defer-feature!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
* TODO defer-until!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
* disable-packages!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
;; Disable packages enabled by DOOM
|
||||||
|
(disable-packages! some-package second-package)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* doom!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
(doom! :completion
|
||||||
|
company
|
||||||
|
ivy
|
||||||
|
;;helm
|
||||||
|
|
||||||
|
:tools
|
||||||
|
(:if (featurep :system 'macos) macos)
|
||||||
|
docker
|
||||||
|
lsp
|
||||||
|
|
||||||
|
:lang
|
||||||
|
(cc +lsp)
|
||||||
|
(:cond ((string= system-name "work-pc")
|
||||||
|
python
|
||||||
|
rust
|
||||||
|
web)
|
||||||
|
((string= system-name "writing-pc")
|
||||||
|
(org +dragndrop)
|
||||||
|
ruby))
|
||||||
|
(:if (featurep :system 'linux)
|
||||||
|
(web +lsp)
|
||||||
|
web)
|
||||||
|
|
||||||
|
:config
|
||||||
|
literate
|
||||||
|
(default +bindings +smartparens))
|
||||||
|
|
||||||
|
(doom!
|
||||||
|
(pin "v3.0.0")
|
||||||
|
|
||||||
|
(source "modules/") ; Modules in $DOOMDIR/modules/*/*
|
||||||
|
(source :name doom :repo "doomemacs/modules" :pin "v21.12.0") ; Doom's default modules
|
||||||
|
(source :name contrib :repo "doomemacs/contrib-modules" :pin "v21.12.0") ; Community-contributed
|
||||||
|
;; Examples:
|
||||||
|
(source :name my :repo "my/modules" :root "unorthodox/path/to/modules/")
|
||||||
|
(source :name more :host gitlab :repo "more/modules")
|
||||||
|
|
||||||
|
;;; To enable (or disable) flags globally, they can be given at top-level:
|
||||||
|
+lsp -tree-sitter
|
||||||
|
|
||||||
|
;;;; Examples of explicit and/or remote modules:
|
||||||
|
:lang
|
||||||
|
(rust :repo "doomemacs/modules" :branch "somePR" :pin "1a2b3c4d"
|
||||||
|
:path "lang/rust"
|
||||||
|
:flags '(-lsp))
|
||||||
|
;; A local, out-of-tree module
|
||||||
|
(python :path "/nonstandard/location/for/modules/python"
|
||||||
|
:flags '(+pyenv +conda))
|
||||||
|
(cc :source 'doom) ; explicit source
|
||||||
|
(agda :source '(doom more)) ; multiple sources
|
||||||
|
|
||||||
|
:lang
|
||||||
|
(clojure +lsp) ; shorthand format still works for flags
|
||||||
|
nix
|
||||||
|
|
||||||
|
;; Conditional modules
|
||||||
|
(:os :if (featurep :system 'macos)) ; category-wide
|
||||||
|
macos
|
||||||
|
(tty :if (equal (system-name) "headless-machine")) ; per-module
|
||||||
|
|
||||||
|
...)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* file-exists-p!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(file-exists-p! "init.el" doom-emacs-dir)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(file-exists-p! (and (or "doesnotexist" "init.el")
|
||||||
|
"LICENSE")
|
||||||
|
doom-emacs-dir)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* fn!
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(mapcar (fn! (symbol-name %)) '(hello world))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(seq-sort (fn! (string-lessp (symbol-name %1)
|
||||||
|
(symbol-name %2)))
|
||||||
|
'(bonzo foo bar buddy doomguy baz zombies))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(format "You passed %d arguments to this function"
|
||||||
|
(funcall (fn! (length %*)) :foo :bar :baz "hello" 123 t))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* kbd!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
(map! "," (kbd! "SPC")
|
||||||
|
";" (kbd! ":"))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* lambda!
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(mapcar (lambda! ((&key foo bar baz))
|
||||||
|
(list foo bar baz))
|
||||||
|
'((:foo 10 :bar 25)
|
||||||
|
(:baz hello :boop nil)
|
||||||
|
(:bar 42)))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* load!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
;;; Lets say we're in ~/.doom.d/config.el
|
||||||
|
(load! "lisp/module") ; loads ~/.doom.d/lisp/module.el
|
||||||
|
(load! "somefile" doom-emacs-dir) ; loads ~/.emacs.d/somefile.el
|
||||||
|
(load! "anotherfile" doom-user-dir) ; loads ~/.doom.d/anotherfile.el
|
||||||
|
|
||||||
|
;; If you don't want a `load!' call to throw an error if the file doesn't exist:
|
||||||
|
(load! "~/.maynotexist" nil t)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* map!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
(map! :map magit-mode-map
|
||||||
|
:m "C-r" 'do-something ; C-r in motion state
|
||||||
|
:nv "q" 'magit-mode-quit-window ; q in normal+visual states
|
||||||
|
"C-x C-r" 'a-global-keybind
|
||||||
|
:g "C-x C-r" 'another-global-keybind ; same as above
|
||||||
|
|
||||||
|
(:when (featurep :system 'macos)
|
||||||
|
:n "M-s" 'some-fn
|
||||||
|
:i "M-o" (cmd! (message "Hi"))))
|
||||||
|
|
||||||
|
(map! (:when (modulep! :completion company) ; Conditional loading
|
||||||
|
:i "C-@" #'+company/complete
|
||||||
|
(:prefix "C-x" ; Use a prefix key
|
||||||
|
:i "C-l" #'+company/whole-lines)))
|
||||||
|
|
||||||
|
(map! (:when (modulep! :lang latex) ; local conditional
|
||||||
|
(:map LaTeX-mode-map
|
||||||
|
:localleader ; Use local leader
|
||||||
|
:desc "View" "v" #'TeX-view)) ; Add which-key description
|
||||||
|
:leader ; Use leader key from now on
|
||||||
|
:desc "Eval expression" ";" #'eval-expression)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
These are side-by-side comparisons, showing how to bind keys with and without
|
||||||
|
~map!~:
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
;; bind a global key
|
||||||
|
(global-set-key (kbd "C-x y") #'do-something)
|
||||||
|
(map! "C-x y" #'do-something)
|
||||||
|
|
||||||
|
;; bind a key on a keymap
|
||||||
|
(define-key emacs-lisp-mode-map (kbd "C-c p") #'do-something)
|
||||||
|
(map! :map emacs-lisp-mode-map "C-c p" #'do-something)
|
||||||
|
|
||||||
|
;; unbind a key defined elsewhere
|
||||||
|
(define-key lua-mode-map (kbd "SPC m b") nil)
|
||||||
|
(map! :map lua-mode-map "SPC m b" nil)
|
||||||
|
|
||||||
|
;; bind multiple keys
|
||||||
|
(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)
|
||||||
|
|
||||||
|
;; bind global keys in normal mode
|
||||||
|
(evil-define-key* 'normal 'global
|
||||||
|
(kbd "C-x x") #'do-something
|
||||||
|
(kbd "C-x y") #'do-something-else
|
||||||
|
(kbd "C-x z") #'do-another-thing)
|
||||||
|
(map! :n "C-x x" #'do-something
|
||||||
|
:n "C-x y" #'do-something-else
|
||||||
|
:n "C-x z" #'do-another-thing)
|
||||||
|
|
||||||
|
;; or on a deferred keymap
|
||||||
|
(evil-define-key 'normal emacs-lisp-mode-map
|
||||||
|
(kbd "C-x x") #'do-something
|
||||||
|
(kbd "C-x y") #'do-something-else
|
||||||
|
(kbd "C-x z") #'do-another-thing)
|
||||||
|
(map! :map emacs-lisp-mode-map
|
||||||
|
:n "C-x x" #'do-something
|
||||||
|
:n "C-x y" #'do-something-else
|
||||||
|
:n "C-x z" #'do-another-thing)
|
||||||
|
|
||||||
|
;; or multiple maps
|
||||||
|
(dolist (map (list emacs-lisp-mode go-mode-map ivy-minibuffer-map))
|
||||||
|
(evil-define-key '(normal insert) map
|
||||||
|
"a" #'a
|
||||||
|
"b" #'b
|
||||||
|
"c" #'c))
|
||||||
|
(map! :map (emacs-lisp-mode go-mode-map ivy-minibuffer-map)
|
||||||
|
:ni "a" #'a
|
||||||
|
:ni "b" #'b
|
||||||
|
:ni "c" #'c)
|
||||||
|
|
||||||
|
;; or in multiple states (order of states doesn't matter)
|
||||||
|
(evil-define-key* '(normal visual) emacs-lisp-mode-map (kbd "C-x x") #'do-something)
|
||||||
|
(evil-define-key* 'insert emacs-lisp-mode-map (kbd "C-x x") #'do-something-else)
|
||||||
|
(evil-define-key* '(visual normal insert emacs) emacs-lisp-mode-map (kbd "C-x z") #'do-another-thing)
|
||||||
|
(map! :map emacs-lisp-mode
|
||||||
|
:nv "C-x x" #'do-something ; normal+visual
|
||||||
|
:i "C-x y" #'do-something-else ; insert
|
||||||
|
:vnie "C-x z" #'do-another-thing) ; visual+normal+insert+emacs
|
||||||
|
|
||||||
|
;; You can nest map! calls:
|
||||||
|
(evil-define-key* '(normal visual) emacs-lisp-mode-map (kbd "C-x x") #'do-something)
|
||||||
|
(evil-define-key* 'normal go-lisp-mode-map (kbd "C-x x") #'do-something-else)
|
||||||
|
(map! (:map emacs-lisp-mode :nv "C-x x" #'do-something)
|
||||||
|
(:map go-lisp-mode :n "C-x x" #'do-something-else))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* package!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
;; To install a package that can be found on ELPA or any of the sources
|
||||||
|
;; specified in `straight-recipe-repositories':
|
||||||
|
(package! evil)
|
||||||
|
(package! js2-mode)
|
||||||
|
(package! rainbow-delimiters)
|
||||||
|
|
||||||
|
;; To disable a package included with Doom (which will no-op all its `after!'
|
||||||
|
;; and `use-package!' blocks):
|
||||||
|
(package! evil :disable t)
|
||||||
|
(package! rainbow-delimiters :disable t)
|
||||||
|
|
||||||
|
;; To install a package from a github repo
|
||||||
|
(package! so-long :host 'github :repo "hlissner/emacs-so-long")
|
||||||
|
|
||||||
|
;; If a package is particularly big and comes with submodules you don't need,
|
||||||
|
;; you can tell the package manager not to clone the repo recursively:
|
||||||
|
(package! ansible :nonrecursive t)
|
||||||
|
|
||||||
|
;; To pin a package to a specific commit:
|
||||||
|
(package! evil :pin "e7bc39de2f9")
|
||||||
|
;; ...or branch:
|
||||||
|
(package! evil :branch "stable")
|
||||||
|
;; 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
|
||||||
|
* prependq!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(let ((x '(a b c)))
|
||||||
|
(prependq! x '(c d e))
|
||||||
|
x)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: (c d e a b c)
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(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)
|
||||||
|
|
||||||
|
* pushnew!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(let ((list '(a b c)))
|
||||||
|
(pushnew! list 'c 'd 'e)
|
||||||
|
list)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: (e d a b c)
|
||||||
|
|
||||||
|
* quiet!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
;; Enters recentf-mode without extra output
|
||||||
|
(quiet! (recentf-mode +1))
|
||||||
|
#+end_src
|
||||||
|
* remove-hook!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
;; With only one hook and one function, this is identical to `remove-hook'. In
|
||||||
|
;; that case, use that instead.
|
||||||
|
(remove-hook! 'some-mode-hook #'enable-something)
|
||||||
|
|
||||||
|
;; Removing N functions from M hooks
|
||||||
|
(remove-hook! some-mode #'enable-something #'and-another)
|
||||||
|
(remove-hook! some-mode #'(enable-something and-another))
|
||||||
|
(remove-hook! '(one-mode-hook second-mode-hook) #'enable-something)
|
||||||
|
(remove-hook! (one-mode second-mode) #'enable-something)
|
||||||
|
|
||||||
|
;; Removing buffer-local hooks
|
||||||
|
(remove-hook! (one-mode second-mode) :local #'enable-something)
|
||||||
|
|
||||||
|
;; 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!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
;; 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!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
;; Set multiple variables after a hook
|
||||||
|
(setq-hook! 'markdown-mode-hook
|
||||||
|
line-spacing 2
|
||||||
|
fill-column 80)
|
||||||
|
|
||||||
|
;; Set variables after multiple hooks
|
||||||
|
(setq-hook! '(eshell-mode-hook term-mode-hook)
|
||||||
|
hscroll-margin 0)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* unsetq-hook!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
(unsetq-hook! 'markdown-mode-hook line-spacing)
|
||||||
|
|
||||||
|
;; Removes the following variable hook
|
||||||
|
(setq-hook! 'markdown-mode-hook line-spacing 2)
|
||||||
|
|
||||||
|
;; Removing N variables from M hooks
|
||||||
|
(unsetq-hook! some-mode enable-something and-another)
|
||||||
|
(unsetq-hook! some-mode (enable-something and-another))
|
||||||
|
(unsetq-hook! '(one-mode-hook second-mode-hook) enable-something)
|
||||||
|
(unsetq-hook! (one-mode second-mode) enable-something)
|
||||||
|
#+end_src
|
||||||
|
* use-package!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp :eval no
|
||||||
|
;; Use after-call to load package before hook
|
||||||
|
(use-package! projectile
|
||||||
|
:after-call (pre-command-hook after-find-file dired-before-readin-hook))
|
||||||
|
|
||||||
|
;; defer recentf packages one by one
|
||||||
|
(use-package! recentf
|
||||||
|
:defer-incrementally easymenu tree-widget timer
|
||||||
|
:after-call after-find-file)
|
||||||
|
|
||||||
|
;; This is equivalent to :defer-incrementally (abc)
|
||||||
|
(use-package! abc
|
||||||
|
:defer-incrementally t)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* versionp!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(versionp! "25.3" > "27.1")
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: nil
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(versionp! "28.0" <= emacs-version <= "28.1")
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: t
|
|
@ -25,22 +25,22 @@
|
||||||
|
|
||||||
;; HACK: Load `cl' and site files manually to prevent polluting logs and
|
;; HACK: Load `cl' and site files manually to prevent polluting logs and
|
||||||
;; stdout with deprecation and/or file load messages.
|
;; stdout with deprecation and/or file load messages.
|
||||||
(let ((inhibit-message (not init-file-debug)))
|
(quiet!
|
||||||
(require 'cl nil t)
|
(require 'cl nil t)
|
||||||
(unless site-run-file
|
(unless site-run-file
|
||||||
(let ((site-run-file "site-start")
|
(let ((site-run-file "site-start")
|
||||||
(tail load-path)
|
(tail load-path)
|
||||||
(lispdir (expand-file-name "../lisp" data-directory))
|
(lispdir (expand-file-name "../lisp" data-directory))
|
||||||
dir)
|
dir)
|
||||||
(while tail
|
(while tail
|
||||||
(setq dir (car tail))
|
(setq dir (car tail))
|
||||||
(let ((default-directory dir))
|
(let ((default-directory dir))
|
||||||
(load (expand-file-name "subdirs.el") t inhibit-message t))
|
(load (expand-file-name "subdirs.el") t inhibit-message t))
|
||||||
(unless (string-prefix-p lispdir dir)
|
(unless (string-prefix-p lispdir dir)
|
||||||
(let ((default-directory dir))
|
(let ((default-directory dir))
|
||||||
(load (expand-file-name "leim-list.el") t inhibit-message t)))
|
(load (expand-file-name "leim-list.el") t inhibit-message t)))
|
||||||
(setq tail (cdr tail)))
|
(setq tail (cdr tail)))
|
||||||
(load site-run-file t inhibit-message))))
|
(load site-run-file t inhibit-message))))
|
||||||
|
|
||||||
(setq-default
|
(setq-default
|
||||||
;; PERF: Don't generate superfluous files when writing temp buffers.
|
;; PERF: Don't generate superfluous files when writing temp buffers.
|
||||||
|
@ -92,15 +92,14 @@
|
||||||
:group 'doom)
|
:group 'doom)
|
||||||
|
|
||||||
(defvar doom-cli-load-path
|
(defvar doom-cli-load-path
|
||||||
(let ((paths (split-string (or (getenv "DOOMPATH") "") path-separator)))
|
(append (when-let ((doompath (getenv "DOOMPATH")))
|
||||||
(if (member "" paths)
|
(cl-loop for dir in (split-string doompath path-separator)
|
||||||
(cl-substitute (doom-path (dir!) "cli/") "" paths :test #'equal)
|
collect (expand-file-name dir)))
|
||||||
paths))
|
(list (file-name-concat (dir!) "cli")))
|
||||||
"A list of paths to search for autoloaded Doom CLIs.
|
"A list of paths to search for autoloaded Doom CLIs.
|
||||||
|
|
||||||
It is prefilled by the DOOMPATH envvar (a colon-separated list on Linux/macOS,
|
It is prefilled by the DOOMPATH envvar (a colon-separated list on Linux/macOS,
|
||||||
semicolon otherwise). Empty entries in DOOMPATH are replaced with the
|
semicolon otherwise).")
|
||||||
$EMACSDIR/cli/.")
|
|
||||||
|
|
||||||
;;; CLI definition variables
|
;;; CLI definition variables
|
||||||
(defvar doom-cli-argument-types
|
(defvar doom-cli-argument-types
|
||||||
|
@ -1050,9 +1049,9 @@ considered as well."
|
||||||
"\n")))
|
"\n")))
|
||||||
(print! (warn "Wrote extended straight log to %s")
|
(print! (warn "Wrote extended straight log to %s")
|
||||||
(path (let ((coding-system-for-write 'utf-8-auto))
|
(path (let ((coding-system-for-write 'utf-8-auto))
|
||||||
(with-temp-file error-file
|
(with-file-modes #o600
|
||||||
(insert-buffer-substring (straight--process-buffer)))
|
(with-temp-file error-file
|
||||||
(set-file-modes error-file #o600)
|
(insert-buffer-substring (straight--process-buffer))))
|
||||||
error-file))))
|
error-file))))
|
||||||
((eq type 'error)
|
((eq type 'error)
|
||||||
(let* ((generic? (eq (car data) 'error))
|
(let* ((generic? (eq (car data) 'error))
|
||||||
|
@ -1123,11 +1122,12 @@ See `doom-cli-log-file-format' for details."
|
||||||
(let* ((buffer (doom-cli-context-stderr context))
|
(let* ((buffer (doom-cli-context-stderr context))
|
||||||
(file (doom-cli--output-file "log" context)))
|
(file (doom-cli--output-file "log" context)))
|
||||||
(when (> (buffer-size buffer) 0)
|
(when (> (buffer-size buffer) 0)
|
||||||
(make-directory (file-name-directory file) t)
|
(with-file-modes #o700
|
||||||
(with-temp-file file
|
(make-directory (file-name-directory file) t))
|
||||||
(insert-buffer-substring buffer)
|
(with-file-modes #o600
|
||||||
(ansi-color-filter-region (point-min) (point-max)))
|
(with-temp-file file
|
||||||
(set-file-modes file #o600)))))
|
(insert-buffer-substring buffer)
|
||||||
|
(ansi-color-filter-region (point-min) (point-max))))))))
|
||||||
|
|
||||||
(defun doom-cli--output-benchmark-h (context)
|
(defun doom-cli--output-benchmark-h (context)
|
||||||
"Write this session's benchmark to stdout or stderr, depending.
|
"Write this session's benchmark to stdout or stderr, depending.
|
||||||
|
@ -1351,10 +1351,11 @@ ARGS are options passed to less. If DOOMPAGER is set, ARGS are ignored."
|
||||||
|
|
||||||
((let ((tmpfile (doom-cli--output-file 'output context))
|
((let ((tmpfile (doom-cli--output-file 'output context))
|
||||||
(coding-system-for-write 'utf-8-auto))
|
(coding-system-for-write 'utf-8-auto))
|
||||||
(make-directory (file-name-directory tmpfile) t)
|
(with-file-modes #o700
|
||||||
(with-temp-file tmpfile
|
(make-directory (file-name-directory tmpfile) t))
|
||||||
(insert-buffer-substring (doom-cli-context-stdout context)))
|
(with-file-modes #o600
|
||||||
(set-file-modes tmpfile #o600)
|
(with-temp-file tmpfile
|
||||||
|
(insert-buffer-substring (doom-cli-context-stdout context))))
|
||||||
(doom-cli--restart
|
(doom-cli--restart
|
||||||
(format "%s <%s; rm -f%s %s"
|
(format "%s <%s; rm -f%s %s"
|
||||||
(or pager
|
(or pager
|
||||||
|
@ -1782,7 +1783,7 @@ See `defcli!' for information about COMMANDSPEC.
|
||||||
TARGET is simply a command list.
|
TARGET is simply a command list.
|
||||||
WHEN specifies what version this command was rendered obsolete."
|
WHEN specifies what version this command was rendered obsolete."
|
||||||
`(let ((ncommand (doom-cli-command-normalize (backquote ,target) doom-cli--group-plist)))
|
`(let ((ncommand (doom-cli-command-normalize (backquote ,target) doom-cli--group-plist)))
|
||||||
(defcli! ,commandspec (&context context &cli cli &rest args)
|
(defcli! ,commandspec (&context _context &cli cli &rest args)
|
||||||
:docs (format "An obsolete alias for '%s'." (doom-cli-command-string ncommand))
|
:docs (format "An obsolete alias for '%s'." (doom-cli-command-string ncommand))
|
||||||
:hide t
|
:hide t
|
||||||
(print! (warn "'%s' was deprecated in %s")
|
(print! (warn "'%s' was deprecated in %s")
|
||||||
|
|
|
@ -3,9 +3,12 @@
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(defvar doom-detect-indentation-excluded-modes
|
(defvar doom-detect-indentation-excluded-modes
|
||||||
'(fundamental-mode pascal-mode so-long-mode doom-docs-org-mode)
|
'(pascal-mode
|
||||||
"A list of major modes in which indentation should be automatically
|
so-long-mode
|
||||||
detected.")
|
;; Automatic indent detection in org files is meaningless. Not to mention, a
|
||||||
|
;; non-standard `tab-width' causes an error in org-mode.
|
||||||
|
org-mode)
|
||||||
|
"A list of major modes where indentation shouldn't be auto-detected.")
|
||||||
|
|
||||||
(defvar-local doom-inhibit-indent-detection nil
|
(defvar-local doom-inhibit-indent-detection nil
|
||||||
"A buffer-local flag that indicates whether `dtrt-indent' should try to detect
|
"A buffer-local flag that indicates whether `dtrt-indent' should try to detect
|
||||||
|
@ -130,7 +133,8 @@ or file path may exist now."
|
||||||
(let ((buffer (or (buffer-base-buffer) (current-buffer))))
|
(let ((buffer (or (buffer-base-buffer) (current-buffer))))
|
||||||
(and (buffer-file-name buffer)
|
(and (buffer-file-name buffer)
|
||||||
(eq buffer (window-buffer (selected-window))) ; only visible buffers
|
(eq buffer (window-buffer (selected-window))) ; only visible buffers
|
||||||
(set-auto-mode))))))
|
(set-auto-mode)
|
||||||
|
(not (eq major-mode 'fundamental-mode)))))))
|
||||||
|
|
||||||
(defadvice! doom--shut-up-autosave-a (fn &rest args)
|
(defadvice! doom--shut-up-autosave-a (fn &rest args)
|
||||||
"If a file has autosaved data, `after-find-file' will pause for 1 second to
|
"If a file has autosaved data, `after-find-file' will pause for 1 second to
|
||||||
|
@ -402,6 +406,11 @@ the unwritable tidbits."
|
||||||
(unless doom-large-file-p
|
(unless doom-large-file-p
|
||||||
(apply fn args)))
|
(apply fn args)))
|
||||||
|
|
||||||
|
(defadvice! doom--inhibit-saveplace-if-point-not-at-bol-a (&rest _)
|
||||||
|
"If something else has moved point, don't try to move it again."
|
||||||
|
:before-while #'save-place-find-file-hook
|
||||||
|
(bobp))
|
||||||
|
|
||||||
(defadvice! doom--dont-prettify-saveplace-cache-a (fn)
|
(defadvice! doom--dont-prettify-saveplace-cache-a (fn)
|
||||||
"`save-place-alist-to-file' uses `pp' to prettify the contents of its cache.
|
"`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
|
`pp' can be expensive for longer lists, and there's no reason to prettify cache
|
||||||
|
@ -501,8 +510,9 @@ files, so this replace calls to `pp' with the much faster `prin1'."
|
||||||
(unless (or (not after-init-time)
|
(unless (or (not after-init-time)
|
||||||
doom-inhibit-indent-detection
|
doom-inhibit-indent-detection
|
||||||
doom-large-file-p
|
doom-large-file-p
|
||||||
(memq major-mode doom-detect-indentation-excluded-modes)
|
(eq major-mode 'fundamental-mode)
|
||||||
(member (substring (buffer-name) 0 1) '(" " "*")))
|
(member (substring (buffer-name) 0 1) '(" " "*"))
|
||||||
|
(apply #'derived-mode-p doom-detect-indentation-excluded-modes))
|
||||||
;; Don't display messages in the echo area, but still log them
|
;; Don't display messages in the echo area, but still log them
|
||||||
(let ((inhibit-message (not init-file-debug)))
|
(let ((inhibit-message (not init-file-debug)))
|
||||||
(dtrt-indent-mode +1))))
|
(dtrt-indent-mode +1))))
|
||||||
|
@ -583,11 +593,9 @@ current buffer."
|
||||||
filename))
|
filename))
|
||||||
(prog1 (apply fn args)
|
(prog1 (apply fn args)
|
||||||
(when (buffer-live-p buf)
|
(when (buffer-live-p buf)
|
||||||
(with-current-buffer buf (goto-char pos)))))))))
|
(with-current-buffer buf (goto-char pos))))))))
|
||||||
|
:config
|
||||||
|
(setq helpful-set-variable-function #'setq!))
|
||||||
;;;###package imenu
|
|
||||||
(add-hook 'imenu-after-jump-hook #'recenter)
|
|
||||||
|
|
||||||
|
|
||||||
(use-package! smartparens
|
(use-package! smartparens
|
||||||
|
|
|
@ -15,6 +15,12 @@
|
||||||
"An alternative leader prefix key, used for Insert and Emacs states, and for
|
"An alternative leader prefix key, used for Insert and Emacs states, and for
|
||||||
non-evil users.")
|
non-evil users.")
|
||||||
|
|
||||||
|
(defvar doom-leader-key-states '(normal visual motion)
|
||||||
|
"which evil modes to activate the leader key for")
|
||||||
|
|
||||||
|
(defvar doom-leader-alt-key-states '(emacs insert)
|
||||||
|
"which evil modes to activate the alternative leader key for")
|
||||||
|
|
||||||
(defvar doom-localleader-key "SPC m"
|
(defvar doom-localleader-key "SPC m"
|
||||||
"The localleader prefix key, for major-mode specific commands.")
|
"The localleader prefix key, for major-mode specific commands.")
|
||||||
|
|
||||||
|
@ -35,7 +41,7 @@ and Emacs states, and for non-evil users.")
|
||||||
;;; Global keybind settings
|
;;; Global keybind settings
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
(IS-MAC
|
(doom--system-macos-p
|
||||||
;; mac-* variables are used by the special emacs-mac build of Emacs by
|
;; mac-* variables are used by the special emacs-mac build of Emacs by
|
||||||
;; Yamamoto Mitsuharu, while other builds use ns-*.
|
;; Yamamoto Mitsuharu, while other builds use ns-*.
|
||||||
(setq mac-command-modifier 'super
|
(setq mac-command-modifier 'super
|
||||||
|
@ -45,18 +51,18 @@ and Emacs states, and for non-evil users.")
|
||||||
;; Free up the right option for character composition
|
;; Free up the right option for character composition
|
||||||
mac-right-option-modifier 'none
|
mac-right-option-modifier 'none
|
||||||
ns-right-option-modifier 'none))
|
ns-right-option-modifier 'none))
|
||||||
(IS-WINDOWS
|
(doom--system-windows-p
|
||||||
(setq w32-lwindow-modifier 'super
|
(setq w32-lwindow-modifier 'super
|
||||||
w32-rwindow-modifier 'super)))
|
w32-rwindow-modifier 'super)))
|
||||||
|
|
||||||
;; HACK: Emacs cannot distinguish between C-i from TAB. This is largely a
|
;; HACK: Emacs cannot distinguish between C-i from TAB. This is largely a
|
||||||
;; byproduct of its history in the terminal, which can't distinguish them
|
;; byproduct of its history in the terminal, which can't distinguish them
|
||||||
;; either, however, when GUIs came about Emacs greated separate input events
|
;; either, however, when GUIs came about Emacs created separate input events
|
||||||
;; for more contentious keys like TAB and RET. Therefore [return] != RET,
|
;; for more contentious keys like TAB and RET. Therefore [return] != RET,
|
||||||
;; [tab] != TAB, and [backspace] != DEL.
|
;; [tab] != TAB, and [backspace] != DEL.
|
||||||
;;
|
;;
|
||||||
;; In the same vein, this keybind adds a [C-i] event, so users can bind to it.
|
;; In the same vein, this keybind adds a [C-i] event, so users can bind to it
|
||||||
;; Otherwise, it falls back to regular C-i keybinds.
|
;; independently of TAB. Otherwise, it falls back to keys bound to C-i.
|
||||||
(define-key key-translation-map [?\C-i]
|
(define-key key-translation-map [?\C-i]
|
||||||
(cmd! (if (let ((keys (this-single-command-raw-keys)))
|
(cmd! (if (let ((keys (this-single-command-raw-keys)))
|
||||||
(and keys
|
(and keys
|
||||||
|
@ -98,19 +104,20 @@ all hooks after it are ignored.")
|
||||||
(defun doom/escape (&optional interactive)
|
(defun doom/escape (&optional interactive)
|
||||||
"Run `doom-escape-hook'."
|
"Run `doom-escape-hook'."
|
||||||
(interactive (list 'interactive))
|
(interactive (list 'interactive))
|
||||||
(cond ((minibuffer-window-active-p (minibuffer-window))
|
(let ((inhibit-quit t))
|
||||||
;; quit the minibuffer if open.
|
(cond ((minibuffer-window-active-p (minibuffer-window))
|
||||||
(when interactive
|
;; quit the minibuffer if open.
|
||||||
(setq this-command 'abort-recursive-edit))
|
|
||||||
(abort-recursive-edit))
|
|
||||||
;; Run all escape hooks. If any returns non-nil, then stop there.
|
|
||||||
((run-hook-with-args-until-success 'doom-escape-hook))
|
|
||||||
;; don't abort macros
|
|
||||||
((or defining-kbd-macro executing-kbd-macro) nil)
|
|
||||||
;; Back to the default
|
|
||||||
((unwind-protect (keyboard-quit)
|
|
||||||
(when interactive
|
(when interactive
|
||||||
(setq this-command 'keyboard-quit))))))
|
(setq this-command 'abort-recursive-edit))
|
||||||
|
(abort-recursive-edit))
|
||||||
|
;; Run all escape hooks. If any returns non-nil, then stop there.
|
||||||
|
((run-hook-with-args-until-success 'doom-escape-hook))
|
||||||
|
;; don't abort macros
|
||||||
|
((or defining-kbd-macro executing-kbd-macro) nil)
|
||||||
|
;; Back to the default
|
||||||
|
((unwind-protect (keyboard-quit)
|
||||||
|
(when interactive
|
||||||
|
(setq this-command 'keyboard-quit)))))))
|
||||||
|
|
||||||
(global-set-key [remap keyboard-quit] #'doom/escape)
|
(global-set-key [remap keyboard-quit] #'doom/escape)
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
;;; Custom error types
|
;;; Custom error types
|
||||||
(define-error 'doom-error "An unexpected Doom error")
|
(define-error 'doom-error "An unexpected Doom error")
|
||||||
|
(define-error 'doom-font-error "Could not find a font on your system" 'doom-error)
|
||||||
(define-error 'doom-nosync-error "Doom hasn't been initialized yet; did you remember to run 'doom sync' in the shell?" 'doom-error)
|
(define-error 'doom-nosync-error "Doom hasn't been initialized yet; did you remember to run 'doom sync' in the shell?" 'doom-error)
|
||||||
(define-error 'doom-core-error "Unexpected error in Doom's core" 'doom-error)
|
(define-error 'doom-core-error "Unexpected error in Doom's core" 'doom-error)
|
||||||
(define-error 'doom-hook-error "Error in a Doom startup hook" 'doom-error)
|
(define-error 'doom-hook-error "Error in a Doom startup hook" 'doom-error)
|
||||||
|
@ -302,9 +303,9 @@ TRIGGER-HOOK is a list of quoted hooks and/or sharp-quoted functions."
|
||||||
(error "file!: cannot deduce the current file path")))
|
(error "file!: cannot deduce the current file path")))
|
||||||
|
|
||||||
(defmacro dir! ()
|
(defmacro dir! ()
|
||||||
"Return the directory of the file this macro was called."
|
"Return the directory of the file in which this macro was called."
|
||||||
(let (file-name-handler-alist)
|
(let (file-name-handler-alist)
|
||||||
(file-name-directory (macroexpand '(file!)))))
|
(file-name-directory (macroexpand '(file!)))))
|
||||||
|
|
||||||
;; REVIEW Should I deprecate this? The macro's name is so long...
|
;; REVIEW Should I deprecate this? The macro's name is so long...
|
||||||
(defalias 'letenv! 'with-environment-variables)
|
(defalias 'letenv! 'with-environment-variables)
|
||||||
|
@ -801,7 +802,7 @@ This macro accepts, in order:
|
||||||
func-forms)))
|
func-forms)))
|
||||||
`(progn
|
`(progn
|
||||||
,@defn-forms
|
,@defn-forms
|
||||||
(dolist (hook (nreverse ',hook-forms))
|
(dolist (hook ',(nreverse hook-forms))
|
||||||
(dolist (func (list ,@func-forms))
|
(dolist (func (list ,@func-forms))
|
||||||
,(if remove-p
|
,(if remove-p
|
||||||
`(remove-hook hook func ,local-p)
|
`(remove-hook hook func ,local-p)
|
||||||
|
@ -882,16 +883,16 @@ testing advice (when combined with `rotate-text').
|
||||||
(dolist (target (cdr targets))
|
(dolist (target (cdr targets))
|
||||||
(advice-remove target #',symbol)))))
|
(advice-remove target #',symbol)))))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Backports
|
||||||
|
|
||||||
(defmacro defbackport! (type symbol &rest body)
|
(defmacro defbackport! (type symbol &rest body)
|
||||||
"Backport a function/macro/alias from later versions of Emacs."
|
"Backport a function/macro/alias from later versions of Emacs."
|
||||||
(declare (indent defun) (doc-string 4))
|
(declare (indent defun) (doc-string 4))
|
||||||
(unless (fboundp (doom-unquote symbol))
|
(unless (fboundp (doom-unquote symbol))
|
||||||
`(,type ,symbol ,@body)))
|
`(,type ,symbol ,@body)))
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;;; Backports
|
|
||||||
|
|
||||||
;; `format-spec' wasn't autoloaded until 28.1
|
;; `format-spec' wasn't autoloaded until 28.1
|
||||||
(defbackport! autoload 'format-spec "format-spec")
|
(defbackport! autoload 'format-spec "format-spec")
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,19 @@
|
||||||
(defvar doom-modules (make-hash-table :test 'equal)
|
(defvar doom-modules (make-hash-table :test 'equal)
|
||||||
"A hash table of enabled modules. Set by `doom-initialize-modules'.")
|
"A hash table of enabled modules. Set by `doom-initialize-modules'.")
|
||||||
|
|
||||||
(defvar doom-modules-dirs
|
(define-obsolete-variable-alias 'doom-modules-dirs 'doom-module-load-path "3.0.0")
|
||||||
(list (expand-file-name "modules/" doom-user-dir)
|
(defvar doom-module-load-path
|
||||||
doom-modules-dir)
|
(list (file-name-concat doom-user-dir "modules")
|
||||||
"A list of module root directories. Order determines priority.")
|
(file-name-concat doom-emacs-dir "modules"))
|
||||||
|
"A list of paths where Doom should search for modules.
|
||||||
|
|
||||||
|
Order determines priority (from highest to lowest).
|
||||||
|
|
||||||
|
Each entry is a string; an absolute path to the root directory of a module tree.
|
||||||
|
In other words, they should contain a two-level nested directory structure,
|
||||||
|
where the module's group and name was deduced from the first and second level of
|
||||||
|
directories. For example: if $DOOMDIR/modules/ is an entry, a
|
||||||
|
$DOOMDIR/modules/lang/ruby/ directory represents a ':lang ruby' module.")
|
||||||
|
|
||||||
;;; Module file variables
|
;;; Module file variables
|
||||||
(defvar doom-module-init-file "init.el"
|
(defvar doom-module-init-file "init.el"
|
||||||
|
@ -41,6 +50,8 @@ NOT IMPLEMENTED YET. This file contains a module's metadata: their version,
|
||||||
maintainers, checks, features, submodules, debug information, etc. And are used
|
maintainers, checks, features, submodules, debug information, etc. And are used
|
||||||
to locate modules in the user's file tree.")
|
to locate modules in the user's file tree.")
|
||||||
|
|
||||||
|
;; DEPRECATED: Module warnings will be rewritten in v3, and this variable will no longer be needed.
|
||||||
|
(make-obsolete-variable 'doom-obsolete-modules nil "3.0.0")
|
||||||
(defconst doom-obsolete-modules
|
(defconst doom-obsolete-modules
|
||||||
'((:feature (version-control (:emacs vc) (:ui vc-gutter))
|
'((:feature (version-control (:emacs vc) (:ui vc-gutter))
|
||||||
(spellcheck (:checkers spell))
|
(spellcheck (:checkers spell))
|
||||||
|
@ -83,6 +94,7 @@ syntax-checker modules obsolete. e.g. If :feature version-control is found in
|
||||||
your `doom!' block, a warning is emitted before replacing it with :emacs vc and
|
your `doom!' block, a warning is emitted before replacing it with :emacs vc and
|
||||||
:ui vc-gutter.")
|
:ui vc-gutter.")
|
||||||
|
|
||||||
|
(make-obsolete-variable 'doom-inhibit-module-warnings nil "3.0.0")
|
||||||
(defvar doom-inhibit-module-warnings (not noninteractive)
|
(defvar doom-inhibit-module-warnings (not noninteractive)
|
||||||
"If non-nil, don't emit deprecated or missing module warnings at startup.")
|
"If non-nil, don't emit deprecated or missing module warnings at startup.")
|
||||||
|
|
||||||
|
@ -111,12 +123,12 @@ your `doom!' block, a warning is emitted before replacing it with :emacs vc and
|
||||||
;;
|
;;
|
||||||
;;; `doom-module-context'
|
;;; `doom-module-context'
|
||||||
|
|
||||||
(defvar doom--empty-module-context [nil nil nil nil nil nil nil])
|
(defvar doom-module--empty-context [nil nil nil nil nil nil nil])
|
||||||
|
|
||||||
(eval-and-compile
|
(eval-and-compile
|
||||||
(setplist 'doom-module-context '(index 0 initdepth 1 configdepth 2
|
(put 'doom-module-context 'keys '(:index 0 :initdepth 1 :configdepth 2
|
||||||
group 3 name 4 flags 5 features 6)))
|
:group 3 :name 4 :flags 5 :features 6)))
|
||||||
(defvar doom-module-context doom--empty-module-context
|
(defvar doom-module-context doom-module--empty-context
|
||||||
"A vector describing the module associated it with the active context.
|
"A vector describing the module associated it with the active context.
|
||||||
|
|
||||||
Contains the following: [INDEX INITDEPTH CONFIGDEPTH :GROUP MODULE FLAGS FEATURES]
|
Contains the following: [INDEX INITDEPTH CONFIGDEPTH :GROUP MODULE FLAGS FEATURES]
|
||||||
|
@ -124,7 +136,8 @@ Contains the following: [INDEX INITDEPTH CONFIGDEPTH :GROUP MODULE FLAGS FEATURE
|
||||||
Do not directly set this variable, only let-bind it.")
|
Do not directly set this variable, only let-bind it.")
|
||||||
|
|
||||||
;; DEPRECATED: Remove this when byte-compilation is introduced to Doom core.
|
;; DEPRECATED: Remove this when byte-compilation is introduced to Doom core.
|
||||||
(defmacro doom-module--context-field (field) (get 'doom-module-context field))
|
(defmacro doom-module--context-field (field)
|
||||||
|
(plist-get (get 'doom-module-context 'keys) field))
|
||||||
|
|
||||||
(defun doom-module-context-get (field &optional context)
|
(defun doom-module-context-get (field &optional context)
|
||||||
"Return the FIELD of CONTEXT.
|
"Return the FIELD of CONTEXT.
|
||||||
|
@ -132,7 +145,9 @@ Do not directly set this variable, only let-bind it.")
|
||||||
FIELD should be one of `index', `initdepth', `configdepth', `group', `name',
|
FIELD should be one of `index', `initdepth', `configdepth', `group', `name',
|
||||||
`flags', or `features'. CONTEXT should be a `doom-module-context' vector. If
|
`flags', or `features'. CONTEXT should be a `doom-module-context' vector. If
|
||||||
omitted, defaults to `doom-module-context'."
|
omitted, defaults to `doom-module-context'."
|
||||||
(aref (or context doom-module-context) (get 'doom-module-context field)))
|
(aref (or context doom-module-context)
|
||||||
|
(plist-get (get 'doom-module-context 'keys)
|
||||||
|
field)))
|
||||||
|
|
||||||
(defun doom-module-context (group &optional name)
|
(defun doom-module-context (group &optional name)
|
||||||
"Create a `doom-module-context' from a module by GROUP and NAME.
|
"Create a `doom-module-context' from a module by GROUP and NAME.
|
||||||
|
@ -142,14 +157,14 @@ If NAME is omitted, GROUP is treated as a module key cons cell: (GROUP . NAME)."
|
||||||
(let ((key (if name (cons group name) group)))
|
(let ((key (if name (cons group name) group)))
|
||||||
(or (get (or (car-safe key) key)
|
(or (get (or (car-safe key) key)
|
||||||
(cdr-safe key))
|
(cdr-safe key))
|
||||||
doom--empty-module-context)))
|
doom-module--empty-context)))
|
||||||
|
|
||||||
(defun doom-module-context-key (&optional context)
|
(defun doom-module-context-key (&optional context)
|
||||||
"Return the module of the active `doom-module-context' as a module key."
|
"Return the module of the active `doom-module-context' as a module key."
|
||||||
(declare (side-effect-free t))
|
(declare (side-effect-free t))
|
||||||
(let ((context (or context doom-module-context)))
|
(let ((context (or context doom-module-context)))
|
||||||
(cons (aref context (doom-module--context-field group))
|
(cons (aref context (doom-module--context-field :group))
|
||||||
(aref context (doom-module--context-field name)))))
|
(aref context (doom-module--context-field :name)))))
|
||||||
|
|
||||||
(defmacro doom-module-context-with (module-key &rest body)
|
(defmacro doom-module-context-with (module-key &rest body)
|
||||||
"Evaluate BODY with `doom-module-context' informed by MODULE-KEY."
|
"Evaluate BODY with `doom-module-context' informed by MODULE-KEY."
|
||||||
|
@ -252,7 +267,7 @@ If PLIST consists of a single nil, the module is purged from memory instead."
|
||||||
|
|
||||||
PATHS-OR-ALL can either be a non-nil value or a list of directories. If given a
|
PATHS-OR-ALL can either be a non-nil value or a list of directories. If given a
|
||||||
list of directories, return a list of module keys for all modules present
|
list of directories, return a list of module keys for all modules present
|
||||||
underneath it. If non-nil, return the same, but search `doom-modules-dirs'
|
underneath it. If non-nil, return the same, but search `doom-module-load-path'
|
||||||
(includes :core and :user). Modules that are enabled are sorted first by their
|
(includes :core and :user). Modules that are enabled are sorted first by their
|
||||||
:depth, followed by disabled modules in lexicographical order (unless a :depth
|
:depth, followed by disabled modules in lexicographical order (unless a :depth
|
||||||
is specified in their .doommodule).
|
is specified in their .doommodule).
|
||||||
|
@ -264,7 +279,7 @@ configdepth. See `doom-module-set' for details."
|
||||||
(append (seq-remove #'cdr (doom-module-list nil initorder?))
|
(append (seq-remove #'cdr (doom-module-list nil initorder?))
|
||||||
(doom-files-in (if (listp paths-or-all)
|
(doom-files-in (if (listp paths-or-all)
|
||||||
paths-or-all
|
paths-or-all
|
||||||
doom-modules-dirs)
|
doom-module-load-path)
|
||||||
:map #'doom-module-from-path
|
:map #'doom-module-from-path
|
||||||
:type 'dirs
|
:type 'dirs
|
||||||
:mindepth 1
|
:mindepth 1
|
||||||
|
@ -294,7 +309,7 @@ If the category isn't enabled this returns nil. For finding disabled modules use
|
||||||
path)))
|
path)))
|
||||||
|
|
||||||
(defun doom-module-locate-path (category &optional module file)
|
(defun doom-module-locate-path (category &optional module file)
|
||||||
"Searches `doom-modules-dirs' to find the path to a module.
|
"Searches `doom-module-load-path' to find the path to a module.
|
||||||
|
|
||||||
CATEGORY is a keyword (e.g. :lang) and MODULE is a symbol (e.g. 'python). FILE
|
CATEGORY is a keyword (e.g. :lang) and MODULE is a symbol (e.g. 'python). FILE
|
||||||
is a string that will be appended to the resulting path. If no path exists, this
|
is a string that will be appended to the resulting path. If no path exists, this
|
||||||
|
@ -310,8 +325,8 @@ returns nil, otherwise an absolute path."
|
||||||
(if file
|
(if file
|
||||||
;; PERF: locate-file-internal is a little faster for finding files,
|
;; PERF: locate-file-internal is a little faster for finding files,
|
||||||
;; but its interface for finding directories is clumsy.
|
;; but its interface for finding directories is clumsy.
|
||||||
(locate-file-internal path doom-modules-dirs '("" ".elc" ".el"))
|
(locate-file-internal path doom-module-load-path '("" ".elc" ".el"))
|
||||||
(cl-loop for default-directory in doom-modules-dirs
|
(cl-loop for default-directory in doom-module-load-path
|
||||||
if (file-exists-p path)
|
if (file-exists-p path)
|
||||||
return (expand-file-name path)))))))
|
return (expand-file-name path)))))))
|
||||||
|
|
||||||
|
@ -320,8 +335,7 @@ returns nil, otherwise an absolute path."
|
||||||
|
|
||||||
MODULE-LIST is a list of cons cells (GROUP . NAME). See `doom-module-list' for
|
MODULE-LIST is a list of cons cells (GROUP . NAME). See `doom-module-list' for
|
||||||
an example."
|
an example."
|
||||||
(cl-loop with file = (file-name-sans-extension file)
|
(cl-loop for (group . name) in (or module-list (doom-module-list))
|
||||||
for (group . name) in module-list
|
|
||||||
if (doom-module-locate-path group name file)
|
if (doom-module-locate-path group name file)
|
||||||
collect it))
|
collect it))
|
||||||
|
|
||||||
|
@ -342,14 +356,15 @@ If ENABLED-ONLY, return nil if the containing module isn't enabled."
|
||||||
((file-in-directory-p path doom-user-dir)
|
((file-in-directory-p path doom-user-dir)
|
||||||
(cons :user nil))))))
|
(cons :user nil))))))
|
||||||
|
|
||||||
(defun doom-module-load-path (&optional module-dirs)
|
(defun doom-module-load-path (&optional module-load-path)
|
||||||
"Return a list of file paths to activated modules.
|
"Return a list of file paths to activated modules.
|
||||||
|
|
||||||
The list is in no particular order and its file paths are absolute. If
|
The list is in no particular order and its file paths are absolute. If
|
||||||
MODULE-DIRS is non-nil, include all modules (even disabled ones) available in
|
MODULE-DIRS is non-nil, include all modules (even disabled ones) available in
|
||||||
those directories."
|
those directories."
|
||||||
(declare (pure t) (side-effect-free t))
|
(declare (pure t) (side-effect-free t))
|
||||||
(cl-loop for (cat . mod) in (doom-module-list module-dirs)
|
(cl-loop with module-load-path = (or module-load-path doom-module-load-path)
|
||||||
|
for (cat . mod) in (doom-module-list module-load-path)
|
||||||
collect (doom-module-locate-path cat mod)))
|
collect (doom-module-locate-path cat mod)))
|
||||||
|
|
||||||
(defun doom-module-mplist-map (fn mplist)
|
(defun doom-module-mplist-map (fn mplist)
|
||||||
|
@ -462,20 +477,20 @@ For more about modules and flags, see `doom!'."
|
||||||
;; PERF: This macro bypasses the module API to spare startup their runtime
|
;; PERF: This macro bypasses the module API to spare startup their runtime
|
||||||
;; cost, as `modulep!' gets called *a lot* during startup. In the future,
|
;; cost, as `modulep!' gets called *a lot* during startup. In the future,
|
||||||
;; Doom will byte-compile its core files. At that time, we can use it again.
|
;; Doom will byte-compile its core files. At that time, we can use it again.
|
||||||
(and (cond (flag (memq flag (aref (or (get category module) doom--empty-module-context)
|
(and (cond (flag (memq flag (aref (or (get category module) doom-module--empty-context)
|
||||||
(doom-module--context-field flags))))
|
(doom-module--context-field :flags))))
|
||||||
(module (get category module))
|
(module (get category module))
|
||||||
((aref doom-module-context 0)
|
((aref doom-module-context 0)
|
||||||
(memq category (aref doom-module-context
|
(memq category (aref doom-module-context
|
||||||
(doom-module--context-field flags))))
|
(doom-module--context-field :flags))))
|
||||||
((let ((file
|
((let ((file
|
||||||
;; This must be expanded at the call site, not in
|
;; This must be expanded at the call site, not in
|
||||||
;; `modulep!'s definition, to get the file we want.
|
;; `modulep!'s definition, to get the file we want.
|
||||||
(macroexpand '(file!))))
|
(macroexpand '(file!))))
|
||||||
(if-let (module (doom-module-from-path file))
|
(if-let (module (doom-module-from-path file))
|
||||||
(memq category (aref (or (get (car module) (cdr module))
|
(memq category (aref (or (get (car module) (cdr module))
|
||||||
doom--empty-module-context)
|
doom-module--empty-context)
|
||||||
(doom-module--context-field flags)))
|
(doom-module--context-field :flags)))
|
||||||
(error "(modulep! %s %s %s) couldn't figure out what module it was called from (in %s)"
|
(error "(modulep! %s %s %s) couldn't figure out what module it was called from (in %s)"
|
||||||
category module flag file)))))
|
category module flag file)))))
|
||||||
t))
|
t))
|
||||||
|
|
|
@ -119,11 +119,11 @@ uses a straight or package.el command directly).")
|
||||||
(append (apply fn args) ; lockfiles still take priority
|
(append (apply fn args) ; lockfiles still take priority
|
||||||
(doom-package-pinned-list)))
|
(doom-package-pinned-list)))
|
||||||
|
|
||||||
;; HACK: This fixes an issue present in recent builds of Emacs 29. See
|
;; HACK: This fixes an issue introduced in emacs-mirror/emacs@0d383b592c2f and
|
||||||
;; emacs-mirror/emacs@0d383b592c2f. Straight.el uses `loaddefs-generate' if it
|
;; is present in >=29: Straight.el uses `loaddefs-generate' if it is
|
||||||
;; is available, which activates `emacs-lisp-mode' to read autoloads files,
|
;; available, which activates `emacs-lisp-mode' to read autoloads files, but
|
||||||
;; but does so without suppressing its hooks. Some packages (like overseer)
|
;; does so without suppressing its hooks. Some packages (like overseer) add
|
||||||
;; add hooks to `emacs-lisp-mode-hook' in their autoloads, and once triggered,
|
;; hooks to `emacs-lisp-mode-hook' in their autoloads, and once triggered,
|
||||||
;; they will try to load their dependencies (like dash or pkg-info), causing
|
;; they will try to load their dependencies (like dash or pkg-info), causing
|
||||||
;; file errors.
|
;; file errors.
|
||||||
;; REVIEW: Report this upstream.
|
;; REVIEW: Report this upstream.
|
||||||
|
|
|
@ -343,7 +343,7 @@ Defaults to the profile at `doom-profile-default'."
|
||||||
";; This file was autogenerated; do not edit it by hand!\n")
|
";; This file was autogenerated; do not edit it by hand!\n")
|
||||||
;; Doom needs to be synced/rebuilt if either Doom or Emacs has been
|
;; Doom needs to be synced/rebuilt if either Doom or Emacs has been
|
||||||
;; up/downgraded. This is because byte-code isn't backwards
|
;; up/downgraded. This is because byte-code isn't backwards
|
||||||
;; compatible, and many packages (including Doom), make in absolute
|
;; compatible, and many packages (including Doom), bake in absolute
|
||||||
;; paths into their caches that need to be refreshed.
|
;; paths into their caches that need to be refreshed.
|
||||||
(prin1 `(unless (equal doom-version ,doom-version)
|
(prin1 `(unless (equal doom-version ,doom-version)
|
||||||
(error ,(concat
|
(error ,(concat
|
||||||
|
@ -368,7 +368,8 @@ Defaults to the profile at `doom-profile-default'."
|
||||||
;; FIX: Make sure this only runs at startup to protect us Emacs' interpreter
|
;; FIX: Make sure this only runs at startup to protect us Emacs' interpreter
|
||||||
;; re-evaluating this file when lazy-loading dynamic docstrings from the
|
;; re-evaluating this file when lazy-loading dynamic docstrings from the
|
||||||
;; byte-compiled init file.
|
;; byte-compiled init file.
|
||||||
`((when (doom-context-p 'init)
|
`((when (or (doom-context-p 'init)
|
||||||
|
(doom-context-p 'reload))
|
||||||
,@(cl-loop for var in doom-autoloads-cached-vars
|
,@(cl-loop for var in doom-autoloads-cached-vars
|
||||||
if (boundp var)
|
if (boundp var)
|
||||||
collect `(set-default ',var ',(symbol-value var)))
|
collect `(set-default ',var ',(symbol-value var)))
|
||||||
|
@ -439,7 +440,7 @@ Defaults to the profile at `doom-profile-default'."
|
||||||
(doom-autoloads--scan
|
(doom-autoloads--scan
|
||||||
(append (doom-glob doom-core-dir "lib/*.el")
|
(append (doom-glob doom-core-dir "lib/*.el")
|
||||||
(cl-loop for dir
|
(cl-loop for dir
|
||||||
in (append (doom-module-load-path doom-modules-dirs)
|
in (append (doom-module-load-path)
|
||||||
(list doom-user-dir))
|
(list doom-user-dir))
|
||||||
if (doom-glob dir "autoload.el") collect (car it)
|
if (doom-glob dir "autoload.el") collect (car it)
|
||||||
if (doom-glob dir "autoload/*.el") append it)
|
if (doom-glob dir "autoload/*.el") append it)
|
||||||
|
@ -449,8 +450,8 @@ Defaults to the profile at `doom-profile-default'."
|
||||||
(defun doom-profile--generate-package-autoloads ()
|
(defun doom-profile--generate-package-autoloads ()
|
||||||
(doom-autoloads--scan
|
(doom-autoloads--scan
|
||||||
(mapcar #'straight--autoloads-file
|
(mapcar #'straight--autoloads-file
|
||||||
(seq-difference (hash-table-keys straight--build-cache)
|
(nreverse (seq-difference (hash-table-keys straight--build-cache)
|
||||||
doom-autoloads-excluded-packages))
|
doom-autoloads-excluded-packages)))
|
||||||
doom-autoloads-excluded-files
|
doom-autoloads-excluded-files
|
||||||
'literal))
|
'literal))
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,10 @@ debian, and derivatives). On most it's 'fd'.")
|
||||||
;;
|
;;
|
||||||
;;; Packages
|
;;; Packages
|
||||||
|
|
||||||
|
(after! project
|
||||||
|
(setq project-list-file (file-name-concat doom-data-dir "projects")))
|
||||||
|
|
||||||
|
;; DEPRECATED: Will be replaced with project.el
|
||||||
(use-package! projectile
|
(use-package! projectile
|
||||||
:commands (projectile-project-root
|
:commands (projectile-project-root
|
||||||
projectile-project-name
|
projectile-project-name
|
||||||
|
@ -147,7 +151,7 @@ c) are not valid projectile projects."
|
||||||
(projectile-serialize-cache))))
|
(projectile-serialize-cache))))
|
||||||
|
|
||||||
;; Some MSYS utilities auto expanded the `/' path separator, so we need to prevent it.
|
;; Some MSYS utilities auto expanded the `/' path separator, so we need to prevent it.
|
||||||
(when IS-WINDOWS
|
(when doom--system-windows-p
|
||||||
(setenv "MSYS_NO_PATHCONV" "1") ; Fix path in Git Bash
|
(setenv "MSYS_NO_PATHCONV" "1") ; Fix path in Git Bash
|
||||||
(setenv "MSYS2_ARG_CONV_EXCL" "--path-separator")) ; Fix path in MSYS2
|
(setenv "MSYS2_ARG_CONV_EXCL" "--path-separator")) ; Fix path in MSYS2
|
||||||
|
|
||||||
|
@ -192,11 +196,11 @@ And if it's a function, evaluate it."
|
||||||
(concat (format "%s . -0 -H --color=never --type file --type symlink --follow --exclude .git %s"
|
(concat (format "%s . -0 -H --color=never --type file --type symlink --follow --exclude .git %s"
|
||||||
bin (if (version< version "8.3.0")
|
bin (if (version< version "8.3.0")
|
||||||
"" "--strip-cwd-prefix"))
|
"" "--strip-cwd-prefix"))
|
||||||
(if IS-WINDOWS " --path-separator=/"))))
|
(if doom--system-windows-p " --path-separator=/"))))
|
||||||
;; Otherwise, resort to ripgrep, which is also faster than find
|
;; Otherwise, resort to ripgrep, which is also faster than find
|
||||||
((executable-find "rg" t)
|
((executable-find "rg" t)
|
||||||
(concat "rg -0 --files --follow --color=never --hidden -g!.git"
|
(concat "rg -0 --files --follow --color=never --hidden -g!.git"
|
||||||
(if IS-WINDOWS " --path-separator=/")))
|
(if doom--system-windows-p " --path-separator=/")))
|
||||||
("find . -type f -print0"))))
|
("find . -type f -print0"))))
|
||||||
|
|
||||||
(defadvice! doom--projectile-default-generic-command-a (fn &rest args)
|
(defadvice! doom--projectile-default-generic-command-a (fn &rest args)
|
||||||
|
|
|
@ -100,13 +100,15 @@
|
||||||
|
|
||||||
;;; Disable UI elements early
|
;;; Disable UI elements early
|
||||||
;; PERF,UI: Doom strives to be keyboard-centric, so I consider these UI elements
|
;; PERF,UI: Doom strives to be keyboard-centric, so I consider these UI elements
|
||||||
;; clutter. Initializing them also costs a morsel of startup time. Whats more,
|
;; clutter. Initializing them also costs a morsel of startup time. What's
|
||||||
;; the menu bar exposes functionality that Doom doesn't endorse. Perhaps one
|
;; more, the menu bar exposes functionality that Doom doesn't endorse. Perhaps
|
||||||
;; day Doom will support these, but today is not that day.
|
;; one day Doom will support these, but today is not that day. By disabling
|
||||||
;;
|
;; them early, we save Emacs some time.
|
||||||
|
|
||||||
;; HACK: I intentionally avoid calling `menu-bar-mode', `tool-bar-mode', and
|
;; HACK: I intentionally avoid calling `menu-bar-mode', `tool-bar-mode', and
|
||||||
;; `scroll-bar-mode' because they do extra work to manipulate frame variables
|
;; `scroll-bar-mode' because their manipulation of frame parameters can
|
||||||
;; that isn't necessary this early in the startup process.
|
;; trigger/queue a superfluous (and expensive, depending on the window system)
|
||||||
|
;; frame redraw at startup.
|
||||||
(push '(menu-bar-lines . 0) default-frame-alist)
|
(push '(menu-bar-lines . 0) default-frame-alist)
|
||||||
(push '(tool-bar-lines . 0) default-frame-alist)
|
(push '(tool-bar-lines . 0) default-frame-alist)
|
||||||
(push '(vertical-scroll-bars) default-frame-alist)
|
(push '(vertical-scroll-bars) default-frame-alist)
|
||||||
|
@ -119,8 +121,8 @@
|
||||||
;; non-application window -- which means it doesn't automatically capture
|
;; non-application window -- which means it doesn't automatically capture
|
||||||
;; focus when it is started, among other things, so enable the menu-bar for
|
;; focus when it is started, among other things, so enable the menu-bar for
|
||||||
;; GUI frames, but keep it disabled in terminal frames because there it
|
;; GUI frames, but keep it disabled in terminal frames because there it
|
||||||
;; activates an ugly, in-frame menu bar.
|
;; unavoidably activates an ugly, in-frame menu bar.
|
||||||
(eval-when! IS-MAC
|
(eval-when! doom--system-macos-p
|
||||||
(add-hook! '(window-setup-hook after-make-frame-functions)
|
(add-hook! '(window-setup-hook after-make-frame-functions)
|
||||||
(defun doom-restore-menu-bar-in-gui-frames-h (&optional frame)
|
(defun doom-restore-menu-bar-in-gui-frames-h (&optional frame)
|
||||||
(when-let (frame (or frame (selected-frame)))
|
(when-let (frame (or frame (selected-frame)))
|
||||||
|
@ -136,8 +138,8 @@
|
||||||
;; a step too opinionated.
|
;; a step too opinionated.
|
||||||
(setq default-input-method nil)
|
(setq default-input-method nil)
|
||||||
;; ...And the clipboard on Windows could be in a wider encoding (UTF-16), so
|
;; ...And the clipboard on Windows could be in a wider encoding (UTF-16), so
|
||||||
;; leave Emacs to its own devices.
|
;; leave Emacs to its own devices there.
|
||||||
(eval-when! IS-WINDOWS
|
(eval-when! (not doom--system-windows-p)
|
||||||
(setq selection-coding-system 'utf-8))
|
(setq selection-coding-system 'utf-8))
|
||||||
|
|
||||||
|
|
||||||
|
@ -180,7 +182,7 @@
|
||||||
(defvar doom-incremental-packages '(t)
|
(defvar doom-incremental-packages '(t)
|
||||||
"A list of packages to load incrementally after startup. Any large packages
|
"A list of packages to load incrementally after startup. Any large packages
|
||||||
here may cause noticeable pauses, so it's recommended you break them up into
|
here may cause noticeable pauses, so it's recommended you break them up into
|
||||||
sub-packages. For example, `org' is comprised of many packages, and can be
|
sub-packages. For example, `org' is comprised of many packages, and might be
|
||||||
broken up into:
|
broken up into:
|
||||||
|
|
||||||
(doom-load-packages-incrementally
|
(doom-load-packages-incrementally
|
||||||
|
@ -192,16 +194,16 @@ broken up into:
|
||||||
This is already done by the lang/org module, however.
|
This is already done by the lang/org module, however.
|
||||||
|
|
||||||
If you want to disable incremental loading altogether, either remove
|
If you want to disable incremental loading altogether, either remove
|
||||||
`doom-load-packages-incrementally-h' from `emacs-startup-hook' or set
|
`doom-load-packages-incrementally-h' from `doom-after-init-hook' or set
|
||||||
`doom-incremental-first-idle-timer' to nil. Incremental loading does not occur
|
`doom-incremental-first-idle-timer' to nil. Incremental loading does not occur
|
||||||
in daemon sessions (they are loaded immediately at startup).")
|
in daemon sessions (they are loaded immediately at startup).")
|
||||||
|
|
||||||
(defvar doom-incremental-first-idle-timer (if (daemonp) 0 2.0)
|
(defvar doom-incremental-first-idle-timer (if (daemonp) 0 2.0)
|
||||||
"How long (in idle seconds) until incremental loading starts.
|
"How long (in idle seconds) until incremental loading starts.
|
||||||
|
|
||||||
Set this to nil to disable incremental loading.
|
Set this to nil to disable incremental loading at startup.
|
||||||
Set this to 0 to load all incrementally deferred packages immediately at
|
Set this to 0 to load all incrementally deferred packages immediately at
|
||||||
`emacs-startup-hook'.")
|
`doom-after-init-hook'.")
|
||||||
|
|
||||||
(defvar doom-incremental-idle-timer 0.75
|
(defvar doom-incremental-idle-timer 0.75
|
||||||
"How long (in idle seconds) in between incrementally loading packages.")
|
"How long (in idle seconds) in between incrementally loading packages.")
|
||||||
|
@ -209,9 +211,13 @@ Set this to 0 to load all incrementally deferred packages immediately at
|
||||||
(defun doom-load-packages-incrementally (packages &optional now)
|
(defun doom-load-packages-incrementally (packages &optional now)
|
||||||
"Registers PACKAGES to be loaded incrementally.
|
"Registers PACKAGES to be loaded incrementally.
|
||||||
|
|
||||||
If NOW is non-nil, load PACKAGES incrementally, in `doom-incremental-idle-timer'
|
If NOW is non-nil, PACKAGES will be marked for incremental loading next time
|
||||||
intervals."
|
Emacs is idle for `doom-incremental-first-idle-timer' seconds (falls back to
|
||||||
(let ((gc-cons-threshold most-positive-fixnum))
|
`doom-incremental-idle-timer'), then in `doom-incremental-idle-timer' intervals
|
||||||
|
afterwards."
|
||||||
|
(let* ((gc-cons-threshold most-positive-fixnum)
|
||||||
|
(first-idle-timer (or doom-incremental-first-idle-timer
|
||||||
|
doom-incremental-idle-timer)))
|
||||||
(if (not now)
|
(if (not now)
|
||||||
(cl-callf append doom-incremental-packages packages)
|
(cl-callf append doom-incremental-packages packages)
|
||||||
(while packages
|
(while packages
|
||||||
|
@ -222,7 +228,7 @@ intervals."
|
||||||
(condition-case-unless-debug e
|
(condition-case-unless-debug e
|
||||||
(and
|
(and
|
||||||
(or (null (setq idle-time (current-idle-time)))
|
(or (null (setq idle-time (current-idle-time)))
|
||||||
(< (float-time idle-time) doom-incremental-first-idle-timer)
|
(< (float-time idle-time) first-idle-timer)
|
||||||
(not
|
(not
|
||||||
(while-no-input
|
(while-no-input
|
||||||
(doom-log "start:iloader: Loading %s (%d left)" req (length packages))
|
(doom-log "start:iloader: Loading %s (%d left)" req (length packages))
|
||||||
|
@ -242,7 +248,7 @@ intervals."
|
||||||
(doom-log "start:iloader: Finished!")
|
(doom-log "start:iloader: Finished!")
|
||||||
(run-at-time (if idle-time
|
(run-at-time (if idle-time
|
||||||
doom-incremental-idle-timer
|
doom-incremental-idle-timer
|
||||||
doom-incremental-first-idle-timer)
|
first-idle-timer)
|
||||||
nil #'doom-load-packages-incrementally
|
nil #'doom-load-packages-incrementally
|
||||||
packages t)
|
packages t)
|
||||||
(setq packages nil))))))))
|
(setq packages nil))))))))
|
||||||
|
|
210
lisp/doom-ui.el
210
lisp/doom-ui.el
|
@ -5,13 +5,13 @@
|
||||||
;;
|
;;
|
||||||
;;; Variables
|
;;; Variables
|
||||||
|
|
||||||
(defvar doom-theme nil
|
(defcustom doom-theme nil
|
||||||
"A symbol representing the Emacs theme to load at startup.
|
"A symbol representing the Emacs theme to load at startup.
|
||||||
|
|
||||||
Set to `nil' to load no theme at all. This variable is changed by
|
Set to `nil' to load no theme at all. This variable is changed by
|
||||||
`load-theme'.")
|
`load-theme'.")
|
||||||
|
|
||||||
(defvar doom-font nil
|
(defcustom doom-font nil
|
||||||
"The default font to use.
|
"The default font to use.
|
||||||
Must be a `font-spec', a font object, an XFT font string, or an XLFD string.
|
Must be a `font-spec', a font object, an XFT font string, or an XLFD string.
|
||||||
|
|
||||||
|
@ -22,60 +22,72 @@ Examples:
|
||||||
(setq doom-font \"Terminus (TTF):pixelsize=12:antialias=off\")
|
(setq doom-font \"Terminus (TTF):pixelsize=12:antialias=off\")
|
||||||
(setq doom-font \"Fira Code-14\")")
|
(setq doom-font \"Fira Code-14\")")
|
||||||
|
|
||||||
(defvar doom-variable-pitch-font nil
|
(defcustom doom-variable-pitch-font nil
|
||||||
"The default font to use for variable-pitch text.
|
"The default font to use for variable-pitch text.
|
||||||
Must be a `font-spec', a font object, an XFT font string, or an XLFD string. See
|
Must be a `font-spec', a font object, an XFT font string, or an XLFD string. See
|
||||||
`doom-font' for examples.
|
`doom-font' for examples.
|
||||||
|
|
||||||
An omitted font size means to inherit `doom-font''s size.")
|
An omitted font size means to inherit `doom-font''s size.")
|
||||||
|
|
||||||
(defvar doom-serif-font nil
|
(defcustom doom-serif-font nil
|
||||||
"The default font to use for the `fixed-pitch-serif' face.
|
"The default font to use for the `fixed-pitch-serif' face.
|
||||||
Must be a `font-spec', a font object, an XFT font string, or an XLFD string. See
|
Must be a `font-spec', a font object, an XFT font string, or an XLFD string. See
|
||||||
`doom-font' for examples.
|
`doom-font' for examples.
|
||||||
|
|
||||||
An omitted font size means to inherit `doom-font''s size.")
|
An omitted font size means to inherit `doom-font''s size.")
|
||||||
|
|
||||||
(defvar doom-unicode-font nil
|
(defcustom doom-symbol-font nil
|
||||||
"Fallback font for Unicode glyphs.
|
"Fallback font for symbols.
|
||||||
Must be a `font-spec', a font object, an XFT font string, or an XLFD string. See
|
Must be a `font-spec', a font object, an XFT font string, or an XLFD string. See
|
||||||
`doom-font' for examples.
|
`doom-font' for examples. Emacs defaults to Symbola.
|
||||||
|
|
||||||
The defaults on macOS and Linux are Apple Color Emoji and Symbola, respectively.
|
|
||||||
|
|
||||||
WARNING: if you specify a size for this font it will hard-lock any usage of this
|
WARNING: if you specify a size for this font it will hard-lock any usage of this
|
||||||
font to that size. It's rarely a good idea to do so!")
|
font to that size. It's rarely a good idea to do so!")
|
||||||
|
|
||||||
(defvar doom-emoji-fallback-font-families
|
(define-obsolete-variable-alias 'doom-unicode-font 'doom-symbol-font "3.0.0")
|
||||||
|
|
||||||
|
(defcustom doom-emoji-font nil
|
||||||
|
"Fallback font for emoji.
|
||||||
|
Must be a `font-spec', a font object, an XFT font string, or an XLFD string. See
|
||||||
|
`doom-font' for examples.
|
||||||
|
|
||||||
|
WARNING: if you specify a size for this font it will hard-lock any usage of this
|
||||||
|
font to that size. It's rarely a good idea to do so!")
|
||||||
|
|
||||||
|
(defconst doom-emoji-fallback-font-families
|
||||||
'("Apple Color Emoji"
|
'("Apple Color Emoji"
|
||||||
"Segoe UI Emoji"
|
"Segoe UI Emoji"
|
||||||
"Noto Color Emoji"
|
"Noto Color Emoji"
|
||||||
"Noto Emoji")
|
"Noto Emoji")
|
||||||
"A list of fallback font families to use for emojis.")
|
"A list of fallback font families to use for emojis.
|
||||||
|
These are platform-specific fallbacks for internal use. If you
|
||||||
|
want to change your emoji font, use `doom-emoji-font'.")
|
||||||
|
|
||||||
(defvar doom-symbol-fallback-font-families
|
(defconst doom-symbol-fallback-font-families
|
||||||
'("Segoe UI Symbol"
|
'("Segoe UI Symbol"
|
||||||
"Apple Symbols")
|
"Apple Symbols")
|
||||||
"A list of fallback font families for general symbol glyphs.")
|
"A list of fallback font families for general symbol glyphs.
|
||||||
|
These are platform-specific fallbacks for internal use. If you
|
||||||
|
want to change your symbol font, use `doom-symbol-font'.")
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;;; Custom hooks
|
;;; Custom hooks
|
||||||
|
|
||||||
(defvar doom-init-ui-hook nil
|
(defcustom doom-init-ui-hook nil
|
||||||
"List of hooks to run when the UI has been initialized.")
|
"List of hooks to run when the UI has been initialized.")
|
||||||
|
|
||||||
(defvar doom-load-theme-hook nil
|
(defcustom doom-load-theme-hook nil
|
||||||
"Hook run after the theme is loaded with `load-theme' or reloaded with
|
"Hook run after the theme is loaded with `load-theme' or reloaded with
|
||||||
`doom/reload-theme'.")
|
`doom/reload-theme'.")
|
||||||
|
|
||||||
(defvar doom-switch-buffer-hook nil
|
(defcustom doom-switch-buffer-hook nil
|
||||||
"A list of hooks run after changing the current buffer.")
|
"A list of hooks run after changing the current buffer.")
|
||||||
|
|
||||||
(defvar doom-switch-window-hook nil
|
(defcustom doom-switch-window-hook nil
|
||||||
"A list of hooks run after changing the focused windows.")
|
"A list of hooks run after changing the focused windows.")
|
||||||
|
|
||||||
(defvar doom-switch-frame-hook nil
|
(defcustom doom-switch-frame-hook nil
|
||||||
"A list of hooks run after changing the focused frame.")
|
"A list of hooks run after changing the focused frame.")
|
||||||
|
|
||||||
(defun doom-run-switch-buffer-hooks-h (&optional _)
|
(defun doom-run-switch-buffer-hooks-h (&optional _)
|
||||||
|
@ -156,8 +168,10 @@ or if the current buffer is read-only or not file-visiting."
|
||||||
;; cursor more than N lines past window edges (where N is the settings of
|
;; cursor more than N lines past window edges (where N is the settings of
|
||||||
;; `scroll-conservatively'). This is especially slow in larger files
|
;; `scroll-conservatively'). This is especially slow in larger files
|
||||||
;; during large-scale scrolling commands. If kept over 100, the window is
|
;; during large-scale scrolling commands. If kept over 100, the window is
|
||||||
;; never automatically recentered.
|
;; never automatically recentered. The default (0) triggers this too
|
||||||
scroll-conservatively 101
|
;; aggressively, so I've set it to 10 to recenter if scrolling too far
|
||||||
|
;; off-screen.
|
||||||
|
scroll-conservatively 10
|
||||||
scroll-margin 0
|
scroll-margin 0
|
||||||
scroll-preserve-screen-position t
|
scroll-preserve-screen-position t
|
||||||
;; Reduce cursor lag by a tiny bit by not auto-adjusting `window-vscroll'
|
;; Reduce cursor lag by a tiny bit by not auto-adjusting `window-vscroll'
|
||||||
|
@ -196,10 +210,7 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
||||||
`kill-current-buffer'."
|
`kill-current-buffer'."
|
||||||
:before-until #'kill-current-buffer
|
:before-until #'kill-current-buffer
|
||||||
(let ((buf (current-buffer)))
|
(let ((buf (current-buffer)))
|
||||||
(cond ((window-dedicated-p)
|
(cond ((eq buf (doom-fallback-buffer))
|
||||||
(delete-window)
|
|
||||||
t)
|
|
||||||
((eq buf (doom-fallback-buffer))
|
|
||||||
(message "Can't kill the fallback buffer.")
|
(message "Can't kill the fallback buffer.")
|
||||||
t)
|
t)
|
||||||
((doom-real-buffer-p buf)
|
((doom-real-buffer-p buf)
|
||||||
|
@ -314,9 +325,10 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
||||||
(setq compilation-always-kill t ; kill compilation process before starting another
|
(setq compilation-always-kill t ; kill compilation process before starting another
|
||||||
compilation-ask-about-save nil ; save all buffers on `compile'
|
compilation-ask-about-save nil ; save all buffers on `compile'
|
||||||
compilation-scroll-output 'first-error)
|
compilation-scroll-output 'first-error)
|
||||||
;; Handle ansi codes in compilation buffer
|
(add-hook 'compilation-filter-hook
|
||||||
;; DEPRECATED Use `ansi-color-compilation-filter' when dropping 27.x support
|
(if (< emacs-major-version 28)
|
||||||
(add-hook 'compilation-filter-hook #'doom-apply-ansi-color-to-compilation-buffer-h)
|
#'doom-apply-ansi-color-to-compilation-buffer-h
|
||||||
|
#'ansi-color-compilation-filter))
|
||||||
;; Automatically truncate compilation buffers so they don't accumulate too
|
;; Automatically truncate compilation buffers so they don't accumulate too
|
||||||
;; much data and bog down the rest of Emacs.
|
;; much data and bog down the rest of Emacs.
|
||||||
(autoload 'comint-truncate-buffer "comint" nil t)
|
(autoload 'comint-truncate-buffer "comint" nil t)
|
||||||
|
@ -417,41 +429,17 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
||||||
;;
|
;;
|
||||||
;;; Third party packages
|
;;; Third party packages
|
||||||
|
|
||||||
(use-package! all-the-icons
|
(use-package! nerd-icons
|
||||||
:commands (all-the-icons-octicon
|
:commands (nerd-icons-octicon
|
||||||
all-the-icons-faicon
|
nerd-icons-faicon
|
||||||
all-the-icons-fileicon
|
nerd-icons-flicon
|
||||||
all-the-icons-wicon
|
nerd-icons-wicon
|
||||||
all-the-icons-material
|
nerd-icons-mdicon
|
||||||
all-the-icons-alltheicon)
|
nerd-icons-codicon
|
||||||
:preface
|
nerd-icons-devicon
|
||||||
(add-hook! 'after-setting-font-hook
|
nerd-icons-ipsicon
|
||||||
(defun doom-init-all-the-icons-fonts-h ()
|
nerd-icons-pomicon
|
||||||
(when (fboundp 'set-fontset-font)
|
nerd-icons-powerline))
|
||||||
(dolist (font (list "Weather Icons"
|
|
||||||
"github-octicons"
|
|
||||||
"FontAwesome"
|
|
||||||
"all-the-icons"
|
|
||||||
"file-icons"
|
|
||||||
"Material Icons"))
|
|
||||||
(set-fontset-font t 'unicode font nil 'append)))))
|
|
||||||
:config
|
|
||||||
(cond ((daemonp)
|
|
||||||
(defadvice! doom--disable-all-the-icons-in-tty-a (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 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)
|
|
||||||
""))))
|
|
||||||
|
|
||||||
;; Hide the mode line in completion popups and MAN pages because they serve
|
;; Hide the mode line in completion popups and MAN pages because they serve
|
||||||
;; little purpose there, and is better hidden.
|
;; little purpose there, and is better hidden.
|
||||||
|
@ -510,49 +498,63 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
||||||
(cons 'custom-theme-directory
|
(cons 'custom-theme-directory
|
||||||
(delq 'custom-theme-directory custom-theme-load-path)))
|
(delq 'custom-theme-directory custom-theme-load-path)))
|
||||||
|
|
||||||
(defun doom--make-font-specs (face font)
|
(defun doom-init-fonts-h (&optional _reload)
|
||||||
(let* ((base-specs (cadr (assq 'user (get face 'theme-face))))
|
"Loads `doom-font', `doom-serif-font', and `doom-variable-pitch-font'."
|
||||||
(base-specs (or base-specs '((t nil))))
|
(let ((this-frame (selected-frame)))
|
||||||
(attrs '(:family :foundry :slant :weight :height :width))
|
(dolist (map `((default . ,doom-font)
|
||||||
(new-specs nil))
|
(fixed-pitch . ,doom-font)
|
||||||
(dolist (spec base-specs)
|
(fixed-pitch-serif . ,doom-serif-font)
|
||||||
;; Each SPEC has the form (DISPLAY ATTRIBUTE-PLIST)
|
(variable-pitch . ,doom-variable-pitch-font)))
|
||||||
(let ((display (car spec))
|
(condition-case e
|
||||||
(plist (copy-tree (nth 1 spec))))
|
(when-let* ((face (car map))
|
||||||
;; Alter only DISPLAY conditions matching this frame.
|
(font (cdr map)))
|
||||||
(when (or (memq display '(t default))
|
(dolist (frame (frame-list))
|
||||||
(face-spec-set-match-display display this-frame))
|
(when (display-multi-font-p frame)
|
||||||
(dolist (attr attrs)
|
(set-face-attribute face frame
|
||||||
(setq plist (plist-put plist attr (face-attribute face attr)))))
|
:width 'normal :weight 'normal
|
||||||
(push (list display plist) new-specs)))
|
:slant 'normal :font font)))
|
||||||
(nreverse new-specs)))
|
(custom-push-theme
|
||||||
|
'theme-face face 'user 'set
|
||||||
(defun doom-init-fonts-h (&optional reload)
|
(let* ((base-specs (cadr (assq 'user (get face 'theme-face))))
|
||||||
"Loads `doom-font'."
|
(base-specs (or base-specs '((t nil))))
|
||||||
(dolist (map `((default . ,doom-font)
|
(attrs '(:family :foundry :slant :weight :height :width))
|
||||||
(fixed-pitch . ,doom-font)
|
(new-specs nil))
|
||||||
(fixed-pitch-serif . ,doom-serif-font)
|
(dolist (spec base-specs)
|
||||||
(variable-pitch . ,doom-variable-pitch-font)))
|
;; Each SPEC has the form (DISPLAY ATTRIBUTE-PLIST)
|
||||||
(when-let* ((face (car map))
|
(let ((display (car spec))
|
||||||
(font (cdr map)))
|
(plist (copy-tree (nth 1 spec))))
|
||||||
(dolist (frame (frame-list))
|
;; Alter only DISPLAY conditions matching this frame.
|
||||||
(when (display-multi-font-p frame)
|
(when (or (memq display '(t default))
|
||||||
(set-face-attribute face frame
|
(face-spec-set-match-display display this-frame))
|
||||||
:width 'normal :weight 'normal
|
(dolist (attr attrs)
|
||||||
:slant 'normal :font font)))
|
(setq plist (plist-put plist attr (face-attribute face attr)))))
|
||||||
(let ((new-specs (doom--make-font-specs face font)))
|
(push (list display plist) new-specs)))
|
||||||
;; Don't save to `customized-face' so it's omitted from `custom-file'
|
(nreverse new-specs)))
|
||||||
;;(put face 'customized-face new-specs)
|
(put face 'face-modified nil))
|
||||||
(custom-push-theme 'theme-face face 'user 'set new-specs)
|
('error
|
||||||
(put face 'face-modified nil))))
|
(ignore-errors (doom--reset-inhibited-vars-h))
|
||||||
|
(if (string-prefix-p "Font not available" (error-message-string e))
|
||||||
|
(signal 'doom-font-error (list (font-get (cdr map) :family)))
|
||||||
|
(signal (car e) (cdr e)))))))
|
||||||
(when (fboundp 'set-fontset-font)
|
(when (fboundp 'set-fontset-font)
|
||||||
(let ((fn (doom-rpartial #'member (font-family-list))))
|
(let* ((fn (doom-rpartial #'member (font-family-list)))
|
||||||
(when-let (font (cl-find-if fn doom-symbol-fallback-font-families))
|
(symbol-font (or doom-symbol-font
|
||||||
(set-fontset-font t 'symbol font))
|
(cl-find-if fn doom-symbol-fallback-font-families)))
|
||||||
(when-let (font (cl-find-if fn doom-emoji-fallback-font-families))
|
(emoji-font (or doom-emoji-font
|
||||||
(set-fontset-font t 'unicode font))
|
(cl-find-if fn doom-emoji-fallback-font-families))))
|
||||||
(when doom-unicode-font
|
(when symbol-font
|
||||||
(set-fontset-font t 'unicode doom-unicode-font))))
|
(dolist (script '(symbol mathematical))
|
||||||
|
(set-fontset-font t script symbol-font)))
|
||||||
|
(when emoji-font
|
||||||
|
;; DEPRECATED: make unconditional when we drop 27 support
|
||||||
|
(when (version<= "28.1" emacs-version)
|
||||||
|
(set-fontset-font t 'emoji emoji-font))
|
||||||
|
;; some characters in the Emacs symbol script are often covered by emoji
|
||||||
|
;; fonts
|
||||||
|
(set-fontset-font t 'symbol emoji-font nil 'append)))
|
||||||
|
;; Nerd Fonts use these Private Use Areas
|
||||||
|
(dolist (range '((#xe000 . #xf8ff) (#xf0000 . #xfffff)))
|
||||||
|
(set-fontset-font t range "Symbols Nerd Font Mono")))
|
||||||
;; Users should inject their own font logic in `after-setting-font-hook'
|
;; Users should inject their own font logic in `after-setting-font-hook'
|
||||||
(run-hooks 'after-setting-font-hook))
|
(run-hooks 'after-setting-font-hook))
|
||||||
|
|
||||||
|
|
340
lisp/doom.el
340
lisp/doom.el
|
@ -59,9 +59,13 @@
|
||||||
;; - On first switched-to buffer: `doom-first-buffer-hook'
|
;; - On first switched-to buffer: `doom-first-buffer-hook'
|
||||||
;; - On first opened file: `doom-first-file-hook'
|
;; - On first opened file: `doom-first-file-hook'
|
||||||
;;
|
;;
|
||||||
;; This is Doom's heart, where I define all its major constants and variables,
|
;; This file is Doom's heart, where I define all its major constants and
|
||||||
;; set only its sanest global defaults, employ its hackiest (and least
|
;; variables, set only its sanest global defaults, employ its hackiest (and
|
||||||
;; offensive) optimizations, and load the minimum for all Doom sessions.
|
;; least offensive) optimizations, and load the minimum needed for all Doom
|
||||||
|
;; sessions, interactive or otherwise.
|
||||||
|
;;
|
||||||
|
;; See doom-start.el for initialization intended solely for interactive
|
||||||
|
;; sessions, and doom-cli.el for non-interactive sessions.
|
||||||
;;
|
;;
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
|
@ -99,7 +103,7 @@
|
||||||
|
|
||||||
;; Doom needs to be synced/rebuilt if either Doom or Emacs has been
|
;; Doom needs to be synced/rebuilt if either Doom or Emacs has been
|
||||||
;; up/downgraded. This is because byte-code isn't backwards compatible, and many
|
;; up/downgraded. This is because byte-code isn't backwards compatible, and many
|
||||||
;; packages (including Doom), make in absolute paths into their caches that need
|
;; packages (including Doom), bake in absolute paths into their caches that need
|
||||||
;; to be refreshed.
|
;; to be refreshed.
|
||||||
(let ((old-version (eval-when-compile emacs-version)))
|
(let ((old-version (eval-when-compile emacs-version)))
|
||||||
(unless (equal emacs-version old-version)
|
(unless (equal emacs-version old-version)
|
||||||
|
@ -107,7 +111,31 @@
|
||||||
"recompile it.")
|
"recompile it.")
|
||||||
emacs-version old-version)))
|
emacs-version old-version)))
|
||||||
|
|
||||||
;;; Custom features
|
;;; Custom features & global constants
|
||||||
|
;; Doom has its own features that its modules, CLI, and user extensions can
|
||||||
|
;; announce, and don't belong in `features', so they are stored here, which can
|
||||||
|
;; include information about the external system environment. Module-specific
|
||||||
|
;; features are kept elsewhere, however.
|
||||||
|
(defconst doom-features
|
||||||
|
(pcase system-type
|
||||||
|
('darwin '(macos bsd))
|
||||||
|
((or 'cygwin 'windows-nt 'ms-dos) '(windows))
|
||||||
|
((or 'gnu 'gnu/linux) '(linux))
|
||||||
|
((or 'gnu/kfreebsd 'berkeley-unix) '(linux bsd)))
|
||||||
|
"A list of symbols denoting available features in the active Doom profile.")
|
||||||
|
|
||||||
|
;; Convenience aliases for internal use only (may be removed later).
|
||||||
|
(defconst doom-system (car doom-features))
|
||||||
|
(defconst doom--system-windows-p (eq 'windows doom-system))
|
||||||
|
(defconst doom--system-macos-p (eq 'macos doom-system))
|
||||||
|
(defconst doom--system-linux-p (eq 'linux doom-system))
|
||||||
|
|
||||||
|
;; `system-type' is esoteric, so I create a pseudo feature as a stable and
|
||||||
|
;; consistent alternative, and all while using the same `featurep' interface
|
||||||
|
;; we're already familiar with.
|
||||||
|
(push :system features)
|
||||||
|
(put :system 'subfeatures doom-features)
|
||||||
|
|
||||||
;; Emacs needs a more consistent way to detect build features, and the docs
|
;; Emacs needs a more consistent way to detect build features, and the docs
|
||||||
;; claim `system-configuration-features' is not da way. Some features (that
|
;; claim `system-configuration-features' is not da way. Some features (that
|
||||||
;; don't represent packages) can be found in `features' (which `featurep'
|
;; don't represent packages) can be found in `features' (which `featurep'
|
||||||
|
@ -116,35 +144,40 @@
|
||||||
(push 'dynamic-modules features))
|
(push 'dynamic-modules features))
|
||||||
(if (fboundp #'json-parse-string)
|
(if (fboundp #'json-parse-string)
|
||||||
(push 'jansson features))
|
(push 'jansson features))
|
||||||
(let ((inhibit-changing-match-data t))
|
(if (string-match-p "HARFBUZZ" system-configuration-features) ; no alternative
|
||||||
(if (string-match "HARFBUZZ" system-configuration-features) ; no alternative
|
(push 'harfbuzz features))
|
||||||
(push 'harfbuzz features)))
|
|
||||||
;; `native-compile' exists whether or not it is functional (e.g. libgcc is
|
;; The `native-compile' feature exists whether or not it is functional (e.g.
|
||||||
;; available or not). This seems silly, so pretend it doesn't exist if it
|
;; libgcc is available or not). This seems silly, so pretend it doesn't exist if
|
||||||
;; isn't available.
|
;; it isn't functional.
|
||||||
(if (featurep 'native-compile)
|
(if (featurep 'native-compile)
|
||||||
(if (not (native-comp-available-p))
|
(if (not (native-comp-available-p))
|
||||||
(delq 'native-compile features)))
|
(delq 'native-compile features)))
|
||||||
|
|
||||||
;;; Global constants
|
|
||||||
;; DEPRECATED remove in v3
|
;; DEPRECATED remove in v3
|
||||||
(defconst IS-MAC (eq system-type 'darwin))
|
(with-no-warnings
|
||||||
(defconst IS-LINUX (memq system-type '(gnu gnu/linux gnu/kfreebsd berkeley-unix)))
|
(defconst IS-MAC doom--system-macos-p)
|
||||||
(defconst IS-WINDOWS (memq system-type '(cygwin windows-nt ms-dos)))
|
(defconst IS-LINUX doom--system-linux-p)
|
||||||
(defconst IS-BSD (memq system-type '(darwin berkeley-unix gnu/kfreebsd)))
|
(defconst IS-WINDOWS doom--system-windows-p)
|
||||||
(defconst EMACS28+ (> emacs-major-version 27))
|
(defconst IS-BSD (memq 'bsd doom-features))
|
||||||
(defconst EMACS29+ (> emacs-major-version 28))
|
(defconst EMACS28+ (> emacs-major-version 27))
|
||||||
(defconst MODULES (featurep 'dynamic-modules))
|
(defconst EMACS29+ (> emacs-major-version 28))
|
||||||
(defconst NATIVECOMP (featurep 'native-compile))
|
(defconst MODULES (featurep 'dynamic-modules))
|
||||||
|
(defconst NATIVECOMP (featurep 'native-compile))
|
||||||
|
|
||||||
|
(make-obsolete-variable 'IS-MAC "Use (featurep :system 'macos) instead" "3.0.0")
|
||||||
|
(make-obsolete-variable 'IS-LINUX "Use (featurep :system 'linux) instead" "3.0.0")
|
||||||
|
(make-obsolete-variable 'IS-WINDOWS "Use (featurep :system 'windows) instead" "3.0.0")
|
||||||
|
(make-obsolete-variable 'IS-BSD "Use (featurep :system 'bsd) instead" "3.0.0")
|
||||||
|
(make-obsolete-variable 'EMACS28+ "Use (>= emacs-major-version 28) instead" "3.0.0")
|
||||||
|
(make-obsolete-variable 'EMACS29+ "Use (>= emacs-major-version 29) instead" "3.0.0")
|
||||||
|
(make-obsolete-variable 'MODULES "Use (featurep 'dynamic-modules) instead" "3.0.0")
|
||||||
|
(make-obsolete-variable 'NATIVECOMP "Use (featurep 'native-compile) instead" "3.0.0"))
|
||||||
|
|
||||||
(make-obsolete-variable 'EMACS28+ "Use (>= emacs-major-version 28) instead" "3.0.0")
|
|
||||||
(make-obsolete-variable 'EMACS29+ "Use (>= emacs-major-version 29) instead" "3.0.0")
|
|
||||||
(make-obsolete-variable 'MODULES "Use (featurep 'dynamic-modules) instead" "3.0.0")
|
|
||||||
(make-obsolete-variable 'NATIVECOMP "Use (featurep 'native-compile) instead" "3.0.0")
|
|
||||||
|
|
||||||
;;; Fix $HOME on Windows
|
;;; Fix $HOME on Windows
|
||||||
;; $HOME isn't normally defined on Windows, but many unix tools expect it.
|
;; $HOME isn't normally defined on Windows, but many unix tools expect it.
|
||||||
(when IS-WINDOWS
|
(when doom--system-windows-p
|
||||||
(when-let (realhome
|
(when-let (realhome
|
||||||
(and (null (getenv-internal "HOME"))
|
(and (null (getenv-internal "HOME"))
|
||||||
(getenv "USERPROFILE")))
|
(getenv "USERPROFILE")))
|
||||||
|
@ -168,7 +201,7 @@
|
||||||
"Current version of Doom Emacs core.")
|
"Current version of Doom Emacs core.")
|
||||||
|
|
||||||
;; DEPRECATED: Remove these when the modules are moved out of core.
|
;; DEPRECATED: Remove these when the modules are moved out of core.
|
||||||
(defconst doom-modules-version "23.08.0-pre"
|
(defconst doom-modules-version "24.03.0-pre"
|
||||||
"Current version of Doom Emacs.")
|
"Current version of Doom Emacs.")
|
||||||
|
|
||||||
(defvar doom-init-time nil
|
(defvar doom-init-time nil
|
||||||
|
@ -228,7 +261,7 @@ These files should not be shared across systems. By default, it is used by
|
||||||
(define-obsolete-variable-alias 'doom-etc-dir 'doom-data-dir "3.0.0")
|
(define-obsolete-variable-alias 'doom-etc-dir 'doom-data-dir "3.0.0")
|
||||||
(defvar doom-data-dir
|
(defvar doom-data-dir
|
||||||
(if doom-profile
|
(if doom-profile
|
||||||
(if IS-WINDOWS
|
(if doom--system-windows-p
|
||||||
(expand-file-name "doomemacs/data/" (getenv-internal "APPDATA"))
|
(expand-file-name "doomemacs/data/" (getenv-internal "APPDATA"))
|
||||||
(expand-file-name "doom/" (or (getenv-internal "XDG_DATA_HOME") "~/.local/share")))
|
(expand-file-name "doom/" (or (getenv-internal "XDG_DATA_HOME") "~/.local/share")))
|
||||||
;; DEPRECATED: .local will be removed entirely in 3.0
|
;; DEPRECATED: .local will be removed entirely in 3.0
|
||||||
|
@ -237,7 +270,7 @@ These files should not be shared across systems. By default, it is used by
|
||||||
|
|
||||||
Data files contain shared and long-lived data that Doom, Emacs, and their
|
Data files contain shared and long-lived data that Doom, Emacs, and their
|
||||||
packages require to function correctly or at all. Deleting them by hand will
|
packages require to function correctly or at all. Deleting them by hand will
|
||||||
cause breakage, and require user intervention (e.g. a 'doom sync' or 'doom env')
|
cause breakage, and require user intervention (e.g. a `doom sync` or `doom env`)
|
||||||
to restore.
|
to restore.
|
||||||
|
|
||||||
Use this for: server binaries, package source, pulled module libraries,
|
Use this for: server binaries, package source, pulled module libraries,
|
||||||
|
@ -247,17 +280,17 @@ For profile-local data files, use `doom-profile-data-dir' instead.")
|
||||||
|
|
||||||
(defvar doom-cache-dir
|
(defvar doom-cache-dir
|
||||||
(if doom-profile
|
(if doom-profile
|
||||||
(if IS-WINDOWS
|
(if doom--system-windows-p
|
||||||
(expand-file-name "doomemacs/cache/" (getenv-internal "APPDATA"))
|
(expand-file-name "doomemacs/cache/" (getenv-internal "APPDATA"))
|
||||||
(expand-file-name "doom/" (or (getenv-internal "XDG_CACHE_HOME") "~/.cache")))
|
(expand-file-name "doom/" (or (getenv-internal "XDG_CACHE_HOME") "~/.cache")))
|
||||||
;; DEPRECATED: .local will be removed entirely in 3.0
|
;; DEPRECATED: .local will be removed entirely in 3.0
|
||||||
(file-name-concat doom-local-dir "cache/"))
|
(file-name-concat doom-local-dir "cache/"))
|
||||||
"Where Doom stores its global cache files.
|
"Where Doom stores its global cache files.
|
||||||
|
|
||||||
Cache files represent non-essential data that shouldn't be problematic when
|
Cache files represent unessential data that shouldn't be problematic when
|
||||||
deleted (besides, perhaps, a one-time performance hit), lack portability (and so
|
deleted (besides, perhaps, a one-time performance hit), lack portability (and so
|
||||||
shouldn't be copied to other systems/configs), and are regenerated when needed,
|
shouldn't be copied to other systems/configs), and are regenerated when needed,
|
||||||
without user input (e.g. a 'doom sync').
|
without user input (e.g. a `doom sync`).
|
||||||
|
|
||||||
Some examples: images/data caches, elisp bytecode, natively compiled elisp,
|
Some examples: images/data caches, elisp bytecode, natively compiled elisp,
|
||||||
session files, ELPA archives, authinfo files, org-persist, etc.
|
session files, ELPA archives, authinfo files, org-persist, etc.
|
||||||
|
@ -266,18 +299,18 @@ For profile-local cache files, use `doom-profile-cache-dir' instead.")
|
||||||
|
|
||||||
(defvar doom-state-dir
|
(defvar doom-state-dir
|
||||||
(if doom-profile
|
(if doom-profile
|
||||||
(if IS-WINDOWS
|
(if doom--system-windows-p
|
||||||
(expand-file-name "doomemacs/state/" (getenv-internal "APPDATA"))
|
(expand-file-name "doomemacs/state/" (getenv-internal "APPDATA"))
|
||||||
(expand-file-name "doom/" (or (getenv-internal "XDG_STATE_HOME") "~/.local/state")))
|
(expand-file-name "doom/" (or (getenv-internal "XDG_STATE_HOME") "~/.local/state")))
|
||||||
;; DEPRECATED: .local will be removed entirely in 3.0
|
;; DEPRECATED: .local will be removed entirely in 3.0
|
||||||
(file-name-concat doom-local-dir "state/"))
|
(file-name-concat doom-local-dir "state/"))
|
||||||
"Where Doom stores its global state files.
|
"Where Doom stores its global state files.
|
||||||
|
|
||||||
State files contain non-essential, unportable, but persistent data which, if
|
State files contain unessential, unportable, but persistent data which, if lost
|
||||||
lost won't cause breakage, but may be inconvenient as they cannot be
|
won't cause breakage, but may be inconvenient as they cannot be automatically
|
||||||
automatically regenerated or restored. For example, a recently-opened file list
|
regenerated or restored. For example, a recently-opened file list is not
|
||||||
is not essential, but losing it means losing this record, and restoring it
|
essential, but losing it means losing this record, and restoring it requires
|
||||||
requires revisiting all those files.
|
revisiting all those files.
|
||||||
|
|
||||||
Use this for: history, logs, user-saved data, autosaves/backup files, known
|
Use this for: history, logs, user-saved data, autosaves/backup files, known
|
||||||
projects, recent files, bookmarks.
|
projects, recent files, bookmarks.
|
||||||
|
@ -331,19 +364,20 @@ users).")
|
||||||
;; `file-remote-p'). You get a noteable boost to startup time by unsetting
|
;; `file-remote-p'). You get a noteable boost to startup time by unsetting
|
||||||
;; or simplifying its value.
|
;; or simplifying its value.
|
||||||
(let ((old-value (default-toplevel-value 'file-name-handler-alist)))
|
(let ((old-value (default-toplevel-value 'file-name-handler-alist)))
|
||||||
(setq file-name-handler-alist
|
(set-default-toplevel-value
|
||||||
;; HACK: If the bundled elisp for this Emacs install isn't
|
'file-name-handler-alist
|
||||||
;; byte-compiled (but is compressed), then leave the gzip file
|
;; HACK: If the bundled elisp for this Emacs install isn't byte-compiled
|
||||||
;; handler there so Emacs won't forget how to read read them.
|
;; (but is compressed), then leave the gzip file handler there so Emacs
|
||||||
;;
|
;; won't forget how to read read them.
|
||||||
;; calc-loaddefs.el is our heuristic for this because it is built-in
|
;;
|
||||||
;; to all supported versions of Emacs, and calc.el explicitly loads
|
;; calc-loaddefs.el is our heuristic for this because it is built-in to
|
||||||
;; it uncompiled. This ensures that the only other, possible
|
;; all supported versions of Emacs, and calc.el explicitly loads it
|
||||||
;; fallback would be calc-loaddefs.el.gz.
|
;; uncompiled. This ensures that the only other, possible fallback would
|
||||||
(if (eval-when-compile
|
;; be calc-loaddefs.el.gz.
|
||||||
(locate-file-internal "calc-loaddefs.el" load-path))
|
(if (eval-when-compile
|
||||||
nil
|
(locate-file-internal "calc-loaddefs.el" load-path))
|
||||||
(list (rassq 'jka-compr-handler old-value))))
|
nil
|
||||||
|
(list (rassq 'jka-compr-handler old-value))))
|
||||||
;; Make sure the new value survives any current let-binding.
|
;; Make sure the new value survives any current let-binding.
|
||||||
(set-default-toplevel-value 'file-name-handler-alist file-name-handler-alist)
|
(set-default-toplevel-value 'file-name-handler-alist file-name-handler-alist)
|
||||||
;; Remember it so it can be reset where needed.
|
;; Remember it so it can be reset where needed.
|
||||||
|
@ -352,10 +386,11 @@ users).")
|
||||||
;; needed for handling encrypted or compressed files, among other things.
|
;; needed for handling encrypted or compressed files, among other things.
|
||||||
(add-hook! 'emacs-startup-hook :depth 101
|
(add-hook! 'emacs-startup-hook :depth 101
|
||||||
(defun doom--reset-file-handler-alist-h ()
|
(defun doom--reset-file-handler-alist-h ()
|
||||||
(setq file-name-handler-alist
|
(set-default-toplevel-value
|
||||||
;; Merge instead of overwrite because there may have been changes to
|
'file-name-handler-alist
|
||||||
;; `file-name-handler-alist' since startup we want to preserve.
|
;; Merge instead of overwrite because there may have been changes to
|
||||||
(delete-dups (append file-name-handler-alist old-value))))))
|
;; `file-name-handler-alist' since startup we want to preserve.
|
||||||
|
(delete-dups (append file-name-handler-alist old-value))))))
|
||||||
|
|
||||||
(unless noninteractive
|
(unless noninteractive
|
||||||
;; PERF: Resizing the Emacs frame (to accommodate fonts that are smaller or
|
;; PERF: Resizing the Emacs frame (to accommodate fonts that are smaller or
|
||||||
|
@ -380,8 +415,9 @@ users).")
|
||||||
|
|
||||||
;; PERF: Shave seconds off startup time by starting the scratch buffer in
|
;; PERF: Shave seconds off startup time by starting the scratch buffer in
|
||||||
;; `fundamental-mode', rather than, say, `org-mode' or `text-mode', which
|
;; `fundamental-mode', rather than, say, `org-mode' or `text-mode', which
|
||||||
;; pull in a ton of packages. `doom/open-scratch-buffer' provides a better
|
;; pull in a ton of packages. This buffer is created whether or not we're
|
||||||
;; scratch buffer anyway.
|
;; in an interactive session. Plus, `doom/open-scratch-buffer' provides a
|
||||||
|
;; better scratch buffer, so keep the initial one blank.
|
||||||
(setq initial-major-mode 'fundamental-mode
|
(setq initial-major-mode 'fundamental-mode
|
||||||
initial-scratch-message nil)
|
initial-scratch-message nil)
|
||||||
|
|
||||||
|
@ -397,82 +433,102 @@ users).")
|
||||||
(doom-partial #'tty-run-terminal-initialization
|
(doom-partial #'tty-run-terminal-initialization
|
||||||
(selected-frame) nil t))))
|
(selected-frame) nil t))))
|
||||||
|
|
||||||
(unless init-file-debug
|
;; PERF,UX: Site files tend to use `load-file', which emits "Loading X..."
|
||||||
;; PERF,UX: Site files tend to use `load-file', which emits "Loading X..."
|
;; messages in the echo area. Writing to the echo-area triggers a
|
||||||
;; messages in the echo area. Writing to the echo-area triggers a
|
;; redisplay, which can be expensive during startup. This may also cause
|
||||||
;; redisplay, which can be expensive during startup. This may also cause
|
;; an flash of white when creating the first frame. Needs to be undo
|
||||||
;; an flash of white when creating the first frame.
|
;; later, though.
|
||||||
(define-advice load-file (:override (file) silence)
|
(define-advice load-file (:override (file) silence)
|
||||||
(load file nil 'nomessage))
|
(load file nil 'nomessage))
|
||||||
;; COMPAT: But undo our `load-file' advice later, as to limit the scope of
|
|
||||||
;; any edge cases it could induce.
|
|
||||||
(define-advice startup--load-user-init-file (:before (&rest _) undo-silence)
|
|
||||||
(advice-remove #'load-file #'load-file@silence))
|
|
||||||
|
|
||||||
;; PERF: `load-suffixes' and `load-file-rep-suffixes' are consulted on each
|
;; PERF: `load-suffixes' and `load-file-rep-suffixes' are consulted on
|
||||||
;; `require' and `load'. Doom won't load any dmodules this early, so omit
|
;; each `require' and `load'. Doom won't load any modules this early, so
|
||||||
;; .so for a small startup boost. This is later restored in doom-start.
|
;; omit .so for a tiny startup boost. Is later restored in doom-start.
|
||||||
(put 'load-suffixes 'initial-value (default-toplevel-value 'load-suffixes))
|
(put 'load-suffixes 'initial-value (default-toplevel-value 'load-suffixes))
|
||||||
(put 'load-file-rep-suffixes 'initial-value (default-toplevel-value 'load-file-rep-suffixes))
|
(put 'load-file-rep-suffixes 'initial-value (default-toplevel-value 'load-file-rep-suffixes))
|
||||||
(set-default-toplevel-value 'load-suffixes '(".elc" ".el"))
|
(set-default-toplevel-value 'load-suffixes '(".elc" ".el"))
|
||||||
(set-default-toplevel-value 'load-file-rep-suffixes '(""))
|
(set-default-toplevel-value 'load-file-rep-suffixes '(""))
|
||||||
;; COMPAT: Undo any problematic startup optimizations; from this point, I make
|
;; COMPAT: Undo any problematic startup optimizations; from this point, I
|
||||||
;; no assumptions about what might be loaded in userland.
|
;; make no assumptions about what might be loaded in userland.
|
||||||
(add-hook! 'doom-before-init-hook
|
(add-hook! 'doom-before-init-hook
|
||||||
(defun doom--reset-load-suffixes-h ()
|
(defun doom--reset-load-suffixes-h ()
|
||||||
(setq load-suffixes (get 'load-suffixes 'initial-value)
|
(setq load-suffixes (get 'load-suffixes 'initial-value)
|
||||||
load-file-rep-suffixes (get 'load-file-rep-suffixes 'initial-value))))
|
load-file-rep-suffixes (get 'load-file-rep-suffixes 'initial-value))))
|
||||||
|
|
||||||
;; PERF: Doom uses `defcustom' to indicate variables that users are expected
|
;; PERF: Doom uses `defcustom' to indicate variables that users are
|
||||||
;; to reconfigure. Trouble is it fires off initializers meant to
|
;; expected to reconfigure. Trouble is it fires off initializers meant
|
||||||
;; accommodate any user attempts to configure them before they were
|
;; to accommodate any user attempts to configure them before they were
|
||||||
;; defined. This is unnecessary before $DOOMDIR/init.el is loaded, so I
|
;; defined. This is unnecessary work before $DOOMDIR/init.el is loaded,
|
||||||
;; disable them until it is.
|
;; so I disable them until it is.
|
||||||
(setq custom-dont-initialize t)
|
(setq custom-dont-initialize t)
|
||||||
(add-hook! 'doom-before-init-hook
|
(add-hook! 'doom-before-init-hook
|
||||||
(defun doom--reset-custom-dont-initialize-h ()
|
(defun doom--reset-custom-dont-initialize-h ()
|
||||||
(setq custom-dont-initialize nil)))
|
(setq custom-dont-initialize nil)))
|
||||||
|
|
||||||
;; PERF: The mode-line procs a couple dozen times during startup. This is
|
;; PERF: Doom disables the UI elements by default, so that there's less
|
||||||
;; normally quite fast, but disabling the default mode-line and reducing the
|
;; for the frame to initialize. However, the toolbar is still populated
|
||||||
;; update delay timer seems to stave off ~30-50ms.
|
;; regardless, so I lazy load it until tool-bar-mode is actually used.
|
||||||
(put 'mode-line-format 'initial-value (default-toplevel-value 'mode-line-format))
|
(advice-add #'tool-bar-setup :override #'ignore)
|
||||||
(setq-default mode-line-format nil)
|
|
||||||
(dolist (buf (buffer-list))
|
|
||||||
(with-current-buffer buf (setq mode-line-format nil)))
|
|
||||||
;; PERF,UX: Premature redisplays can substantially affect startup times and
|
|
||||||
;; produce ugly flashes of unstyled Emacs.
|
|
||||||
(setq-default inhibit-redisplay t
|
|
||||||
inhibit-message t)
|
|
||||||
;; COMPAT: Then reset it with advice, because `startup--load-user-init-file'
|
|
||||||
;; will never be interrupted by errors. And if these settings are left
|
|
||||||
;; set, Emacs could appear frozen or garbled.
|
|
||||||
(defun doom--reset-inhibited-vars-h ()
|
|
||||||
(setq-default inhibit-redisplay nil
|
|
||||||
;; Inhibiting `message' only prevents redraws and
|
|
||||||
inhibit-message nil)
|
|
||||||
(redraw-frame))
|
|
||||||
(add-hook 'after-init-hook #'doom--reset-inhibited-vars-h)
|
|
||||||
(define-advice startup--load-user-init-file (:after (&rest _) undo-inhibit-vars)
|
|
||||||
(when init-file-had-error
|
|
||||||
(doom--reset-inhibited-vars-h))
|
|
||||||
(unless (default-toplevel-value 'mode-line-format)
|
|
||||||
(setq-default mode-line-format (get 'mode-line-format 'initial-value))))
|
|
||||||
|
|
||||||
;; PERF: Doom disables the UI elements by default, so that there's less for
|
;; PERF: The mode-line procs a couple dozen times during startup. This is
|
||||||
;; the frame to initialize. However, the toolbar is still populated
|
;; normally quite fast, but disabling the default mode-line and reducing
|
||||||
;; regardless, so I lazy load it until tool-bar-mode is actually used.
|
;; the update delay timer seems to stave off ~30-50ms.
|
||||||
(advice-add #'tool-bar-setup :override #'ignore)
|
(put 'mode-line-format 'initial-value (default-toplevel-value 'mode-line-format))
|
||||||
(define-advice startup--load-user-init-file (:before (&rest _) defer-tool-bar-setup)
|
(setq-default mode-line-format nil)
|
||||||
(advice-remove #'tool-bar-setup #'ignore)
|
(dolist (buf (buffer-list))
|
||||||
(add-transient-hook! 'tool-bar-mode (tool-bar-setup)))
|
(with-current-buffer buf (setq mode-line-format nil)))
|
||||||
|
;; PERF,UX: Premature redisplays can substantially affect startup times
|
||||||
|
;; and/or produce ugly flashes of unstyled Emacs.
|
||||||
|
(setq-default inhibit-redisplay t
|
||||||
|
inhibit-message t)
|
||||||
|
;; COMPAT: Then reset with advice, because `startup--load-user-init-file'
|
||||||
|
;; will never be interrupted by errors. And if these settings are left
|
||||||
|
;; set, Emacs could appear frozen or garbled.
|
||||||
|
(defun doom--reset-inhibited-vars-h ()
|
||||||
|
(setq-default inhibit-redisplay nil
|
||||||
|
;; Inhibiting `message' only prevents redraws and
|
||||||
|
inhibit-message nil)
|
||||||
|
(redraw-frame))
|
||||||
|
(add-hook 'after-init-hook #'doom--reset-inhibited-vars-h)
|
||||||
|
|
||||||
;; PERF: Unset a non-trivial list of command line options that aren't
|
;; PERF,UX: An annoying aspect of site-lisp files is that they're often
|
||||||
;; relevant to our current OS, but `command-line-1' still processes.
|
;; noisy (they emit load messages or other output to stdout). These
|
||||||
(unless IS-MAC
|
;; queue unnecessary redraws at startup, cost startup time, and pollute
|
||||||
(setq command-line-ns-option-alist nil))
|
;; the logs. I get around it by suppressing it until we can load it
|
||||||
(unless (memq initial-window-system '(x pgtk))
|
;; manually, later (in the `startup--load-user-init-file' advice below).
|
||||||
(setq command-line-x-option-alist nil)))))
|
(put 'site-run-file 'initial-value site-run-file)
|
||||||
|
(setq site-run-file nil)
|
||||||
|
|
||||||
|
(define-advice startup--load-user-init-file (:around (fn &rest args) undo-inhibit-vars)
|
||||||
|
(let (--init--)
|
||||||
|
(unwind-protect
|
||||||
|
(progn
|
||||||
|
;; COMPAT: Onces startup is sufficiently complete, undo some
|
||||||
|
;; optimizations to reduce the scope of potential edge cases.
|
||||||
|
(advice-remove #'load-file #'load-file@silence)
|
||||||
|
(advice-remove #'tool-bar-setup #'ignore)
|
||||||
|
(add-transient-hook! 'tool-bar-mode (tool-bar-setup))
|
||||||
|
(when (setq site-run-file (get 'site-run-file 'initial-value))
|
||||||
|
(let ((inhibit-startup-screen inhibit-startup-screen))
|
||||||
|
(letf! (defun load (file &optional noerror _nomessage &rest args)
|
||||||
|
(apply load file noerror t args))
|
||||||
|
(load site-run-file t t))))
|
||||||
|
;; Then startup as normal.
|
||||||
|
(apply fn args)
|
||||||
|
(setq --init-- t))
|
||||||
|
(when (or (not --init--) init-file-had-error)
|
||||||
|
;; If we don't undo our inhibit-{message,redisplay} and there's an
|
||||||
|
;; error, we'll see nothing but a blank Emacs frame.
|
||||||
|
(doom--reset-inhibited-vars-h))
|
||||||
|
(unless (default-toplevel-value 'mode-line-format)
|
||||||
|
(setq-default mode-line-format (get 'mode-line-format 'initial-value))))))
|
||||||
|
|
||||||
|
;; PERF: Unset a non-trivial list of command line options that aren't
|
||||||
|
;; relevant to this session, but `command-line-1' still processes.
|
||||||
|
(unless doom--system-macos-p
|
||||||
|
(setq command-line-ns-option-alist nil))
|
||||||
|
(unless (memq initial-window-system '(x pgtk))
|
||||||
|
(setq command-line-x-option-alist nil))))
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
@ -497,7 +553,7 @@ All valid contexts:
|
||||||
(put 'doom-context 'valid-values '(cli compile eval init modules packages reload doctor sandbox))
|
(put 'doom-context 'valid-values '(cli compile eval init modules packages reload doctor sandbox))
|
||||||
(put 'doom-context 'risky-local-variable t)
|
(put 'doom-context 'risky-local-variable t)
|
||||||
|
|
||||||
(defun doom-context--check (context)
|
(defun doom-context--assert (context)
|
||||||
(let ((valid (get 'doom-context 'valid-values)))
|
(let ((valid (get 'doom-context 'valid-values)))
|
||||||
(unless (memq context valid)
|
(unless (memq context valid)
|
||||||
(signal 'doom-context-error
|
(signal 'doom-context-error
|
||||||
|
@ -512,7 +568,7 @@ All valid contexts:
|
||||||
|
|
||||||
Return non-nil if successful. Throws an error if CONTEXT is invalid."
|
Return non-nil if successful. Throws an error if CONTEXT is invalid."
|
||||||
(unless (memq context doom-context)
|
(unless (memq context doom-context)
|
||||||
(doom-context--check context)
|
(doom-context--assert context)
|
||||||
(doom-log ":context: +%s %s" context doom-context)
|
(doom-log ":context: +%s %s" context doom-context)
|
||||||
(push context doom-context)))
|
(push context doom-context)))
|
||||||
|
|
||||||
|
@ -529,7 +585,7 @@ wasn't active when this was called."
|
||||||
(setq doom-context (delq context doom-context))))
|
(setq doom-context (delq context doom-context))))
|
||||||
|
|
||||||
(defmacro doom-context-with (contexts &rest body)
|
(defmacro doom-context-with (contexts &rest body)
|
||||||
"Evaluate BODY with CONTEXT added to `doom-context'."
|
"Evaluate BODY with CONTEXTS added to `doom-context'."
|
||||||
(declare (indent 1))
|
(declare (indent 1))
|
||||||
`(let ((doom-context doom-context))
|
`(let ((doom-context doom-context))
|
||||||
(dolist (context (ensure-list ,contexts))
|
(dolist (context (ensure-list ,contexts))
|
||||||
|
@ -607,7 +663,15 @@ Otherwise, `en/disable-command' (in novice.el.gz) is hardcoded to write them to
|
||||||
(and (null comp-num-cpus)
|
(and (null comp-num-cpus)
|
||||||
(zerop native-comp-async-jobs-number)
|
(zerop native-comp-async-jobs-number)
|
||||||
(setq comp-num-cpus
|
(setq comp-num-cpus
|
||||||
(max 1 (/ (num-processors) (if noninteractive 1 4)))))))
|
(max 1 (/ (num-processors) (if noninteractive 1 4))))))
|
||||||
|
|
||||||
|
(define-advice comp-run-async-workers (:around (fn &rest args) dont-litter-tmpdir)
|
||||||
|
"Normally, native-comp writes a ton to /tmp. This advice forces it to write
|
||||||
|
to `doom-cache-dir'/comp/ instead, so that Doom can safely clean it up as part
|
||||||
|
of 'doom sync' or 'doom gc'."
|
||||||
|
(let ((temporary-file-directory (expand-file-name "comp/" doom-profile-cache-dir)))
|
||||||
|
(make-directory temporary-file-directory t)
|
||||||
|
(apply fn args))))
|
||||||
|
|
||||||
;;; Suppress package.el
|
;;; Suppress package.el
|
||||||
;; Since Emacs 27, package initialization occurs before `user-init-file' is
|
;; Since Emacs 27, package initialization occurs before `user-init-file' is
|
||||||
|
@ -639,7 +703,7 @@ Otherwise, `en/disable-command' (in novice.el.gz) is hardcoded to write them to
|
||||||
gnutls-algorithm-priority
|
gnutls-algorithm-priority
|
||||||
(when (boundp 'libgnutls-version)
|
(when (boundp 'libgnutls-version)
|
||||||
(concat "SECURE128:+SECURE192:-VERS-ALL"
|
(concat "SECURE128:+SECURE192:-VERS-ALL"
|
||||||
(if (and (not IS-WINDOWS)
|
(if (and (not doom--system-windows-p)
|
||||||
(>= libgnutls-version 30605))
|
(>= libgnutls-version 30605))
|
||||||
":+VERS-TLS1.3")
|
":+VERS-TLS1.3")
|
||||||
":+VERS-TLS1.2"))
|
":+VERS-TLS1.2"))
|
||||||
|
@ -689,10 +753,22 @@ appropriately against `noninteractive' or the `cli' context."
|
||||||
;;
|
;;
|
||||||
;;; Last minute initialization
|
;;; Last minute initialization
|
||||||
|
|
||||||
|
(when (daemonp)
|
||||||
|
(message "Starting Doom Emacs in daemon mode!")
|
||||||
|
(unless doom-inhibit-log
|
||||||
|
(add-hook! 'doom-after-init-hook :depth 106
|
||||||
|
(unless doom-inhibit-log
|
||||||
|
(setq doom-inhibit-log (not (or noninteractive init-file-debug))))
|
||||||
|
(message "Disabling verbose mode. Have fun!"))
|
||||||
|
(add-hook! 'kill-emacs-hook :depth 110
|
||||||
|
(message "Killing Emacs. Sayonara!"))))
|
||||||
|
|
||||||
(add-hook! 'doom-before-init-hook :depth -105
|
(add-hook! 'doom-before-init-hook :depth -105
|
||||||
(defun doom--begin-init-h ()
|
(defun doom--begin-init-h ()
|
||||||
"Begin the startup process."
|
"Begin the startup process."
|
||||||
(when (doom-context-push 'init)
|
(when (doom-context-push 'init)
|
||||||
|
;; HACK: Ensure OS checks are as fast as possible (given their ubiquity).
|
||||||
|
(setq features (cons :system (delq :system features)))
|
||||||
;; Remember these variables' initial values, so we can safely reset them at
|
;; Remember these variables' initial values, so we can safely reset them at
|
||||||
;; a later time, or consult them without fear of contamination.
|
;; a later time, or consult them without fear of contamination.
|
||||||
(dolist (var '(exec-path load-path process-environment))
|
(dolist (var '(exec-path load-path process-environment))
|
||||||
|
|
|
@ -186,7 +186,7 @@ non-nil, treat FILES as pre-generated autoload files instead."
|
||||||
(let ((load-file-name file)
|
(let ((load-file-name file)
|
||||||
(load-path
|
(load-path
|
||||||
(append (list doom-user-dir)
|
(append (list doom-user-dir)
|
||||||
doom-modules-dirs
|
doom-module-load-path
|
||||||
load-path)))
|
load-path)))
|
||||||
(condition-case _
|
(condition-case _
|
||||||
(while t
|
(while t
|
||||||
|
|
|
@ -59,9 +59,6 @@ symbol and CDR is the value to set it to when `doom-debug-mode' is activated.")
|
||||||
(let ((enabled doom-debug-mode))
|
(let ((enabled doom-debug-mode))
|
||||||
(doom-log "debug: enabled!")
|
(doom-log "debug: enabled!")
|
||||||
(mapc #'doom-debug--set-var doom-debug-variables)
|
(mapc #'doom-debug--set-var doom-debug-variables)
|
||||||
(when (called-interactively-p 'any)
|
|
||||||
(when (fboundp 'explain-pause-mode)
|
|
||||||
(explain-pause-mode (if enabled +1 -1))))
|
|
||||||
;; Watch for changes in `doom-debug-variables', or when packages load (and
|
;; Watch for changes in `doom-debug-variables', or when packages load (and
|
||||||
;; potentially define one of `doom-debug-variables'), in case some of them
|
;; potentially define one of `doom-debug-variables'), in case some of them
|
||||||
;; aren't defined when `doom-debug-mode' is first loaded.
|
;; aren't defined when `doom-debug-mode' is first loaded.
|
||||||
|
@ -260,7 +257,8 @@ ready to be pasted in a bug report on github."
|
||||||
(bound-and-true-p emacs-repository-branch)
|
(bound-and-true-p emacs-repository-branch)
|
||||||
(and (stringp emacs-repository-version)
|
(and (stringp emacs-repository-version)
|
||||||
(substring emacs-repository-version 0 9))
|
(substring emacs-repository-version 0 9))
|
||||||
(symlink-path doom-emacs-dir))))
|
(format "EMACSDIR=%s" (symlink-path doom-emacs-dir))
|
||||||
|
(format "EMACS=%s" (expand-file-name invocation-name invocation-directory)))))
|
||||||
(doom . ,(list doom-version
|
(doom . ,(list doom-version
|
||||||
(if doom-profile
|
(if doom-profile
|
||||||
(format "PROFILE=%s@%s"
|
(format "PROFILE=%s@%s"
|
||||||
|
@ -300,7 +298,7 @@ ready to be pasted in a bug report on github."
|
||||||
'compiled-user-config)
|
'compiled-user-config)
|
||||||
(if (doom-files-in doom-core-dir :type 'files :match "\\.elc$")
|
(if (doom-files-in doom-core-dir :type 'files :match "\\.elc$")
|
||||||
'compiled-core)
|
'compiled-core)
|
||||||
(if (doom-files-in doom-modules-dirs :type 'files :match "\\.elc$")
|
(if (doom-files-in doom-module-load-path :type 'files :match "\\.elc$")
|
||||||
'compiled-modules)))))
|
'compiled-modules)))))
|
||||||
(custom
|
(custom
|
||||||
,@(when (and (stringp custom-file)
|
,@(when (and (stringp custom-file)
|
||||||
|
|
|
@ -19,24 +19,24 @@
|
||||||
(defvar doom-docs-header-specs
|
(defvar doom-docs-header-specs
|
||||||
'(("/docs/index\\.org$"
|
'(("/docs/index\\.org$"
|
||||||
(:label "FAQ"
|
(:label "FAQ"
|
||||||
:icon "question_answer"
|
:icon "nf-md-message_question_outline"
|
||||||
:link "doom-faq:"
|
:link "doom-faq:"
|
||||||
:help-echo "Open the FAQ document"))
|
:help-echo "Open the FAQ document"))
|
||||||
(("/docs/[^/]+\\.org$" "/modules/README\\.org$")
|
(("/docs/[^/]+\\.org$" "/modules/README\\.org$")
|
||||||
(:label "Back to index"
|
(:label "Back to index"
|
||||||
:icon "arrow_back"
|
:icon "nf-md-arrow_left"
|
||||||
:link ("doom-index" . "")
|
:link "doom-index"
|
||||||
:help-echo "Navigate to the root index"))
|
:help-echo "Navigate to the root index"))
|
||||||
("/modules/[^/]+/README\\.org$"
|
("/modules/[^/]+/README\\.org$"
|
||||||
(:label "Back to module index"
|
(:label "Back to module index"
|
||||||
:icon "arrow_back"
|
:icon "nf-md-arrow_left"
|
||||||
:link "doom-module-index:"))
|
:link "doom-module-index:"))
|
||||||
("/modules/[^/]+/[^/]+/README\\.org$"
|
("/modules/[^/]+/[^/]+/README\\.org$"
|
||||||
(:label "Back to module index"
|
(:label "Back to module index"
|
||||||
:icon "arrow_back"
|
:icon "nf-md-arrow_left"
|
||||||
:link "doom-module-index:")
|
:link "doom-module-index:")
|
||||||
(:label "History"
|
(:label "History"
|
||||||
:icon "history"
|
:icon "nf-md-history"
|
||||||
:icon-face font-lock-variable-name-face
|
:icon-face font-lock-variable-name-face
|
||||||
:link (lambda ()
|
:link (lambda ()
|
||||||
(cl-destructuring-bind (category . module) (doom-module-from-path (buffer-file-name))
|
(cl-destructuring-bind (category . module) (doom-module-from-path (buffer-file-name))
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
:help-echo "View the module history"
|
:help-echo "View the module history"
|
||||||
:align right)
|
:align right)
|
||||||
(:label "Issues"
|
(:label "Issues"
|
||||||
:icon "error_outline"
|
:icon "nf-md-flag"
|
||||||
:icon-face error
|
:icon-face error
|
||||||
:link (lambda ()
|
:link (lambda ()
|
||||||
(cl-destructuring-bind (category . module) (doom-module-from-path (buffer-file-name))
|
(cl-destructuring-bind (category . module) (doom-module-from-path (buffer-file-name))
|
||||||
|
@ -52,12 +52,12 @@
|
||||||
:align right))
|
:align right))
|
||||||
(t
|
(t
|
||||||
(:label "Suggest edits"
|
(:label "Suggest edits"
|
||||||
:icon "edit"
|
:icon "nf-md-account_edit"
|
||||||
:icon-face warning
|
:icon-face warning
|
||||||
:link "doom-suggest-edit"
|
:link "doom-suggest-edit"
|
||||||
:align right)
|
:align right)
|
||||||
(:label "Help"
|
(:label "Help"
|
||||||
:icon "help_outline"
|
:icon "nf-md-timeline_help_outline"
|
||||||
:icon-face font-lock-function-name-face
|
:icon-face font-lock-function-name-face
|
||||||
:link (lambda ()
|
:link (lambda ()
|
||||||
(let ((title (cadar (org-collect-keywords '("TITLE")))))
|
(let ((title (cadar (org-collect-keywords '("TITLE")))))
|
||||||
|
@ -101,9 +101,10 @@
|
||||||
(defun doom-docs--make-header-link (spec)
|
(defun doom-docs--make-header-link (spec)
|
||||||
"Create a header link according to SPEC."
|
"Create a header link according to SPEC."
|
||||||
(let ((icon (and (plist-get spec :icon)
|
(let ((icon (and (plist-get spec :icon)
|
||||||
(funcall (or (plist-get spec :icon-function)
|
(with-demoted-errors "DOCS ERROR: %s"
|
||||||
#'all-the-icons-material)
|
(funcall (or (plist-get spec :icon-function)
|
||||||
(plist-get spec :icon))))
|
#'nerd-icons-mdicon)
|
||||||
|
(plist-get spec :icon)))))
|
||||||
(label (pcase (plist-get spec :label)
|
(label (pcase (plist-get spec :label)
|
||||||
((and (pred functionp) lab)
|
((and (pred functionp) lab)
|
||||||
(funcall lab))
|
(funcall lab))
|
||||||
|
@ -239,11 +240,9 @@
|
||||||
(beg (max (point-min) (1- (org-element-property :begin el))))
|
(beg (max (point-min) (1- (org-element-property :begin el))))
|
||||||
(end (org-element-property :end el))
|
(end (org-element-property :end el))
|
||||||
((memq (org-element-type el) '(drawer property-drawer))))
|
((memq (org-element-type el) '(drawer property-drawer))))
|
||||||
(when (org-current-level)
|
(when (org-element-property-inherited :level el)
|
||||||
(cl-decf end))
|
(cl-decf end))
|
||||||
(org-fold-core-region beg end doom-docs-mode 'doom-doc-hidden)
|
(org-fold-core-region beg end doom-docs-mode 'doom-doc-hidden))))
|
||||||
(when doom-docs-mode
|
|
||||||
(org-fold-core-region beg end nil 'org-hide-drawer)))))
|
|
||||||
;; FIX: If the cursor remains within a newly folded region, that folk will
|
;; FIX: If the cursor remains within a newly folded region, that folk will
|
||||||
;; come undone, so we move it.
|
;; come undone, so we move it.
|
||||||
(if pt (goto-char pt))))
|
(if pt (goto-char pt))))
|
||||||
|
@ -373,7 +372,7 @@ depending.")
|
||||||
(defvar doom-docs--cookies nil)
|
(defvar doom-docs--cookies nil)
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(define-minor-mode doom-docs-mode
|
(define-minor-mode doom-docs-mode
|
||||||
"Hides metadata, tags, & drawers and activates all org-mode pretiffications.
|
"Hides metadata, tags, & drawers and activates all org-mode prettifications.
|
||||||
This primes `org-mode' for reading."
|
This primes `org-mode' for reading."
|
||||||
:lighter " Doom Docs"
|
:lighter " Doom Docs"
|
||||||
:after-hook (org-restart-font-lock)
|
:after-hook (org-restart-font-lock)
|
||||||
|
@ -387,7 +386,7 @@ This primes `org-mode' for reading."
|
||||||
(if doom-docs-mode
|
(if doom-docs-mode
|
||||||
(set (make-local-variable sym) t)
|
(set (make-local-variable sym) t)
|
||||||
(kill-local-variable sym)))
|
(kill-local-variable sym)))
|
||||||
`(org-pretty-entities
|
'(org-pretty-entities
|
||||||
org-hide-emphasis-markers
|
org-hide-emphasis-markers
|
||||||
org-hide-macro-markers))
|
org-hide-macro-markers))
|
||||||
(when doom-docs-mode
|
(when doom-docs-mode
|
||||||
|
@ -428,13 +427,13 @@ This primes `org-mode' for reading."
|
||||||
|
|
||||||
(defvar doom-docs--id-locations nil)
|
(defvar doom-docs--id-locations nil)
|
||||||
(defvar doom-docs--id-files nil)
|
(defvar doom-docs--id-files nil)
|
||||||
|
(defvar doom-docs--id-location-file (file-name-concat doom-cache-dir "doom-docs-org-ids"))
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/reload-docs (&optional force)
|
(defun doom/reload-docs (&optional force)
|
||||||
"Reload the ID locations in Doom's documentation and open docs buffers."
|
"Reload the ID locations in Doom's documentation and open docs buffers."
|
||||||
(interactive (list 'interactive))
|
(interactive (list 'interactive))
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(let ((org-id-locations-file
|
(let ((org-id-locations-file doom-docs--id-location-file)
|
||||||
(doom-path (file-truename doom-cache-dir) "doom-docs-org-ids"))
|
|
||||||
(org-id-track-globally t)
|
(org-id-track-globally t)
|
||||||
org-agenda-files
|
org-agenda-files
|
||||||
org-id-extra-files
|
org-id-extra-files
|
||||||
|
@ -465,14 +464,26 @@ This primes `org-mode' for reading."
|
||||||
(let ((org-id-link-to-org-use-id t)
|
(let ((org-id-link-to-org-use-id t)
|
||||||
(org-id-method 'uuid)
|
(org-id-method 'uuid)
|
||||||
(org-id-track-globally t)
|
(org-id-track-globally t)
|
||||||
(org-id-locations-file (doom-path doom-cache-dir "doom-docs-org-ids"))
|
(org-id-locations-file doom-docs--id-location-file)
|
||||||
(org-id-locations doom-docs--id-locations)
|
(org-id-locations doom-docs--id-locations)
|
||||||
(org-id-files doom-docs--id-files))
|
(org-id-files doom-docs--id-files))
|
||||||
(doom/reload-docs)
|
(doom/reload-docs)
|
||||||
(let ((id (org-id-new)))
|
(when-let (fname (buffer-file-name (buffer-base-buffer)))
|
||||||
(org-id-add-location
|
(let ((id (org-id-new)))
|
||||||
id (buffer-file-name (buffer-base-buffer)))
|
(org-id-add-location id fname)
|
||||||
id)))
|
id))))
|
||||||
|
|
||||||
|
(defconst doom-docs-org-font-lock-keywords
|
||||||
|
'(("^\\( *\\)#\\+begin_quote\n\\1 \\([]\\) "
|
||||||
|
2 (pcase (match-string 2)
|
||||||
|
("" 'font-lock-comment-face)
|
||||||
|
("" 'font-lock-comment-face)
|
||||||
|
("" 'error)
|
||||||
|
("" 'success)
|
||||||
|
("" 'font-lock-keyword-face)
|
||||||
|
("" 'font-lock-constant-face)
|
||||||
|
("" 'warning))))
|
||||||
|
"Extra font-lock keywords for Doom documentation.")
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(define-derived-mode doom-docs-org-mode org-mode "Doom Docs"
|
(define-derived-mode doom-docs-org-mode org-mode "Doom Docs"
|
||||||
|
@ -481,6 +492,7 @@ This primes `org-mode' for reading."
|
||||||
Keeps track of its own IDs in `doom-docs-dir' and toggles `doom-docs-mode' when
|
Keeps track of its own IDs in `doom-docs-dir' and toggles `doom-docs-mode' when
|
||||||
`read-only-mode' is activated."
|
`read-only-mode' is activated."
|
||||||
:after-hook (visual-line-mode -1)
|
:after-hook (visual-line-mode -1)
|
||||||
|
(font-lock-add-keywords nil doom-docs-org-font-lock-keywords)
|
||||||
(let ((gc-cons-threshold most-positive-fixnum)
|
(let ((gc-cons-threshold most-positive-fixnum)
|
||||||
(gc-cons-percentage 1.0))
|
(gc-cons-percentage 1.0))
|
||||||
(require 'org-id)
|
(require 'org-id)
|
||||||
|
@ -488,7 +500,7 @@ Keeps track of its own IDs in `doom-docs-dir' and toggles `doom-docs-mode' when
|
||||||
(setq-local org-id-link-to-org-use-id t
|
(setq-local org-id-link-to-org-use-id t
|
||||||
org-id-method 'uuid
|
org-id-method 'uuid
|
||||||
org-id-track-globally t
|
org-id-track-globally t
|
||||||
org-id-locations-file (doom-path doom-cache-dir "doom-docs-org-ids")
|
org-id-locations-file doom-docs--id-location-file
|
||||||
org-id-locations doom-docs--id-locations
|
org-id-locations doom-docs--id-locations
|
||||||
org-id-files doom-docs--id-files
|
org-id-files doom-docs--id-files
|
||||||
org-num-max-level 3
|
org-num-max-level 3
|
||||||
|
|
|
@ -220,7 +220,7 @@ single file or nested compound statement of `and' and `or' statements."
|
||||||
(let* ((buffer-file-name (doom-path ,file))
|
(let* ((buffer-file-name (doom-path ,file))
|
||||||
(coding-system-for-read (or ,coding 'binary))
|
(coding-system-for-read (or ,coding 'binary))
|
||||||
(coding-system-for-write (or coding-system-for-write coding-system-for-read 'binary)))
|
(coding-system-for-write (or coding-system-for-write coding-system-for-read 'binary)))
|
||||||
(unless (eq coding-system-for-read 'binary)
|
(when (eq coding-system-for-read 'binary)
|
||||||
(set-buffer-multibyte nil)
|
(set-buffer-multibyte nil)
|
||||||
(setq-local buffer-file-coding-system 'binary))
|
(setq-local buffer-file-coding-system 'binary))
|
||||||
,@body))
|
,@body))
|
||||||
|
@ -245,7 +245,8 @@ special values:
|
||||||
'read* -- read all forms in FILE and return it as a list of S-exps.
|
'read* -- read all forms in FILE and return it as a list of S-exps.
|
||||||
'(read . N) -- read the first N (an integer) S-exps in FILE.
|
'(read . N) -- read the first N (an integer) S-exps in FILE.
|
||||||
|
|
||||||
CODING dictates the encoding of the buffer. This defaults to `utf-8'.
|
CODING dictates the encoding of the buffer. This defaults to `utf-8'. If set to
|
||||||
|
nil, `binary' is used.
|
||||||
|
|
||||||
If NOERROR is non-nil, don't throw an error if FILE doesn't exist. This will
|
If NOERROR is non-nil, don't throw an error if FILE doesn't exist. This will
|
||||||
still throw an error if FILE is unreadable, however.
|
still throw an error if FILE is unreadable, however.
|
||||||
|
@ -301,18 +302,21 @@ If CONTENTS is list of forms. Any literal strings in the list are inserted
|
||||||
verbatim, as text followed by a newline, with `insert'. Sexps are inserted with
|
verbatim, as text followed by a newline, with `insert'. Sexps are inserted with
|
||||||
`prin1'. BY is the function to use to emit
|
`prin1'. BY is the function to use to emit
|
||||||
|
|
||||||
MODE dictates the permissions of the file. If FILE already exists, its
|
MODE dictates the permissions of created file and directories. MODE is either an
|
||||||
permissions will be changed.
|
integer or a cons cell whose car is the mode for files and cdr the mode for
|
||||||
|
directories. If FILE already exists, its permissions will be changed. The
|
||||||
|
permissions of existing directories will never be changed.
|
||||||
|
|
||||||
CODING dictates the encoding to read/write with (see `coding-system-for-write').
|
CODING dictates the encoding to read/write with (see `coding-system-for-write').
|
||||||
If set to nil, `binary' is used.
|
This defaults to `utf-8'. If set to nil, `binary' is used.
|
||||||
|
|
||||||
APPEND dictates where CONTENTS will be written. If neither is set,
|
APPEND dictates where CONTENTS will be written. If neither is set,
|
||||||
the file will be overwritten. If both are, the contents will be written to both
|
the file will be overwritten. If both are, the contents will be written to both
|
||||||
ends. Set either APPEND or PREPEND to `noerror' to silently ignore read errors."
|
ends. Set either APPEND or PREPEND to `noerror' to silently ignore read errors."
|
||||||
(doom--with-prepared-file-buffer file coding mode
|
(let ((mode (ensure-list mode))
|
||||||
(let ((contents (ensure-list contents))
|
(contents (ensure-list contents))
|
||||||
datum)
|
datum)
|
||||||
|
(doom--with-prepared-file-buffer file coding (car mode)
|
||||||
(while (setq datum (pop contents))
|
(while (setq datum (pop contents))
|
||||||
(cond ((stringp datum)
|
(cond ((stringp datum)
|
||||||
(funcall
|
(funcall
|
||||||
|
@ -325,15 +329,21 @@ ends. Set either APPEND or PREPEND to `noerror' to silently ignore read errors."
|
||||||
((let ((standard-output (current-buffer))
|
((let ((standard-output (current-buffer))
|
||||||
(print-quoted t)
|
(print-quoted t)
|
||||||
(print-level nil)
|
(print-level nil)
|
||||||
(print-length nil))
|
(print-length nil)
|
||||||
(funcall printfn datum))))))
|
;; Escape special chars to avoid any shenanigans
|
||||||
(let (write-region-annotate-functions
|
(print-escape-newlines t)
|
||||||
write-region-post-annotation-function)
|
(print-escape-control-characters t)
|
||||||
(when mkdir
|
(print-escape-nonascii t)
|
||||||
(make-directory (file-name-directory buffer-file-name)
|
(print-escape-multibyte t))
|
||||||
(eq mkdir 'parents)))
|
(funcall printfn datum)))))
|
||||||
(write-region nil nil buffer-file-name append :silent))
|
(let (write-region-annotate-functions
|
||||||
buffer-file-name))
|
write-region-post-annotation-function)
|
||||||
|
(when mkdir
|
||||||
|
(with-file-modes (or (cdr mode) (default-file-modes))
|
||||||
|
(make-directory (file-name-directory buffer-file-name)
|
||||||
|
(eq mkdir 'parents))))
|
||||||
|
(write-region nil nil buffer-file-name append :silent))
|
||||||
|
buffer-file-name)))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defmacro with-file-contents! (file &rest body)
|
(defmacro with-file-contents! (file &rest body)
|
||||||
|
@ -477,7 +487,7 @@ If FORCE-P, overwrite the destination file if it exists, without confirmation."
|
||||||
(defun doom/sudo-find-file (file)
|
(defun doom/sudo-find-file (file)
|
||||||
"Open FILE as root."
|
"Open FILE as root."
|
||||||
(interactive "FOpen file as root: ")
|
(interactive "FOpen file as root: ")
|
||||||
(find-file (doom--sudo-file-path file)))
|
(find-file (doom--sudo-file-path (expand-file-name file))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/sudo-this-file ()
|
(defun doom/sudo-this-file ()
|
||||||
|
@ -517,5 +527,77 @@ If FORCE-P, overwrite the destination file if it exists, without confirmation."
|
||||||
(recentf-save-list)
|
(recentf-save-list)
|
||||||
(message "Removed %S from `recentf-list'" (abbreviate-file-name file)))
|
(message "Removed %S from `recentf-list'" (abbreviate-file-name file)))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Backports
|
||||||
|
|
||||||
|
;; Introduced in Emacs 29.
|
||||||
|
;;;###autoload
|
||||||
|
(eval-when! (not (fboundp 'find-sibling-file))
|
||||||
|
(defvar find-sibling-rules nil)
|
||||||
|
|
||||||
|
(defun find-sibling-file (file)
|
||||||
|
"Visit a \"sibling\" file of FILE.
|
||||||
|
When called interactively, FILE is the currently visited file.
|
||||||
|
|
||||||
|
The \"sibling\" file is defined by the `find-sibling-rules' variable."
|
||||||
|
(interactive (progn
|
||||||
|
(unless buffer-file-name
|
||||||
|
(user-error "Not visiting a file"))
|
||||||
|
(list buffer-file-name)))
|
||||||
|
(unless find-sibling-rules
|
||||||
|
(user-error "The `find-sibling-rules' variable has not been configured"))
|
||||||
|
(let ((siblings (find-sibling-file-search (expand-file-name file)
|
||||||
|
find-sibling-rules)))
|
||||||
|
(cond
|
||||||
|
((null siblings)
|
||||||
|
(user-error "Couldn't find any sibling files"))
|
||||||
|
((length= siblings 1)
|
||||||
|
(find-file (car siblings)))
|
||||||
|
(t
|
||||||
|
(let ((relatives (mapcar (lambda (sibling)
|
||||||
|
(file-relative-name
|
||||||
|
sibling (file-name-directory file)))
|
||||||
|
siblings)))
|
||||||
|
(find-file
|
||||||
|
(completing-read (format-prompt "Find file" (car relatives))
|
||||||
|
relatives nil t nil nil (car relatives))))))))
|
||||||
|
|
||||||
|
(defun find-sibling-file-search (file &optional rules)
|
||||||
|
"Return a list of FILE's \"siblings\".
|
||||||
|
RULES should be a list on the form defined by `find-sibling-rules' (which
|
||||||
|
see), and if nil, defaults to `find-sibling-rules'."
|
||||||
|
(let ((results nil))
|
||||||
|
(pcase-dolist (`(,match . ,expansions) (or rules find-sibling-rules))
|
||||||
|
;; Go through the list and find matches.
|
||||||
|
(when (string-match match file)
|
||||||
|
(let ((match-data (match-data)))
|
||||||
|
(dolist (expansion expansions)
|
||||||
|
(let ((start 0))
|
||||||
|
;; Expand \\1 forms in the expansions.
|
||||||
|
(while (string-match "\\\\\\([&0-9]+\\)" expansion start)
|
||||||
|
(let ((index (string-to-number (match-string 1 expansion))))
|
||||||
|
(setq start (match-end 0)
|
||||||
|
expansion
|
||||||
|
(replace-match
|
||||||
|
(substring file
|
||||||
|
(elt match-data (* index 2))
|
||||||
|
(elt match-data (1+ (* index 2))))
|
||||||
|
t t expansion)))))
|
||||||
|
;; Then see which files we have that are matching. (And
|
||||||
|
;; expand from the end of the file's match, since we might
|
||||||
|
;; be doing a relative match.)
|
||||||
|
(let ((default-directory (substring file 0 (car match-data))))
|
||||||
|
;; Keep the first matches first.
|
||||||
|
(setq results
|
||||||
|
(nconc
|
||||||
|
results
|
||||||
|
(mapcar #'expand-file-name
|
||||||
|
(file-expand-wildcards expansion nil t)))))))))
|
||||||
|
;; Delete the file itself (in case it matched), and remove
|
||||||
|
;; duplicates, in case we have several expansions and some match
|
||||||
|
;; the same subsets of files.
|
||||||
|
(delete file (delete-dups results)))))
|
||||||
|
|
||||||
(provide 'doom-lib '(files))
|
(provide 'doom-lib '(files))
|
||||||
;;; files.el ends here
|
;;; files.el ends here
|
||||||
|
|
|
@ -168,7 +168,8 @@ selection of all minor-modes, active or not."
|
||||||
(location
|
(location
|
||||||
(goto-char location)))
|
(goto-char location)))
|
||||||
(ignore-errors
|
(ignore-errors
|
||||||
(when (outline-invisible-p)
|
(when (memq (get-char-property (point) 'invisible)
|
||||||
|
'(outline org-fold-outline))
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(outline-previous-visible-heading 1)
|
(outline-previous-visible-heading 1)
|
||||||
(org-show-subtree))))))
|
(org-show-subtree))))))
|
||||||
|
@ -575,7 +576,10 @@ If prefix arg is present, refresh the cache."
|
||||||
(pp-to-string recipe))))
|
(pp-to-string recipe))))
|
||||||
|
|
||||||
(package--print-help-section "Homepage")
|
(package--print-help-section "Homepage")
|
||||||
(doom--help-insert-button (doom-package-homepage package)))
|
(let ((homepage (doom-package-homepage package)))
|
||||||
|
(if homepage
|
||||||
|
(doom--help-insert-button homepage)
|
||||||
|
(insert "n/a"))))
|
||||||
|
|
||||||
(`elpa (insert "[M]ELPA ")
|
(`elpa (insert "[M]ELPA ")
|
||||||
(doom--help-insert-button (doom-package-homepage package))
|
(doom--help-insert-button (doom-package-homepage package))
|
||||||
|
|
|
@ -239,13 +239,14 @@ Must be run from a magit diff buffer."
|
||||||
(unless (= (length before) (length after))
|
(unless (= (length before) (length after))
|
||||||
(user-error "Uneven number of packages being bumped"))
|
(user-error "Uneven number of packages being bumped"))
|
||||||
(dolist (p1 before)
|
(dolist (p1 before)
|
||||||
(cl-destructuring-bind (package &key plist _beg _end &allow-other-keys) p1
|
(when (and (listp p1) (plist-get (cdr p1) :package))
|
||||||
(let ((p2 (cdr (assq package after))))
|
(cl-destructuring-bind (package &key plist _beg _end &allow-other-keys) p1
|
||||||
(if (null p2)
|
(let ((p2 (cdr (assq package after))))
|
||||||
(push package errors)
|
(if (null p2)
|
||||||
(let ((bstr1 (doom--package-to-bump-string package plist))
|
(push package errors)
|
||||||
(bstr2 (doom--package-to-bump-string package (plist-get p2 :plist))))
|
(let ((bstr1 (doom--package-to-bump-string package plist))
|
||||||
(cl-pushnew (format "%s -> %s" bstr1 bstr2) lines :test #'equal))))))
|
(bstr2 (doom--package-to-bump-string package (plist-get p2 :plist))))
|
||||||
|
(cl-pushnew (format "%s -> %s" bstr1 bstr2) lines :test #'equal)))))))
|
||||||
(if (null lines)
|
(if (null lines)
|
||||||
(user-error "No bumps to bumpify")
|
(user-error "No bumps to bumpify")
|
||||||
(prog1 (funcall (if interactive #'kill-new #'identity)
|
(prog1 (funcall (if interactive #'kill-new #'identity)
|
||||||
|
|
|
@ -84,7 +84,8 @@ and `format!' into colored output, where COLOR is any car of this list (or
|
||||||
(doom-print--indent
|
(doom-print--indent
|
||||||
(if args (apply #'format str args) str)
|
(if args (apply #'format str args) str)
|
||||||
"> ")))
|
"> ")))
|
||||||
(path . abbreviate-file-name)
|
(path . (lambda (&rest segments)
|
||||||
|
(abbreviate-file-name (apply #'doom-path segments))))
|
||||||
(symbol . symbol-name)
|
(symbol . symbol-name)
|
||||||
(relpath . (lambda (str &optional dir)
|
(relpath . (lambda (str &optional dir)
|
||||||
(if (or (not str)
|
(if (or (not str)
|
||||||
|
|
|
@ -149,14 +149,11 @@ If DIR is not a project, it will be indexed (but not cached)."
|
||||||
(if (doom-module-p :completion 'ivy)
|
(if (doom-module-p :completion 'ivy)
|
||||||
#'counsel-projectile-find-file
|
#'counsel-projectile-find-file
|
||||||
#'projectile-find-file)))
|
#'projectile-find-file)))
|
||||||
((and (bound-and-true-p vertico-mode)
|
|
||||||
(fboundp '+vertico/find-file-in))
|
|
||||||
(+vertico/find-file-in default-directory))
|
|
||||||
((and (bound-and-true-p ivy-mode)
|
((and (bound-and-true-p ivy-mode)
|
||||||
(fboundp 'counsel-file-jump))
|
(fboundp 'counsel-file-jump))
|
||||||
(call-interactively #'counsel-file-jump))
|
(call-interactively #'counsel-file-jump))
|
||||||
((project-current nil dir)
|
((when-let ((pr (project-current nil dir)))
|
||||||
(project-find-file-in nil nil dir))
|
(project-find-file-in nil nil pr)))
|
||||||
((and (bound-and-true-p helm-mode)
|
((and (bound-and-true-p helm-mode)
|
||||||
(fboundp 'helm-find-files))
|
(fboundp 'helm-find-files))
|
||||||
(call-interactively #'helm-find-files))
|
(call-interactively #'helm-find-files))
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
(defun doom-system-distro ()
|
(defun doom-system-distro ()
|
||||||
"Return a symbol representing the installed distro."
|
"Return a symbol representing the installed distro."
|
||||||
(with-memoization (get 'doom-system-distro 'cached-value)
|
(with-memoization (get 'doom-system-distro 'cached-value)
|
||||||
(cond (IS-WINDOWS 'windows)
|
(cond (doom--system-windows-p 'windows)
|
||||||
(IS-MAC 'macos)
|
(doom--system-macos-p 'macos)
|
||||||
((ignore-errors
|
((ignore-errors
|
||||||
(with-file-contents! "/etc/os-release"
|
(with-file-contents! "/etc/os-release"
|
||||||
(when (re-search-forward "^ID=\"?\\([^\"\n]+\\)\"?" nil t)
|
(when (re-search-forward "^ID=\"?\\([^\"\n]+\\)\"?" nil t)
|
||||||
|
@ -52,8 +52,8 @@
|
||||||
(with-memoization (get 'doom-system-distro-icon 'cached-value)
|
(with-memoization (get 'doom-system-distro-icon 'cached-value)
|
||||||
(propertize
|
(propertize
|
||||||
(pcase (doom-system-distro)
|
(pcase (doom-system-distro)
|
||||||
(`windows (all-the-icons-faicon "windows"))
|
(`windows (nerd-icons-faicon "nf-fa-windows"))
|
||||||
(`macos (all-the-icons-faicon "apple"))
|
(`macos (nerd-icons-faicon "nf-fa-apple"))
|
||||||
(`arch "\uF303")
|
(`arch "\uF303")
|
||||||
(`debian "\uF306")
|
(`debian "\uF306")
|
||||||
(`raspbian "\uF315")
|
(`raspbian "\uF315")
|
||||||
|
@ -74,7 +74,7 @@
|
||||||
(`devuan "\uF307")
|
(`devuan "\uF307")
|
||||||
(`manjaro "\uF312")
|
(`manjaro "\uF312")
|
||||||
((or `void `artix) "\uF17c")
|
((or `void `artix) "\uF17c")
|
||||||
(_ (all-the-icons-faicon "linux")))
|
(_ (nerd-icons-faicon "nf-fa-linux")))
|
||||||
'face '(:height 1)
|
'face '(:height 1)
|
||||||
'display '(raise 0))))
|
'display '(raise 0))))
|
||||||
|
|
||||||
|
|
|
@ -88,10 +88,11 @@ Uses `evil-visual-beginning' if available."
|
||||||
"Return end position of selection.
|
"Return end position of selection.
|
||||||
Uses `evil-visual-end' if available."
|
Uses `evil-visual-end' if available."
|
||||||
(declare (side-effect-free t))
|
(declare (side-effect-free t))
|
||||||
(if (and (bound-and-true-p evil-local-mode)
|
(or (and (bound-and-true-p evil-local-mode)
|
||||||
(evil-visual-state-p))
|
(evil-visual-state-p)
|
||||||
evil-visual-end
|
(markerp evil-visual-end)
|
||||||
(region-end)))
|
(marker-position evil-visual-end))
|
||||||
|
(region-end)))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom-thing-at-point-or-region (&optional thing prompt)
|
(defun doom-thing-at-point-or-region (&optional thing prompt)
|
||||||
|
|
|
@ -175,11 +175,18 @@ Use `winner-undo' to undo this. Alternatively, use
|
||||||
"Interactively change the current frame's opacity.
|
"Interactively change the current frame's opacity.
|
||||||
|
|
||||||
OPACITY is an integer between 0 to 100, inclusive."
|
OPACITY is an integer between 0 to 100, inclusive."
|
||||||
(interactive
|
(interactive '(interactive))
|
||||||
(list (read-number "Opacity (0-100): "
|
(let* ((parameter
|
||||||
(or (frame-parameter nil 'alpha)
|
(if (eq window-system 'pgtk)
|
||||||
100))))
|
'alpha-background
|
||||||
(set-frame-parameter nil 'alpha opacity))
|
'alpha))
|
||||||
|
(opacity
|
||||||
|
(if (eq opacity 'interactive)
|
||||||
|
(read-number "Opacity (0-100): "
|
||||||
|
(or (frame-parameter nil parameter)
|
||||||
|
100))
|
||||||
|
opacity)))
|
||||||
|
(set-frame-parameter nil parameter opacity)))
|
||||||
|
|
||||||
(defvar doom--narrowed-base-buffer nil)
|
(defvar doom--narrowed-base-buffer nil)
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
|
@ -191,12 +198,9 @@ narrowing doesn't affect other windows displaying the same buffer. Call
|
||||||
`doom/widen-indirectly-narrowed-buffer' to undo it (incrementally).
|
`doom/widen-indirectly-narrowed-buffer' to undo it (incrementally).
|
||||||
|
|
||||||
Inspired from http://demonastery.org/2013/04/emacs-evil-narrow-region/"
|
Inspired from http://demonastery.org/2013/04/emacs-evil-narrow-region/"
|
||||||
(interactive
|
(interactive (if (region-active-p)
|
||||||
(list (or (bound-and-true-p evil-visual-beginning) (region-beginning))
|
(list (doom-region-beginning) (doom-region-end))
|
||||||
(or (bound-and-true-p evil-visual-end) (region-end))))
|
(list (bol) (eol))))
|
||||||
(unless (region-active-p)
|
|
||||||
(setq beg (line-beginning-position)
|
|
||||||
end (line-end-position)))
|
|
||||||
(deactivate-mark)
|
(deactivate-mark)
|
||||||
(let ((orig-buffer (current-buffer)))
|
(let ((orig-buffer (current-buffer)))
|
||||||
(with-current-buffer (switch-to-buffer (clone-indirect-buffer nil nil))
|
(with-current-buffer (switch-to-buffer (clone-indirect-buffer nil nil))
|
||||||
|
@ -235,12 +239,9 @@ If the current buffer is not an indirect buffer, it is `widen'ed."
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/toggle-narrow-buffer (beg end)
|
(defun doom/toggle-narrow-buffer (beg end)
|
||||||
"Narrow the buffer to BEG END. If narrowed, widen it."
|
"Narrow the buffer to BEG END. If narrowed, widen it."
|
||||||
(interactive
|
(interactive (if (region-active-p)
|
||||||
(list (or (bound-and-true-p evil-visual-beginning) (region-beginning))
|
(list (doom-region-beginning) (doom-region-end))
|
||||||
(or (bound-and-true-p evil-visual-end) (region-end))))
|
(list (bol) (eol))))
|
||||||
(if (buffer-narrowed-p)
|
(if (buffer-narrowed-p)
|
||||||
(widen)
|
(widen)
|
||||||
(unless (region-active-p)
|
|
||||||
(setq beg (line-beginning-position)
|
|
||||||
end (line-end-position)))
|
|
||||||
(narrow-to-region beg end)))
|
(narrow-to-region beg end)))
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
;;; lisp/packages.el
|
;;; lisp/packages.el
|
||||||
|
|
||||||
;; doom.el
|
;; doom.el
|
||||||
(package! auto-minor-mode :pin "17cfa1b54800fdef2975c0c0531dad34846a5065")
|
(package! auto-minor-mode
|
||||||
(package! gcmh :pin "0089f9c3a6d4e9a310d0791cf6fa8f35642ecfd9")
|
:pin "17cfa1b54800fdef2975c0c0531dad34846a5065")
|
||||||
(package! explain-pause-mode
|
(package! compat
|
||||||
:recipe (:host github
|
:recipe (:host github :repo "emacs-compat/compat")
|
||||||
:repo "lastquestion/explain-pause-mode")
|
:pin "8d4e8a366681def88751f5e9975738ecd3180deb")
|
||||||
:pin "2356c8c3639cbeeb9751744dbe737267849b4b51")
|
(package! gcmh
|
||||||
|
:pin "0089f9c3a6d4e9a310d0791cf6fa8f35642ecfd9")
|
||||||
|
|
||||||
;; doom-packages.el
|
;; doom-packages.el
|
||||||
(package! straight
|
(package! straight
|
||||||
|
@ -17,21 +18,21 @@
|
||||||
:branch ,straight-repository-branch
|
:branch ,straight-repository-branch
|
||||||
:local-repo "straight.el"
|
:local-repo "straight.el"
|
||||||
:files ("straight*.el"))
|
:files ("straight*.el"))
|
||||||
:pin "5e84c4e2cd8ca79560477782ee4c9e5187725def")
|
:pin "b1062df10ba4c10ff7a3c61b9e124b3242b11bb2")
|
||||||
|
|
||||||
;; doom-ui.el
|
;; doom-ui.el
|
||||||
(package! all-the-icons :pin "f491f39c21336d354e85bdb4cca281e0a0c2f880")
|
(package! nerd-icons :pin "8095215a503d8048739de8b4ea4066598edb8cbb")
|
||||||
(package! hide-mode-line :pin "bc5d293576c5e08c29e694078b96a5ed85631942")
|
(package! hide-mode-line :pin "bc5d293576c5e08c29e694078b96a5ed85631942")
|
||||||
(package! highlight-numbers :pin "8b4744c7f46c72b1d3d599d4fb75ef8183dee307")
|
(package! highlight-numbers :pin "8b4744c7f46c72b1d3d599d4fb75ef8183dee307")
|
||||||
(package! rainbow-delimiters :pin "a32b39bdfe6c61c322c37226d66e1b6d4f107ed0")
|
(package! rainbow-delimiters :pin "f40ece58df8b2f0fb6c8576b527755a552a5e763")
|
||||||
(package! restart-emacs :pin "1607da2bc657fe05ae01f7fdf26f716eafead02c")
|
(package! restart-emacs :pin "1607da2bc657fe05ae01f7fdf26f716eafead02c")
|
||||||
|
|
||||||
;; doom-editor.el
|
;; doom-editor.el
|
||||||
(package! better-jumper :pin "47622213783ece37d5337dc28d33b530540fc319")
|
(package! better-jumper :pin "47622213783ece37d5337dc28d33b530540fc319")
|
||||||
(package! dtrt-indent :pin "be07f4979a5b402a0cf5311c86c30b89ca0e1ee4")
|
(package! dtrt-indent :pin "5d1b44f9a1a484ca229cc14f8062609a10ef4891")
|
||||||
(package! helpful :pin "c57ff0d284b50ff430fe1f13fd48deaa0d1a910e")
|
(package! helpful :pin "a32a5b3d959a7fccf09a71d97b3d7c888ac31c69")
|
||||||
(package! pcre2el :pin "b941ed8a96299868171fac625ecffec77de3e986")
|
(package! pcre2el :pin "380723b2701cceb75c266440fb8db918f3340d50")
|
||||||
(package! smartparens :pin "79a338db115f441cd47bb91e6f75816c5e78a772")
|
(package! smartparens :pin "ddc6233ea6fc2da7a3a8e44face465c15631b02b")
|
||||||
(package! ws-butler
|
(package! ws-butler
|
||||||
;; Use my fork of ws-butler, which has a few choice improvements and
|
;; Use my fork of ws-butler, which has a few choice improvements and
|
||||||
;; optimizations (the original has been abandoned).
|
;; optimizations (the original has been abandoned).
|
||||||
|
@ -39,13 +40,9 @@
|
||||||
:pin "572a10c11b6cb88293de48acbb59a059d36f9ba5")
|
:pin "572a10c11b6cb88293de48acbb59a059d36f9ba5")
|
||||||
|
|
||||||
;; doom-projects.el
|
;; doom-projects.el
|
||||||
(package! projectile :pin "971cd5c4f25ff1f84ab7e8337ffc7f89f67a1b52")
|
(package! projectile :pin "0163b335a18af0f077a474d4dc6b36e22b5e3274")
|
||||||
(package! project :pin "6c41ad68edf1f44110abe478d17c36f57a517e66")
|
(package! project :pin "b6989856abe9411872bdff5c8aa190bef4d86409")
|
||||||
|
|
||||||
;; doom-keybinds.el
|
;; doom-keybinds.el
|
||||||
(package! general :pin "833dea2c4a60e06fcd552b653dfc8960935c9fb4")
|
(package! general :pin "ced143c30de8e20f5a3761a465e684a1dc48471e")
|
||||||
(package! which-key :pin "df6b0cb8449812e7fb200bc852107fa7eb708496")
|
(package! which-key :pin "96911a1d3faf8426a33241f4821319e98421f380")
|
||||||
|
|
||||||
(package! compat
|
|
||||||
:recipe (:host github :repo "emacs-compat/compat")
|
|
||||||
:pin "75d0b8527f51aae42d23eee4aeb263e19055747e")
|
|
||||||
|
|
|
@ -330,7 +330,7 @@ Modules that turn Emacs in an email client.
|
||||||
|
|
||||||
This module makes Emacs an email client, using [[https://www.djcbsoftware.nl/code/mu/mu4e.html][mu4e]].
|
This module makes Emacs an email client, using [[https://www.djcbsoftware.nl/code/mu/mu4e.html][mu4e]].
|
||||||
|
|
||||||
- Tidied mu4e headers view, with flags from [[doom-package:all-the-icons]].
|
- Tidied mu4e headers view, with flags from [[doom-package:nerd-icons]].
|
||||||
- Consistent coloring of reply depths (across compose and gnus modes).
|
- Consistent coloring of reply depths (across compose and gnus modes).
|
||||||
- Prettified =mu4e:main= view.
|
- Prettified =mu4e:main= view.
|
||||||
- Cooperative locking of the =mu= process. Another Emacs instance may request
|
- Cooperative locking of the =mu= process. Another Emacs instance may request
|
||||||
|
@ -1152,8 +1152,8 @@ you'd expect from IDEs, like code completion, realtime linting, language-aware
|
||||||
|
|
||||||
As of this writing, this is the state of LSP support in Doom Emacs:
|
As of this writing, this is the state of LSP support in Doom Emacs:
|
||||||
|
|
||||||
| Module | Major modes | Default language server |
|
| Module | Major modes | Default language server |
|
||||||
|------------------+---------------------------------------------------------+---------------------------------------------------------------|
|
|----------------------------------+---------------------------------------------------------+---------------------------------------------------------------|
|
||||||
| [[doom-module::lang cc]] | c-mode, c++-mode, objc-mode | ccls, clangd |
|
| [[doom-module::lang cc]] | c-mode, c++-mode, objc-mode | ccls, clangd |
|
||||||
| [[doom-module::lang clojure]] | clojure-mode | clojure-lsp |
|
| [[doom-module::lang clojure]] | clojure-mode | clojure-lsp |
|
||||||
| [[doom-module::lang csharp]] | csharp-mode | omnisharp |
|
| [[doom-module::lang csharp]] | csharp-mode | omnisharp |
|
||||||
|
@ -1417,12 +1417,12 @@ emacs fontset to cover as many unicode glyphs as possible by scanning all
|
||||||
available glyphs from all available fonts.
|
available glyphs from all available fonts.
|
||||||
|
|
||||||
When this module is enabled:
|
When this module is enabled:
|
||||||
- Emacs will prefer to use the ~doom-unicode-font~ font to display non-latin
|
- Emacs will prefer to use the ~doom-symbol-font~ font to display non-latin
|
||||||
glyphs if it provides coverage for them.
|
glyphs if it provides coverage for them.
|
||||||
- The first time you run Emacs a unicode cache will be generated -- this will
|
- The first time you run Emacs a unicode cache will be generated -- this will
|
||||||
take a while!
|
take a while!
|
||||||
- The cache will be regenerated every time Emacs is made aware of new fonts or
|
- The cache will be regenerated every time Emacs is made aware of new fonts or
|
||||||
you change the font configuration e.g. by modifying ~doom-unicode-font~.
|
you change the font configuration e.g. by modifying ~doom-symbol-font~.
|
||||||
- The cache will be stored and should not be regenerated unless font-related
|
- The cache will be stored and should not be regenerated unless font-related
|
||||||
configuration or the versions of relevant packages changes.
|
configuration or the versions of relevant packages changes.
|
||||||
|
|
||||||
|
|
|
@ -34,12 +34,12 @@ This module requires:
|
||||||
|
|
||||||
* TODO Usage
|
* TODO Usage
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]
|
This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
* TODO Configuration
|
* TODO Configuration
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
/This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
** Changing calendar sources
|
** Changing calendar sources
|
||||||
|
@ -74,5 +74,5 @@ to link your calendar with Google calendars.
|
||||||
|
|
||||||
* TODO Appendix
|
* TODO Appendix
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
|
@ -5,4 +5,4 @@
|
||||||
(package! calfw-org :pin "03abce97620a4a7f7ec5f911e669da9031ab9088")
|
(package! calfw-org :pin "03abce97620a4a7f7ec5f911e669da9031ab9088")
|
||||||
(package! calfw-cal :pin "03abce97620a4a7f7ec5f911e669da9031ab9088")
|
(package! calfw-cal :pin "03abce97620a4a7f7ec5f911e669da9031ab9088")
|
||||||
(package! calfw-ical :pin "03abce97620a4a7f7ec5f911e669da9031ab9088")
|
(package! calfw-ical :pin "03abce97620a4a7f7ec5f911e669da9031ab9088")
|
||||||
(package! org-gcal :pin "9bb3720525ad1c45823abab8ce910dd1225e7dcd")
|
(package! org-gcal :pin "a2d16b372e5a5972d8cc343cf999ee5f0ba1eea7")
|
||||||
|
|
|
@ -34,7 +34,7 @@ These should be available through your OS package manager.
|
||||||
|
|
||||||
* TODO Usage
|
* TODO Usage
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
/This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
** Keybinds
|
** Keybinds
|
||||||
|
@ -56,7 +56,7 @@ These should be available through your OS package manager.
|
||||||
|
|
||||||
* TODO Configuration
|
* TODO Configuration
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]]
|
This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
* Troubleshooting
|
* Troubleshooting
|
||||||
|
@ -70,5 +70,5 @@ Try [[kbd:][M-x +emms/mpd-restart-music-daemon]] then restart emacs.
|
||||||
|
|
||||||
* TODO Appendix
|
* TODO Appendix
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
;; -*- no-byte-compile: t; -*-
|
;; -*- no-byte-compile: t; -*-
|
||||||
;;; app/emms/packages.el
|
;;; app/emms/packages.el
|
||||||
|
|
||||||
(package! emms :pin "43c61412492229eb641fe572c89c826d8fcf64d9")
|
(package! emms :pin "87d0d1fb0566a80229029d0d8d7c863138d70aae")
|
||||||
|
|
|
@ -68,5 +68,5 @@ Most other behavior is implemented as hooks on ~emacs-everywhere-init-hooks~.
|
||||||
|
|
||||||
* TODO Appendix
|
* TODO Appendix
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
|
@ -8,19 +8,23 @@
|
||||||
:config
|
:config
|
||||||
(set-yas-minor-mode! 'emacs-everywhere-mode)
|
(set-yas-minor-mode! 'emacs-everywhere-mode)
|
||||||
|
|
||||||
;; HACK Inhibit MAJOR-MODE-local-vars-hook in emacs-everywhere buffers,
|
;; HACK: Inhibit MAJOR-MODE-local-vars-hook in emacs-everywhere buffers,
|
||||||
;; because Doom commonly starts servers and other extraneous services on
|
;; because Doom commonly starts servers and other extraneous services on
|
||||||
;; this hook, which will rarely work well in emacs-everywhere's temporary
|
;; this hook, which will rarely work well in emacs-everywhere's temporary
|
||||||
;; buffers anyway.
|
;; buffers anyway.
|
||||||
(setq-hook! 'emacs-everywhere-init-hooks doom-inhibit-local-var-hooks t)
|
(setq-hook! 'emacs-everywhere-init-hooks doom-inhibit-local-var-hooks t)
|
||||||
|
|
||||||
|
;; REVIEW: Fixes tecosaur/emacs-everywhere#75. Remove when dealt with
|
||||||
|
;; upstream.
|
||||||
|
(define-key emacs-everywhere-mode-map "\C-c\C-c" #'emacs-everywhere-finish)
|
||||||
|
|
||||||
(after! doom-modeline
|
(after! doom-modeline
|
||||||
(doom-modeline-def-segment emacs-everywhere
|
(doom-modeline-def-segment emacs-everywhere
|
||||||
(concat
|
(concat
|
||||||
(doom-modeline-spc)
|
(doom-modeline-spc)
|
||||||
(when (emacs-everywhere-markdown-p)
|
(when (emacs-everywhere-markdown-p)
|
||||||
(concat
|
(concat
|
||||||
(all-the-icons-octicon "markdown" :face 'all-the-icons-green :v-adjust 0.02)
|
(nerd-icons-octicon "nf-oct-markdown" :face 'nerd-icons-green :v-adjust 0.02)
|
||||||
(doom-modeline-spc)))
|
(doom-modeline-spc)))
|
||||||
(propertize (emacs-everywhere-app-class emacs-everywhere-current-app)
|
(propertize (emacs-everywhere-app-class emacs-everywhere-current-app)
|
||||||
'face 'doom-modeline-project-dir)
|
'face 'doom-modeline-project-dir)
|
||||||
|
@ -32,7 +36,7 @@
|
||||||
(doom-modeline-def-modeline 'emacs-everywhere
|
(doom-modeline-def-modeline 'emacs-everywhere
|
||||||
'(bar modals emacs-everywhere buffer-position
|
'(bar modals emacs-everywhere buffer-position
|
||||||
word-count parrot selection-info)
|
word-count parrot selection-info)
|
||||||
'(input-method major-mode checker
|
'(input-method major-mode check
|
||||||
#(" " 0 1 ; "Exit to app" icon + a little padding
|
#(" " 0 1 ; "Exit to app" icon + a little padding
|
||||||
(rear-nonsticky t
|
(rear-nonsticky t
|
||||||
display (raise -0.25)
|
display (raise -0.25)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
;;; app/everywhere/doctor.el -*- lexical-binding: t; -*-
|
;;; app/everywhere/doctor.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
(when IS-WINDOWS
|
(when (featurep :system 'windows)
|
||||||
(error! "emacs-everywhere package does not support windows."))
|
(error! "emacs-everywhere package does not support windows."))
|
||||||
|
|
||||||
(when IS-LINUX
|
(when (featurep :system 'linux)
|
||||||
(let (unmet-deps)
|
(let (unmet-deps)
|
||||||
(dolist (dep '("xclip" "xdotool" "xprop" "xwininfo"))
|
(dolist (dep '("xclip" "xdotool" "xprop" "xwininfo"))
|
||||||
(unless (executable-find dep)
|
(unless (executable-find dep)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
;; -*- no-byte-compile: t; -*-
|
;; -*- no-byte-compile: t; -*-
|
||||||
;;; app/everywhere/packages.el
|
;;; app/everywhere/packages.el
|
||||||
|
|
||||||
(package! emacs-everywhere :pin "b461c4b42093abc42e5ec0f73cb7021c2915cea8")
|
(package! emacs-everywhere :pin "fbeff19825336777dccaefedf3f376dd622cd294")
|
||||||
|
|
|
@ -52,7 +52,7 @@ environment.systemPackages = [ pkgs.gnutls ];
|
||||||
|
|
||||||
* TODO Usage
|
* TODO Usage
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
/This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
To connect to IRC use ~M-x =irc~.
|
To connect to IRC use ~M-x =irc~.
|
||||||
|
@ -70,7 +70,7 @@ When in a circe buffer these keybindings will be available:
|
||||||
|
|
||||||
* TODO Configuration
|
* TODO Configuration
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
/This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
Use ~set-irc-server! SERVER PLIST~ to configure IRC servers. Its second argument
|
Use ~set-irc-server! SERVER PLIST~ to configure IRC servers. Its second argument
|
||||||
|
@ -92,7 +92,7 @@ here are ways to avoid that:
|
||||||
|
|
||||||
** TODO Pass: the unix password manager
|
** TODO Pass: the unix password manager
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This section is outdated and needs to be rewritten./ [[doom-contrib-module:][Rewrite it?]]
|
/This section is outdated and needs to be rewritten./ [[doom-contrib-module:][Rewrite it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
[[https://www.passwordstore.org/][Pass]] is my tool of choice. I use it to manage my passwords. If you activate the
|
[[https://www.passwordstore.org/][Pass]] is my tool of choice. I use it to manage my passwords. If you activate the
|
||||||
|
@ -169,5 +169,5 @@ username: myusername
|
||||||
|
|
||||||
* TODO Appendix
|
* TODO Appendix
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
|
@ -55,7 +55,8 @@ workspace for it."
|
||||||
circe-server-killed-confirmation)
|
circe-server-killed-confirmation)
|
||||||
(when +irc--defer-timer
|
(when +irc--defer-timer
|
||||||
(cancel-timer +irc--defer-timer))
|
(cancel-timer +irc--defer-timer))
|
||||||
(disable-circe-notifications)
|
(when (fboundp #'disable-circe-notifications)
|
||||||
|
(disable-circe-notifications))
|
||||||
(mapc #'kill-buffer (doom-buffers-in-mode 'circe-mode (buffer-list) t))
|
(mapc #'kill-buffer (doom-buffers-in-mode 'circe-mode (buffer-list) t))
|
||||||
(when (modulep! :ui workspaces)
|
(when (modulep! :ui workspaces)
|
||||||
(when (equal (+workspace-current-name) +irc--workspace-name)
|
(when (equal (+workspace-current-name) +irc--workspace-name)
|
||||||
|
|
|
@ -187,8 +187,8 @@ playback.")
|
||||||
(setq circe-notifications-watch-strings +irc-notifications-watch-strings
|
(setq circe-notifications-watch-strings +irc-notifications-watch-strings
|
||||||
circe-notifications-emacs-focused nil
|
circe-notifications-emacs-focused nil
|
||||||
circe-notifications-alert-style
|
circe-notifications-alert-style
|
||||||
(cond (IS-MAC 'osx-notifier)
|
(cond ((featurep :system 'macos) 'osx-notifier)
|
||||||
(IS-LINUX 'libnotify)
|
((featurep :system 'linux) 'libnotify)
|
||||||
(circe-notifications-alert-style))))
|
(circe-notifications-alert-style))))
|
||||||
|
|
||||||
|
|
||||||
|
|
5
modules/app/irc/doctor.el
Normal file
5
modules/app/irc/doctor.el
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||||
|
;;; app/irc/doctor.el
|
||||||
|
|
||||||
|
(when (memq 'circe-notifications doom-disabled-packages)
|
||||||
|
(warn! "Circe Notifications has been disabled, You will not receive desktop notifications from IRC channels."))
|
|
@ -1,5 +1,5 @@
|
||||||
;; -*- no-byte-compile: t; -*-
|
;; -*- no-byte-compile: t; -*-
|
||||||
;;; app/irc/packages.el
|
;;; app/irc/packages.el
|
||||||
|
|
||||||
(package! circe :pin "57fe189d7c0b98b9b1b5a59767cea1c7e2c22b13")
|
(package! circe :pin "d374042741cfd0691135f215d311dca8b7a47d19")
|
||||||
(package! circe-notifications :pin "291149ac12877bbd062da993479d3533a26862b0")
|
(package! circe-notifications :pin "291149ac12877bbd062da993479d3533a26862b0")
|
||||||
|
|
|
@ -39,7 +39,7 @@ Read RSS feeds in the comfort of Emacs.
|
||||||
|
|
||||||
* TODO Usage
|
* TODO Usage
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
/This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
- As there isn't currently binding for ~elfeed-update~ you can run it with ~M-x
|
- As there isn't currently binding for ~elfeed-update~ you can run it with ~M-x
|
||||||
|
@ -47,7 +47,7 @@ Read RSS feeds in the comfort of Emacs.
|
||||||
|
|
||||||
* TODO Configuration
|
* TODO Configuration
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
/This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
** Without +org
|
** Without +org
|
||||||
|
@ -78,7 +78,7 @@ configure feeds to follow:
|
||||||
- You can "name" feeds as you please with ~org-mode~ ~org-insert-link~ ([[kbd:][C-c C-l]])
|
- You can "name" feeds as you please with ~org-mode~ ~org-insert-link~ ([[kbd:][C-c C-l]])
|
||||||
and put name as you want into ~description~.
|
and put name as you want into ~description~.
|
||||||
- If you don't want to use ~org-directory/elfeed.org~ file you can specify it
|
- If you don't want to use ~org-directory/elfeed.org~ file you can specify it
|
||||||
with ~(setq rmh-elfeed-org-files '("path/to/your/elfeed/file.org))~
|
with ~(setq rmh-elfeed-org-files '("path/to/your/elfeed/file.org"))~
|
||||||
|
|
||||||
** Keybindings
|
** Keybindings
|
||||||
+ General
|
+ General
|
||||||
|
@ -128,5 +128,5 @@ Hook ~elfeed-update~ to ~elfeed-search-mode-hook~:
|
||||||
|
|
||||||
* TODO Appendix
|
* TODO Appendix
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
|
@ -14,8 +14,9 @@ easier to scroll through.")
|
||||||
(defvar +rss-workspace-name "*rss*"
|
(defvar +rss-workspace-name "*rss*"
|
||||||
"Name of the workspace that contains the elfeed buffer.")
|
"Name of the workspace that contains the elfeed buffer.")
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Packages
|
;;; Packages
|
||||||
|
|
||||||
(use-package! elfeed
|
(use-package! elfeed
|
||||||
:commands elfeed
|
:commands elfeed
|
||||||
|
@ -83,6 +84,7 @@ easier to scroll through.")
|
||||||
(message "elfeed-org: ignoring %S because it can't be read" file))
|
(message "elfeed-org: ignoring %S because it can't be read" file))
|
||||||
(setq rmh-elfeed-org-files (cl-remove-if-not #'file-exists-p files))))))
|
(setq rmh-elfeed-org-files (cl-remove-if-not #'file-exists-p files))))))
|
||||||
|
|
||||||
|
|
||||||
(use-package! elfeed-goodies
|
(use-package! elfeed-goodies
|
||||||
:after elfeed
|
:after elfeed
|
||||||
:config
|
:config
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
;; -*- no-byte-compile: t; -*-
|
;; -*- no-byte-compile: t; -*-
|
||||||
;;; app/rss/packages.el
|
;;; app/rss/packages.el
|
||||||
|
|
||||||
(package! elfeed :pin "162d7d545ed41c27967d108c04aa31f5a61c8e16")
|
(package! elfeed :pin "55fb162fa27e71b88effa59a83c57842e262b00f")
|
||||||
(package! elfeed-goodies :pin "544ef42ead011d960a0ad1c1d34df5d222461a6b")
|
(package! elfeed-goodies :pin "544ef42ead011d960a0ad1c1d34df5d222461a6b")
|
||||||
(when (modulep! +org)
|
(when (modulep! +org)
|
||||||
(package! elfeed-org :pin "3242ec0519800a58f20480c8a6e3b3337d137084"))
|
(package! elfeed-org :pin "d62d23e25c5e3be3d70b7fbe1eaeb6e43f93a061"))
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
#+created: October 11, 2019
|
#+created: October 11, 2019
|
||||||
#+since: 2.0.0
|
#+since: 2.0.0
|
||||||
|
|
||||||
|
#+begin_quote
|
||||||
|
*This module is deprecated.* Changes upstream to Twitter's API has rendered
|
||||||
|
twittering-mode non-functional, and there is no known alternative.
|
||||||
|
#+end_quote
|
||||||
|
|
||||||
* Description :unfold:
|
* Description :unfold:
|
||||||
Enjoy twitter from emacs.
|
Enjoy twitter from emacs.
|
||||||
|
|
||||||
|
@ -48,12 +53,12 @@ This module requires:
|
||||||
|
|
||||||
* TODO Usage
|
* TODO Usage
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]
|
This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
* TODO Configuration
|
* TODO Configuration
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
/This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
** Commands & Keybindings
|
** Commands & Keybindings
|
||||||
|
@ -96,6 +101,6 @@ key for evil users. To work around this issue you may use [[kbd:][M-SPC]] instea
|
||||||
|
|
||||||
* TODO Appendix
|
* TODO Appendix
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
;;; app/twitter/packages.el
|
;;; app/twitter/packages.el
|
||||||
|
|
||||||
(package! twittering-mode :pin "114891e8fdb4f06b1326a6cf795e49c205cf9e29")
|
(package! twittering-mode :pin "114891e8fdb4f06b1326a6cf795e49c205cf9e29")
|
||||||
(package! avy :pin "955c8dedd68c74f3cf692c1249513f048518c4c9")
|
(package! avy :pin "be612110cb116a38b8603df367942e2bb3d9bdbe")
|
||||||
|
|
|
@ -41,7 +41,7 @@ will need to set ~langtool-language-tool-jar~ to its location.
|
||||||
|
|
||||||
* TODO Usage
|
* TODO Usage
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
/This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
** Language Tool
|
** Language Tool
|
||||||
|
@ -49,7 +49,7 @@ will need to set ~langtool-language-tool-jar~ to its location.
|
||||||
stylistic issues in your writing. This requires Java 1.8+.
|
stylistic issues in your writing. This requires Java 1.8+.
|
||||||
|
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🚧 This requires Java 1.8+
|
This requires Java 1.8+
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
*** Commands
|
*** Commands
|
||||||
|
@ -61,7 +61,7 @@ This minor mode highlights weasel words, duplication and passive voice.
|
||||||
|
|
||||||
* TODO Configuration
|
* TODO Configuration
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]]
|
This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
* Troubleshooting
|
* Troubleshooting
|
||||||
|
@ -72,5 +72,5 @@ This minor mode highlights weasel words, duplication and passive voice.
|
||||||
|
|
||||||
* TODO Appendix
|
* TODO Appendix
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
(cond ((setq langtool-bin
|
(cond ((setq langtool-bin
|
||||||
(or (executable-find "languagetool-commandline")
|
(or (executable-find "languagetool-commandline")
|
||||||
(executable-find "languagetool")))) ; for nixpkgs.languagetool
|
(executable-find "languagetool")))) ; for nixpkgs.languagetool
|
||||||
(IS-MAC
|
((featurep :system 'macos)
|
||||||
(cond
|
(cond
|
||||||
;; is user using home brew?
|
;; is user using home brew?
|
||||||
((file-directory-p "/usr/local/Cellar/languagetool")
|
((file-directory-p "/usr/local/Cellar/languagetool")
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
;; macports compatibility
|
;; macports compatibility
|
||||||
((file-directory-p "/opt/local/share/java/LanguageTool")
|
((file-directory-p "/opt/local/share/java/LanguageTool")
|
||||||
(setq langtool-java-classpath "/opt/local/share/java/LanguageTool/*"))))
|
(setq langtool-java-classpath "/opt/local/share/java/LanguageTool/*"))))
|
||||||
(IS-LINUX
|
((featurep :system 'linux)
|
||||||
(setq langtool-java-classpath "/usr/share/languagetool:/usr/share/java/languagetool/*")))))
|
(setq langtool-java-classpath "/usr/share/languagetool:/usr/share/java/languagetool/*")))))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
;; -*- no-byte-compile: t; -*-
|
;; -*- no-byte-compile: t; -*-
|
||||||
;;; checkers/grammar/packages.el
|
;;; checkers/grammar/packages.el
|
||||||
|
|
||||||
(package! langtool :pin "8276eccc5587bc12fd205ee58a7a982f0a136e41")
|
(package! langtool :pin "d86101eafe9a994eb0425e08e7c1795e9cb0cd42")
|
||||||
(package! writegood-mode :pin "ed42d918d98826ad88928b7af9f2597502afc6b0")
|
(package! writegood-mode :pin "d54eadeedb8bf3aa0e0a584c0a7373c69644f4b8")
|
||||||
|
|
|
@ -58,7 +58,7 @@ your system and in your =$PATH=. They also need dictionaries for your
|
||||||
language(s).
|
language(s).
|
||||||
|
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🚧 If you *are not* using [[doom-module:+flyspell]], you will need =aspell= (and a dictionary)
|
If you *are not* using [[doom-module:+flyspell]], you will need =aspell= (and a dictionary)
|
||||||
installed whether or not you have [[doom-module:+hunspell]] or [[doom-module:+enchant]] enabled. This is
|
installed whether or not you have [[doom-module:+hunspell]] or [[doom-module:+enchant]] enabled. This is
|
||||||
because [[doom-package:spell-fu]] does not support generating the word list with anything
|
because [[doom-package:spell-fu]] does not support generating the word list with anything
|
||||||
other than =aspell= yet.
|
other than =aspell= yet.
|
||||||
|
@ -108,7 +108,7 @@ language(s).
|
||||||
|
|
||||||
* TODO Usage
|
* TODO Usage
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
/This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
When using [[doom-module:+everywhere]], spell checking is performed for as many major modes as
|
When using [[doom-module:+everywhere]], spell checking is performed for as many major modes as
|
||||||
|
@ -117,7 +117,7 @@ major modes.
|
||||||
|
|
||||||
* TODO Configuration
|
* TODO Configuration
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
/This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
Dictionary is set by ~ispell-dictionary~ variable. Can be changed locally with
|
Dictionary is set by ~ispell-dictionary~ variable. Can be changed locally with
|
||||||
|
@ -231,5 +231,5 @@ After the file is created, restart emacs and adding words should work.
|
||||||
|
|
||||||
* TODO Appendix
|
* TODO Appendix
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
;;; checkers/spell/packages.el
|
;;; checkers/spell/packages.el
|
||||||
|
|
||||||
(if (not (modulep! +flyspell))
|
(if (not (modulep! +flyspell))
|
||||||
(package! spell-fu :pin "aed6e87aa31013534b7a6cbedb26e4f29ccea735")
|
(package! spell-fu
|
||||||
(package! flyspell-correct :pin "7d7b6b01188bd28e20a13736ac9f36c3367bd16e")
|
:recipe (:host github :repo "emacsmirror/spell-fu")
|
||||||
|
:pin "e4031935803c66eca2f076dce72b0a6a770d026c")
|
||||||
|
(package! flyspell-correct :pin "1e7a5a56362dd875dddf848b9a9e25d1395b9d37")
|
||||||
(cond ((modulep! :completion ivy)
|
(cond ((modulep! :completion ivy)
|
||||||
(package! flyspell-correct-ivy))
|
(package! flyspell-correct-ivy))
|
||||||
((modulep! :completion helm)
|
((modulep! :completion helm)
|
||||||
|
|
|
@ -40,7 +40,7 @@ find out if you're missing any dependencies.
|
||||||
|
|
||||||
* TODO Usage
|
* TODO Usage
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
/This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
Most of flycheck's features are under [[kbd:][C-c !]], regardless of whether evil mode is
|
Most of flycheck's features are under [[kbd:][C-c !]], regardless of whether evil mode is
|
||||||
|
@ -67,7 +67,7 @@ Evil Specific:
|
||||||
|
|
||||||
* TODO Configuration
|
* TODO Configuration
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]]
|
This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
* Troubleshooting
|
* Troubleshooting
|
||||||
|
@ -81,5 +81,5 @@ Evil Specific:
|
||||||
|
|
||||||
* TODO Appendix
|
* TODO Appendix
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
;;; checkers/syntax/packages.el
|
;;; checkers/syntax/packages.el
|
||||||
|
|
||||||
(unless (modulep! +flymake)
|
(unless (modulep! +flymake)
|
||||||
(package! flycheck :pin "784f184cdd9f9cb4e3dbb997c09d93e954142842")
|
(package! flycheck :pin "02148c6ce7edb0fd0986460db327cc9463939747")
|
||||||
(package! flycheck-popup-tip :pin "ef86aad907f27ca076859d8d9416f4f7727619c6")
|
(package! flycheck-popup-tip :pin "ef86aad907f27ca076859d8d9416f4f7727619c6")
|
||||||
(when (modulep! +childframe)
|
(when (modulep! +childframe)
|
||||||
(package! flycheck-posframe :pin "8f60c9bf124ab9597d681504a73fdf116a0bde12")))
|
(package! flycheck-posframe :pin "19896b922c76a0f460bf3fe8d8ebc2f9ac9028d8")))
|
||||||
|
|
||||||
;; Flymake
|
;; Flymake
|
||||||
(when (modulep! +flymake)
|
(when (modulep! +flymake)
|
||||||
|
|
|
@ -44,7 +44,7 @@ find out if you're missing any dependencies.
|
||||||
|
|
||||||
* TODO Usage
|
* TODO Usage
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
/This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
** Code completion
|
** Code completion
|
||||||
|
@ -87,7 +87,7 @@ More information can be found [[https://github.com/oantolin/orderless#company][h
|
||||||
|
|
||||||
* TODO Configuration
|
* TODO Configuration
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
/This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
** Enable company backend(s) in certain modes
|
** Enable company backend(s) in certain modes
|
||||||
|
@ -142,5 +142,5 @@ on changing what backends are available for that mode.
|
||||||
|
|
||||||
* TODO Appendix
|
* TODO Appendix
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
|
@ -97,47 +97,46 @@
|
||||||
:config
|
:config
|
||||||
(setq company-box-show-single-candidate t
|
(setq company-box-show-single-candidate t
|
||||||
company-box-backends-colors nil
|
company-box-backends-colors nil
|
||||||
company-box-max-candidates 50
|
company-box-tooltip-limit 50
|
||||||
company-box-icons-alist 'company-box-icons-all-the-icons
|
company-box-icons-alist 'company-box-icons-nerd-icons
|
||||||
;; Move company-box-icons--elisp to the end, because it has a catch-all
|
;; Move company-box-icons--elisp to the end, because it has a catch-all
|
||||||
;; clause that ruins icons from other backends in elisp buffers.
|
;; clause that ruins icons from other backends in elisp buffers.
|
||||||
company-box-icons-functions
|
company-box-icons-functions
|
||||||
(cons #'+company-box-icons--elisp-fn
|
(cons #'+company-box-icons--elisp-fn
|
||||||
(delq 'company-box-icons--elisp
|
(delq 'company-box-icons--elisp
|
||||||
company-box-icons-functions))
|
company-box-icons-functions))
|
||||||
company-box-icons-all-the-icons
|
company-box-icons-nerd-icons
|
||||||
(let ((all-the-icons-scale-factor 0.8))
|
`((Unknown . ,(nerd-icons-codicon "nf-cod-code" :face 'font-lock-warning-face))
|
||||||
`((Unknown . ,(all-the-icons-material "find_in_page" :face 'all-the-icons-purple))
|
(Text . ,(nerd-icons-codicon "nf-cod-text_size" :face 'font-lock-doc-face))
|
||||||
(Text . ,(all-the-icons-material "text_fields" :face 'all-the-icons-green))
|
(Method . ,(nerd-icons-codicon "nf-cod-symbol_method" :face 'font-lock-function-name-face))
|
||||||
(Method . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
(Function . ,(nerd-icons-codicon "nf-cod-symbol_method" :face 'font-lock-function-name-face))
|
||||||
(Function . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
(Constructor . ,(nerd-icons-codicon "nf-cod-triangle_right" :face 'font-lock-function-name-face))
|
||||||
(Constructor . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
(Field . ,(nerd-icons-codicon "nf-cod-symbol_field" :face 'font-lock-variable-name-face))
|
||||||
(Field . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
(Variable . ,(nerd-icons-codicon "nf-cod-symbol_variable" :face 'font-lock-variable-name-face))
|
||||||
(Variable . ,(all-the-icons-material "adjust" :face 'all-the-icons-blue))
|
(Class . ,(nerd-icons-codicon "nf-cod-symbol_class" :face 'font-lock-type-face))
|
||||||
(Class . ,(all-the-icons-material "class" :face 'all-the-icons-red))
|
(Interface . ,(nerd-icons-codicon "nf-cod-symbol_interface" :face 'font-lock-type-face))
|
||||||
(Interface . ,(all-the-icons-material "settings_input_component" :face 'all-the-icons-red))
|
(Module . ,(nerd-icons-codicon "nf-cod-file_submodule" :face 'font-lock-preprocessor-face))
|
||||||
(Module . ,(all-the-icons-material "view_module" :face 'all-the-icons-red))
|
(Property . ,(nerd-icons-codicon "nf-cod-symbol_property" :face 'font-lock-variable-name-face))
|
||||||
(Property . ,(all-the-icons-material "settings" :face 'all-the-icons-red))
|
(Unit . ,(nerd-icons-codicon "nf-cod-symbol_ruler" :face 'font-lock-constant-face))
|
||||||
(Unit . ,(all-the-icons-material "straighten" :face 'all-the-icons-red))
|
(Value . ,(nerd-icons-codicon "nf-cod-symbol_field" :face 'font-lock-builtin-face))
|
||||||
(Value . ,(all-the-icons-material "filter_1" :face 'all-the-icons-red))
|
(Enum . ,(nerd-icons-codicon "nf-cod-symbol_enum" :face 'font-lock-builtin-face))
|
||||||
(Enum . ,(all-the-icons-material "plus_one" :face 'all-the-icons-red))
|
(Keyword . ,(nerd-icons-codicon "nf-cod-symbol_keyword" :face 'font-lock-keyword-face))
|
||||||
(Keyword . ,(all-the-icons-material "filter_center_focus" :face 'all-the-icons-red))
|
(Snippet . ,(nerd-icons-codicon "nf-cod-symbol_snippet" :face 'font-lock-string-face))
|
||||||
(Snippet . ,(all-the-icons-material "short_text" :face 'all-the-icons-red))
|
(Color . ,(nerd-icons-codicon "nf-cod-symbol_color" :face 'success))
|
||||||
(Color . ,(all-the-icons-material "color_lens" :face 'all-the-icons-red))
|
(File . ,(nerd-icons-codicon "nf-cod-symbol_file" :face 'font-lock-string-face))
|
||||||
(File . ,(all-the-icons-material "insert_drive_file" :face 'all-the-icons-red))
|
(Reference . ,(nerd-icons-codicon "nf-cod-references" :face 'font-lock-variable-name-face))
|
||||||
(Reference . ,(all-the-icons-material "collections_bookmark" :face 'all-the-icons-red))
|
(Folder . ,(nerd-icons-codicon "nf-cod-folder" :face 'font-lock-variable-name-face))
|
||||||
(Folder . ,(all-the-icons-material "folder" :face 'all-the-icons-red))
|
(EnumMember . ,(nerd-icons-codicon "nf-cod-symbol_enum_member" :face 'font-lock-builtin-face))
|
||||||
(EnumMember . ,(all-the-icons-material "people" :face 'all-the-icons-red))
|
(Constant . ,(nerd-icons-codicon "nf-cod-symbol_constant" :face 'font-lock-constant-face))
|
||||||
(Constant . ,(all-the-icons-material "pause_circle_filled" :face 'all-the-icons-red))
|
(Struct . ,(nerd-icons-codicon "nf-cod-symbol_structure" :face 'font-lock-variable-name-face))
|
||||||
(Struct . ,(all-the-icons-material "streetview" :face 'all-the-icons-red))
|
(Event . ,(nerd-icons-codicon "nf-cod-symbol_event" :face 'font-lock-warning-face))
|
||||||
(Event . ,(all-the-icons-material "event" :face 'all-the-icons-red))
|
(Operator . ,(nerd-icons-codicon "nf-cod-symbol_operator" :face 'font-lock-comment-delimiter-face))
|
||||||
(Operator . ,(all-the-icons-material "control_point" :face 'all-the-icons-red))
|
(TypeParameter . ,(nerd-icons-codicon "nf-cod-list_unordered" :face 'font-lock-type-face))
|
||||||
(TypeParameter . ,(all-the-icons-material "class" :face 'all-the-icons-red))
|
(Template . ,(nerd-icons-codicon "nf-cod-symbol_snippet" :face 'font-lock-string-face))
|
||||||
(Template . ,(all-the-icons-material "short_text" :face 'all-the-icons-green))
|
(ElispFunction . ,(nerd-icons-codicon "nf-cod-symbol_method" :face 'font-lock-function-name-face))
|
||||||
(ElispFunction . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
(ElispVariable . ,(nerd-icons-codicon "nf-cod-symbol_variable" :face 'font-lock-variable-name-face))
|
||||||
(ElispVariable . ,(all-the-icons-material "check_circle" :face 'all-the-icons-blue))
|
(ElispFeature . ,(nerd-icons-codicon "nf-cod-globe" :face 'font-lock-builtin-face))
|
||||||
(ElispFeature . ,(all-the-icons-material "stars" :face 'all-the-icons-orange))
|
(ElispFace . ,(nerd-icons-codicon "nf-cod-symbol_color" :face 'success))))
|
||||||
(ElispFace . ,(all-the-icons-material "format_paint" :face 'all-the-icons-pink)))))
|
|
||||||
|
|
||||||
;; HACK Fix oversized scrollbar in some odd cases
|
;; HACK Fix oversized scrollbar in some odd cases
|
||||||
;; REVIEW `resize-mode' is deprecated and may stop working in the future.
|
;; REVIEW `resize-mode' is deprecated and may stop working in the future.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
;; -*- no-byte-compile: t; -*-
|
;; -*- no-byte-compile: t; -*-
|
||||||
;;; completion/company/packages.el
|
;;; completion/company/packages.el
|
||||||
|
|
||||||
(package! company :pin "2ca3e29abf87392714bc2b26e50e1c0f4b9f4e2c")
|
(package! company :pin "02903bd7088d65a87df0ae0f0d0a7118de147b69")
|
||||||
(package! company-dict :pin "cd7b8394f6014c57897f65d335d6b2bd65dab1f4")
|
(package! company-dict :pin "cd7b8394f6014c57897f65d335d6b2bd65dab1f4")
|
||||||
(when (modulep! +childframe)
|
(when (modulep! +childframe)
|
||||||
(package! company-box :pin "766546b2668b5ef4eb4abbde632c9acd370c7788"))
|
(package! company-box :pin "b6f53e26adf948aca55c3ff6c22c21a6a6614253"))
|
||||||
|
|
269
modules/completion/corfu/README.org
Normal file
269
modules/completion/corfu/README.org
Normal file
|
@ -0,0 +1,269 @@
|
||||||
|
#+title: :completion corfu
|
||||||
|
#+subtitle: Complete with cap(f), cape and a flying feather
|
||||||
|
#+created: September 9, 2022
|
||||||
|
#+since: 3.0.0 (#7002)
|
||||||
|
|
||||||
|
* Description :unfold:
|
||||||
|
This module provides code completion, powered by [[doom-package:corfu]].
|
||||||
|
|
||||||
|
It is recommended to enable either this or [[doom-module::completion company]] in
|
||||||
|
case you desire pre-configured auto-completion. Corfu is much lighter weight and
|
||||||
|
focused, plus it's built on native Emacs functionality, whereas Company is heavy
|
||||||
|
and highly non-native, but has some extra features and more maturity.
|
||||||
|
|
||||||
|
If you choose Corfu, we also highly recomend reading [[https://github.com/minad/corfu][its README]] and [[https://github.com/minad/cape][cape's
|
||||||
|
README]], as the backend is very configurable and provides many power-user
|
||||||
|
utilities for fine-tuning. Only some of common behaviors are documented here.
|
||||||
|
|
||||||
|
** Maintainers
|
||||||
|
- [[doom-user:][@LuigiPiucco]]
|
||||||
|
- [[doom-user:][@LemonBreezes]]
|
||||||
|
|
||||||
|
[[doom-contrib-maintainer:][Become a maintainer?]]
|
||||||
|
|
||||||
|
** Module flags
|
||||||
|
- +icons ::
|
||||||
|
Display icons beside completion suggestions.
|
||||||
|
- +orderless ::
|
||||||
|
Pull in [[doom-package:orderless]] if necessary and apply multi-component
|
||||||
|
completion (still needed if [[doom-module::completion vertico]] is active).
|
||||||
|
- +dabbrev ::
|
||||||
|
Enable and configure [[doom-package:dabbrev]] as a close-to-universal CAPF
|
||||||
|
fallback.
|
||||||
|
|
||||||
|
** Packages
|
||||||
|
- [[doom-package:corfu]]
|
||||||
|
- [[doom-package:cape]]
|
||||||
|
- [[doom-package:nerd-icons-corfu]] if [[doom-module::completion corfu +icons]]
|
||||||
|
- [[doom-package:orderless]] if [[doom-module::completion corfu +orderless]]
|
||||||
|
- [[doom-package:corfu-terminal]] if [[doom-module::os tty]]
|
||||||
|
- [[doom-package:yasnippet-capf]] if [[doom-module::editor snippets]]
|
||||||
|
|
||||||
|
** Hacks
|
||||||
|
/No hacks documented for this module./
|
||||||
|
|
||||||
|
** TODO Changelog
|
||||||
|
# This section will be machine generated. Don't edit it by hand.
|
||||||
|
/This module does not have a changelog yet./
|
||||||
|
|
||||||
|
* Installation
|
||||||
|
Enable this module in your ~doom!~ block.
|
||||||
|
|
||||||
|
This module has no direct requirements, but some languages may have their own
|
||||||
|
requirements to fulfill before you get code completion in them (and some
|
||||||
|
languages may lack code completion support altogether). Run ~$ doom doctor~ to
|
||||||
|
find out if you're missing any dependencies. Note that Corfu may have support
|
||||||
|
for completions in languages that have no development intelligence, since it
|
||||||
|
supports generic, context insensitive candidates such as file names or recurring
|
||||||
|
words. Snippets may also appear in the candidate list if available.
|
||||||
|
|
||||||
|
* TODO Usage
|
||||||
|
#+begin_quote
|
||||||
|
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
|
#+end_quote
|
||||||
|
|
||||||
|
By default, completion gets triggered after typing 2 non-space consecutive
|
||||||
|
characters, by means of [[kbd:][C-SPC]] at any moment or [[kbd:][TAB]] on a line with proper
|
||||||
|
indentation. Many styles of completion are documented below, which can be
|
||||||
|
composed to suit the user. The following keybindings are generally available:
|
||||||
|
|
||||||
|
| Keybind | Description |
|
||||||
|
|---------+--------------------------------------------|
|
||||||
|
| [[kbd:][C-n]] | Go to next candidate |
|
||||||
|
| [[kbd:][C-p]] | Go to previous candidate |
|
||||||
|
| [[kbd:][C-S-n]] | Go to next doc line |
|
||||||
|
| [[kbd:][C-S-p]] | Go to previous doc line |
|
||||||
|
| [[kbd:][C-S-s]] | Export to minibuffer |
|
||||||
|
| [[kbd:][TAB]] | (when not completing) Indent or complete |
|
||||||
|
| [[kbd:][C-SPC]] | (when not completing) Complete |
|
||||||
|
| [[kbd:][C-u]] | (evil) Go to next candidate page |
|
||||||
|
| [[kbd:][C-d]] | (evil) Go to previous candidate page |
|
||||||
|
| [[kbd:][C-h]] | (evil) Toggle documentation (if available) |
|
||||||
|
| [[kbd:][M-t]] | (emacs) (when not completing) Complete |
|
||||||
|
|
||||||
|
Bindings in the following sections are additive, and unless otherwise noted, are
|
||||||
|
enabled by default with configurable behavior. Additionally, for users of evil,
|
||||||
|
[[kdb:][C-SPC]] is smart regarding your state. In normal-like states, enter insert then
|
||||||
|
start corfu; in visual-like states, perform [[help:evil-change][evil-change]] (which leaves you in
|
||||||
|
insert state) then start corfu; in insert-like states, start corfu immediatelly.
|
||||||
|
|
||||||
|
** Commit preview on type
|
||||||
|
When the completion popup is visible, by default the current candidate is
|
||||||
|
previewed into the buffer, and further input commits that candidate as previewed
|
||||||
|
(note it does not perform candidate exit actions, such as expanding snippets).
|
||||||
|
|
||||||
|
The feature is in line with other common editors, but if you prefer the preview
|
||||||
|
to be only visual or for there to be no preview, configure
|
||||||
|
[[var:corfu-preview-current]].
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
;; Non-inserting preview
|
||||||
|
(setq corfu-preview-current t)
|
||||||
|
;; No preview
|
||||||
|
(setq corfu-preview-current nil)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Commit on [[kbd:][RET]] with pass-through
|
||||||
|
A lot of people like to use [[kbd:][RET]] to commit, so here we bind it to Corfu's
|
||||||
|
insertion function. Note that Corfu allows "no candidate" to be selected, and in
|
||||||
|
that case, we have a custom binding to quit completion and pass-through. To make
|
||||||
|
it less obtrusive by default, the popup starts in this unselected state. See
|
||||||
|
[[var:corfu-preselect]] to alter the initial behavior; it can start with the first
|
||||||
|
one selected, for instance. Then, you have to move one candidate backwards to
|
||||||
|
pass-through The exact action of [[kbd:][RET]] can be changed via
|
||||||
|
[[var:+corfu-want-ret-to-confirm]].
|
||||||
|
|
||||||
|
| Keybind | Description |
|
||||||
|
|---------+-----------------------|
|
||||||
|
| [[kbd:][RET]] | Insert candidate DWIM |
|
||||||
|
|
||||||
|
** Cycle directionally
|
||||||
|
If you'd rather think in directions rather than next/previous, arrow keys and vi
|
||||||
|
movements to control the selection and documentation view are bound by default.
|
||||||
|
You may unbind them by setting to nil, see ~map!~'s documentation.
|
||||||
|
|
||||||
|
| Keybind | Description |
|
||||||
|
|----------+---------------------------------|
|
||||||
|
| [[kbd:][<down>]] | Go to next candidate |
|
||||||
|
| [[kbd:][<up>]] | Go to previous candidate |
|
||||||
|
| [[kbd:][C-j]] | (evil) Go to next candidate |
|
||||||
|
| [[kbd:][C-k]] | (evil) Go to previous candidate |
|
||||||
|
| [[kbd:][C-<down>]] | Go to next doc line |
|
||||||
|
| [[kbd:][C-<up>]] | Go to previous doc line |
|
||||||
|
| [[kbd:][C-S-j]] | (evil) Go to next doc line |
|
||||||
|
| [[kbd:][C-S-k]] | (evil) Go to previous doc line |
|
||||||
|
|
||||||
|
** Cycle with [[kbd:][TAB]]
|
||||||
|
[[kbd:][TAB]]-based cycling alternatives are also bound according to the table below:
|
||||||
|
|
||||||
|
| Keybind | Description |
|
||||||
|
|---------+--------------------------|
|
||||||
|
| [[kbd:][TAB]] | Go to next candidate |
|
||||||
|
| [[kbd:][S-TAB]] | Go to previous candidate |
|
||||||
|
|
||||||
|
** Searching with multiple keywords (~+orderless~)
|
||||||
|
If the [[doom-module::completion corfu +orderless]] flag is enabled, users can
|
||||||
|
perform code completion with multiple search keywords by use of space as the
|
||||||
|
separator. More information can be found [[https://github.com/oantolin/orderless#company][here]]. Pressing [[kdb:][C-SPC]] again while
|
||||||
|
completing inserts a space as separator. This allows searching with
|
||||||
|
space-separated terms; each piece will match individually and in any order, with
|
||||||
|
smart casing. Pressing just [[kbd:][SPC]] acts as normal and quits completion, so that
|
||||||
|
when typing sentences it doesn't try to complete the whole sentence instead of
|
||||||
|
just the word. Pressing [[kdb:][C-SPC]] with point after a separator escapes it with a
|
||||||
|
backslash, including the space in the search term, and pressing it with an
|
||||||
|
already escaped separator before point deletes it. Thus, you can cycle back if
|
||||||
|
you accidentaly press more than needed.
|
||||||
|
|
||||||
|
| Keybind | Description |
|
||||||
|
|---------+-------------------------------------------------|
|
||||||
|
| [[kbd:][C-SPC]] | (evil) (when completing) Insert separator DWIM |
|
||||||
|
| [[kbd:][M-SPC]] | (emacs) (when completing) Insert separator DWIM |
|
||||||
|
| [[kbd:][SPC]] | (when completing) Quit autocompletion |
|
||||||
|
| [[kbd:][SPC]] | (when completing with separators) Self-insert |
|
||||||
|
|
||||||
|
** Exporting to the minibuffer
|
||||||
|
The entries shown in the completion popup can be exported to a ~completing-read~
|
||||||
|
minibuffer, giving access to all the manipulations that suite allows. Using
|
||||||
|
Vertico for instance, one could use this to export with [[doom-package:embark]] via
|
||||||
|
[[kbd:][C-c C-l]] and get a buffer with all candidates.
|
||||||
|
|
||||||
|
* Configuration
|
||||||
|
A few variables may be set to change behavior of this module:
|
||||||
|
|
||||||
|
- [[var:completion-at-point-functions]] ::
|
||||||
|
This is not a module/package variable, but a builtin Emacs one. Even so, it's
|
||||||
|
very important to how Corfu works, so we document it here. It contains a list
|
||||||
|
of functions that are called in turn to generate completion candidates. The
|
||||||
|
regular (non-lexical) value should contain few entries and they should
|
||||||
|
generally be context aware, so as to predict what you need. Additional
|
||||||
|
functions can be added as you get into more and more specific contexts. Also,
|
||||||
|
there may be cases where you know beforehand the kind of candidate needed, and
|
||||||
|
want to enable only that one. For this, the variable may be lexically bound to
|
||||||
|
the correct value, or you may call the CAPF interactively if a single function
|
||||||
|
is all you need.
|
||||||
|
- [[var:corfu-auto-delay]] ::
|
||||||
|
Number of seconds till completion occurs automatically. Defaults to 0.1.
|
||||||
|
- [[var:corfu-auto-prefix]] ::
|
||||||
|
Number of characters till auto-completion starts to happen. Defaults to 2.
|
||||||
|
- [[var:corfu-on-exact-match]] ::
|
||||||
|
Configures behavior for exact matches.
|
||||||
|
- [[var:corfu-preselect]] ::
|
||||||
|
Configures startup selection, choosing between the first candidate or the
|
||||||
|
prompt.
|
||||||
|
- [[var:corfu-preview-current]] ::
|
||||||
|
Configures current candidate preview.
|
||||||
|
- [[var:+corfu-want-ret-to-confirm]] ::
|
||||||
|
Enables commiting with [[RET]] when the popup is visible. Default is ~t~, may be set to
|
||||||
|
~'minibuffer~ if you want to commit both the completion and the minibuffer when
|
||||||
|
active. When ~nil~, it is always passed-through.
|
||||||
|
- [[var:+corfu-buffer-scanning-size-limit]] ::
|
||||||
|
Sets the maximum buffer size to be scanned by ~cape-dabbrev~. Defaults to 1 MB.
|
||||||
|
Set this if you are having performance problems using the CAPF.
|
||||||
|
- [[var:+corfu-want-minibuffer-completion]] ::
|
||||||
|
Whether to enable Corfu in the minibuffer. See its documentation for
|
||||||
|
additional tweaks.
|
||||||
|
|
||||||
|
** Adding CAPFs to a mode
|
||||||
|
To add other CAPFs on a mode-per-mode basis, put either of the following in your
|
||||||
|
~config.el~:
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(add-hook! some-mode (add-hook 'completion-at-point-functions #'some-capf depth t))
|
||||||
|
;; OR, but note the different call signature
|
||||||
|
(add-hook 'some-mode-hook (lambda () (add-hook 'completion-at-point-functions #'some-capf depth t)))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
~DEPTH~ above is an integer between -100, 100, and defaults to 0 if nil. Also
|
||||||
|
see ~add-hook!~'s documentation for additional ways to call it. ~add-hook~ only
|
||||||
|
accepts the quoted arguments form above.
|
||||||
|
|
||||||
|
** Adding CAPFs to a key
|
||||||
|
To add other CAPFs to keys, adapt the snippet below into your ~config.el~:
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(map! :map some-mode-map
|
||||||
|
"C-x e" #'cape-emoji)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
It's okay to add to the mode directly because ~completion-at-point~ works
|
||||||
|
regardless of Corfu (the latter is an enhanced UI for the former). Just note not
|
||||||
|
all CAPFs are interactive to be called this way, in which case you can use
|
||||||
|
[[doom-package:cape]]'s adapter to enable this.
|
||||||
|
|
||||||
|
* Troubleshooting
|
||||||
|
[[doom-report:][Report an issue?]]
|
||||||
|
|
||||||
|
If you have performance issues with ~cape-dabbrev~, the first thing I recommend
|
||||||
|
doing is to look at the list of buffers Dabbrev is scanning:
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(dabbrev--select-buffers) ; => (#<buffer README.org> #<buffer config.el<3>> #<buffer cape.el> ...)
|
||||||
|
(length (dabbrev--select-buffers)) ; => 37
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
... and modify ~dabbrev-ignored-buffer-regexps~ or ~dabbrev-ignored-buffer-modes~
|
||||||
|
accordingly.
|
||||||
|
|
||||||
|
If you see garbage completion candidates, you can use the following command to
|
||||||
|
debug the issue:
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
;;;###autoload
|
||||||
|
(defun search-in-dabbrev-buffers (search-string)
|
||||||
|
"Search for SEARCH-STRING in all buffers returned by `dabbrev--select-buffers'."
|
||||||
|
(interactive "sSearch string: ")
|
||||||
|
(let ((buffers (dabbrev--select-buffers)))
|
||||||
|
(multi-occur buffers search-string)))
|
||||||
|
|
||||||
|
;; Example usage:
|
||||||
|
;; Why are these weird characters appearing in my completions?
|
||||||
|
(search-in-dabbrev-buffers "\342\200\231")
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* Frequently asked questions
|
||||||
|
/This module has no FAQs yet./ [[doom-suggest-faq:][Ask one?]]
|
||||||
|
|
||||||
|
* TODO Appendix
|
||||||
|
#+begin_quote
|
||||||
|
🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
||||||
|
#+end_quote
|
39
modules/completion/corfu/autoload.el
Normal file
39
modules/completion/corfu/autoload.el
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
;;; completion/corfu/autoload.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +corfu-move-to-minibuffer ()
|
||||||
|
"Move the current list of candidates to your choice of minibuffer completion UI."
|
||||||
|
(interactive)
|
||||||
|
(pcase completion-in-region--data
|
||||||
|
(`(,beg ,end ,table ,pred ,extras)
|
||||||
|
(let ((completion-extra-properties extras)
|
||||||
|
completion-cycle-threshold completion-cycling)
|
||||||
|
(cond ((and (modulep! :completion vertico)
|
||||||
|
(fboundp #'consult-completion-in-region))
|
||||||
|
(consult-completion-in-region beg end table pred))
|
||||||
|
((and (modulep! :completion ivy)
|
||||||
|
(fboundp #'ivy-completion-in-region))
|
||||||
|
(ivy-completion-in-region (marker-position beg) (marker-position end) table pred))
|
||||||
|
;; Important: `completion-in-region-function' is set to corfu at
|
||||||
|
;; this moment, so `completion-in-region' (single -) doesn't work
|
||||||
|
;; below.
|
||||||
|
((modulep! :completion helm)
|
||||||
|
;; Helm is special and wants to _wrap_ `completion--in-region'
|
||||||
|
;; instead of replacing it in `completion-in-region-function'.
|
||||||
|
;; But because the advice is too unreliable we "fake" the wrapping.
|
||||||
|
(helm--completion-in-region #'completion--in-region beg end table pred))
|
||||||
|
((modulep! :completion ido)
|
||||||
|
(completion--in-region beg end table pred))
|
||||||
|
(t (error "No minibuffer completion UI available for moving to!")))))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +corfu-smart-sep-toggle-escape ()
|
||||||
|
"Insert `corfu-separator' or toggle escape if it's already there."
|
||||||
|
(interactive)
|
||||||
|
(cond ((and (char-equal (char-before) corfu-separator)
|
||||||
|
(char-equal (char-before (1- (point))) ?\\))
|
||||||
|
(save-excursion (delete-char -2)))
|
||||||
|
((char-equal (char-before) corfu-separator)
|
||||||
|
(save-excursion (backward-char 1)
|
||||||
|
(insert-char ?\\)))
|
||||||
|
(t (call-interactively #'corfu-insert-separator))))
|
185
modules/completion/corfu/config.el
Normal file
185
modules/completion/corfu/config.el
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
;;; completion/corfu/config.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
(defvar +corfu-want-ret-to-confirm t
|
||||||
|
"Configure how the user expects RET to behave.
|
||||||
|
Possible values are:
|
||||||
|
- t (default): Insert candidate if one is selected, pass-through otherwise;
|
||||||
|
- `minibuffer': Insert candidate if one is selected, pass-through otherwise,
|
||||||
|
and immediatelly exit if in the minibuffer;
|
||||||
|
- nil: Pass-through without inserting.")
|
||||||
|
|
||||||
|
(defvar +corfu-buffer-scanning-size-limit (* 1 1024 1024) ; 1 MB
|
||||||
|
"Size limit for a buffer to be scanned by `cape-dabbrev'.")
|
||||||
|
|
||||||
|
(defvar +corfu-want-minibuffer-completion t
|
||||||
|
"Whether to enable Corfu in the minibuffer.
|
||||||
|
Setting this to `aggressive' will enable Corfu in more commands which
|
||||||
|
use the minibuffer such as `query-replace'.")
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Packages
|
||||||
|
(use-package! corfu
|
||||||
|
:hook (doom-first-input . global-corfu-mode)
|
||||||
|
:init
|
||||||
|
(add-hook! 'minibuffer-setup-hook
|
||||||
|
(defun +corfu-enable-in-minibuffer ()
|
||||||
|
"Enable Corfu in the minibuffer."
|
||||||
|
(when (pcase +corfu-want-minibuffer-completion
|
||||||
|
('aggressive
|
||||||
|
(not (or (bound-and-true-p mct--active)
|
||||||
|
(bound-and-true-p vertico--input)
|
||||||
|
(eq (current-local-map) read-passwd-map)
|
||||||
|
(and (featurep 'helm-core) (helm--alive-p))
|
||||||
|
(and (featurep 'ido) (ido-active))
|
||||||
|
(where-is-internal 'minibuffer-complete
|
||||||
|
(list (current-local-map)))
|
||||||
|
(memq #'ivy--queue-exhibit post-command-hook))))
|
||||||
|
('nil nil)
|
||||||
|
(_ (where-is-internal #'completion-at-point
|
||||||
|
(list (current-local-map)))))
|
||||||
|
(setq-local corfu-echo-delay nil)
|
||||||
|
(corfu-mode +1))))
|
||||||
|
:config
|
||||||
|
(setq corfu-auto t
|
||||||
|
corfu-auto-delay 0.18
|
||||||
|
corfu-auto-prefix 2
|
||||||
|
global-corfu-modes '((not
|
||||||
|
erc-mode
|
||||||
|
circe-mode
|
||||||
|
help-mode
|
||||||
|
gud-mode
|
||||||
|
vterm-mode)
|
||||||
|
t)
|
||||||
|
corfu-cycle t
|
||||||
|
corfu-preselect 'prompt
|
||||||
|
corfu-count 16
|
||||||
|
corfu-max-width 120
|
||||||
|
corfu-on-exact-match nil
|
||||||
|
corfu-quit-at-boundary (if (or (modulep! :completion vertico)
|
||||||
|
(modulep! +orderless))
|
||||||
|
'separator t)
|
||||||
|
corfu-quit-no-match corfu-quit-at-boundary
|
||||||
|
tab-always-indent 'complete)
|
||||||
|
(add-to-list 'completion-category-overrides `(lsp-capf (styles ,@completion-styles)))
|
||||||
|
(add-to-list 'corfu-auto-commands #'lispy-colon)
|
||||||
|
(add-to-list 'corfu-continue-commands #'+corfu-move-to-minibuffer)
|
||||||
|
(add-to-list 'corfu-continue-commands #'+corfu-smart-sep-toggle-escape)
|
||||||
|
(add-hook 'evil-insert-state-exit-hook #'corfu-quit)
|
||||||
|
|
||||||
|
;; If you want to update the visual hints after completing minibuffer commands
|
||||||
|
;; with Corfu and exiting, you have to do it manually.
|
||||||
|
(defadvice! +corfu--insert-before-exit-minibuffer-a ()
|
||||||
|
:before #'exit-minibuffer
|
||||||
|
(when (or (and (frame-live-p corfu--frame)
|
||||||
|
(frame-visible-p corfu--frame))
|
||||||
|
(and (featurep 'corfu-terminal)
|
||||||
|
(popon-live-p corfu-terminal--popon)))
|
||||||
|
(when (member isearch-lazy-highlight-timer timer-idle-list)
|
||||||
|
(apply (timer--function isearch-lazy-highlight-timer)
|
||||||
|
(timer--args isearch-lazy-highlight-timer)))
|
||||||
|
(when (member (bound-and-true-p anzu--update-timer) timer-idle-list)
|
||||||
|
(apply (timer--function anzu--update-timer)
|
||||||
|
(timer--args anzu--update-timer)))
|
||||||
|
(when (member (bound-and-true-p evil--ex-search-update-timer)
|
||||||
|
timer-idle-list)
|
||||||
|
(apply (timer--function evil--ex-search-update-timer)
|
||||||
|
(timer--args evil--ex-search-update-timer)))))
|
||||||
|
|
||||||
|
;; HACK: If your dictionaries aren't set up in text-mode buffers, ispell will
|
||||||
|
;; continuously pester you about errors. This ensures it only happens once
|
||||||
|
;; per session.
|
||||||
|
(defadvice! +corfu--auto-disable-ispell-capf-a (fn &rest args)
|
||||||
|
"If ispell isn't properly set up, only complain once per session."
|
||||||
|
:around #'ispell-completion-at-point
|
||||||
|
(condition-case-unless-debug e
|
||||||
|
(apply fn args)
|
||||||
|
('error
|
||||||
|
(message "Error: %s" (error-message-string e))
|
||||||
|
(message "Auto-disabling `text-mode-ispell-word-completion'")
|
||||||
|
(setq text-mode-ispell-word-completion nil)
|
||||||
|
(remove-hook 'completion-at-point-functions #'ispell-completion-at-point t)))))
|
||||||
|
|
||||||
|
(use-package! cape
|
||||||
|
:defer t
|
||||||
|
:init
|
||||||
|
(add-hook! prog-mode
|
||||||
|
(defun +corfu-add-cape-file-h ()
|
||||||
|
(add-hook 'completion-at-point-functions #'cape-file -10 t)))
|
||||||
|
(add-hook! (org-mode markdown-mode)
|
||||||
|
(defun +corfu-add-cape-elisp-block-h ()
|
||||||
|
(add-hook 'completion-at-point-functions #'cape-elisp-block 0 t)))
|
||||||
|
;; Enable Dabbrev completion basically everywhere as a fallback.
|
||||||
|
(when (modulep! +dabbrev)
|
||||||
|
(setq cape-dabbrev-check-other-buffers t)
|
||||||
|
;; Set up `cape-dabbrev' options.
|
||||||
|
(defun +dabbrev-friend-buffer-p (other-buffer)
|
||||||
|
(< (buffer-size other-buffer) +corfu-buffer-scanning-size-limit))
|
||||||
|
(add-hook! (prog-mode text-mode conf-mode comint-mode minibuffer-setup
|
||||||
|
eshell-mode)
|
||||||
|
(defun +corfu-add-cape-dabbrev-h ()
|
||||||
|
(add-hook 'completion-at-point-functions #'cape-dabbrev 20 t)))
|
||||||
|
(after! dabbrev
|
||||||
|
(setq dabbrev-friend-buffer-function #'+dabbrev-friend-buffer-p
|
||||||
|
dabbrev-ignored-buffer-regexps
|
||||||
|
'("^ "
|
||||||
|
"\\(TAGS\\|tags\\|ETAGS\\|etags\\|GTAGS\\|GRTAGS\\|GPATH\\)\\(<[0-9]+>\\)?")
|
||||||
|
dabbrev-upcase-means-case-search t)
|
||||||
|
(add-to-list 'dabbrev-ignored-buffer-modes 'pdf-view-mode)))
|
||||||
|
|
||||||
|
;; Make these capfs composable.
|
||||||
|
(advice-add #'lsp-completion-at-point :around #'cape-wrap-noninterruptible)
|
||||||
|
(advice-add #'lsp-completion-at-point :around #'cape-wrap-nonexclusive)
|
||||||
|
(advice-add #'comint-completion-at-point :around #'cape-wrap-nonexclusive)
|
||||||
|
(advice-add #'eglot-completion-at-point :around #'cape-wrap-nonexclusive)
|
||||||
|
(advice-add #'pcomplete-completions-at-point :around #'cape-wrap-nonexclusive)
|
||||||
|
;; From the `cape' readme. Without this, Eshell autocompletion is broken on
|
||||||
|
;; Emacs28.
|
||||||
|
(when (< emacs-major-version 29)
|
||||||
|
(advice-add 'pcomplete-completions-at-point :around #'cape-wrap-silent)
|
||||||
|
(advice-add 'pcomplete-completions-at-point :around #'cape-wrap-purify)))
|
||||||
|
|
||||||
|
(use-package! yasnippet-capf
|
||||||
|
:when (modulep! :editor snippets)
|
||||||
|
:defer t
|
||||||
|
:init
|
||||||
|
(add-hook! 'yas-minor-mode-hook
|
||||||
|
(defun +corfu-add-yasnippet-capf-h ()
|
||||||
|
(add-hook 'completion-at-point-functions #'yasnippet-capf 30 t))))
|
||||||
|
|
||||||
|
(use-package! corfu-terminal
|
||||||
|
:when (modulep! :os tty)
|
||||||
|
:when (not (display-graphic-p))
|
||||||
|
:hook ((corfu-mode . corfu-terminal-mode)))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Extensions
|
||||||
|
|
||||||
|
(use-package! corfu-history
|
||||||
|
:hook ((corfu-mode . corfu-history-mode))
|
||||||
|
:config
|
||||||
|
(after! savehist (add-to-list 'savehist-additional-variables 'corfu-history)))
|
||||||
|
|
||||||
|
(use-package! corfu-popupinfo
|
||||||
|
:hook ((corfu-mode . corfu-popupinfo-mode))
|
||||||
|
:config
|
||||||
|
(setq corfu-popupinfo-delay '(0.5 . 1.0)))
|
||||||
|
|
||||||
|
(use-package! nerd-icons-corfu
|
||||||
|
:when (modulep! +icons)
|
||||||
|
:defer t
|
||||||
|
:init
|
||||||
|
(after! corfu
|
||||||
|
(add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter)))
|
||||||
|
|
||||||
|
;; If vertico is not enabled, orderless will be installed but not configured.
|
||||||
|
;; That may break smart separator behavior, so we conditionally configure it.
|
||||||
|
(use-package! orderless
|
||||||
|
:when (and (not (modulep! :completion vertico))
|
||||||
|
(modulep! +orderless))
|
||||||
|
:config
|
||||||
|
(setq completion-styles '(orderless basic)
|
||||||
|
completion-category-defaults nil
|
||||||
|
completion-category-overrides '((file (styles orderless partial-completion)))
|
||||||
|
orderless-component-separator #'orderless-escapable-split-on-space)
|
||||||
|
(set-face-attribute 'completions-first-difference nil :inherit nil))
|
17
modules/completion/corfu/packages.el
Normal file
17
modules/completion/corfu/packages.el
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
;; -*- no-byte-compile: t; -*-
|
||||||
|
;;; completion/corfu/packages.el
|
||||||
|
|
||||||
|
(package! corfu :pin "c1e7b6190b00158e67347b4db0a8f7964e5d2f8b")
|
||||||
|
(package! cape :pin "a397a0c92de38277b7f835fa999fac400a764908")
|
||||||
|
(when (modulep! +icons)
|
||||||
|
(package! nerd-icons-corfu :pin "7077bb76fefc15aed967476406a19dc5c2500b3c"))
|
||||||
|
(when (and (not (modulep! :completion vertico))
|
||||||
|
(modulep! +orderless))
|
||||||
|
;; enabling +orderless without vertico should be fairly niche enough that to
|
||||||
|
;; save contributor headaches we should only pin vertico's orderless and leave
|
||||||
|
;; this one unpinned
|
||||||
|
(package! orderless))
|
||||||
|
(when (modulep! :os tty)
|
||||||
|
(package! corfu-terminal :pin "501548c3d51f926c687e8cd838c5865ec45d03cc"))
|
||||||
|
(when (modulep! :editor snippets)
|
||||||
|
(package! yasnippet-capf :pin "9043f8275176a8f198ce8e81fadab1870fa165bb"))
|
|
@ -22,7 +22,7 @@ For official documentation about Helm, see:
|
||||||
Enable fuzzy completion for Helm searches.
|
Enable fuzzy completion for Helm searches.
|
||||||
- +icons ::
|
- +icons ::
|
||||||
Display icons on completion results (where possible) using either
|
Display icons on completion results (where possible) using either
|
||||||
[[doom-package:all-the-icons]] or [[doom-package:treemacs]] iconsets.
|
[[doom-package:nerd-icons]] or [[doom-package:treemacs]] iconsets.
|
||||||
|
|
||||||
** Packages
|
** Packages
|
||||||
- [[doom-package:helm]]
|
- [[doom-package:helm]]
|
||||||
|
@ -40,7 +40,7 @@ For official documentation about Helm, see:
|
||||||
|
|
||||||
** TODO Hacks
|
** TODO Hacks
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module's hacks haven't been documented yet. [[doom-contrib-module:][Document them?]]
|
This module's hacks haven't been documented yet. [[doom-contrib-module:][Document them?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
** TODO Changelog
|
** TODO Changelog
|
||||||
|
@ -74,18 +74,18 @@ its highlights will be covered here.
|
||||||
** Jump-to navigation
|
** Jump-to navigation
|
||||||
Similar to Ivy, this module provides an interface to navigate within a project
|
Similar to Ivy, this module provides an interface to navigate within a project
|
||||||
using [[doom-package:projectile]]:
|
using [[doom-package:projectile]]:
|
||||||
| Keybind | Description |
|
| Keybind | Description |
|
||||||
|------------------+---------------------------------------------------------|
|
|--------------------------------------+-------------------------------------------------------|
|
||||||
| [[kbd:][SPC p f]], [[kbd:][SPC SPC]] | Jump to file in project (~+helm/projectile-find-file~) |
|
| [[kbd:][SPC p f]], [[kbd:][SPC SPC]] | Jump to file in project (~+helm/projectile-find-file~) |
|
||||||
| [[kbd:][SPC f f]], [[kbd:][SPC .]] | Jump to file from current directory (~helm-find-files~) |
|
| [[kbd:][SPC f f]], [[kbd:][SPC .]] | Jump to file from current directory (~helm-find-files~) |
|
||||||
| [[kbd:][SPC s i]] | Jump to symbol in file (~helm-semantic-or-imenu~) |
|
| [[kbd:][SPC s i]] | Jump to symbol in file (~helm-semantic-or-imenu~) |
|
||||||
|
|
||||||
** Project search & replace
|
** Project search & replace
|
||||||
This module also provides interactive text search and replace using [[https://github.com/BurntSushi/ripgrep][Ripgrep]].
|
This module also provides interactive text search and replace using [[https://github.com/BurntSushi/ripgrep][Ripgrep]].
|
||||||
|
|
||||||
*** Search
|
*** Search
|
||||||
| Keybind | Description |
|
| Keybind | Description |
|
||||||
|---------+-----------------------------------------------------------|
|
|-------------------+---------------------------------------------------------|
|
||||||
| [[kbd:][SPC s p]] | Search project (~+default/search-project~) |
|
| [[kbd:][SPC s p]] | Search project (~+default/search-project~) |
|
||||||
| [[kbd:][SPC s P]] | Search another project (~+default/search-other-project~) |
|
| [[kbd:][SPC s P]] | Search another project (~+default/search-other-project~) |
|
||||||
| [[kbd:][SPC s d]] | Search this directory (~+default/search-cwd~) |
|
| [[kbd:][SPC s d]] | Search this directory (~+default/search-cwd~) |
|
||||||
|
@ -96,8 +96,8 @@ otherwise) changes the behavior of these commands, instructing the underlying
|
||||||
search engine to include ignored files.
|
search engine to include ignored files.
|
||||||
|
|
||||||
This module also provides Ex Commands for evil users:
|
This module also provides Ex Commands for evil users:
|
||||||
| Ex command | Description |
|
| Ex command | Description |
|
||||||
|------------------------+------------------------------------------------------------------|
|
|----------------------+----------------------------------------------------------------|
|
||||||
| ~:pg[rep][!] [QUERY]~ | Search project (if ~!~, include hidden files) |
|
| ~:pg[rep][!] [QUERY]~ | Search project (if ~!~, include hidden files) |
|
||||||
| ~:pg[rep]d[!] [QUERY]~ | Search from current directory (if ~!~, don't search recursively) |
|
| ~:pg[rep]d[!] [QUERY]~ | Search from current directory (if ~!~, don't search recursively) |
|
||||||
|
|
||||||
|
@ -106,8 +106,8 @@ commands.
|
||||||
|
|
||||||
*** Replace
|
*** Replace
|
||||||
These keybindings are available while a search is active:
|
These keybindings are available while a search is active:
|
||||||
| Keybind | Description |
|
| Keybind | Description |
|
||||||
|---------+-----------------------------------------------|
|
|-------------------+-----------------------------------------------|
|
||||||
| [[kbd:][C-c C-o]] | Open a buffer with your search results |
|
| [[kbd:][C-c C-o]] | Open a buffer with your search results |
|
||||||
| [[kbd:][C-c C-e]] | Open a writable buffer of your search results |
|
| [[kbd:][C-c C-e]] | Open a writable buffer of your search results |
|
||||||
| [[kbd:][C-SPC]] | Preview the current candidate |
|
| [[kbd:][C-SPC]] | Preview the current candidate |
|
||||||
|
@ -131,38 +131,38 @@ A [[doom-package:wgrep]] buffer can be opened from swiper with [[kbd:][C-c C-e]]
|
||||||
Helm also has a number of overrides for built-in functionality:
|
Helm also has a number of overrides for built-in functionality:
|
||||||
|
|
||||||
*** General
|
*** General
|
||||||
| Keybind | Description |
|
| Keybind | Description |
|
||||||
|------------+---------------------------|
|
|--------------------------------+---------------------------|
|
||||||
| [[kbd:][M-x]], [[kbd:][SPC :]] | Smarter, smex-powered M-x |
|
| [[kbd:][M-x]], [[kbd:][SPC :]] | Smarter, smex-powered M-x |
|
||||||
| [[kbd:][SPC ']] | Resume last ivy session |
|
| [[kbd:][SPC ']] | Resume last ivy session |
|
||||||
|
|
||||||
*** Jump to files, buffers or projects
|
*** Jump to files, buffers or projects
|
||||||
| Keybind | Description |
|
| Keybind | Description |
|
||||||
|---------+----------------------------------------------------------------------|
|
|-------------------+--------------------------------------------------------------------|
|
||||||
| [[kbd:][SPC p t]] | List all TODO/FIXMEs in project |
|
| [[kbd:][SPC p t]] | List all TODO/FIXMEs in project |
|
||||||
| [[kbd:][SPC s b]] | Search the current buffer (~+default/search-buffer~) |
|
| [[kbd:][SPC s b]] | Search the current buffer (~+default/search-buffer~) |
|
||||||
| [[kbd:][SPC s d]] | Search this directory (~+default/search-cwd~) |
|
| [[kbd:][SPC s d]] | Search this directory (~+default/search-cwd~) |
|
||||||
| [[kbd:][SPC s D]] | Search another directory (~+default/search-other-cwd~) |
|
| [[kbd:][SPC s D]] | Search another directory (~+default/search-other-cwd~) |
|
||||||
| [[kbd:][SPC s i]] | Search for symbol in current buffer |
|
| [[kbd:][SPC s i]] | Search for symbol in current buffer |
|
||||||
| [[kbd:][SPC s p]] | Search project (~+default/search-project~) |
|
| [[kbd:][SPC s p]] | Search project (~+default/search-project~) |
|
||||||
| [[kbd:][SPC s P]] | Search another project (~+default/search-other-project~) |
|
| [[kbd:][SPC s P]] | Search another project (~+default/search-other-project~) |
|
||||||
| [[kbd:][SPC s s]] | Search the current buffer (incrementally) (~+default/search-buffer~) |
|
| [[kbd:][SPC s s]] | Search the current buffer (incrementally) (~+default/search-buffer~) |
|
||||||
|
|
||||||
*** Search
|
*** Search
|
||||||
| Keybind | Description |
|
| Keybind | Description |
|
||||||
|---------+----------------------------------------------------------------------|
|
|-------------------+--------------------------------------------------------------------|
|
||||||
| [[kbd:][SPC p t]] | List all TODO/FIXMEs in project |
|
| [[kbd:][SPC p t]] | List all TODO/FIXMEs in project |
|
||||||
| [[kbd:][SPC s b]] | Search the current buffer (~+default/search-buffer~) |
|
| [[kbd:][SPC s b]] | Search the current buffer (~+default/search-buffer~) |
|
||||||
| [[kbd:][SPC s d]] | Search this directory (~+default/search-cwd~) |
|
| [[kbd:][SPC s d]] | Search this directory (~+default/search-cwd~) |
|
||||||
| [[kbd:][SPC s D]] | Search another directory (~+default/search-other-cwd~) |
|
| [[kbd:][SPC s D]] | Search another directory (~+default/search-other-cwd~) |
|
||||||
| [[kbd:][SPC s i]] | Search for symbol in current buffer |
|
| [[kbd:][SPC s i]] | Search for symbol in current buffer |
|
||||||
| [[kbd:][SPC s p]] | Search project (~+default/search-project~) |
|
| [[kbd:][SPC s p]] | Search project (~+default/search-project~) |
|
||||||
| [[kbd:][SPC s P]] | Search another project (~+default/search-other-project~) |
|
| [[kbd:][SPC s P]] | Search another project (~+default/search-other-project~) |
|
||||||
| [[kbd:][SPC s s]] | Search the current buffer (incrementally) (~+default/search-buffer~) |
|
| [[kbd:][SPC s s]] | Search the current buffer (incrementally) (~+default/search-buffer~) |
|
||||||
|
|
||||||
* TODO Configuration
|
* TODO Configuration
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
/This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
** helm-mode
|
** helm-mode
|
||||||
|
@ -182,9 +182,9 @@ makes sense to exempt ~foo~ with the following:
|
||||||
|
|
||||||
** Icons
|
** Icons
|
||||||
There are two icon "themes" available for this module:
|
There are two icon "themes" available for this module:
|
||||||
[[doom-package:all-the-icons]] and [[doom-package:treemacs]]. By default, and to
|
[[doom-package:nerd-icons]] and [[doom-package:treemacs]]. By default, and to
|
||||||
maintain consistency with other icons across Doom's modules,
|
maintain consistency with other icons across Doom's modules,
|
||||||
[[doom-package:all-the-icons]] is used. To change this:
|
[[doom-package:nerd-icons]] is used. To change this:
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
;; add to $DOOMDIR/config.el
|
;; add to $DOOMDIR/config.el
|
||||||
(after! helm
|
(after! helm
|
||||||
|
@ -202,5 +202,5 @@ See [[id:4f36ae11-1da8-4624-9c30-46b764e849fc][this answer]].
|
||||||
|
|
||||||
* TODO Appendix
|
* TODO Appendix
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
|
@ -148,7 +148,7 @@ Can be negative.")
|
||||||
|
|
||||||
(defvar helm-generic-files-map (make-sparse-keymap))
|
(defvar helm-generic-files-map (make-sparse-keymap))
|
||||||
(after! helm-locate
|
(after! helm-locate
|
||||||
(when (and IS-MAC
|
(when (and (featurep :system 'macos)
|
||||||
(null helm-locate-command)
|
(null helm-locate-command)
|
||||||
(executable-find "mdfind"))
|
(executable-find "mdfind"))
|
||||||
(setq helm-locate-command "mdfind -name %s"))
|
(setq helm-locate-command "mdfind -name %s"))
|
||||||
|
@ -195,7 +195,4 @@ Can be negative.")
|
||||||
:when (modulep! +icons)
|
:when (modulep! +icons)
|
||||||
:hook (helm-mode . helm-icons-enable)
|
:hook (helm-mode . helm-icons-enable)
|
||||||
:init
|
:init
|
||||||
(setq helm-icons-provider 'all-the-icons)
|
(setq helm-icons-provider 'nerd-icons))
|
||||||
:config
|
|
||||||
(when (eq helm-icons-provider 'all-the-icons)
|
|
||||||
(setq helm-icons-mode->icon nil)))
|
|
||||||
|
|
7
modules/completion/helm/doctor.el
Normal file
7
modules/completion/helm/doctor.el
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||||
|
;;; completion/helm/doctor.el
|
||||||
|
|
||||||
|
(dolist (module '(ivy ido vertico))
|
||||||
|
(when (doom-module-p :completion module)
|
||||||
|
(error! "This module is incompatible with :completion %s; disable one or the other"
|
||||||
|
module)))
|
|
@ -1,20 +1,20 @@
|
||||||
;; -*- no-byte-compile: t; -*-
|
;; -*- no-byte-compile: t; -*-
|
||||||
;;; completion/helm/packages.el
|
;;; completion/helm/packages.el
|
||||||
|
|
||||||
(package! helm :pin "dfd6403947c5cd9f32afcd6bc92a1756cc958c82")
|
(package! helm :pin "f34ea6b702648e5c7535a704bdb6c4d7afb4b3b8")
|
||||||
(package! helm-company :pin "6eb5c2d730a60e394e005b47c1db018697094dde")
|
(package! helm-company :pin "4622b82353220ee6cc33468f710fa5b6b253b7f1")
|
||||||
(package! helm-c-yasnippet :pin "e214eec8b2875d8a7cd09006dfb6a8e15e9e4079")
|
(package! helm-c-yasnippet :pin "c5880e740da101fde7a995e94a7b16c330e57583")
|
||||||
(package! helm-descbinds :pin "b72515982396b6e336ad7beb6767e95a80fca192")
|
(package! helm-descbinds :pin "b72515982396b6e336ad7beb6767e95a80fca192")
|
||||||
(package! helm-describe-modes :pin "11fb36af119b784539d31c6160002de1957408aa")
|
(package! helm-describe-modes :pin "11fb36af119b784539d31c6160002de1957408aa")
|
||||||
(package! helm-projectile :pin "35a2111d00c0c0c9d8743280d3f1243bb217118a")
|
(package! helm-projectile :pin "e2e38825c975269a4971df25e79b2ae98929624e")
|
||||||
(package! helm-rg :pin "ee0a3c09da0c843715344919400ab0a0190cc9dc")
|
(package! helm-rg :pin "ee0a3c09da0c843715344919400ab0a0190cc9dc")
|
||||||
(package! swiper-helm :pin "93fb6db87bc6a5967898b5fd3286954cc72a0008")
|
(package! swiper-helm :pin "93fb6db87bc6a5967898b5fd3286954cc72a0008")
|
||||||
|
|
||||||
(when (modulep! +childframe)
|
(when (modulep! +childframe)
|
||||||
(package! helm-posframe :pin "87461b52b6f3f378c63642a33f584d4a4ba28351"))
|
(package! helm-posframe :pin "0b6bb016f0ff4980860a9d00574de311748c40b0"))
|
||||||
(when (modulep! +fuzzy)
|
(when (modulep! +fuzzy)
|
||||||
(package! helm-flx :pin "5220099e695a3586dba2d59640217fe378e66310"))
|
(package! helm-flx :pin "5220099e695a3586dba2d59640217fe378e66310"))
|
||||||
(when (modulep! +icons)
|
(when (modulep! +icons)
|
||||||
(package! helm-icons :pin "8d2f5e705c8b78a390677cf242024739c932fc95"))
|
(package! helm-icons :pin "0d113719ee72cb7b6bb7db29f7200d667bd86607"))
|
||||||
(when (modulep! :lang org)
|
(when (modulep! :lang org)
|
||||||
(package! helm-org :pin "d67186d3a64e610c03a5f3d583488f018fb032e4"))
|
(package! helm-org :pin "c80e53315ce6b096e2d0e630702df924bf00bf6a"))
|
||||||
|
|
|
@ -33,12 +33,12 @@ Interactive DO things. The completion engine that is /mostly/ built-into Emacs.
|
||||||
|
|
||||||
* Usage
|
* Usage
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]
|
This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
* Configuration
|
* Configuration
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]]
|
This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
* Troubleshooting
|
* Troubleshooting
|
||||||
|
@ -52,5 +52,5 @@ See [[id:4f36ae11-1da8-4624-9c30-46b764e849fc][this answer]].
|
||||||
|
|
||||||
* Appendix
|
* Appendix
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
7
modules/completion/ido/doctor.el
Normal file
7
modules/completion/ido/doctor.el
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||||
|
;;; completion/ido/doctor.el
|
||||||
|
|
||||||
|
(dolist (module '(helm ivy vertico))
|
||||||
|
(when (doom-module-p :completion module)
|
||||||
|
(error! "This module is incompatible with :completion %s; disable one or the other"
|
||||||
|
module)))
|
|
@ -1,8 +1,8 @@
|
||||||
;; -*- no-byte-compile: t; -*-
|
;; -*- no-byte-compile: t; -*-
|
||||||
;;; completion/ido/packages.el
|
;;; completion/ido/packages.el
|
||||||
|
|
||||||
(package! flx-ido :pin "7b44a5abb254bbfbeca7a29336f7f4ebd8aabbf2")
|
(package! flx-ido :pin "4b1346eb9a8a76ee9c9dede69738c63ad97ac5b6")
|
||||||
(package! ido-completing-read+ :pin "49e7967ea8c0ab0a206b40d70fc19be115083fa1")
|
(package! ido-completing-read+ :pin "5995b4605b4f2d568489491704ef21bc49ddecd5")
|
||||||
(package! ido-sort-mtime :pin "f638ff0c922af862f5211779f2311a27fde428eb")
|
(package! ido-sort-mtime :pin "f638ff0c922af862f5211779f2311a27fde428eb")
|
||||||
(package! ido-vertical-mode :pin "b1659e967da0687abceca733b389ace24004fa66")
|
(package! ido-vertical-mode :pin "b1659e967da0687abceca733b389ace24004fa66")
|
||||||
(package! crm-custom :pin "f1aaccf64306a5f99d9bf7ba815d7ea41c15518d")
|
(package! crm-custom :pin "f1aaccf64306a5f99d9bf7ba815d7ea41c15518d")
|
||||||
|
|
|
@ -27,7 +27,7 @@ lighter, simpler and faster in many cases.
|
||||||
Enable prescient filtering and sorting for Ivy searches.
|
Enable prescient filtering and sorting for Ivy searches.
|
||||||
|
|
||||||
** Packages
|
** Packages
|
||||||
- [[doom-package:all-the-icons-ivy]]* if [[doom-module:+icons]]
|
- [[doom-package:nerd-icons-ivy]]* if [[doom-module:+icons]]
|
||||||
- [[doom-package:amx]]
|
- [[doom-package:amx]]
|
||||||
- [[doom-package:counsel]]
|
- [[doom-package:counsel]]
|
||||||
- [[doom-package:counsel-projectile]]
|
- [[doom-package:counsel-projectile]]
|
||||||
|
@ -64,7 +64,7 @@ use their associated Helm command or plugin.
|
||||||
|
|
||||||
* TODO Usage
|
* TODO Usage
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
/This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
[[doom-package:ivy]] is a /large/ framework for completing things. Covering all its features is
|
[[doom-package:ivy]] is a /large/ framework for completing things. Covering all its features is
|
||||||
|
@ -169,14 +169,23 @@ A wgrep buffer can be opened from swiper with [[kbd:][C-c C-e]].
|
||||||
|
|
||||||
* TODO Configuration
|
* TODO Configuration
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
/This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
** TODO Enable fuzzy/non-fuzzy search for specific commands
|
** TODO Enable fuzzy/non-fuzzy search for specific commands
|
||||||
** TODO Change the position of the ivy childframe
|
** TODO Change the position of the ivy childframe
|
||||||
|
|
||||||
* TODO Troubleshooting
|
* TODO Troubleshooting
|
||||||
/There are no known problems with this module./ [[doom-report:][Report one?]]
|
** Sorting is not applied at all sometimes
|
||||||
|
If the number of candidates is greater than ~ivy-sort-max-size~, sorting will be
|
||||||
|
disabled completely. Doom lowers the default value to prevent performance
|
||||||
|
issues, so increasing the value may fix your issue:
|
||||||
|
#+begin_src elisp
|
||||||
|
;;; add to $DOOMDIR/config.el
|
||||||
|
(after! ivy
|
||||||
|
(setq ivy-sort-max-size 30000)) ; Doom sets this to 7500, but Ivy's default is 30k
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
|
||||||
* Frequently asked questions
|
* Frequently asked questions
|
||||||
[[doom-suggest-faq:][Ask a question?]]
|
[[doom-suggest-faq:][Ask a question?]]
|
||||||
|
@ -186,5 +195,5 @@ See [[id:4f36ae11-1da8-4624-9c30-46b764e849fc][this answer]].
|
||||||
|
|
||||||
* TODO Appendix
|
* TODO Appendix
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
|
@ -34,22 +34,6 @@ Buffers that are considered unreal (see `doom-real-buffer-p') are dimmed with
|
||||||
(ivy-append-face candidate 'ivy-modified-buffer))
|
(ivy-append-face candidate 'ivy-modified-buffer))
|
||||||
(candidate))))
|
(candidate))))
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun +ivy-rich-buffer-icon (candidate)
|
|
||||||
"Display the icon for CANDIDATE buffer."
|
|
||||||
;; NOTE This is inspired by `all-the-icons-ivy-buffer-transformer', minus the
|
|
||||||
;; buffer name and extra padding as those are handled by `ivy-rich'.
|
|
||||||
(propertize "\t" 'display
|
|
||||||
(if-let* ((buffer (get-buffer candidate))
|
|
||||||
(mode (buffer-local-value 'major-mode buffer)))
|
|
||||||
(or
|
|
||||||
(all-the-icons-ivy--icon-for-mode mode)
|
|
||||||
(all-the-icons-ivy--icon-for-mode (get mode 'derived-mode-parent))
|
|
||||||
(funcall
|
|
||||||
all-the-icons-ivy-family-fallback-for-buffer
|
|
||||||
all-the-icons-ivy-name-fallback-for-buffer))
|
|
||||||
(all-the-icons-icon-for-file candidate))))
|
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun +ivy-rich-describe-variable-transformer (cand)
|
(defun +ivy-rich-describe-variable-transformer (cand)
|
||||||
"Previews the value of the variable in the minibuffer"
|
"Previews the value of the variable in the minibuffer"
|
||||||
|
|
|
@ -116,12 +116,6 @@ results buffer.")
|
||||||
:config
|
:config
|
||||||
(setq ivy-rich-parse-remote-buffer nil)
|
(setq ivy-rich-parse-remote-buffer nil)
|
||||||
|
|
||||||
(when (modulep! +icons)
|
|
||||||
(cl-pushnew '(+ivy-rich-buffer-icon)
|
|
||||||
(cadr (plist-get ivy-rich-display-transformers-list
|
|
||||||
'ivy-switch-buffer))
|
|
||||||
:test #'equal))
|
|
||||||
|
|
||||||
(defun ivy-rich-bookmark-filename-or-empty (candidate)
|
(defun ivy-rich-bookmark-filename-or-empty (candidate)
|
||||||
(let ((filename (ivy-rich-bookmark-filename candidate)))
|
(let ((filename (ivy-rich-bookmark-filename candidate)))
|
||||||
(if (not filename) "" filename)))
|
(if (not filename) "" filename)))
|
||||||
|
@ -155,25 +149,16 @@ results buffer.")
|
||||||
(switch-buffer-alist (assq 'ivy-rich-candidate (plist-get plist :columns))))
|
(switch-buffer-alist (assq 'ivy-rich-candidate (plist-get plist :columns))))
|
||||||
(setcar switch-buffer-alist '+ivy-rich-buffer-name))
|
(setcar switch-buffer-alist '+ivy-rich-buffer-name))
|
||||||
|
|
||||||
|
(when (modulep! +icons)
|
||||||
|
(nerd-icons-ivy-rich-mode +1))
|
||||||
(ivy-rich-mode +1)
|
(ivy-rich-mode +1)
|
||||||
(ivy-rich-project-root-cache-mode +1))
|
(ivy-rich-project-root-cache-mode +1))
|
||||||
|
|
||||||
|
|
||||||
(use-package! all-the-icons-ivy
|
(use-package! nerd-icons-ivy-rich
|
||||||
:when (modulep! +icons)
|
:when (modulep! +icons)
|
||||||
:after ivy
|
:commands (nerd-icons-ivy-rich-mode)
|
||||||
:config
|
:after counsel-projectile)
|
||||||
;; `all-the-icons-ivy' is incompatible with ivy-rich's switch-buffer
|
|
||||||
;; modifications, so we disable them and merge them ourselves
|
|
||||||
(setq all-the-icons-ivy-buffer-commands nil)
|
|
||||||
|
|
||||||
(all-the-icons-ivy-setup)
|
|
||||||
(after! counsel-projectile
|
|
||||||
(let ((all-the-icons-ivy-file-commands
|
|
||||||
'(counsel-projectile
|
|
||||||
counsel-projectile-find-file
|
|
||||||
counsel-projectile-find-dir)))
|
|
||||||
(all-the-icons-ivy-setup))))
|
|
||||||
|
|
||||||
|
|
||||||
(use-package! counsel
|
(use-package! counsel
|
||||||
|
@ -237,7 +222,6 @@ results buffer.")
|
||||||
|
|
||||||
;; Record in jumplist when opening files via counsel-{ag,rg,pt,git-grep}
|
;; Record in jumplist when opening files via counsel-{ag,rg,pt,git-grep}
|
||||||
(add-hook 'counsel-grep-post-action-hook #'better-jumper-set-jump)
|
(add-hook 'counsel-grep-post-action-hook #'better-jumper-set-jump)
|
||||||
(add-hook 'counsel-grep-post-action-hook #'recenter)
|
|
||||||
(ivy-add-actions
|
(ivy-add-actions
|
||||||
'counsel-rg ; also applies to `counsel-rg'
|
'counsel-rg ; also applies to `counsel-rg'
|
||||||
'(("O" +ivy-git-grep-other-window-action "open in other window")))
|
'(("O" +ivy-git-grep-other-window-action "open in other window")))
|
||||||
|
@ -253,7 +237,7 @@ results buffer.")
|
||||||
(add-to-list 'ivy-sort-functions-alist '(counsel-imenu))
|
(add-to-list 'ivy-sort-functions-alist '(counsel-imenu))
|
||||||
|
|
||||||
;; `counsel-locate'
|
;; `counsel-locate'
|
||||||
(when IS-MAC
|
(when (featurep :system 'macos)
|
||||||
;; Use spotlight on mac by default since it doesn't need any additional setup
|
;; Use spotlight on mac by default since it doesn't need any additional setup
|
||||||
(setq counsel-locate-cmd #'counsel-locate-cmd-mdfind))
|
(setq counsel-locate-cmd #'counsel-locate-cmd-mdfind))
|
||||||
|
|
||||||
|
@ -292,13 +276,13 @@ results buffer.")
|
||||||
(cl-loop for dir in projectile-globally-ignored-directories
|
(cl-loop for dir in projectile-globally-ignored-directories
|
||||||
collect "--exclude"
|
collect "--exclude"
|
||||||
collect dir)
|
collect dir)
|
||||||
(if IS-WINDOWS '("--path-separator=/")))))
|
(if (featurep :system 'windows) '("--path-separator=/")))))
|
||||||
((executable-find "rg" t)
|
((executable-find "rg" t)
|
||||||
(append (list "rg" "--hidden" "--files" "--follow" "--color=never" "--no-messages")
|
(append (list "rg" "--hidden" "--files" "--follow" "--color=never" "--no-messages")
|
||||||
(cl-loop for dir in projectile-globally-ignored-directories
|
(cl-loop for dir in projectile-globally-ignored-directories
|
||||||
collect "--glob"
|
collect "--glob"
|
||||||
collect (concat "!" dir))
|
collect (concat "!" dir))
|
||||||
(if IS-WINDOWS '("--path-separator=/"))))
|
(if (featurep :system 'windows) '("--path-separator=/"))))
|
||||||
((cons find-program args)))
|
((cons find-program args)))
|
||||||
(unless (listp args)
|
(unless (listp args)
|
||||||
(user-error "`counsel-file-jump-args' is a list now, please customize accordingly."))
|
(user-error "`counsel-file-jump-args' is a list now, please customize accordingly."))
|
||||||
|
@ -315,7 +299,7 @@ results buffer.")
|
||||||
|
|
||||||
|
|
||||||
(use-package! counsel-projectile
|
(use-package! counsel-projectile
|
||||||
:defer t
|
:after ivy-rich
|
||||||
:init
|
:init
|
||||||
(define-key!
|
(define-key!
|
||||||
[remap projectile-find-file] #'+ivy/projectile-find-file
|
[remap projectile-find-file] #'+ivy/projectile-find-file
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||||
;;; completion/ivy/doctor.el
|
;;; completion/ivy/doctor.el
|
||||||
|
|
||||||
|
(dolist (module '(helm ido vertico))
|
||||||
|
(when (doom-module-p :completion module)
|
||||||
|
(error! "This module is incompatible with :completion %s; disable one or the other"
|
||||||
|
module)))
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
;; -*- no-byte-compile: t; -*-
|
;; -*- no-byte-compile: t; -*-
|
||||||
;;; completion/ivy/packages.el
|
;;; completion/ivy/packages.el
|
||||||
|
|
||||||
(package! swiper :pin "9d630d800e856a2c984c5a62a6f0ad313a9d2228")
|
(package! swiper :pin "8c30f4cab5948aa8d942a3b2bbf5fb6a94d9441d")
|
||||||
(package! ivy)
|
(package! ivy)
|
||||||
(package! ivy-hydra)
|
(package! ivy-hydra)
|
||||||
(package! ivy-avy)
|
(package! ivy-avy)
|
||||||
|
@ -10,15 +10,15 @@
|
||||||
(package! amx :pin "5b3aa1aae84f4a225cb8d26ab79a32f97693f023")
|
(package! amx :pin "5b3aa1aae84f4a225cb8d26ab79a32f97693f023")
|
||||||
(package! counsel-projectile :pin "40d1e1d4bb70acb00fddd6f4df9778bf2c52734b")
|
(package! counsel-projectile :pin "40d1e1d4bb70acb00fddd6f4df9778bf2c52734b")
|
||||||
(package! ivy-rich :pin "aff9b6bd53e0fdcf350ab83c90e64e651b47dba4")
|
(package! ivy-rich :pin "aff9b6bd53e0fdcf350ab83c90e64e651b47dba4")
|
||||||
(package! wgrep :pin "3132abd3750b8c87cbcf6942db952acfab5edccd")
|
(package! wgrep :pin "208b9d01cfffa71037527e3a324684b3ce45ddc4")
|
||||||
|
|
||||||
(if (modulep! +prescient)
|
(if (modulep! +prescient)
|
||||||
(package! ivy-prescient :pin "d7cc55dad453c465af9ececbab94426202b5b32b")
|
(package! ivy-prescient :pin "4b875be52e75f7b81e68a16b62cfbb2f2584042c")
|
||||||
(when (modulep! +fuzzy)
|
(when (modulep! +fuzzy)
|
||||||
(package! flx :pin "7b44a5abb254bbfbeca7a29336f7f4ebd8aabbf2")))
|
(package! flx :pin "4b1346eb9a8a76ee9c9dede69738c63ad97ac5b6")))
|
||||||
|
|
||||||
(when (modulep! +childframe)
|
(when (modulep! +childframe)
|
||||||
(package! ivy-posframe :pin "533a8e368fcabfd534761a5c685ce713376fa594"))
|
(package! ivy-posframe :pin "533a8e368fcabfd534761a5c685ce713376fa594"))
|
||||||
|
|
||||||
(when (modulep! +icons)
|
(when (modulep! +icons)
|
||||||
(package! all-the-icons-ivy :pin "a70cbfa1effe36efc946a823a580cec686d5e88d"))
|
(package! nerd-icons-ivy-rich :pin "7197614b27fd562e64b11c91d41bed4443aded90"))
|
||||||
|
|
|
@ -31,7 +31,7 @@ like [[doom-package:ivy]] and [[doom-package:helm]] do. The primary packages are
|
||||||
Add icons to =file= and =buffer= category completion selections.
|
Add icons to =file= and =buffer= category completion selections.
|
||||||
|
|
||||||
** Packages
|
** Packages
|
||||||
- [[doom-package:all-the-icons-completion]] if [[doom-module:+icons]]
|
- [[doom-package:nerd-icons-completion]] if [[doom-module:+icons]]
|
||||||
- [[doom-package:consult]]
|
- [[doom-package:consult]]
|
||||||
- [[doom-package:consult-flycheck]] if [[doom-module::checkers syntax]]
|
- [[doom-package:consult-flycheck]] if [[doom-module::checkers syntax]]
|
||||||
- [[doom-package:embark]]
|
- [[doom-package:embark]]
|
||||||
|
@ -63,7 +63,7 @@ intend to use their associated Helm command or plugin.
|
||||||
|
|
||||||
* TODO Usage
|
* TODO Usage
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
/This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
The packages in this module modify and use the built-in ~completing-read~
|
The packages in this module modify and use the built-in ~completing-read~
|
||||||
|
@ -76,16 +76,16 @@ Doom-specific additions:
|
||||||
When in an active Vertico completion session, the following doom added
|
When in an active Vertico completion session, the following doom added
|
||||||
keybindings are available:
|
keybindings are available:
|
||||||
|
|
||||||
| Keybind | Description |
|
| Keybind | Description |
|
||||||
|-------------------+----------------------------------------------------------------|
|
|---------------------------------------+--------------------------------------------------------------|
|
||||||
| [[kbd:][C-k]] | (evil) Go to previous candidate |
|
| [[kbd:][C-k]] | (evil) Go to previous candidate |
|
||||||
| [[kbd:][C-j]] | (evil) Go to next candidate |
|
| [[kbd:][C-j]] | (evil) Go to next candidate |
|
||||||
| [[kbd:][C-M-k]] | (evil) Go to previous group |
|
| [[kbd:][C-M-k]] | (evil) Go to previous group |
|
||||||
| [[kbd:][C-M-j]] | (evil) Go to next group |
|
| [[kbd:][C-M-j]] | (evil) Go to next group |
|
||||||
| [[kbd:][C-;]] or [[kbd:][<leader> a]] | Open an ~embark-act~ menu to chose a useful action |
|
| [[kbd:][C-;]] or [[kbd:][<leader> a]] | Open an ~embark-act~ menu to chose a useful action |
|
||||||
| [[kbd:][C-c C-;]] | export the current candidate list to a buffer |
|
| [[kbd:][C-c C-;]] | export the current candidate list to a buffer |
|
||||||
| [[kbd:][C-c C-l]] | ~embark-collect~ the current candidate list (collect verbatim) |
|
| [[kbd:][C-c C-l]] | ~embark-collect~ the current candidate list (collect verbatim) |
|
||||||
| [[kbd:][C-SPC]] | Preview the current candidate |
|
| [[kbd:][C-SPC]] | Preview the current candidate |
|
||||||
|
|
||||||
~embark-act~ will prompt you with a =which-key= menu with useful commands on the
|
~embark-act~ will prompt you with a =which-key= menu with useful commands on the
|
||||||
selected candidate or candidate list, depending on the completion category. Note
|
selected candidate or candidate list, depending on the completion category. Note
|
||||||
|
@ -99,17 +99,17 @@ This module provides an interface to navigate within a project using
|
||||||
|
|
||||||
https://assets.doomemacs.org/completion/vertico/projectile.png
|
https://assets.doomemacs.org/completion/vertico/projectile.png
|
||||||
|
|
||||||
| Keybind | Description |
|
| Keybind | Description |
|
||||||
|------------------+-------------------------------------|
|
|--------------------------------------+-------------------------------------|
|
||||||
| [[kbd:][SPC p f]], [[kbd:][SPC SPC]] | Jump to file in project |
|
| [[kbd:][SPC p f]], [[kbd:][SPC SPC]] | Jump to file in project |
|
||||||
| [[kbd:][SPC f f]], [[kbd:][SPC .]] | Jump to file from current directory |
|
| [[kbd:][SPC f f]], [[kbd:][SPC .]] | Jump to file from current directory |
|
||||||
| [[kbd:][SPC s i]] | Jump to symbol in file |
|
| [[kbd:][SPC s i]] | Jump to symbol in file |
|
||||||
|
|
||||||
** Project search & replace
|
** Project search & replace
|
||||||
This module provides interactive text search and replace using ripgrep.
|
This module provides interactive text search and replace using ripgrep.
|
||||||
|
|
||||||
| Keybind | Description |
|
| Keybind | Description |
|
||||||
|---------+--------------------------|
|
|------------------------+--------------------------|
|
||||||
| [[kbd:][<leader> s p]] | Search project |
|
| [[kbd:][<leader> s p]] | Search project |
|
||||||
| [[kbd:][<leader> s P]] | Search another project |
|
| [[kbd:][<leader> s P]] | Search another project |
|
||||||
| [[kbd:][<leader> s d]] | Search this directory |
|
| [[kbd:][<leader> s d]] | Search this directory |
|
||||||
|
@ -153,19 +153,19 @@ An ~occur-edit~ buffer can be opened from ~consult-line~ with [[kbd:][C-c C-e]].
|
||||||
|
|
||||||
** Vertico integration for various completing commands
|
** Vertico integration for various completing commands
|
||||||
*** General
|
*** General
|
||||||
| Keybind | Description |
|
| Keybind | Description |
|
||||||
|------------+-----------------------------|
|
|--------------------------------+-----------------------------|
|
||||||
| [[kbd:][M-x]], [[kbd:][SPC :]] | Enhanced M-x |
|
| [[kbd:][M-x]], [[kbd:][SPC :]] | Enhanced M-x |
|
||||||
| [[kbd:][SPC ']] | Resume last Vertico session |
|
| [[kbd:][SPC ']] | Resume last Vertico session |
|
||||||
|
|
||||||
*** Jump to files, buffers or projects
|
*** Jump to files, buffers or projects
|
||||||
| Keybind | Description |
|
| Keybind | Description |
|
||||||
|------------------+---------------------------------------|
|
|--------------------------------------+---------------------------------------|
|
||||||
| [[kbd:][SPC RET]] | Find bookmark |
|
| [[kbd:][SPC RET]] | Find bookmark |
|
||||||
| [[kbd:][SPC f f]], [[kbd:][SPC .]] | Browse from current directory |
|
| [[kbd:][SPC f f]], [[kbd:][SPC .]] | Browse from current directory |
|
||||||
| [[kbd:][SPC p f]], [[kbd:][SPC SPC]] | Find file in project |
|
| [[kbd:][SPC p f]], [[kbd:][SPC SPC]] | Find file in project |
|
||||||
| [[kbd:][SPC f r]] | Find recently opened file |
|
| [[kbd:][SPC f r]] | Find recently opened file |
|
||||||
| [[kbd:][SPC p p]] | Open another project |
|
| [[kbd:][SPC p p]] | Open another project |
|
||||||
| [[kbd:][SPC b b]], [[kbd:][SPC ,]] | Switch to buffer in current workspace |
|
| [[kbd:][SPC b b]], [[kbd:][SPC ,]] | Switch to buffer in current workspace |
|
||||||
| [[kbd:][SPC b B]], [[kbd:][SPC <]] | Switch to buffer |
|
| [[kbd:][SPC b B]], [[kbd:][SPC <]] | Switch to buffer |
|
||||||
|
|
||||||
|
@ -177,8 +177,8 @@ the last workspace by typing [[kbd:][0 SPC]].
|
||||||
[[kbd:][SPC f f]] and [[kbd:][SPC .]] support exporting to a [[kbd:][wdired]] buffer using [[kbd:][C-c C-e]].
|
[[kbd:][SPC f f]] and [[kbd:][SPC .]] support exporting to a [[kbd:][wdired]] buffer using [[kbd:][C-c C-e]].
|
||||||
|
|
||||||
*** Search
|
*** Search
|
||||||
| Keybind | Description |
|
| Keybind | Description |
|
||||||
|---------+-------------------------------------------|
|
|-------------------+-------------------------------------------|
|
||||||
| [[kbd:][SPC p t]] | List all TODO/FIXMEs in project |
|
| [[kbd:][SPC p t]] | List all TODO/FIXMEs in project |
|
||||||
| [[kbd:][SPC s b]] | Search the current buffer |
|
| [[kbd:][SPC s b]] | Search the current buffer |
|
||||||
| [[kbd:][SPC s d]] | Search this directory |
|
| [[kbd:][SPC s d]] | Search this directory |
|
||||||
|
@ -200,10 +200,10 @@ to =~/=.
|
||||||
*** Multiple candidate search
|
*** Multiple candidate search
|
||||||
This module modifies the default keybindings used in
|
This module modifies the default keybindings used in
|
||||||
~consult-completing-read-multiple~:
|
~consult-completing-read-multiple~:
|
||||||
| Keybind | Description |
|
| Keybind | Description |
|
||||||
|---------+-------------------------------------------------------------|
|
|---------------+-------------------------------------------------------------|
|
||||||
| [[kbd:][TAB]] | Select or deselect current candidate |
|
| [[kbd:][TAB]] | Select or deselect current candidate |
|
||||||
| [[kbd:][RET]] | Enters selected candidates (also toggles current candidate) |
|
| [[kbd:][RET]] | Enters selected candidates (also toggles current candidate) |
|
||||||
|
|
||||||
*** Async search commands
|
*** Async search commands
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
|
@ -226,9 +226,9 @@ filtering should be done after a second =#=.
|
||||||
For more information [[https://github.com/minad/consult#asynchronous-search][see here]].
|
For more information [[https://github.com/minad/consult#asynchronous-search][see here]].
|
||||||
|
|
||||||
** Marginalia
|
** Marginalia
|
||||||
| Keybind | Description |
|
| Keybind | Description |
|
||||||
|---------+---------------------------------|
|
|---------------+---------------------------------|
|
||||||
| [[kbd:][M-A]] | Cycle between annotation levels |
|
| [[kbd:][M-A]] | Cycle between annotation levels |
|
||||||
|
|
||||||
Marginalia annotations for symbols (e.g. [[kbd:][SPC h f]] and [[kbd:][SPC h v]]) come with extra
|
Marginalia annotations for symbols (e.g. [[kbd:][SPC h f]] and [[kbd:][SPC h v]]) come with extra
|
||||||
information the nature of the symbol. For the meaning of the annotations see
|
information the nature of the symbol. For the meaning of the annotations see
|
||||||
|
@ -260,7 +260,7 @@ you can use to further specify each space separated input in the following ways:
|
||||||
|
|
||||||
* TODO Configuration
|
* TODO Configuration
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
/This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
If you want to further configure this module, here are some good places to
|
If you want to further configure this module, here are some good places to
|
||||||
|
@ -302,5 +302,5 @@ See [[id:4f36ae11-1da8-4624-9c30-46b764e849fc][this answer]].
|
||||||
|
|
||||||
* TODO Appendix
|
* TODO Appendix
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
This module has no appendix yet. [[doom-contrib-module:][Write one?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
:in PATH
|
:in PATH
|
||||||
Sets what directory to base the search out of. Defaults to the current project's root.
|
Sets what directory to base the search out of. Defaults to the current project's root.
|
||||||
:recursive BOOL
|
:recursive BOOL
|
||||||
Whether or not to search files recursively from the base directory."
|
Whether or not to search files recursively from the base directory.
|
||||||
|
:args LIST
|
||||||
|
Arguments to be appended to `consult-ripgrep-args'."
|
||||||
(declare (indent defun))
|
(declare (indent defun))
|
||||||
(unless (executable-find "rg")
|
(unless (executable-find "rg")
|
||||||
(user-error "Couldn't find ripgrep in your PATH"))
|
(user-error "Couldn't find ripgrep in your PATH"))
|
||||||
|
@ -29,7 +31,7 @@
|
||||||
"--path-separator / --smart-case --no-heading "
|
"--path-separator / --smart-case --no-heading "
|
||||||
"--with-filename --line-number --search-zip "
|
"--with-filename --line-number --search-zip "
|
||||||
"--hidden -g !.git -g !.svn -g !.hg "
|
"--hidden -g !.git -g !.svn -g !.hg "
|
||||||
(mapconcat #'shell-quote-argument args " ")))
|
(mapconcat #'identity args " ")))
|
||||||
(prompt (if (stringp prompt) (string-trim prompt) "Search"))
|
(prompt (if (stringp prompt) (string-trim prompt) "Search"))
|
||||||
(query (or query
|
(query (or query
|
||||||
(when (doom-region-active-p)
|
(when (doom-region-active-p)
|
||||||
|
@ -135,26 +137,6 @@ Supports exporting consult-grep to wgrep, file to wdeired, and consult-location
|
||||||
(+vertico/embark-preview)
|
(+vertico/embark-preview)
|
||||||
(user-error (vertico-directory-enter)))))
|
(user-error (vertico-directory-enter)))))
|
||||||
|
|
||||||
(defvar +vertico/find-file-in--history nil)
|
|
||||||
;;;###autoload
|
|
||||||
(defun +vertico/find-file-in (&optional dir initial)
|
|
||||||
"Jump to file under DIR (recursive).
|
|
||||||
If INITIAL is non-nil, use as initial input."
|
|
||||||
(interactive)
|
|
||||||
(require 'consult)
|
|
||||||
(let* ((default-directory (or dir default-directory))
|
|
||||||
(prompt-dir (consult--directory-prompt "Find" default-directory))
|
|
||||||
(cmd (split-string-and-unquote +vertico-consult-fd-args " ")))
|
|
||||||
(find-file
|
|
||||||
(consult--read
|
|
||||||
(split-string (cdr (apply #'doom-call-process cmd)) "\n" t)
|
|
||||||
:prompt default-directory
|
|
||||||
:sort nil
|
|
||||||
:initial (if initial (shell-quote-argument initial))
|
|
||||||
:add-history (thing-at-point 'filename)
|
|
||||||
:category 'file
|
|
||||||
:history '(:input +vertico/find-file-in--history)))))
|
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun +vertico/jump-list (jump)
|
(defun +vertico/jump-list (jump)
|
||||||
"Go to an entry in evil's (or better-jumper's) jumplist."
|
"Go to an entry in evil's (or better-jumper's) jumplist."
|
||||||
|
@ -227,27 +209,23 @@ targets."
|
||||||
(not (string-suffix-p "-argument" (cdr binding))))))))
|
(not (string-suffix-p "-argument" (cdr binding))))))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun +vertico--consult--fd-make-builder ()
|
(defun +vertico/consult-fd-or-find (&optional dir initial)
|
||||||
(let ((cmd (split-string-and-unquote +vertico-consult-fd-args)))
|
"Runs consult-fd if fd version > 8.6.0 exists, consult-find otherwise.
|
||||||
(lambda (input)
|
See URL `https://github.com/minad/consult/issues/770'."
|
||||||
(pcase-let* ((`(,arg . ,opts) (consult--command-split input))
|
|
||||||
(`(,re . ,hl) (funcall consult--regexp-compiler
|
|
||||||
arg 'extended t)))
|
|
||||||
(when re
|
|
||||||
(cons (append cmd
|
|
||||||
(list (consult--join-regexps re 'extended))
|
|
||||||
opts)
|
|
||||||
hl))))))
|
|
||||||
|
|
||||||
(autoload #'consult--directory-prompt "consult")
|
|
||||||
;;;###autoload
|
|
||||||
(defun +vertico/consult-fd (&optional dir initial)
|
|
||||||
(interactive "P")
|
(interactive "P")
|
||||||
(if doom-projectile-fd-binary
|
;; TODO this condition was adapted from a similar one in lisp/doom-projects.el, to be replaced with a more robust check post v3
|
||||||
(pcase-let* ((`(,prompt ,paths ,dir) (consult--directory-prompt "Fd" dir))
|
(if (when-let*
|
||||||
(default-directory dir)
|
((bin (if (ignore-errors (file-remote-p default-directory nil t))
|
||||||
(builder (consult--find-make-builder paths)))
|
(cl-find-if (doom-rpartial #'executable-find t)
|
||||||
(find-file (consult--find prompt builder initial)))
|
(list "fdfind" "fd"))
|
||||||
|
doom-projectile-fd-binary))
|
||||||
|
(version (with-memoization doom-projects--fd-version
|
||||||
|
(cadr (split-string (cdr (doom-call-process bin "--version"))
|
||||||
|
" " t))))
|
||||||
|
((ignore-errors (version-to-list version))))
|
||||||
|
;; TODO remove once fd 8.6.0 is widespread enough to be the minimum version for doom
|
||||||
|
(version< "8.6.0" version))
|
||||||
|
(consult-fd dir initial)
|
||||||
(consult-find dir initial)))
|
(consult-find dir initial)))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
|
|
|
@ -86,8 +86,8 @@ buffer will be opened in the current workspace instead."
|
||||||
(funcall consult--buffer-display (car buffer)))))))
|
(funcall consult--buffer-display (car buffer)))))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun +vertico/embark-open-in-new-workspace (x)
|
(defun +vertico/embark-open-in-new-workspace (file)
|
||||||
"Open X (a file) in a new workspace."
|
"Open file in a new workspace."
|
||||||
(interactive)
|
(interactive "GFile:")
|
||||||
(+workspace/new)
|
(+workspace/new)
|
||||||
(find-file x))
|
(find-file file))
|
||||||
|
|
|
@ -7,8 +7,11 @@ The completion/vertico module uses the orderless completion style by default,
|
||||||
but this returns too broad a candidate set for company completion. This variable
|
but this returns too broad a candidate set for company completion. This variable
|
||||||
overrides `completion-styles' during company completion sessions.")
|
overrides `completion-styles' during company completion sessions.")
|
||||||
|
|
||||||
(defvar +vertico-consult-fd-args nil
|
(defvar +vertico-consult-dir-container-executable "docker"
|
||||||
"Shell command and arguments the vertico module uses for fd.")
|
"Command to call for listing container hosts.")
|
||||||
|
|
||||||
|
(defvar +vertico-consult-dir-container-args nil
|
||||||
|
"Command to call for listing container hosts.")
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;;; Packages
|
;;; Packages
|
||||||
|
@ -80,6 +83,9 @@ orderless."
|
||||||
((string= "!" pattern) `(orderless-literal . ""))
|
((string= "!" pattern) `(orderless-literal . ""))
|
||||||
;; Without literal
|
;; Without literal
|
||||||
((string-prefix-p "!" pattern) `(orderless-without-literal . ,(substring pattern 1)))
|
((string-prefix-p "!" pattern) `(orderless-without-literal . ,(substring pattern 1)))
|
||||||
|
;; Annotation
|
||||||
|
((string-prefix-p "&" pattern) `(orderless-annotation . ,(substring pattern 1)))
|
||||||
|
((string-suffix-p "&" pattern) `(orderless-annotation . ,(substring pattern 0 -1)))
|
||||||
;; Character folding
|
;; Character folding
|
||||||
((string-prefix-p "%" pattern) `(char-fold-to-regexp . ,(substring pattern 1)))
|
((string-prefix-p "%" pattern) `(char-fold-to-regexp . ,(substring pattern 1)))
|
||||||
((string-suffix-p "%" pattern) `(char-fold-to-regexp . ,(substring pattern 0 -1)))
|
((string-suffix-p "%" pattern) `(char-fold-to-regexp . ,(substring pattern 0 -1)))
|
||||||
|
@ -104,7 +110,7 @@ orderless."
|
||||||
;; find-file etc.
|
;; find-file etc.
|
||||||
completion-category-overrides '((file (styles +vertico-basic-remote orderless partial-completion)))
|
completion-category-overrides '((file (styles +vertico-basic-remote orderless partial-completion)))
|
||||||
orderless-style-dispatchers '(+vertico-orderless-dispatch)
|
orderless-style-dispatchers '(+vertico-orderless-dispatch)
|
||||||
orderless-component-separator "[ &]")
|
orderless-component-separator #'orderless-escapable-split-on-space)
|
||||||
;; ...otherwise find-file gets different highlighting than other commands
|
;; ...otherwise find-file gets different highlighting than other commands
|
||||||
(set-face-attribute 'completions-first-difference nil :inherit nil))
|
(set-face-attribute 'completions-first-difference nil :inherit nil))
|
||||||
|
|
||||||
|
@ -130,25 +136,26 @@ orderless."
|
||||||
[remap yank-pop] #'consult-yank-pop
|
[remap yank-pop] #'consult-yank-pop
|
||||||
[remap persp-switch-to-buffer] #'+vertico/switch-workspace-buffer)
|
[remap persp-switch-to-buffer] #'+vertico/switch-workspace-buffer)
|
||||||
:config
|
:config
|
||||||
(defadvice! +vertico--consult-recent-file-a (&rest _args)
|
(defadvice! +vertico--consult-recentf-a (&rest _args)
|
||||||
"`consult-recent-file' needs to have `recentf-mode' on to work correctly"
|
"`consult-recent-file' needs to have `recentf-mode' on to work correctly.
|
||||||
:before #'consult-recent-file
|
`consult-buffer' needs `recentf-mode' to show file candidates."
|
||||||
|
:before (list #'consult-recent-file #'consult-buffer)
|
||||||
(recentf-mode +1))
|
(recentf-mode +1))
|
||||||
|
|
||||||
(setq consult-project-root-function #'doom-project-root
|
(setq consult-project-function #'doom-project-root
|
||||||
consult-narrow-key "<"
|
consult-narrow-key "<"
|
||||||
consult-line-numbers-widen t
|
consult-line-numbers-widen t
|
||||||
consult-async-min-input 2
|
consult-async-min-input 2
|
||||||
consult-async-refresh-delay 0.15
|
consult-async-refresh-delay 0.15
|
||||||
consult-async-input-throttle 0.2
|
consult-async-input-throttle 0.2
|
||||||
consult-async-input-debounce 0.1)
|
consult-async-input-debounce 0.1
|
||||||
(unless +vertico-consult-fd-args
|
consult-fd-args
|
||||||
(setq +vertico-consult-fd-args
|
'((if (executable-find "fdfind" 'remote) "fdfind" "fd")
|
||||||
(if doom-projectile-fd-binary
|
"--color=never"
|
||||||
(format "%s --color=never -i -H -E .git --regex %s"
|
;; https://github.com/sharkdp/fd/issues/839
|
||||||
doom-projectile-fd-binary
|
"--full-path --absolute-path"
|
||||||
(if IS-WINDOWS "--path-separator=/" ""))
|
"--hidden --exclude .git"
|
||||||
consult-find-args)))
|
(if (featurep :system 'windows) "--path-separator=/")))
|
||||||
|
|
||||||
(consult-customize
|
(consult-customize
|
||||||
consult-ripgrep consult-git-grep consult-grep
|
consult-ripgrep consult-git-grep consult-grep
|
||||||
|
@ -191,28 +198,42 @@ orderless."
|
||||||
|
|
||||||
|
|
||||||
(use-package! consult-dir
|
(use-package! consult-dir
|
||||||
:bind (([remap list-directory] . consult-dir)
|
:defer t
|
||||||
|
:init
|
||||||
|
(map! [remap list-directory] #'consult-dir
|
||||||
|
(:after vertico
|
||||||
:map vertico-map
|
:map vertico-map
|
||||||
("C-x C-d" . consult-dir)
|
"C-x C-d" #'consult-dir
|
||||||
("C-x C-j" . consult-dir-jump-file))
|
"C-x C-j" #'consult-dir-jump-file))
|
||||||
:config
|
:config
|
||||||
(when (modulep! :tools docker)
|
(when (modulep! :tools docker)
|
||||||
|
;; TODO: Replace with `tramp-container--completion-function' when we drop
|
||||||
|
;; support for <29
|
||||||
|
(defun +vertico--consult-dir-container-hosts (host)
|
||||||
|
"Get a list of hosts from HOST."
|
||||||
|
(cl-loop for line in (cdr
|
||||||
|
(ignore-errors
|
||||||
|
(apply #'process-lines +vertico-consult-dir-container-executable
|
||||||
|
(append +vertico-consult-dir-container-args (list "ps")))))
|
||||||
|
for cand = (split-string line "[[:space:]]+" t)
|
||||||
|
collect (format "/%s:%s:/" host (car (last cand)))))
|
||||||
|
|
||||||
|
(defun +vertico--consult-dir-podman-hosts ()
|
||||||
|
(let ((+vertico-consult-dir-container-executable "podman"))
|
||||||
|
(+vertico--consult-dir-container-hosts "podman")))
|
||||||
|
|
||||||
(defun +vertico--consult-dir-docker-hosts ()
|
(defun +vertico--consult-dir-docker-hosts ()
|
||||||
"Get a list of hosts from docker."
|
(let ((+vertico-consult-dir-container-executable "docker"))
|
||||||
(when (if (>= emacs-major-version 29)
|
(+vertico--consult-dir-container-hosts "docker")))
|
||||||
(require 'tramp-container nil t)
|
|
||||||
(setq-local docker-tramp-use-names t)
|
(defvar +vertico--consult-dir-source-tramp-podman
|
||||||
(require 'docker-tramp nil t))
|
`(:name "Podman"
|
||||||
(let ((hosts)
|
:narrow ?p
|
||||||
(docker-query-fn #'docker-tramp--parse-running-containers))
|
:category file
|
||||||
(when (>= emacs-major-version 29)
|
:face consult-file
|
||||||
(setq docker-query-fn #'tramp-docker--completion-function))
|
:history file-name-history
|
||||||
(dolist (cand (funcall docker-query-fn))
|
:items ,#'+vertico--consult-dir-podman-hosts)
|
||||||
(let ((user (unless (string-empty-p (car cand))
|
"Podman candidate source for `consult-dir'.")
|
||||||
(concat (car cand) "@")))
|
|
||||||
(host (car (cdr cand))))
|
|
||||||
(push (concat "/docker:" user host ":/") hosts)))
|
|
||||||
hosts)))
|
|
||||||
|
|
||||||
(defvar +vertico--consult-dir-source-tramp-docker
|
(defvar +vertico--consult-dir-source-tramp-docker
|
||||||
`(:name "Docker"
|
`(:name "Docker"
|
||||||
|
@ -221,8 +242,9 @@ orderless."
|
||||||
:face consult-file
|
:face consult-file
|
||||||
:history file-name-history
|
:history file-name-history
|
||||||
:items ,#'+vertico--consult-dir-docker-hosts)
|
:items ,#'+vertico--consult-dir-docker-hosts)
|
||||||
"Docker candiadate source for `consult-dir'.")
|
"Docker candidate source for `consult-dir'.")
|
||||||
|
|
||||||
|
(add-to-list 'consult-dir-sources '+vertico--consult-dir-source-tramp-podman t)
|
||||||
(add-to-list 'consult-dir-sources '+vertico--consult-dir-source-tramp-docker t))
|
(add-to-list 'consult-dir-sources '+vertico--consult-dir-source-tramp-docker t))
|
||||||
|
|
||||||
(add-to-list 'consult-dir-sources 'consult-dir--source-tramp-ssh t)
|
(add-to-list 'consult-dir-sources 'consult-dir--source-tramp-ssh t)
|
||||||
|
@ -233,6 +255,11 @@ orderless."
|
||||||
(not (modulep! :checkers syntax +flymake)))
|
(not (modulep! :checkers syntax +flymake)))
|
||||||
:after (consult flycheck))
|
:after (consult flycheck))
|
||||||
|
|
||||||
|
(use-package! consult-yasnippet
|
||||||
|
:when (modulep! :editor snippets)
|
||||||
|
:defer t
|
||||||
|
:init (map! [remap yas-insert-snippet] #'consult-yasnippet))
|
||||||
|
|
||||||
|
|
||||||
(use-package! embark
|
(use-package! embark
|
||||||
:defer t
|
:defer t
|
||||||
|
@ -253,14 +280,16 @@ orderless."
|
||||||
|
|
||||||
(set-popup-rule! "^\\*Embark Export:" :size 0.35 :ttl 0 :quit nil)
|
(set-popup-rule! "^\\*Embark Export:" :size 0.35 :ttl 0 :quit nil)
|
||||||
|
|
||||||
(defadvice! +vertico--embark-which-key-prompt-a (fn &rest args)
|
(after! which-key
|
||||||
"Hide the which-key indicator immediately when using the completing-read prompter."
|
(defadvice! +vertico--embark-which-key-prompt-a (fn &rest args)
|
||||||
:around #'embark-completing-read-prompter
|
"Hide the which-key indicator immediately when using the completing-read prompter."
|
||||||
(which-key--hide-popup-ignore-command)
|
:around #'embark-completing-read-prompter
|
||||||
(let ((embark-indicators
|
(which-key--hide-popup-ignore-command)
|
||||||
(remq #'embark-which-key-indicator embark-indicators)))
|
(let ((embark-indicators
|
||||||
(apply fn args)))
|
(remq #'embark-which-key-indicator embark-indicators)))
|
||||||
(cl-nsubstitute #'+vertico-embark-which-key-indicator #'embark-mixed-indicator embark-indicators)
|
(apply fn args)))
|
||||||
|
(cl-nsubstitute #'+vertico-embark-which-key-indicator #'embark-mixed-indicator embark-indicators))
|
||||||
|
|
||||||
;; add the package! target finder before the file target finder,
|
;; add the package! target finder before the file target finder,
|
||||||
;; so we don't get a false positive match.
|
;; so we don't get a false positive match.
|
||||||
(let ((pos (or (cl-position
|
(let ((pos (or (cl-position
|
||||||
|
@ -282,9 +311,10 @@ orderless."
|
||||||
(map! (:map embark-file-map
|
(map! (:map embark-file-map
|
||||||
:desc "Open target with sudo" "s" #'doom/sudo-find-file
|
:desc "Open target with sudo" "s" #'doom/sudo-find-file
|
||||||
(:when (modulep! :tools magit)
|
(:when (modulep! :tools magit)
|
||||||
:desc "Open magit-status of target" "g" #'+vertico/embark-magit-status)
|
:desc "Open magit-status of target" "g" #'+vertico/embark-magit-status)
|
||||||
(:when (modulep! :ui workspaces)
|
(:when (modulep! :ui workspaces)
|
||||||
:desc "Open in new workspace" "TAB" #'+vertico/embark-open-in-new-workspace))))
|
:desc "Open in new workspace" "TAB" #'+vertico/embark-open-in-new-workspace
|
||||||
|
:desc "Open in new workspace" "<tab>" #'+vertico/embark-open-in-new-workspace))))
|
||||||
|
|
||||||
|
|
||||||
(use-package! marginalia
|
(use-package! marginalia
|
||||||
|
@ -294,7 +324,7 @@ orderless."
|
||||||
:desc "Cycle marginalia views" "M-A" #'marginalia-cycle)
|
:desc "Cycle marginalia views" "M-A" #'marginalia-cycle)
|
||||||
:config
|
:config
|
||||||
(when (modulep! +icons)
|
(when (modulep! +icons)
|
||||||
(add-hook 'marginalia-mode-hook #'all-the-icons-completion-marginalia-setup))
|
(add-hook 'marginalia-mode-hook #'nerd-icons-completion-marginalia-setup))
|
||||||
(advice-add #'marginalia--project-root :override #'doom-project-root)
|
(advice-add #'marginalia--project-root :override #'doom-project-root)
|
||||||
(pushnew! marginalia-command-categories
|
(pushnew! marginalia-command-categories
|
||||||
'(+default/find-file-under-here . file)
|
'(+default/find-file-under-here . file)
|
||||||
|
@ -320,3 +350,44 @@ orderless."
|
||||||
:hook (vertico-mode . vertico-posframe-mode)
|
:hook (vertico-mode . vertico-posframe-mode)
|
||||||
:config
|
:config
|
||||||
(add-hook 'doom-after-reload-hook #'posframe-delete-all))
|
(add-hook 'doom-after-reload-hook #'posframe-delete-all))
|
||||||
|
|
||||||
|
;; From https://github.com/minad/vertico/wiki#candidate-display-transformations-custom-candidate-highlighting
|
||||||
|
;;
|
||||||
|
;; Uses `add-face-text-property' instead of `propertize' unlike the above snippet
|
||||||
|
;; because `'append' is necessary to not override the match font lock
|
||||||
|
;; See: https://github.com/minad/vertico/issues/389
|
||||||
|
(use-package! vertico-multiform
|
||||||
|
:hook (vertico-mode . vertico-multiform-mode)
|
||||||
|
:config
|
||||||
|
(defvar +vertico-transform-functions nil)
|
||||||
|
|
||||||
|
(cl-defmethod vertico--format-candidate :around
|
||||||
|
(cand prefix suffix index start &context ((not +vertico-transform-functions) null))
|
||||||
|
(dolist (fun (ensure-list +vertico-transform-functions))
|
||||||
|
(setq cand (funcall fun cand)))
|
||||||
|
(cl-call-next-method cand prefix suffix index start))
|
||||||
|
|
||||||
|
(defun +vertico-highlight-directory (file)
|
||||||
|
"If FILE ends with a slash, highlight it as a directory."
|
||||||
|
(when (string-suffix-p "/" file)
|
||||||
|
(add-face-text-property 0 (length file) 'marginalia-file-priv-dir 'append file))
|
||||||
|
file)
|
||||||
|
|
||||||
|
(defun +vertico-highlight-enabled-mode (cmd)
|
||||||
|
"If MODE is enabled, highlight it as font-lock-constant-face."
|
||||||
|
(let ((sym (intern cmd)))
|
||||||
|
(with-current-buffer (nth 1 (buffer-list))
|
||||||
|
(if (or (eq sym major-mode)
|
||||||
|
(and
|
||||||
|
(memq sym minor-mode-list)
|
||||||
|
(boundp sym)
|
||||||
|
(symbol-value sym)))
|
||||||
|
(add-face-text-property 0 (length cmd) 'font-lock-constant-face 'append cmd)))
|
||||||
|
cmd))
|
||||||
|
|
||||||
|
(add-to-list 'vertico-multiform-categories
|
||||||
|
'(file
|
||||||
|
(+vertico-transform-functions . +vertico-highlight-directory)))
|
||||||
|
(add-to-list 'vertico-multiform-commands
|
||||||
|
'(execute-extended-command
|
||||||
|
(+vertico-transform-functions . +vertico-highlight-enabled-mode))))
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
;;; completion/vertico/doctor.el -*- lexical-binding: t; -*-
|
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||||
|
;;; completion/vertico/doctor.el
|
||||||
|
|
||||||
|
(dolist (module '(ivy helm ido))
|
||||||
|
(when (doom-module-p :completion module)
|
||||||
|
(error! "This module is incompatible with :completion %s; disable one or the other"
|
||||||
|
module)))
|
||||||
|
|
||||||
(when (require 'consult nil t)
|
(when (require 'consult nil t)
|
||||||
;; FIXME: This throws an error if grep is missing.
|
;; FIXME: This throws an error if grep is missing.
|
||||||
|
|
|
@ -1,29 +1,29 @@
|
||||||
;; -*- no-byte-compile: t; -*-
|
;; -*- no-byte-compile: t; -*-
|
||||||
;;; completion/vertico/packages.el
|
;;; completion/vertico/packages.el
|
||||||
|
|
||||||
(package! vertico
|
(package! vertico :pin "68cbd47589446e9674921bae0b98ff8fbe28be23")
|
||||||
:recipe (:host github :repo "minad/vertico"
|
|
||||||
:files ("*.el" "extensions/*.el"))
|
|
||||||
:pin "a28370d07f35c5387c7a9ec2e5b67f0d4598058d")
|
|
||||||
|
|
||||||
(package! orderless :pin "e6784026717a8a6a7dcd0bf31fd3414f148c542e")
|
(package! orderless :pin "dc7a781acf2e58ac7d20d1b522be0cde5213e057")
|
||||||
|
|
||||||
(package! consult :pin "fe49dedd71802ff97be7b89f1ec4bd61b98c2b13")
|
(package! consult :pin "b48ff6bf0527baeb6bfd07c6da9d303ff0b79c3d")
|
||||||
(package! consult-dir :pin "ed8f0874d26f10f5c5b181ab9f2cf4107df8a0eb")
|
(package! consult-dir :pin "3f5f4b71ebe819392cb090cda71bd39a93bd830a")
|
||||||
(when (and (modulep! :checkers syntax)
|
(when (and (modulep! :checkers syntax)
|
||||||
(not (modulep! :checkers syntax +flymake)))
|
(not (modulep! :checkers syntax +flymake)))
|
||||||
(package! consult-flycheck :pin "3f2a7c17cc2fe64e0c07e3bf90e33c885c0d7062"))
|
(package! consult-flycheck :pin "754f5497d827f7d58009256a21af614cc44378a3"))
|
||||||
(package! embark :pin "9a44418c349e41020cdc5ad1bd21e8c77a429062")
|
(package! embark :pin "c93abadc8220c0caa6fea805f7a736c346d47e7e")
|
||||||
(package! embark-consult :pin "9a44418c349e41020cdc5ad1bd21e8c77a429062")
|
(package! embark-consult :pin "c93abadc8220c0caa6fea805f7a736c346d47e7e")
|
||||||
|
|
||||||
(package! marginalia :pin "866e50aee4f066b0903752c69b33e9b7cab93f97")
|
(package! marginalia :pin "f6fe86b989a177355ab3ff7e97a384e10a7b0bb1")
|
||||||
|
|
||||||
(package! wgrep :pin "3132abd3750b8c87cbcf6942db952acfab5edccd")
|
(package! wgrep :pin "208b9d01cfffa71037527e3a324684b3ce45ddc4")
|
||||||
|
|
||||||
(when (modulep! +icons)
|
(when (modulep! +icons)
|
||||||
(package! all-the-icons-completion :pin "8eb3e410d63f5d0657b41829e7898793e81f31c0"))
|
(package! nerd-icons-completion :pin "c2db8557a3c1a9588d111f8c8e91cae96ee85010"))
|
||||||
|
|
||||||
(when (modulep! +childframe)
|
(when (modulep! +childframe)
|
||||||
(package! vertico-posframe
|
(package! vertico-posframe
|
||||||
:recipe (:host github :repo "tumashu/vertico-posframe")
|
:recipe (:host github :repo "tumashu/vertico-posframe")
|
||||||
:pin "7da6d648ff4202a48eb6647ee7dce8d65de48779"))
|
:pin "2e0e09e5bbd6ec576ddbe566ab122575ef051fab"))
|
||||||
|
|
||||||
|
(when (modulep! :editor snippets)
|
||||||
|
(package! consult-yasnippet :pin "834d39acfe8a7d2c304afbe4d649b9372118c756"))
|
||||||
|
|
|
@ -126,6 +126,9 @@
|
||||||
:desc "Search .emacs.d" "e" #'+default/search-emacsd
|
:desc "Search .emacs.d" "e" #'+default/search-emacsd
|
||||||
:desc "Locate file" "f" #'+lookup/file
|
:desc "Locate file" "f" #'+lookup/file
|
||||||
:desc "Jump to symbol" "i" #'imenu
|
:desc "Jump to symbol" "i" #'imenu
|
||||||
|
:desc "Jump to symbol in open buffers" "I"
|
||||||
|
(cond ((modulep! :completion vertico) #'consult-imenu-multi)
|
||||||
|
((modulep! :completion helm) #'helm-imenu-in-all-buffers))
|
||||||
:desc "Jump to visible link" "l" #'link-hint-open-link
|
:desc "Jump to visible link" "l" #'link-hint-open-link
|
||||||
:desc "Jump to link" "L" #'ffap-menu
|
:desc "Jump to link" "L" #'ffap-menu
|
||||||
:desc "Jump to bookmark" "m" #'bookmark-jump
|
:desc "Jump to bookmark" "m" #'bookmark-jump
|
||||||
|
@ -145,7 +148,10 @@
|
||||||
|
|
||||||
;;; <leader> i --- insert
|
;;; <leader> i --- insert
|
||||||
(:prefix-map ("i" . "insert")
|
(:prefix-map ("i" . "insert")
|
||||||
:desc "Emoji" "e" #'emojify-insert-emoji
|
(:when (> emacs-major-version 28)
|
||||||
|
:desc "Emoji" "e" #'emoji-search)
|
||||||
|
(:when (modulep! :ui emoji)
|
||||||
|
:desc "Emoji" "e" #'emojify-insert-emoji)
|
||||||
:desc "Current file name" "f" #'+default/insert-file-path
|
:desc "Current file name" "f" #'+default/insert-file-path
|
||||||
:desc "Current file path" "F" (cmd!! #'+default/insert-file-path t)
|
:desc "Current file path" "F" (cmd!! #'+default/insert-file-path t)
|
||||||
:desc "Snippet" "s" #'yas-insert-snippet
|
:desc "Snippet" "s" #'yas-insert-snippet
|
||||||
|
@ -505,7 +511,7 @@
|
||||||
"C-x C-b" #'ibuffer
|
"C-x C-b" #'ibuffer
|
||||||
"C-x K" #'doom/kill-this-buffer-in-all-windows
|
"C-x K" #'doom/kill-this-buffer-in-all-windows
|
||||||
|
|
||||||
;;; company-mode
|
;;; completion (in-buffer)
|
||||||
(:when (modulep! :completion company)
|
(:when (modulep! :completion company)
|
||||||
"C-;" #'+company/complete
|
"C-;" #'+company/complete
|
||||||
(:after company
|
(:after company
|
||||||
|
|
|
@ -43,7 +43,10 @@
|
||||||
#'yas-expand
|
#'yas-expand
|
||||||
(and (bound-and-true-p company-mode)
|
(and (bound-and-true-p company-mode)
|
||||||
(modulep! :completion company +tng))
|
(modulep! :completion company +tng))
|
||||||
#'company-indent-or-complete-common)
|
#'company-indent-or-complete-common
|
||||||
|
(and (bound-and-true-p corfu-mode)
|
||||||
|
(modulep! :completion corfu))
|
||||||
|
#'completion-at-point)
|
||||||
:m [tab] (cmds! (and (modulep! :editor snippets)
|
:m [tab] (cmds! (and (modulep! :editor snippets)
|
||||||
(evil-visual-state-p)
|
(evil-visual-state-p)
|
||||||
(or (eq evil-visual-selection 'line)
|
(or (eq evil-visual-selection 'line)
|
||||||
|
@ -127,7 +130,7 @@
|
||||||
;;
|
;;
|
||||||
;;; Module keybinds
|
;;; Module keybinds
|
||||||
|
|
||||||
;;; :completion
|
;;; :completion (in-buffer)
|
||||||
(map! (:when (modulep! :completion company)
|
(map! (:when (modulep! :completion company)
|
||||||
:i "C-@" (cmds! (not (minibufferp)) #'company-complete-common)
|
:i "C-@" (cmds! (not (minibufferp)) #'company-complete-common)
|
||||||
:i "C-SPC" (cmds! (not (minibufferp)) #'company-complete-common)
|
:i "C-SPC" (cmds! (not (minibufferp)) #'company-complete-common)
|
||||||
|
@ -156,7 +159,38 @@
|
||||||
"C-s" #'company-filter-candidates
|
"C-s" #'company-filter-candidates
|
||||||
[escape] #'company-search-abort)))
|
[escape] #'company-search-abort)))
|
||||||
|
|
||||||
(:when (modulep! :completion ivy)
|
(:when (modulep! :completion corfu)
|
||||||
|
(:after corfu
|
||||||
|
(:map corfu-mode-map
|
||||||
|
:i "C-SPC" #'completion-at-point
|
||||||
|
:n "C-SPC" (cmd! (call-interactively #'evil-insert-state)
|
||||||
|
(call-interactively #'completion-at-point))
|
||||||
|
:v "C-SPC" (cmd! (call-interactively #'evil-change)
|
||||||
|
(call-interactively #'completion-at-point)))
|
||||||
|
(:map corfu-map
|
||||||
|
:i "C-SPC" #'corfu-insert-separator
|
||||||
|
"C-k" #'corfu-previous
|
||||||
|
"C-j" #'corfu-next
|
||||||
|
"C-u" (cmd! (let (corfu-cycle)
|
||||||
|
(funcall-interactively #'corfu-next (- corfu-count))))
|
||||||
|
"C-d" (cmd! (let (corfu-cycle)
|
||||||
|
(funcall-interactively #'corfu-next corfu-count)))))
|
||||||
|
(:after corfu-popupinfo
|
||||||
|
:map corfu-popupinfo-map
|
||||||
|
"C-h" #'corfu-popupinfo-toggle
|
||||||
|
;; Reversed because popupinfo assumes opposite of what feels intuitive
|
||||||
|
;; with evil.
|
||||||
|
"C-S-k" #'corfu-popupinfo-scroll-down
|
||||||
|
"C-S-j" #'corfu-popupinfo-scroll-up
|
||||||
|
"C-<up>" #'corfu-popupinfo-scroll-down
|
||||||
|
"C-<down>" #'corfu-popupinfo-scroll-up
|
||||||
|
"C-S-p" #'corfu-popupinfo-scroll-down
|
||||||
|
"C-S-n" #'corfu-popupinfo-scroll-up
|
||||||
|
"C-S-u" (cmd!! #'corfu-popupinfo-scroll-down nil corfu-popupinfo-min-height)
|
||||||
|
"C-S-d" (cmd!! #'corfu-popupinfo-scroll-up nil corfu-popupinfo-min-height))))
|
||||||
|
|
||||||
|
;;; :completion (separate)
|
||||||
|
(map! (:when (modulep! :completion ivy)
|
||||||
(:after ivy
|
(:after ivy
|
||||||
:map ivy-minibuffer-map
|
:map ivy-minibuffer-map
|
||||||
"C-SPC" #'ivy-call-and-recenter ; preview file
|
"C-SPC" #'ivy-call-and-recenter ; preview file
|
||||||
|
@ -169,7 +203,8 @@
|
||||||
[C-return] #'+ivy/git-grep-other-window-action))
|
[C-return] #'+ivy/git-grep-other-window-action))
|
||||||
|
|
||||||
(:when (modulep! :completion helm)
|
(:when (modulep! :completion helm)
|
||||||
(:after helm :map helm-map
|
(:after helm
|
||||||
|
:map helm-map
|
||||||
[remap next-line] #'helm-next-line
|
[remap next-line] #'helm-next-line
|
||||||
[remap previous-line] #'helm-previous-line
|
[remap previous-line] #'helm-previous-line
|
||||||
[left] #'left-char
|
[left] #'left-char
|
||||||
|
@ -228,7 +263,7 @@
|
||||||
:g "M-8" #'+workspace/switch-to-7
|
:g "M-8" #'+workspace/switch-to-7
|
||||||
:g "M-9" #'+workspace/switch-to-8
|
:g "M-9" #'+workspace/switch-to-8
|
||||||
:g "M-0" #'+workspace/switch-to-final
|
:g "M-0" #'+workspace/switch-to-final
|
||||||
(:when IS-MAC
|
(:when (featurep :system 'macos)
|
||||||
:g "s-t" #'+workspace/new
|
:g "s-t" #'+workspace/new
|
||||||
:g "s-T" #'+workspace/display
|
:g "s-T" #'+workspace/display
|
||||||
:n "s-1" #'+workspace/switch-to-0
|
:n "s-1" #'+workspace/switch-to-0
|
||||||
|
@ -371,8 +406,11 @@
|
||||||
;;; <leader> c --- code
|
;;; <leader> c --- code
|
||||||
(:prefix-map ("c" . "code")
|
(:prefix-map ("c" . "code")
|
||||||
(:when (and (modulep! :tools lsp) (not (modulep! :tools lsp +eglot)))
|
(:when (and (modulep! :tools lsp) (not (modulep! :tools lsp +eglot)))
|
||||||
:desc "LSP Execute code action" "a" #'lsp-execute-code-action
|
:desc "LSP Execute code action" "a" #'lsp-execute-code-action
|
||||||
:desc "LSP Organize imports" "o" #'lsp-organize-imports
|
:desc "LSP Organize imports" "o" #'lsp-organize-imports
|
||||||
|
:desc "LSP" "l" #'+default/lsp-command-map
|
||||||
|
:desc "LSP Rename" "r" #'lsp-rename
|
||||||
|
:desc "Symbols" "S" #'lsp-treemacs-symbols
|
||||||
(:when (modulep! :completion ivy)
|
(:when (modulep! :completion ivy)
|
||||||
:desc "Jump to symbol in current workspace" "j" #'lsp-ivy-workspace-symbol
|
:desc "Jump to symbol in current workspace" "j" #'lsp-ivy-workspace-symbol
|
||||||
:desc "Jump to symbol in any workspace" "J" #'lsp-ivy-global-workspace-symbol)
|
:desc "Jump to symbol in any workspace" "J" #'lsp-ivy-global-workspace-symbol)
|
||||||
|
@ -386,10 +424,7 @@
|
||||||
:desc "Errors list" "X" #'lsp-treemacs-errors-list
|
:desc "Errors list" "X" #'lsp-treemacs-errors-list
|
||||||
:desc "Incoming call hierarchy" "y" #'lsp-treemacs-call-hierarchy
|
:desc "Incoming call hierarchy" "y" #'lsp-treemacs-call-hierarchy
|
||||||
:desc "Outgoing call hierarchy" "Y" (cmd!! #'lsp-treemacs-call-hierarchy t)
|
:desc "Outgoing call hierarchy" "Y" (cmd!! #'lsp-treemacs-call-hierarchy t)
|
||||||
:desc "References tree" "R" (cmd!! #'lsp-treemacs-references t)
|
:desc "References tree" "R" (cmd!! #'lsp-treemacs-references t)))
|
||||||
:desc "Symbols" "S" #'lsp-treemacs-symbols)
|
|
||||||
:desc "LSP" "l" #'+default/lsp-command-map
|
|
||||||
:desc "LSP Rename" "r" #'lsp-rename)
|
|
||||||
(:when (modulep! :tools lsp +eglot)
|
(:when (modulep! :tools lsp +eglot)
|
||||||
:desc "LSP Execute code action" "a" #'eglot-code-actions
|
:desc "LSP Execute code action" "a" #'eglot-code-actions
|
||||||
:desc "LSP Rename" "r" #'eglot-rename
|
:desc "LSP Rename" "r" #'eglot-rename
|
||||||
|
@ -496,7 +531,10 @@
|
||||||
|
|
||||||
;;; <leader> i --- insert
|
;;; <leader> i --- insert
|
||||||
(:prefix-map ("i" . "insert")
|
(:prefix-map ("i" . "insert")
|
||||||
:desc "Emoji" "e" #'emojify-insert-emoji
|
(:when (> emacs-major-version 28)
|
||||||
|
:desc "Emoji" "e" #'emoji-search)
|
||||||
|
(:when (modulep! :ui emoji)
|
||||||
|
:desc "Emoji" "e" #'emojify-insert-emoji)
|
||||||
:desc "Current file name" "f" #'+default/insert-file-path
|
:desc "Current file name" "f" #'+default/insert-file-path
|
||||||
:desc "Current file path" "F" (cmd!! #'+default/insert-file-path t)
|
:desc "Current file path" "F" (cmd!! #'+default/insert-file-path t)
|
||||||
:desc "Evil ex path" "p" (cmd! (evil-ex "R!echo "))
|
:desc "Evil ex path" "p" (cmd! (evil-ex "R!echo "))
|
||||||
|
@ -674,7 +712,7 @@
|
||||||
:desc "Configure project" "g" #'projectile-configure-project
|
:desc "Configure project" "g" #'projectile-configure-project
|
||||||
:desc "Invalidate project cache" "i" #'projectile-invalidate-cache
|
:desc "Invalidate project cache" "i" #'projectile-invalidate-cache
|
||||||
:desc "Kill project buffers" "k" #'projectile-kill-buffers
|
:desc "Kill project buffers" "k" #'projectile-kill-buffers
|
||||||
:desc "Find other file" "o" #'projectile-find-other-file
|
:desc "Find sibling file" "o" #'find-sibling-file
|
||||||
:desc "Switch project" "p" #'projectile-switch-project
|
:desc "Switch project" "p" #'projectile-switch-project
|
||||||
:desc "Find recent project files" "r" #'projectile-recentf
|
:desc "Find recent project files" "r" #'projectile-recentf
|
||||||
:desc "Run project" "R" #'projectile-run-project
|
:desc "Run project" "R" #'projectile-run-project
|
||||||
|
@ -736,6 +774,9 @@
|
||||||
:desc "Search .emacs.d" "e" #'+default/search-emacsd
|
:desc "Search .emacs.d" "e" #'+default/search-emacsd
|
||||||
:desc "Locate file" "f" #'locate
|
:desc "Locate file" "f" #'locate
|
||||||
:desc "Jump to symbol" "i" #'imenu
|
:desc "Jump to symbol" "i" #'imenu
|
||||||
|
:desc "Jump to symbol in open buffers" "I"
|
||||||
|
(cond ((modulep! :completion vertico) #'consult-imenu-multi)
|
||||||
|
((modulep! :completion helm) #'helm-imenu-in-all-buffers))
|
||||||
:desc "Jump to visible link" "l" #'link-hint-open-link
|
:desc "Jump to visible link" "l" #'link-hint-open-link
|
||||||
:desc "Jump to link" "L" #'ffap-menu
|
:desc "Jump to link" "L" #'ffap-menu
|
||||||
:desc "Jump list" "j" #'evil-show-jumps
|
:desc "Jump list" "j" #'evil-show-jumps
|
||||||
|
@ -754,8 +795,9 @@
|
||||||
((modulep! :completion helm) #'swiper-isearch-thing-at-point))
|
((modulep! :completion helm) #'swiper-isearch-thing-at-point))
|
||||||
:desc "Dictionary" "t" #'+lookup/dictionary-definition
|
:desc "Dictionary" "t" #'+lookup/dictionary-definition
|
||||||
:desc "Thesaurus" "T" #'+lookup/synonyms
|
:desc "Thesaurus" "T" #'+lookup/synonyms
|
||||||
(:when (fboundp 'vundo)
|
:desc "Undo history" "u"
|
||||||
:desc "Undo history" "u" #'vundo))
|
(cond ((modulep! :emacs undo +tree) #'undo-tree-visualize)
|
||||||
|
((modulep! :emacs undo) #'vundo)))
|
||||||
|
|
||||||
;;; <leader> t --- toggle
|
;;; <leader> t --- toggle
|
||||||
(:prefix-map ("t" . "toggle")
|
(:prefix-map ("t" . "toggle")
|
||||||
|
|
|
@ -43,12 +43,12 @@ This module provides a set of reasonable defaults, including:
|
||||||
|
|
||||||
* TODO Usage
|
* TODO Usage
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]
|
This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
* TODO Configuration
|
* TODO Configuration
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]]
|
This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
* Troubleshooting
|
* Troubleshooting
|
||||||
|
@ -59,7 +59,7 @@ This module provides a set of reasonable defaults, including:
|
||||||
|
|
||||||
* TODO Appendix
|
* TODO Appendix
|
||||||
#+begin_quote
|
#+begin_quote
|
||||||
🔨 /This module's appendix is incomplete./ [[doom-contrib-module:][Write more?]]
|
/This module's appendix is incomplete./ [[doom-contrib-module:][Write more?]]
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
** Commands
|
** Commands
|
||||||
|
|
|
@ -24,15 +24,16 @@ If ARG (universal argument), runs `compile' from the current directory."
|
||||||
generate `completing-read' candidates."
|
generate `completing-read' candidates."
|
||||||
(interactive)
|
(interactive)
|
||||||
(call-interactively
|
(call-interactively
|
||||||
(if (and (not IS-MAC) (executable-find "man"))
|
(if (and (not (featurep :system 'macos)) (executable-find "man"))
|
||||||
#'man
|
(or (command-remapping #'man)
|
||||||
|
#'man)
|
||||||
#'woman)))
|
#'woman)))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun +default/new-buffer ()
|
(defun +default/new-buffer ()
|
||||||
"TODO"
|
"TODO"
|
||||||
(interactive)
|
(interactive)
|
||||||
(if (modulep! 'evil)
|
(if (modulep! +evil)
|
||||||
(call-interactively #'evil-buffer-new)
|
(call-interactively #'evil-buffer-new)
|
||||||
(let ((buffer (generate-new-buffer "*new*")))
|
(let ((buffer (generate-new-buffer "*new*")))
|
||||||
(set-window-buffer nil buffer)
|
(set-window-buffer nil buffer)
|
||||||
|
@ -51,7 +52,7 @@ generate `completing-read' candidates."
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun +default/diagnostics (&rest arg)
|
(defun +default/diagnostics (&rest arg)
|
||||||
"List diagnostics for the current buffer/project.
|
"List diagnostics for the current buffer/project.
|
||||||
If the the vertico and lsp modules are active, list lsp diagnostics for the
|
If the vertico and lsp modules are active, list lsp diagnostics for the
|
||||||
current project. Otherwise list them for the current buffer"
|
current project. Otherwise list them for the current buffer"
|
||||||
(interactive)
|
(interactive)
|
||||||
(cond ((and (modulep! :completion vertico)
|
(cond ((and (modulep! :completion vertico)
|
||||||
|
|
|
@ -59,11 +59,16 @@
|
||||||
(after! woman
|
(after! woman
|
||||||
;; The woman-manpath default value does not necessarily match man. If we have
|
;; The woman-manpath default value does not necessarily match man. If we have
|
||||||
;; man available but aren't using it for performance reasons, we can extract
|
;; man available but aren't using it for performance reasons, we can extract
|
||||||
;; it's manpath.
|
;; its manpath.
|
||||||
(when (executable-find "man")
|
(let ((manpath (cond
|
||||||
(setq woman-manpath
|
((executable-find "manpath")
|
||||||
(split-string (cdr (doom-call-process "man" "--path"))
|
(split-string (cdr (doom-call-process "manpath"))
|
||||||
path-separator t))))
|
path-separator t))
|
||||||
|
((executable-find "man")
|
||||||
|
(split-string (cdr (doom-call-process "man" "--path"))
|
||||||
|
path-separator t)))))
|
||||||
|
(when manpath
|
||||||
|
(setq woman-manpath manpath))))
|
||||||
|
|
||||||
|
|
||||||
(use-package! drag-stuff
|
(use-package! drag-stuff
|
||||||
|
@ -76,7 +81,7 @@
|
||||||
|
|
||||||
|
|
||||||
;;;###package tramp
|
;;;###package tramp
|
||||||
(unless IS-WINDOWS
|
(unless (featurep :system 'windows)
|
||||||
(setq tramp-default-method "ssh")) ; faster than the default scp
|
(setq tramp-default-method "ssh")) ; faster than the default scp
|
||||||
|
|
||||||
|
|
||||||
|
@ -295,7 +300,7 @@ Continues comments if executed from a commented line. Consults
|
||||||
(define-key tabulated-list-mode-map "q" #'quit-window))
|
(define-key tabulated-list-mode-map "q" #'quit-window))
|
||||||
|
|
||||||
;; OS specific fixes
|
;; OS specific fixes
|
||||||
(when IS-MAC
|
(when (featurep :system 'macos)
|
||||||
;; Fix MacOS shift+tab
|
;; Fix MacOS shift+tab
|
||||||
(define-key key-translation-map [S-iso-lefttab] [backtab])
|
(define-key key-translation-map [S-iso-lefttab] [backtab])
|
||||||
;; Fix conventional OS keys in Emacs
|
;; Fix conventional OS keys in Emacs
|
||||||
|
@ -453,6 +458,48 @@ Continues comments if executed from a commented line. Consults
|
||||||
'(evil-ex-completion-map)))
|
'(evil-ex-completion-map)))
|
||||||
"C-s" command))
|
"C-s" command))
|
||||||
|
|
||||||
|
(map! :when (modulep! :completion corfu)
|
||||||
|
:after corfu
|
||||||
|
(:map corfu-map
|
||||||
|
[remap corfu-insert-separator] #'+corfu-smart-sep-toggle-escape
|
||||||
|
"C-S-s" #'+corfu-move-to-minibuffer
|
||||||
|
"C-p" #'corfu-previous
|
||||||
|
"C-n" #'corfu-next
|
||||||
|
"S-TAB" #'corfu-previous
|
||||||
|
[backtab] #'corfu-previous
|
||||||
|
"TAB" #'corfu-next
|
||||||
|
[tab] #'corfu-next))
|
||||||
|
(let ((cmds-del
|
||||||
|
`(menu-item "Reset completion" corfu-reset
|
||||||
|
:filter ,(lambda (cmd)
|
||||||
|
(when (and (>= corfu--index 0)
|
||||||
|
(eq corfu-preview-current 'insert))
|
||||||
|
cmd))))
|
||||||
|
(cmds-ret
|
||||||
|
`(menu-item "Insert completion DWIM" corfu-insert
|
||||||
|
:filter ,(lambda (cmd)
|
||||||
|
(interactive)
|
||||||
|
(cond ((null +corfu-want-ret-to-confirm)
|
||||||
|
(corfu-quit)
|
||||||
|
nil)
|
||||||
|
((eq +corfu-want-ret-to-confirm 'minibuffer)
|
||||||
|
(funcall-interactively cmd)
|
||||||
|
nil)
|
||||||
|
((and (or (not (minibufferp nil t))
|
||||||
|
(eq +corfu-want-ret-to-confirm t))
|
||||||
|
(>= corfu--index 0))
|
||||||
|
cmd)
|
||||||
|
((or (not (minibufferp nil t))
|
||||||
|
(eq +corfu-want-ret-to-confirm t))
|
||||||
|
nil)
|
||||||
|
(t cmd))))))
|
||||||
|
(map! :when (modulep! :completion corfu)
|
||||||
|
:map corfu-map
|
||||||
|
[backspace] cmds-del
|
||||||
|
"DEL" cmds-del
|
||||||
|
:gi [return] cmds-ret
|
||||||
|
:gi "RET" cmds-ret))
|
||||||
|
|
||||||
;; Smarter C-a/C-e for both Emacs and Evil. C-a will jump to indentation.
|
;; Smarter C-a/C-e for both Emacs and Evil. C-a will jump to indentation.
|
||||||
;; Pressing it again will send you to the true bol. Same goes for C-e, except
|
;; Pressing it again will send you to the true bol. Same goes for C-e, except
|
||||||
;; it will ignore comments+trailing whitespace before jumping to eol.
|
;; it will ignore comments+trailing whitespace before jumping to eol.
|
||||||
|
@ -482,7 +529,7 @@ Continues comments if executed from a commented line. Consults
|
||||||
:gi "C-S-RET" #'+default/newline-above
|
:gi "C-S-RET" #'+default/newline-above
|
||||||
:gn [C-S-return] #'+default/newline-above
|
:gn [C-S-return] #'+default/newline-above
|
||||||
|
|
||||||
(:when IS-MAC
|
(:when (featurep :system 'macos)
|
||||||
:gn "s-RET" #'+default/newline-below
|
:gn "s-RET" #'+default/newline-below
|
||||||
:gn [s-return] #'+default/newline-below
|
:gn [s-return] #'+default/newline-below
|
||||||
:gn "S-s-RET" #'+default/newline-above
|
:gn "S-s-RET" #'+default/newline-above
|
||||||
|
|
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