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
|
||||
description: Report something that isn't working as intended
|
||||
labels: ["is:bug", "needs-triage"]
|
||||
projects: ["doomemacs/2"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
@ -32,9 +33,8 @@ body:
|
|||
Doom.
|
||||
required: true
|
||||
- label: >
|
||||
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
|
||||
version ending in .50 or .9x)*
|
||||
The issue can be reproduced on a stable release of Emacs, such as 27,
|
||||
28, or 29. *(Unstable versions end in .50, .60, or .9x)*
|
||||
required: true
|
||||
- type: markdown
|
||||
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
|
||||
/profiles/*.el
|
||||
/.local*/
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
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
|
||||
a copy of this software and associated documentation files (the
|
||||
|
|
31
README.md
31
README.md
|
@ -5,7 +5,7 @@
|
|||
[Install](#install) • [Documentation] • [FAQ] • [Screenshots] • [Contribute](#contribute)
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
[][Discord]
|
||||
|
@ -98,20 +98,23 @@ Check out [the FAQ][FAQ] for answers to common questions about the project.
|
|||
|
||||
|
||||
# Prerequisites
|
||||
+ Git 2.23+
|
||||
+ Emacs 27.1–29.1 (**Recommended: 29.1 +
|
||||
- Git 2.23+
|
||||
- Emacs 27.1–29.2 (**Recommended: 29.2 +
|
||||
[native-comp](https://www.emacswiki.org/emacs/GccEmacs)**)
|
||||
> :warning: Unstable and pre-release builds of Emacs -- which end in `.50`,
|
||||
> `.60`, or `.9X` (e.g. `28.1.91`) -- **are not officially supported**. There
|
||||
> *is* some effort to support Emacs HEAD, however. [Follow this Discourse
|
||||
> post](https://discourse.doomemacs.org/t/3241) for details.
|
||||
+ [ripgrep] 11.0+
|
||||
+ GNU `find`
|
||||
+ *OPTIONAL:* [fd] 7.3.0+ (improves file indexing performance for some commands)
|
||||
- [ripgrep] 11.0+
|
||||
- GNU `find`
|
||||
- *OPTIONAL:* [fd] 7.3.0+ (improves file indexing performance for some commands)
|
||||
|
||||
Doom is comprised of [~150 optional modules][Modules], some of which may have
|
||||
additional dependencies. [Visit their documentation][Modules] or run `bin/doom
|
||||
doctor` to check for any that you may have missed.
|
||||
> [!WARNING]
|
||||
> Unstable and pre-release builds of Emacs -- which end in `.50`, `.60`, or
|
||||
> `.9X` (e.g. `28.1.91`) -- **are not officially supported**. There *is* some
|
||||
> effort to support Emacs HEAD, however. [Follow this Discourse
|
||||
> post](https://discourse.doomemacs.org/t/3241) for details.
|
||||
|
||||
> [!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
|
||||
|
@ -135,8 +138,6 @@ commands you should know about:
|
|||
+ `doom env` to dump a snapshot of your shell environment to a file that Doom
|
||||
will load at startup. This allows Emacs to inherit your `PATH`, among other
|
||||
things.
|
||||
+ `doom build` to recompile all installed packages (use this if you up/downgrade
|
||||
Emacs).
|
||||
|
||||
|
||||
# Roadmap
|
||||
|
|
12
bin/doom
12
bin/doom
|
@ -89,9 +89,9 @@
|
|||
(user-error (message "Error: %s" (cadr e))
|
||||
(kill-emacs 2)))
|
||||
|
||||
;; UX: Abort if the user is using 'doom' as root, unless ~/.config/emacs is
|
||||
;; owned by root, in which case we assume the user genuinely wants root to be
|
||||
;; their primary user account for Emacs.
|
||||
;; UX: Abort if the user is using 'doom' as root, unless $EMACSDIR is owned by
|
||||
;; root, in which case we can safely assume the user genuinely wants root to
|
||||
;; be their primary user account for this session.
|
||||
(when (equal 0 (user-real-uid))
|
||||
(unless (equal 0 (file-attribute-user-id (file-attributes doom-emacs-dir)))
|
||||
(message
|
||||
|
@ -271,10 +271,8 @@ SEE ALSO:
|
|||
(defcli-autoload! ((profiles profile)))
|
||||
(defcli-autoload! ((upgrade up)))
|
||||
(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! ((compile c)))
|
||||
(defcli-autoload! (clean) "compile")
|
||||
|
||||
;; TODO Post-3.0 commands
|
||||
;; (load! "gc" dir)
|
||||
|
@ -282,8 +280,6 @@ SEE ALSO:
|
|||
;; (load! "nuke" dir)
|
||||
;; (load! "package" 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"
|
||||
|
|
|
@ -173,7 +173,7 @@
|
|||
behaviour for known commands.
|
||||
|
||||
#+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]].
|
||||
#+end_quote
|
||||
|
||||
|
|
|
@ -5,6 +5,12 @@
|
|||
#+subtitle: Samples of Emacs/Doom dotfiles, concepts, and sub-projects
|
||||
#+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
|
||||
Examples speak louder than technical explanations, so this file exists to house
|
||||
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
|
||||
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 Emacs package
|
||||
*** 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
|
||||
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
|
||||
*** =profiles.el=
|
||||
:PROPERTIES:
|
||||
|
|
34
docs/faq.org
34
docs/faq.org
|
@ -5,6 +5,12 @@
|
|||
#+subtitle: Answers to common issues and questions
|
||||
#+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
|
||||
:PROPERTIES:
|
||||
: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
|
||||
variable-pitch-mode or mixed-pitch-mode). Popular for text modes, like Org or
|
||||
Markdown.
|
||||
- [[var:doom-unicode-font]]: used for rendering unicode glyphs. This is ~Symbola~ by
|
||||
default. It is ignored if the [[doom-module::ui unicode]] module is enabled.
|
||||
- [[var:doom-emoji-font]]: used for rendering emoji. Only needed if you want to use
|
||||
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]]
|
||||
face is used.
|
||||
- [[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
|
||||
(setq doom-font (font-spec :family "JetBrainsMono" :size 12 :weight 'light)
|
||||
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))
|
||||
#+end_src
|
||||
|
||||
#+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
|
||||
issues are /rarely/ Doom issues!*
|
||||
#+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?
|
||||
*Short answer:* it is safe to sync =$DOOMDIR= across systems, but not
|
||||
=$EMACSDIR=. Once moved, use ~$ doom sync && doom build~ to ensure everything is
|
||||
set up correctly.
|
||||
=$EMACSDIR=. Once moved, use ~$ doom sync~ to ensure everything is set up
|
||||
correctly.
|
||||
|
||||
*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
|
||||
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
|
||||
moved.
|
||||
should be solved by running ~$ doom sync~ on the other end, once moved.
|
||||
|
||||
** Start over, in case something went terribly wrong?
|
||||
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
|
||||
(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
|
||||
the [[doom-module::ui ligatures]] module altogether.
|
||||
|
@ -618,7 +624,7 @@ keybinds to work:
|
|||
#+end_src
|
||||
|
||||
#+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.
|
||||
#+end_quote
|
||||
** 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.
|
||||
|
||||
#+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!
|
||||
#+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?
|
||||
#+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]].
|
||||
#+end_quote
|
||||
|
||||
** TODO How does Doom Emacs improve runtime performance?
|
||||
#+begin_quote
|
||||
🔨 *This post is a work in progress!*
|
||||
*This post is a work in progress!*
|
||||
#+end_quote
|
||||
|
||||
** 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.
|
||||
|
||||
#+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.
|
||||
#+end_quote
|
||||
|
||||
|
|
|
@ -551,9 +551,7 @@ doom sync
|
|||
doom env
|
||||
|
||||
# Lastly, install the icon fonts Doom uses:
|
||||
emacs --batch -f all-the-icons-install-fonts
|
||||
# On Windows, `all-the-icons-install-fonts` will only download the fonts, you'll
|
||||
# have to install them by hand afterwards!
|
||||
emacs --batch -f nerd-icons-install-fonts
|
||||
#+END_SRC
|
||||
|
||||
To understand the purpose of the =~/.doom.d= directory and =~/.doom.d/init.el=
|
||||
|
|
|
@ -27,16 +27,17 @@
|
|||
;;; Code:
|
||||
|
||||
;; 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
|
||||
;; cause stuttering/freezes.
|
||||
;; off, but will be reset later by `gcmh-mode' (or in doom-cli.el, if in a
|
||||
;; noninteractive session). Not resetting it later causes stuttering/freezes.
|
||||
(setq gc-cons-threshold most-positive-fixnum)
|
||||
|
||||
;; PERF: Don't use precious startup time checking mtime on elisp bytecode.
|
||||
;; 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)
|
||||
|
||||
;; 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.
|
||||
(when (getenv-internal "DEBUG")
|
||||
(setq init-file-debug t
|
||||
|
@ -48,10 +49,10 @@
|
|||
|
||||
(or
|
||||
;; 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,
|
||||
;; a more complete version of this optimization can be found in lisp/doom.el.
|
||||
;; notable saving in startup time. This is just a stopgap though; this
|
||||
;; optimization is continued more comprehensively in lisp/doom.el.
|
||||
(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.
|
||||
(command-line-args (unless noninteractive command-line-args))
|
||||
;; I avoid using `command-switch-alist' to process --profile (and
|
||||
|
@ -84,7 +85,10 @@
|
|||
(or (load (expand-file-name
|
||||
(format (let ((lfile (getenv-internal "DOOMPROFILELOADFILE")))
|
||||
(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")
|
||||
"profiles/load.%d.elc"))
|
||||
emacs-major-version)
|
||||
|
@ -95,32 +99,32 @@
|
|||
;; PERF: When `load'ing or `require'ing files, each permutation of
|
||||
;; `load-suffixes' and `load-file-rep-suffixes' (then `load-suffixes' +
|
||||
;; `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
|
||||
;; hundreds/thousands of files Emacs needs to load.
|
||||
;; amounts to at least one file op, which is normally very fast, but can
|
||||
;; add up over the hundreds/thousands of files Emacs loads.
|
||||
;;
|
||||
;; 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
|
||||
;; `load'. See the docs of `load' for details.
|
||||
;; this early -- I remove `.so' from `load-suffixes' and pass the
|
||||
;; `must-suffix' arg to `load'. See the docs of `load' for details.
|
||||
(if (let ((load-suffixes '(".elc" ".el")))
|
||||
;; I avoid `load's NOERROR argument because other, legitimate errors
|
||||
;; (like permission or IO errors) should not be suppressed or
|
||||
;; interpreted as "this is not a Doom config".
|
||||
(condition-case _
|
||||
;; I avoid `load's NOERROR argument because it suppresses other,
|
||||
;; legitimate errors (like permission or IO errors), which gets
|
||||
;; incorrectly interpreted as "this is not a Doom config".
|
||||
(condition-case-unless-debug _
|
||||
;; Load the heart of Doom Emacs.
|
||||
(load (expand-file-name "lisp/doom" user-emacs-directory)
|
||||
nil (not init-file-debug) nil 'must-suffix)
|
||||
;; Failing that, assume that we're loading a non-Doom config.
|
||||
(file-missing
|
||||
;; HACK: `startup--load-user-init-file' resolves $EMACSDIR from a
|
||||
;; lexically bound `startup-init-directory', which means changes
|
||||
;; to `user-emacs-directory' won't be respected when loading
|
||||
;; $EMACSDIR/init.el, so I force it to:
|
||||
;; lexical (and so, not-trivially-modifiable)
|
||||
;; `startup-init-directory', so Emacs will fail to locate the
|
||||
;; correct $EMACSDIR/init.el without help.
|
||||
(define-advice startup--load-user-init-file (:filter-args (args) reroute-to-profile)
|
||||
(list (lambda () (expand-file-name "init.el" user-emacs-directory))
|
||||
nil (nth 2 args)))
|
||||
;; Set `user-init-file' for the `load' call further below, and do so
|
||||
;; here while our `file-name-handler-alist' optimization is still
|
||||
;; effective (benefits `expand-file-name'). BTW: Emacs resets
|
||||
;; (Re)set `user-init-file' for the `load' call further below, and
|
||||
;; do so here while our `file-name-handler-alist' optimization is
|
||||
;; still effective (benefits `expand-file-name'). BTW: Emacs resets
|
||||
;; `user-init-file' and `early-init-file' after this file is loaded.
|
||||
(setq user-init-file (expand-file-name "early-init" user-emacs-directory))
|
||||
;; 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.
|
||||
(setq gc-cons-threshold (* 16 1024 1024))
|
||||
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))))
|
||||
|
||||
;; 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,13 +96,33 @@ in."
|
|||
(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..."))
|
||||
(when (file-exists-p "~/.emacs")
|
||||
(warn! "Detected an ~/.emacs file, which may prevent Doom from loading")
|
||||
(explain! "If Emacs finds an ~/.emacs file, it will ignore ~/.emacs.d, where Doom is "
|
||||
"typically installed. If you're seeing a vanilla Emacs splash screen, this "
|
||||
"may explain why. If you use Chemacs, you may ignore this warning."))
|
||||
(print-group!
|
||||
(unless (or (file-equal-p doom-emacs-dir "~/.emacs.d")
|
||||
(file-equal-p doom-emacs-dir "~/.config/emacs"))
|
||||
(print! (warn "Doom is installed in a non-standard location"))
|
||||
(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..."))
|
||||
(print-group!
|
||||
(unless (functionp 'json-serialize)
|
||||
(warn! "Emacs was not built with native JSON support")
|
||||
(explain! "Users will see a substantial performance gain by building Emacs with "
|
||||
|
@ -114,9 +134,10 @@ in."
|
|||
(explain! "Users will see a substantial performance gain by building Emacs with "
|
||||
"native compilation support, availible in emacs 28+."
|
||||
"You must install a prebuilt Emacs binary with this included, or compile "
|
||||
"Emacs with the --with-native-compilation option."))
|
||||
"Emacs with the --with-native-compilation option.")))
|
||||
|
||||
(print! (start "Checking for private config conflicts..."))
|
||||
(print-group!
|
||||
(let* ((xdg-dir (concat (or (getenv "XDG_CONFIG_HOME")
|
||||
"~/.config")
|
||||
"/doom/"))
|
||||
|
@ -137,7 +158,24 @@ in."
|
|||
(print! (warn "Detected two private configs, in %s and %s")
|
||||
(abbreviate-file-name xdg-dir)
|
||||
doom-dir)
|
||||
(explain! "The second directory will be ignored, as it has lower precedence.")))
|
||||
(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..."))
|
||||
(elc-check-dir doom-core-dir)
|
||||
|
@ -205,13 +243,13 @@ in."
|
|||
;; Check for fonts
|
||||
(if (not (executable-find "fc-list"))
|
||||
(warn! "Warning: unable to detect fonts because fontconfig isn't installed")
|
||||
;; all-the-icons fonts
|
||||
;; nerd-icons fonts
|
||||
(when (and (pcase system-type
|
||||
(`gnu/linux (concat (or (getenv "XDG_DATA_HOME")
|
||||
"~/.local/share")
|
||||
"/fonts/"))
|
||||
(`darwin "~/Library/Fonts/"))
|
||||
(require 'all-the-icons nil t))
|
||||
(require 'nerd-icons nil t))
|
||||
(with-temp-buffer
|
||||
(let ((errors 0))
|
||||
(cl-destructuring-bind (status . output)
|
||||
|
@ -219,15 +257,16 @@ in."
|
|||
(if (not (zerop status))
|
||||
(print! (error "There was an error running `fc-list'. Is fontconfig installed correctly?"))
|
||||
(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))
|
||||
(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)
|
||||
(explain! "Some all-the-icons fonts were missing.\n\n"
|
||||
"You can install them by running `M-x all-the-icons-install-fonts' within Emacs.\n"
|
||||
"This could also mean you've installed them in non-standard locations, in which "
|
||||
"case feel free to ignore this warning.")))))))))
|
||||
(explain! "Some needed fonts are not properly installed on your system. To download and "
|
||||
"install them, run `M-x nerd-icons-install-fonts' from within Doom Emacs. "
|
||||
"However, on Windows this command will only download them; the fonts must "
|
||||
"be installed manually afterwards.")))))))))
|
||||
|
||||
(print! (start "Checking for stale elc files in your DOOMDIR..."))
|
||||
(when (file-directory-p doom-user-dir)
|
||||
|
|
|
@ -33,7 +33,8 @@
|
|||
"^SSH_\\(AUTH_SOCK\\|AGENT_PID\\)$" "^\\(SSH\\|GPG\\)_TTY$"
|
||||
"^GPG_AGENT_INFO$"
|
||||
;; Internal Doom envvars
|
||||
"^DEBUG$" "^INSECURE$" "^\\(EMACS\\|DOOM\\)DIR$" "^DOOMPROFILE$" "^__")
|
||||
"^DEBUG$" "^INSECURE$" "^\\(EMACS\\|DOOM\\)DIR$"
|
||||
"^DOOM\\(PATH\\|PROFILE\\)$" "^__")
|
||||
"Environment variables to omit from envvar files.
|
||||
|
||||
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?")
|
||||
(envfile? ("--env" :yes) "(Re)generate an envvars file? (see `$ doom help env`)")
|
||||
(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?")
|
||||
&context context)
|
||||
"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,
|
||||
4. Prompts you to generate an envvar file (same as `$ doom env`),
|
||||
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.
|
||||
|
||||
|
@ -55,20 +55,19 @@ Change `$DOOMDIR' with the `--doomdir' option, e.g.
|
|||
(setq doom-user-dir (expand-file-name "doom/" xdg-config-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)
|
||||
(print! (success "Created %s") (relpath doom-user-dir)))
|
||||
(print! (success "Created %s") (path doom-user-dir)))
|
||||
|
||||
;; Create init.el, config.el & packages.el
|
||||
(print-group!
|
||||
(mapc (lambda (file)
|
||||
(cl-destructuring-bind (filename . template) file
|
||||
(if (file-exists-p! filename doom-user-dir)
|
||||
(print! (item "Skipping %s (already exists)")
|
||||
(path filename))
|
||||
(print! (item "Creating %s%s") (relpath doom-user-dir) filename)
|
||||
(with-temp-file (doom-path doom-user-dir filename)
|
||||
(insert-file-contents template))
|
||||
(setq filename (doom-path doom-user-dir filename))
|
||||
(if (file-exists-p filename)
|
||||
(print! (item "Skipping %s (already exists)...") (path filename))
|
||||
(print! (item "Creating %s...") (path filename))
|
||||
(with-temp-file filename (insert-file-contents template))
|
||||
(print! (success "Done!")))))
|
||||
(let ((template-dir (doom-path doom-emacs-dir "templates")))
|
||||
`((,doom-module-init-file
|
||||
|
@ -96,7 +95,7 @@ Change `$DOOMDIR' with the `--doomdir' option, e.g.
|
|||
(if (eq install? :no)
|
||||
(print! (warn "Not installing plugins, as requested"))
|
||||
(print! "Installing plugins")
|
||||
(doom-packages-install))
|
||||
(doom-packages-ensure))
|
||||
|
||||
(print! "Regenerating autoloads files")
|
||||
(doom-profile-generate)
|
||||
|
@ -110,22 +109,6 @@ Change `$DOOMDIR' with the `--doomdir' option, e.g.
|
|||
('user-error
|
||||
(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")
|
||||
(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)))
|
||||
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))))))
|
||||
(defun doom-cli-help--similarity (a b)
|
||||
(- 1 (/ (float (doom-cli-help--string-distance a b))
|
||||
(max (length a) (length b)))))
|
||||
|
||||
(defun doom-cli-help--string-distance (a b)
|
||||
"Calculate the Restricted Damerau-Levenshtein distance between A and B.
|
||||
This is also known as the Optimal String Alignment algorithm.
|
||||
|
||||
It is assumed that A and B are both strings, and before processing both are
|
||||
converted to lowercase.
|
||||
|
||||
This returns the minimum number of edits required to transform A
|
||||
to B, where each edit is a deletion, insertion, substitution, or
|
||||
transposition of a character, with the restriction that no
|
||||
substring is edited more than once."
|
||||
(let ((a (downcase a))
|
||||
(b (downcase b))
|
||||
(alen (length a))
|
||||
(blen (length b))
|
||||
(start 0))
|
||||
(when (> alen blen)
|
||||
(let ((c a)
|
||||
(clen alen))
|
||||
(setq a b alen blen
|
||||
b c blen clen)))
|
||||
(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
|
||||
;; TODO Parameterize optional args with `cl-defun'
|
||||
|
|
|
@ -13,28 +13,12 @@
|
|||
;;
|
||||
;;; Commands
|
||||
|
||||
(defcli! (:before (build b purge p)) (&context context)
|
||||
(require 'comp nil t)
|
||||
(doom-initialize-core-packages))
|
||||
(defcli-obsolete! ((build b)) (sync "--rebuild") "v3.0.0")
|
||||
|
||||
;; DEPRECATED Replace with "doom sync --rebuild"
|
||||
(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)
|
||||
(defcli-obsolete! ((purge p)) (gc) "v3.0.0")
|
||||
|
||||
;; 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")
|
||||
(noelpa-p ("-p" "--no-elpa") "Don't purge ELPA packages")
|
||||
(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
|
||||
list remains lean."
|
||||
:benchmark t
|
||||
(require 'comp nil t)
|
||||
(doom-initialize-core-packages)
|
||||
(straight-check-all)
|
||||
(when (doom-packages-purge
|
||||
(not noelpa-p)
|
||||
|
@ -242,7 +228,6 @@ list remains lean."
|
|||
|
||||
(defun doom-packages--write-missing-eln-errors ()
|
||||
"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
|
||||
for eln-name = (doom-packages--eln-file-name file)
|
||||
for eln-file = (doom-packages--eln-output-file eln-name)
|
||||
|
@ -254,11 +239,10 @@ list remains lean."
|
|||
do (make-directory error-dir 'parents)
|
||||
(write-region "" nil 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 ()
|
||||
"Queue async compilation for all non-doom Elisp files."
|
||||
(when (featurep 'native-compile)
|
||||
(cl-loop with paths = (cl-loop for path in load-path
|
||||
unless (file-in-directory-p path doom-local-dir)
|
||||
collect path)
|
||||
|
@ -268,55 +252,16 @@ list remains lean."
|
|||
(not (cl-some (fn! (string-match-p % file))
|
||||
native-comp-deferred-compilation-deny-list))) do
|
||||
(doom-log "Compiling %s" file)
|
||||
(native-compile-async file))))
|
||||
(native-compile-async file)))
|
||||
|
||||
(defun doom-packages-install ()
|
||||
"Installs missing packages.
|
||||
|
||||
This function will install any primary package (i.e. a package with a `package!'
|
||||
declaration) or dependency thereof that hasn't already been."
|
||||
(defun doom-packages-ensure (&optional force-p)
|
||||
"Ensure packages are installed, built"
|
||||
(doom-initialize-packages)
|
||||
(print! (start "Installing packages..."))
|
||||
(let ((pinned (doom-package-pinned-list)))
|
||||
(print-group!
|
||||
(add-hook 'native-comp-async-cu-done-functions #'doom-packages--native-compile-done-h)
|
||||
(if-let (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 " ""))
|
||||
(if (not (file-directory-p (straight--repos-dir)))
|
||||
(print! (start "Installing all packages for the first time (this may take a while)..."))
|
||||
(if force-p
|
||||
(print! (start "Rebuilding all packages (this may take a while)..."))
|
||||
(print! (start "Ensuring packages are installed and built..."))))
|
||||
(print-group!
|
||||
(let ((straight-check-for-modifications
|
||||
(when (file-directory-p (straight--modified-dir))
|
||||
|
@ -330,17 +275,17 @@ declaration) or dependency thereof that hasn't already been."
|
|||
(straight--packages-to-rebuild
|
||||
(or (if force-p :all straight--packages-to-rebuild)
|
||||
(make-hash-table :test #'equal)))
|
||||
(recipes (doom-package-recipe-list)))
|
||||
(recipes (doom-package-recipe-list))
|
||||
(pinned (doom-package-pinned-list)))
|
||||
(add-hook 'native-comp-async-cu-done-functions #'doom-packages--native-compile-done-h)
|
||||
(unless force-p
|
||||
(straight--make-build-cache-available))
|
||||
(straight--make-build-cache-available)
|
||||
(if-let (built
|
||||
(doom-packages--with-recipes recipes (package local-repo recipe)
|
||||
(let ((repo-dir (straight--repos-dir (or local-repo package)))
|
||||
(build-dir (straight--build-dir package)))
|
||||
(unless force-p
|
||||
;; Ensure packages with outdated files/bytecode are rebuilt
|
||||
(let* ((build-dir (straight--build-dir package))
|
||||
(repo-dir (straight--repos-dir local-repo))
|
||||
(build (if (plist-member recipe :build)
|
||||
(let* ((build (if (plist-member recipe :build)
|
||||
(plist-get recipe :build)
|
||||
t))
|
||||
(want-byte-compile
|
||||
|
@ -366,30 +311,66 @@ declaration) or dependency thereof that hasn't already been."
|
|||
(push file doom-packages--eln-output-expected))
|
||||
finally return outdated))
|
||||
(puthash package t straight--packages-to-rebuild))))
|
||||
(straight-use-package (intern package))))
|
||||
(unless (file-directory-p repo-dir)
|
||||
(doom-packages--cli-recipes-update))
|
||||
(condition-case-unless-debug e
|
||||
(let ((straight-vc-git-post-clone-hook
|
||||
(cons (lambda! (&key repo-dir commit)
|
||||
(print-group!
|
||||
(if-let (pin (cdr (assoc package pinned)))
|
||||
(print! (item "Pinned to %s") pin)
|
||||
(print! (item "Checked out %s") commit)))
|
||||
;; 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 #2637), so have git handle
|
||||
;; 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/.
|
||||
;; 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:
|
||||
;; 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[KRebuilt %d package(s)") (length built)))
|
||||
(print! (item "No packages need rebuilding"))
|
||||
(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."
|
||||
(doom-initialize-packages)
|
||||
(doom-packages--barf-if-incomplete)
|
||||
(doom-packages--cli-recipes-update)
|
||||
(let* ((repo-dir (straight--repos-dir))
|
||||
(pinned (doom-package-pinned-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))
|
||||
(total (length recipes))
|
||||
(esc (unless init-file-debug "\033[1A"))
|
||||
(i 0)
|
||||
errors)
|
||||
(print! (start "Updating packages (this may take a while)..."))
|
||||
(i 0))
|
||||
(if pinned-only-p
|
||||
(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)
|
||||
(cl-incf i)
|
||||
(print-group!
|
||||
|
@ -412,11 +394,13 @@ declaration) or dependency thereof that hasn't already been."
|
|||
(cl-return))
|
||||
(let ((default-directory (straight--repos-dir local-repo)))
|
||||
(unless (file-in-directory-p default-directory repo-dir)
|
||||
(print! (warn "(%d/%d) Skipping %s because it is local") i total package)
|
||||
(print! (warn "(%d/%d) Skipping %s because it is out-of-tree...") i total package)
|
||||
(cl-return))
|
||||
(when (eq type 'git)
|
||||
(unless (file-exists-p ".git")
|
||||
(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
|
||||
(let ((ref (straight-vc-get-commit type local-repo))
|
||||
(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)
|
||||
(when .it
|
||||
(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 output (doom-packages--commit-log-between ref target-ref)
|
||||
commits (length (split-string output "\n" t)))
|
||||
|
@ -520,13 +497,14 @@ declaration) or dependency thereof that hasn't already been."
|
|||
(princ "\033[K")
|
||||
(if (hash-table-empty-p packages-to-rebuild)
|
||||
(ignore (print! (success "All %d packages are up-to-date") total))
|
||||
(doom-packages--cli-recipes-update)
|
||||
(straight--transaction-finalize)
|
||||
(let ((default-directory (straight--build-dir)))
|
||||
(mapc (doom-rpartial #'delete-directory 'recursive)
|
||||
(hash-table-keys packages-to-rebuild)))
|
||||
(print! (success "Updated %d package(s)")
|
||||
(hash-table-count packages-to-rebuild))
|
||||
(doom-packages-build)
|
||||
(doom-packages-ensure)
|
||||
t))))
|
||||
|
||||
|
||||
|
@ -652,6 +630,7 @@ If ELPA-P, include packages installed with package.el (M-x package-install)."
|
|||
(doom-initialize-packages)
|
||||
(doom-packages--barf-if-incomplete)
|
||||
(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)
|
||||
(let ((rdirs
|
||||
(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
|
||||
(if (not builds-p)
|
||||
(ignore (print! (item "Skipping builds")))
|
||||
(and (/= 0 (doom-packages--purge-builds builds-to-purge))
|
||||
(quiet! (straight-prune-build-cache))))
|
||||
(/= 0 (doom-packages--purge-builds builds-to-purge)))
|
||||
(if (not elpa-p)
|
||||
(ignore (print! (item "Skipping elpa packages")))
|
||||
(/= 0 (doom-packages--purge-elpa)))
|
||||
|
@ -821,5 +799,31 @@ However, in batch mode, print to stdout instead of stderr."
|
|||
"/dev/null")))
|
||||
(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)
|
||||
;;; packages.el ends here
|
||||
|
|
|
@ -14,18 +14,21 @@
|
|||
(defvar doom-before-sync-hook ()
|
||||
"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
|
||||
|
||||
(defcli-alias! (:before (sync s)) (:before build))
|
||||
|
||||
(defcli! ((sync s))
|
||||
((noenvvar? ("-e") "Don't regenerate the envvar file")
|
||||
(noelc? ("-c") "Don't recompile config")
|
||||
(update? ("-u") "Update installed packages after syncing")
|
||||
(purge? ("-p") "Purge orphaned package repos & regraft them")
|
||||
(jobs ("-j" "--jobs" num) "How many CPUs to use for native compilation"))
|
||||
(update? ("-u") "Update all installed packages after syncing")
|
||||
(noupdate? ("-U") "Don't update any packages")
|
||||
(purge? ("--gc") "Purge orphaned package repos & regraft them")
|
||||
(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.
|
||||
|
||||
This is the equivalent of running autoremove, install, autoloads, then
|
||||
|
@ -33,8 +36,10 @@ recompile. Run this whenever you:
|
|||
|
||||
1. Modify your `doom!' block,
|
||||
2. Add or remove `package!' blocks to your config,
|
||||
3. Add or remove autoloaded functions in module autoloaded files.
|
||||
4. Update Doom outside of Doom (e.g. with git)
|
||||
3. Add or remove autoloaded functions in module autoloaded files,
|
||||
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
|
||||
installed, autoloads files are up-to-date and no byte-compiled files have gone
|
||||
|
@ -47,25 +52,48 @@ OPTIONS:
|
|||
:benchmark t
|
||||
(when (doom-profiles-bootloadable-p)
|
||||
(call! '(profiles sync "--reload")))
|
||||
(run-hooks 'doom-before-sync-hook)
|
||||
(add-hook 'kill-emacs-hook #'doom-sync--abort-warning-h)
|
||||
(when jobs
|
||||
(setq native-comp-async-jobs-number (truncate jobs)))
|
||||
(print! (start "Synchronizing %S profile..." )
|
||||
(or (car doom-profile) "default"))
|
||||
(run-hooks 'doom-before-sync-hook)
|
||||
(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
|
||||
(print-group!
|
||||
;; If the user has up/downgraded Emacs since last sync, or copied their
|
||||
;; config to a different system, then their packages need to be
|
||||
;; recompiled. This is necessary because Emacs byte-code is not
|
||||
;; necessarily back/forward compatible across major versions, and many
|
||||
;; packages bake in hardcoded data at compile-time.
|
||||
(pcase-let ((`(,old-version . ,old-host) (doom-file-read doom-cli-sync-info-file :by 'read :noerror t))
|
||||
(to-rebuild nil))
|
||||
(when (and old-version (not (equal old-version emacs-version)))
|
||||
(print! (warn "Emacs version has changed since last sync (from %s to %s)") old-version emacs-version)
|
||||
(setq to-rebuild t))
|
||||
(when (and old-host (not (equal old-host (system-name))))
|
||||
(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-install)
|
||||
(doom-packages-build)
|
||||
(when update?
|
||||
(doom-packages-update))
|
||||
(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)))
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
;;; Code:
|
||||
|
||||
(load! "packages")
|
||||
(load! "compile")
|
||||
|
||||
|
||||
;;
|
||||
|
@ -22,6 +21,7 @@
|
|||
(defcli! ((upgrade up))
|
||||
((packages? ("-p" "--packages") "Only upgrade packages, not Doom")
|
||||
(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)
|
||||
"Updates Doom and packages.
|
||||
|
||||
|
@ -30,10 +30,11 @@ following shell commands:
|
|||
|
||||
cd ~/.emacs.d
|
||||
git pull --rebase
|
||||
doom clean
|
||||
doom sync -u"
|
||||
(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
|
||||
(packages?
|
||||
;; 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.
|
||||
;; Major changes will still break, however
|
||||
(print! (item "Reloading Doom Emacs"))
|
||||
(doom-cli-context-put context 'upgrading t)
|
||||
(exit! "doom" "upgrade" "-p"
|
||||
(if nobuild? "-B")
|
||||
(if force? "--force")
|
||||
(if jobs (format "--jobs=%d" jobs))))
|
||||
|
||||
|
@ -96,6 +99,8 @@ following shell commands:
|
|||
(sh! "git" "reset" "--hard" (format "origin/%s" branch))
|
||||
(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)
|
||||
(unwind-protect
|
||||
(let (result)
|
||||
|
@ -136,7 +141,6 @@ following shell commands:
|
|||
(ignore (print! (error "Aborted")))
|
||||
(print! (start "Upgrading Doom Emacs..."))
|
||||
(print-group!
|
||||
(doom-compile-clean)
|
||||
(doom-cli-context-put context 'straight-recipe (doom-upgrade--get-straight-recipe))
|
||||
(or (and (zerop (car (sh! "git" "reset" "--hard" target-remote)))
|
||||
(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,7 +25,7 @@
|
|||
|
||||
;; HACK: Load `cl' and site files manually to prevent polluting logs and
|
||||
;; stdout with deprecation and/or file load messages.
|
||||
(let ((inhibit-message (not init-file-debug)))
|
||||
(quiet!
|
||||
(require 'cl nil t)
|
||||
(unless site-run-file
|
||||
(let ((site-run-file "site-start")
|
||||
|
@ -92,15 +92,14 @@
|
|||
:group 'doom)
|
||||
|
||||
(defvar doom-cli-load-path
|
||||
(let ((paths (split-string (or (getenv "DOOMPATH") "") path-separator)))
|
||||
(if (member "" paths)
|
||||
(cl-substitute (doom-path (dir!) "cli/") "" paths :test #'equal)
|
||||
paths))
|
||||
(append (when-let ((doompath (getenv "DOOMPATH")))
|
||||
(cl-loop for dir in (split-string doompath path-separator)
|
||||
collect (expand-file-name dir)))
|
||||
(list (file-name-concat (dir!) "cli")))
|
||||
"A list of paths to search for autoloaded Doom CLIs.
|
||||
|
||||
It is prefilled by the DOOMPATH envvar (a colon-separated list on Linux/macOS,
|
||||
semicolon otherwise). Empty entries in DOOMPATH are replaced with the
|
||||
$EMACSDIR/cli/.")
|
||||
semicolon otherwise).")
|
||||
|
||||
;;; CLI definition variables
|
||||
(defvar doom-cli-argument-types
|
||||
|
@ -1050,9 +1049,9 @@ considered as well."
|
|||
"\n")))
|
||||
(print! (warn "Wrote extended straight log to %s")
|
||||
(path (let ((coding-system-for-write 'utf-8-auto))
|
||||
(with-file-modes #o600
|
||||
(with-temp-file error-file
|
||||
(insert-buffer-substring (straight--process-buffer)))
|
||||
(set-file-modes error-file #o600)
|
||||
(insert-buffer-substring (straight--process-buffer))))
|
||||
error-file))))
|
||||
((eq type '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))
|
||||
(file (doom-cli--output-file "log" context)))
|
||||
(when (> (buffer-size buffer) 0)
|
||||
(make-directory (file-name-directory file) t)
|
||||
(with-file-modes #o700
|
||||
(make-directory (file-name-directory file) t))
|
||||
(with-file-modes #o600
|
||||
(with-temp-file file
|
||||
(insert-buffer-substring buffer)
|
||||
(ansi-color-filter-region (point-min) (point-max)))
|
||||
(set-file-modes file #o600)))))
|
||||
(ansi-color-filter-region (point-min) (point-max))))))))
|
||||
|
||||
(defun doom-cli--output-benchmark-h (context)
|
||||
"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))
|
||||
(coding-system-for-write 'utf-8-auto))
|
||||
(make-directory (file-name-directory tmpfile) t)
|
||||
(with-file-modes #o700
|
||||
(make-directory (file-name-directory tmpfile) t))
|
||||
(with-file-modes #o600
|
||||
(with-temp-file tmpfile
|
||||
(insert-buffer-substring (doom-cli-context-stdout context)))
|
||||
(set-file-modes tmpfile #o600)
|
||||
(insert-buffer-substring (doom-cli-context-stdout context))))
|
||||
(doom-cli--restart
|
||||
(format "%s <%s; rm -f%s %s"
|
||||
(or pager
|
||||
|
@ -1782,7 +1783,7 @@ See `defcli!' for information about COMMANDSPEC.
|
|||
TARGET is simply a command list.
|
||||
WHEN specifies what version this command was rendered obsolete."
|
||||
`(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))
|
||||
:hide t
|
||||
(print! (warn "'%s' was deprecated in %s")
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
;;; Code:
|
||||
|
||||
(defvar doom-detect-indentation-excluded-modes
|
||||
'(fundamental-mode pascal-mode so-long-mode doom-docs-org-mode)
|
||||
"A list of major modes in which indentation should be automatically
|
||||
detected.")
|
||||
'(pascal-mode
|
||||
so-long-mode
|
||||
;; 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
|
||||
"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))))
|
||||
(and (buffer-file-name buffer)
|
||||
(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)
|
||||
"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
|
||||
(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)
|
||||
"`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
|
||||
|
@ -501,8 +510,9 @@ files, so this replace calls to `pp' with the much faster `prin1'."
|
|||
(unless (or (not after-init-time)
|
||||
doom-inhibit-indent-detection
|
||||
doom-large-file-p
|
||||
(memq major-mode doom-detect-indentation-excluded-modes)
|
||||
(member (substring (buffer-name) 0 1) '(" " "*")))
|
||||
(eq major-mode 'fundamental-mode)
|
||||
(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
|
||||
(let ((inhibit-message (not init-file-debug)))
|
||||
(dtrt-indent-mode +1))))
|
||||
|
@ -583,11 +593,9 @@ current buffer."
|
|||
filename))
|
||||
(prog1 (apply fn args)
|
||||
(when (buffer-live-p buf)
|
||||
(with-current-buffer buf (goto-char pos)))))))))
|
||||
|
||||
|
||||
;;;###package imenu
|
||||
(add-hook 'imenu-after-jump-hook #'recenter)
|
||||
(with-current-buffer buf (goto-char pos))))))))
|
||||
:config
|
||||
(setq helpful-set-variable-function #'setq!))
|
||||
|
||||
|
||||
(use-package! smartparens
|
||||
|
|
|
@ -15,6 +15,12 @@
|
|||
"An alternative leader prefix key, used for Insert and Emacs states, and for
|
||||
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"
|
||||
"The localleader prefix key, for major-mode specific commands.")
|
||||
|
||||
|
@ -35,7 +41,7 @@ and Emacs states, and for non-evil users.")
|
|||
;;; Global keybind settings
|
||||
|
||||
(cond
|
||||
(IS-MAC
|
||||
(doom--system-macos-p
|
||||
;; mac-* variables are used by the special emacs-mac build of Emacs by
|
||||
;; Yamamoto Mitsuharu, while other builds use ns-*.
|
||||
(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
|
||||
mac-right-option-modifier 'none
|
||||
ns-right-option-modifier 'none))
|
||||
(IS-WINDOWS
|
||||
(doom--system-windows-p
|
||||
(setq w32-lwindow-modifier 'super
|
||||
w32-rwindow-modifier 'super)))
|
||||
|
||||
;; 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
|
||||
;; 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,
|
||||
;; [tab] != TAB, and [backspace] != DEL.
|
||||
;;
|
||||
;; 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.
|
||||
;; In the same vein, this keybind adds a [C-i] event, so users can bind to it
|
||||
;; independently of TAB. Otherwise, it falls back to keys bound to C-i.
|
||||
(define-key key-translation-map [?\C-i]
|
||||
(cmd! (if (let ((keys (this-single-command-raw-keys)))
|
||||
(and keys
|
||||
|
@ -98,6 +104,7 @@ all hooks after it are ignored.")
|
|||
(defun doom/escape (&optional interactive)
|
||||
"Run `doom-escape-hook'."
|
||||
(interactive (list 'interactive))
|
||||
(let ((inhibit-quit t))
|
||||
(cond ((minibuffer-window-active-p (minibuffer-window))
|
||||
;; quit the minibuffer if open.
|
||||
(when interactive
|
||||
|
@ -110,7 +117,7 @@ all hooks after it are ignored.")
|
|||
;; Back to the default
|
||||
((unwind-protect (keyboard-quit)
|
||||
(when interactive
|
||||
(setq this-command 'keyboard-quit))))))
|
||||
(setq this-command 'keyboard-quit)))))))
|
||||
|
||||
(global-set-key [remap keyboard-quit] #'doom/escape)
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
;;; Custom error types
|
||||
(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-core-error "Unexpected error in Doom's core" 'doom-error)
|
||||
(define-error 'doom-hook-error "Error in a Doom startup hook" 'doom-error)
|
||||
|
@ -302,7 +303,7 @@ TRIGGER-HOOK is a list of quoted hooks and/or sharp-quoted functions."
|
|||
(error "file!: cannot deduce the current file path")))
|
||||
|
||||
(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)
|
||||
(file-name-directory (macroexpand '(file!)))))
|
||||
|
||||
|
@ -801,7 +802,7 @@ This macro accepts, in order:
|
|||
func-forms)))
|
||||
`(progn
|
||||
,@defn-forms
|
||||
(dolist (hook (nreverse ',hook-forms))
|
||||
(dolist (hook ',(nreverse hook-forms))
|
||||
(dolist (func (list ,@func-forms))
|
||||
,(if remove-p
|
||||
`(remove-hook hook func ,local-p)
|
||||
|
@ -882,16 +883,16 @@ testing advice (when combined with `rotate-text').
|
|||
(dolist (target (cdr targets))
|
||||
(advice-remove target #',symbol)))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Backports
|
||||
|
||||
(defmacro defbackport! (type symbol &rest body)
|
||||
"Backport a function/macro/alias from later versions of Emacs."
|
||||
(declare (indent defun) (doc-string 4))
|
||||
(unless (fboundp (doom-unquote symbol))
|
||||
`(,type ,symbol ,@body)))
|
||||
|
||||
|
||||
;;
|
||||
;;; Backports
|
||||
|
||||
;; `format-spec' wasn't autoloaded until 28.1
|
||||
(defbackport! autoload 'format-spec "format-spec")
|
||||
|
||||
|
|
|
@ -8,10 +8,19 @@
|
|||
(defvar doom-modules (make-hash-table :test 'equal)
|
||||
"A hash table of enabled modules. Set by `doom-initialize-modules'.")
|
||||
|
||||
(defvar doom-modules-dirs
|
||||
(list (expand-file-name "modules/" doom-user-dir)
|
||||
doom-modules-dir)
|
||||
"A list of module root directories. Order determines priority.")
|
||||
(define-obsolete-variable-alias 'doom-modules-dirs 'doom-module-load-path "3.0.0")
|
||||
(defvar doom-module-load-path
|
||||
(list (file-name-concat doom-user-dir "modules")
|
||||
(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
|
||||
(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
|
||||
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
|
||||
'((:feature (version-control (:emacs vc) (:ui vc-gutter))
|
||||
(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
|
||||
:ui vc-gutter.")
|
||||
|
||||
(make-obsolete-variable 'doom-inhibit-module-warnings nil "3.0.0")
|
||||
(defvar doom-inhibit-module-warnings (not noninteractive)
|
||||
"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'
|
||||
|
||||
(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
|
||||
(setplist 'doom-module-context '(index 0 initdepth 1 configdepth 2
|
||||
group 3 name 4 flags 5 features 6)))
|
||||
(defvar doom-module-context doom--empty-module-context
|
||||
(put 'doom-module-context 'keys '(:index 0 :initdepth 1 :configdepth 2
|
||||
:group 3 :name 4 :flags 5 :features 6)))
|
||||
(defvar doom-module-context doom-module--empty-context
|
||||
"A vector describing the module associated it with the active context.
|
||||
|
||||
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.")
|
||||
|
||||
;; 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)
|
||||
"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',
|
||||
`flags', or `features'. CONTEXT should be a `doom-module-context' vector. If
|
||||
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)
|
||||
"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)))
|
||||
(or (get (or (car-safe key) key)
|
||||
(cdr-safe key))
|
||||
doom--empty-module-context)))
|
||||
doom-module--empty-context)))
|
||||
|
||||
(defun doom-module-context-key (&optional context)
|
||||
"Return the module of the active `doom-module-context' as a module key."
|
||||
(declare (side-effect-free t))
|
||||
(let ((context (or context doom-module-context)))
|
||||
(cons (aref context (doom-module--context-field group))
|
||||
(aref context (doom-module--context-field name)))))
|
||||
(cons (aref context (doom-module--context-field :group))
|
||||
(aref context (doom-module--context-field :name)))))
|
||||
|
||||
(defmacro doom-module-context-with (module-key &rest body)
|
||||
"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
|
||||
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
|
||||
:depth, followed by disabled modules in lexicographical order (unless a :depth
|
||||
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?))
|
||||
(doom-files-in (if (listp paths-or-all)
|
||||
paths-or-all
|
||||
doom-modules-dirs)
|
||||
doom-module-load-path)
|
||||
:map #'doom-module-from-path
|
||||
:type 'dirs
|
||||
:mindepth 1
|
||||
|
@ -294,7 +309,7 @@ If the category isn't enabled this returns nil. For finding disabled modules use
|
|||
path)))
|
||||
|
||||
(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
|
||||
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
|
||||
;; PERF: locate-file-internal is a little faster for finding files,
|
||||
;; but its interface for finding directories is clumsy.
|
||||
(locate-file-internal path doom-modules-dirs '("" ".elc" ".el"))
|
||||
(cl-loop for default-directory in doom-modules-dirs
|
||||
(locate-file-internal path doom-module-load-path '("" ".elc" ".el"))
|
||||
(cl-loop for default-directory in doom-module-load-path
|
||||
if (file-exists-p 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
|
||||
an example."
|
||||
(cl-loop with file = (file-name-sans-extension file)
|
||||
for (group . name) in module-list
|
||||
(cl-loop for (group . name) in (or module-list (doom-module-list))
|
||||
if (doom-module-locate-path group name file)
|
||||
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)
|
||||
(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.
|
||||
|
||||
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
|
||||
those directories."
|
||||
(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)))
|
||||
|
||||
(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
|
||||
;; 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.
|
||||
(and (cond (flag (memq flag (aref (or (get category module) doom--empty-module-context)
|
||||
(doom-module--context-field flags))))
|
||||
(and (cond (flag (memq flag (aref (or (get category module) doom-module--empty-context)
|
||||
(doom-module--context-field :flags))))
|
||||
(module (get category module))
|
||||
((aref doom-module-context 0)
|
||||
(memq category (aref doom-module-context
|
||||
(doom-module--context-field flags))))
|
||||
(doom-module--context-field :flags))))
|
||||
((let ((file
|
||||
;; This must be expanded at the call site, not in
|
||||
;; `modulep!'s definition, to get the file we want.
|
||||
(macroexpand '(file!))))
|
||||
(if-let (module (doom-module-from-path file))
|
||||
(memq category (aref (or (get (car module) (cdr module))
|
||||
doom--empty-module-context)
|
||||
(doom-module--context-field flags)))
|
||||
doom-module--empty-context)
|
||||
(doom-module--context-field :flags)))
|
||||
(error "(modulep! %s %s %s) couldn't figure out what module it was called from (in %s)"
|
||||
category module flag file)))))
|
||||
t))
|
||||
|
|
|
@ -119,11 +119,11 @@ uses a straight or package.el command directly).")
|
|||
(append (apply fn args) ; lockfiles still take priority
|
||||
(doom-package-pinned-list)))
|
||||
|
||||
;; HACK: This fixes an issue present in recent builds of Emacs 29. See
|
||||
;; emacs-mirror/emacs@0d383b592c2f. Straight.el uses `loaddefs-generate' if it
|
||||
;; is available, which activates `emacs-lisp-mode' to read autoloads files,
|
||||
;; but does so without suppressing its hooks. Some packages (like overseer)
|
||||
;; add hooks to `emacs-lisp-mode-hook' in their autoloads, and once triggered,
|
||||
;; HACK: This fixes an issue introduced in emacs-mirror/emacs@0d383b592c2f and
|
||||
;; is present in >=29: Straight.el uses `loaddefs-generate' if it is
|
||||
;; available, which activates `emacs-lisp-mode' to read autoloads files, but
|
||||
;; does so without suppressing its hooks. Some packages (like overseer) add
|
||||
;; 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
|
||||
;; file errors.
|
||||
;; 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")
|
||||
;; 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 packages (including Doom), make in absolute
|
||||
;; compatible, and many packages (including Doom), bake in absolute
|
||||
;; paths into their caches that need to be refreshed.
|
||||
(prin1 `(unless (equal doom-version ,doom-version)
|
||||
(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
|
||||
;; re-evaluating this file when lazy-loading dynamic docstrings from the
|
||||
;; 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
|
||||
if (boundp var)
|
||||
collect `(set-default ',var ',(symbol-value var)))
|
||||
|
@ -439,7 +440,7 @@ Defaults to the profile at `doom-profile-default'."
|
|||
(doom-autoloads--scan
|
||||
(append (doom-glob doom-core-dir "lib/*.el")
|
||||
(cl-loop for dir
|
||||
in (append (doom-module-load-path doom-modules-dirs)
|
||||
in (append (doom-module-load-path)
|
||||
(list doom-user-dir))
|
||||
if (doom-glob dir "autoload.el") collect (car 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 ()
|
||||
(doom-autoloads--scan
|
||||
(mapcar #'straight--autoloads-file
|
||||
(seq-difference (hash-table-keys straight--build-cache)
|
||||
doom-autoloads-excluded-packages))
|
||||
(nreverse (seq-difference (hash-table-keys straight--build-cache)
|
||||
doom-autoloads-excluded-packages)))
|
||||
doom-autoloads-excluded-files
|
||||
'literal))
|
||||
|
||||
|
|
|
@ -23,6 +23,10 @@ debian, and derivatives). On most it's 'fd'.")
|
|||
;;
|
||||
;;; Packages
|
||||
|
||||
(after! project
|
||||
(setq project-list-file (file-name-concat doom-data-dir "projects")))
|
||||
|
||||
;; DEPRECATED: Will be replaced with project.el
|
||||
(use-package! projectile
|
||||
:commands (projectile-project-root
|
||||
projectile-project-name
|
||||
|
@ -147,7 +151,7 @@ c) are not valid projectile projects."
|
|||
(projectile-serialize-cache))))
|
||||
|
||||
;; 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 "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"
|
||||
bin (if (version< version "8.3.0")
|
||||
"" "--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
|
||||
((executable-find "rg" t)
|
||||
(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"))))
|
||||
|
||||
(defadvice! doom--projectile-default-generic-command-a (fn &rest args)
|
||||
|
|
|
@ -100,13 +100,15 @@
|
|||
|
||||
;;; Disable UI elements early
|
||||
;; 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,
|
||||
;; the menu bar exposes functionality that Doom doesn't endorse. Perhaps one
|
||||
;; day Doom will support these, but today is not that day.
|
||||
;;
|
||||
;; clutter. Initializing them also costs a morsel of startup time. What's
|
||||
;; more, the menu bar exposes functionality that Doom doesn't endorse. Perhaps
|
||||
;; 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
|
||||
;; `scroll-bar-mode' because they do extra work to manipulate frame variables
|
||||
;; that isn't necessary this early in the startup process.
|
||||
;; `scroll-bar-mode' because their manipulation of frame parameters can
|
||||
;; trigger/queue a superfluous (and expensive, depending on the window system)
|
||||
;; frame redraw at startup.
|
||||
(push '(menu-bar-lines . 0) default-frame-alist)
|
||||
(push '(tool-bar-lines . 0) default-frame-alist)
|
||||
(push '(vertical-scroll-bars) default-frame-alist)
|
||||
|
@ -119,8 +121,8 @@
|
|||
;; non-application window -- which means it doesn't automatically capture
|
||||
;; 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
|
||||
;; activates an ugly, in-frame menu bar.
|
||||
(eval-when! IS-MAC
|
||||
;; unavoidably activates an ugly, in-frame menu bar.
|
||||
(eval-when! doom--system-macos-p
|
||||
(add-hook! '(window-setup-hook after-make-frame-functions)
|
||||
(defun doom-restore-menu-bar-in-gui-frames-h (&optional frame)
|
||||
(when-let (frame (or frame (selected-frame)))
|
||||
|
@ -136,8 +138,8 @@
|
|||
;; a step too opinionated.
|
||||
(setq default-input-method nil)
|
||||
;; ...And the clipboard on Windows could be in a wider encoding (UTF-16), so
|
||||
;; leave Emacs to its own devices.
|
||||
(eval-when! IS-WINDOWS
|
||||
;; leave Emacs to its own devices there.
|
||||
(eval-when! (not doom--system-windows-p)
|
||||
(setq selection-coding-system 'utf-8))
|
||||
|
||||
|
||||
|
@ -180,7 +182,7 @@
|
|||
(defvar doom-incremental-packages '(t)
|
||||
"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
|
||||
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:
|
||||
|
||||
(doom-load-packages-incrementally
|
||||
|
@ -192,16 +194,16 @@ broken up into:
|
|||
This is already done by the lang/org module, however.
|
||||
|
||||
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
|
||||
in daemon sessions (they are loaded immediately at startup).")
|
||||
|
||||
(defvar doom-incremental-first-idle-timer (if (daemonp) 0 2.0)
|
||||
"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
|
||||
`emacs-startup-hook'.")
|
||||
`doom-after-init-hook'.")
|
||||
|
||||
(defvar doom-incremental-idle-timer 0.75
|
||||
"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)
|
||||
"Registers PACKAGES to be loaded incrementally.
|
||||
|
||||
If NOW is non-nil, load PACKAGES incrementally, in `doom-incremental-idle-timer'
|
||||
intervals."
|
||||
(let ((gc-cons-threshold most-positive-fixnum))
|
||||
If NOW is non-nil, PACKAGES will be marked for incremental loading next time
|
||||
Emacs is idle for `doom-incremental-first-idle-timer' seconds (falls back to
|
||||
`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)
|
||||
(cl-callf append doom-incremental-packages packages)
|
||||
(while packages
|
||||
|
@ -222,7 +228,7 @@ intervals."
|
|||
(condition-case-unless-debug e
|
||||
(and
|
||||
(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
|
||||
(while-no-input
|
||||
(doom-log "start:iloader: Loading %s (%d left)" req (length packages))
|
||||
|
@ -242,7 +248,7 @@ intervals."
|
|||
(doom-log "start:iloader: Finished!")
|
||||
(run-at-time (if idle-time
|
||||
doom-incremental-idle-timer
|
||||
doom-incremental-first-idle-timer)
|
||||
first-idle-timer)
|
||||
nil #'doom-load-packages-incrementally
|
||||
packages t)
|
||||
(setq packages nil))))))))
|
||||
|
|
180
lisp/doom-ui.el
180
lisp/doom-ui.el
|
@ -5,13 +5,13 @@
|
|||
;;
|
||||
;;; Variables
|
||||
|
||||
(defvar doom-theme nil
|
||||
(defcustom doom-theme nil
|
||||
"A symbol representing the Emacs theme to load at startup.
|
||||
|
||||
Set to `nil' to load no theme at all. This variable is changed by
|
||||
`load-theme'.")
|
||||
|
||||
(defvar doom-font nil
|
||||
(defcustom doom-font nil
|
||||
"The default font to use.
|
||||
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 \"Fira Code-14\")")
|
||||
|
||||
(defvar doom-variable-pitch-font nil
|
||||
(defcustom doom-variable-pitch-font nil
|
||||
"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
|
||||
`doom-font' for examples.
|
||||
|
||||
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.
|
||||
Must be a `font-spec', a font object, an XFT font string, or an XLFD string. See
|
||||
`doom-font' for examples.
|
||||
|
||||
An omitted font size means to inherit `doom-font''s size.")
|
||||
|
||||
(defvar doom-unicode-font nil
|
||||
"Fallback font for Unicode glyphs.
|
||||
(defcustom doom-symbol-font nil
|
||||
"Fallback font for symbols.
|
||||
Must be a `font-spec', a font object, an XFT font string, or an XLFD string. See
|
||||
`doom-font' for examples.
|
||||
|
||||
The defaults on macOS and Linux are Apple Color Emoji and Symbola, respectively.
|
||||
`doom-font' for examples. Emacs defaults to Symbola.
|
||||
|
||||
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!")
|
||||
|
||||
(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"
|
||||
"Segoe UI Emoji"
|
||||
"Noto Color 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"
|
||||
"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
|
||||
|
||||
(defvar doom-init-ui-hook nil
|
||||
(defcustom doom-init-ui-hook nil
|
||||
"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
|
||||
`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.")
|
||||
|
||||
(defvar doom-switch-window-hook nil
|
||||
(defcustom doom-switch-window-hook nil
|
||||
"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.")
|
||||
|
||||
(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
|
||||
;; `scroll-conservatively'). This is especially slow in larger files
|
||||
;; during large-scale scrolling commands. If kept over 100, the window is
|
||||
;; never automatically recentered.
|
||||
scroll-conservatively 101
|
||||
;; never automatically recentered. The default (0) triggers this too
|
||||
;; aggressively, so I've set it to 10 to recenter if scrolling too far
|
||||
;; off-screen.
|
||||
scroll-conservatively 10
|
||||
scroll-margin 0
|
||||
scroll-preserve-screen-position t
|
||||
;; 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'."
|
||||
:before-until #'kill-current-buffer
|
||||
(let ((buf (current-buffer)))
|
||||
(cond ((window-dedicated-p)
|
||||
(delete-window)
|
||||
t)
|
||||
((eq buf (doom-fallback-buffer))
|
||||
(cond ((eq buf (doom-fallback-buffer))
|
||||
(message "Can't kill the fallback buffer.")
|
||||
t)
|
||||
((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
|
||||
compilation-ask-about-save nil ; save all buffers on `compile'
|
||||
compilation-scroll-output 'first-error)
|
||||
;; Handle ansi codes in compilation buffer
|
||||
;; DEPRECATED Use `ansi-color-compilation-filter' when dropping 27.x support
|
||||
(add-hook 'compilation-filter-hook #'doom-apply-ansi-color-to-compilation-buffer-h)
|
||||
(add-hook 'compilation-filter-hook
|
||||
(if (< emacs-major-version 28)
|
||||
#'doom-apply-ansi-color-to-compilation-buffer-h
|
||||
#'ansi-color-compilation-filter))
|
||||
;; Automatically truncate compilation buffers so they don't accumulate too
|
||||
;; much data and bog down the rest of Emacs.
|
||||
(autoload 'comint-truncate-buffer "comint" nil t)
|
||||
|
@ -417,41 +429,17 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
|||
;;
|
||||
;;; Third party packages
|
||||
|
||||
(use-package! all-the-icons
|
||||
:commands (all-the-icons-octicon
|
||||
all-the-icons-faicon
|
||||
all-the-icons-fileicon
|
||||
all-the-icons-wicon
|
||||
all-the-icons-material
|
||||
all-the-icons-alltheicon)
|
||||
:preface
|
||||
(add-hook! 'after-setting-font-hook
|
||||
(defun doom-init-all-the-icons-fonts-h ()
|
||||
(when (fboundp 'set-fontset-font)
|
||||
(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)
|
||||
""))))
|
||||
(use-package! nerd-icons
|
||||
:commands (nerd-icons-octicon
|
||||
nerd-icons-faicon
|
||||
nerd-icons-flicon
|
||||
nerd-icons-wicon
|
||||
nerd-icons-mdicon
|
||||
nerd-icons-codicon
|
||||
nerd-icons-devicon
|
||||
nerd-icons-ipsicon
|
||||
nerd-icons-pomicon
|
||||
nerd-icons-powerline))
|
||||
|
||||
;; Hide the mode line in completion popups and MAN pages because they serve
|
||||
;; little purpose there, and is better hidden.
|
||||
|
@ -510,7 +498,23 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
|||
(cons 'custom-theme-directory
|
||||
(delq 'custom-theme-directory custom-theme-load-path)))
|
||||
|
||||
(defun doom--make-font-specs (face font)
|
||||
(defun doom-init-fonts-h (&optional _reload)
|
||||
"Loads `doom-font', `doom-serif-font', and `doom-variable-pitch-font'."
|
||||
(let ((this-frame (selected-frame)))
|
||||
(dolist (map `((default . ,doom-font)
|
||||
(fixed-pitch . ,doom-font)
|
||||
(fixed-pitch-serif . ,doom-serif-font)
|
||||
(variable-pitch . ,doom-variable-pitch-font)))
|
||||
(condition-case e
|
||||
(when-let* ((face (car map))
|
||||
(font (cdr map)))
|
||||
(dolist (frame (frame-list))
|
||||
(when (display-multi-font-p frame)
|
||||
(set-face-attribute face frame
|
||||
:width 'normal :weight 'normal
|
||||
:slant 'normal :font font)))
|
||||
(custom-push-theme
|
||||
'theme-face face 'user 'set
|
||||
(let* ((base-specs (cadr (assq 'user (get face 'theme-face))))
|
||||
(base-specs (or base-specs '((t nil))))
|
||||
(attrs '(:family :foundry :slant :weight :height :width))
|
||||
|
@ -526,33 +530,31 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
|||
(setq plist (plist-put plist attr (face-attribute face attr)))))
|
||||
(push (list display plist) new-specs)))
|
||||
(nreverse new-specs)))
|
||||
|
||||
(defun doom-init-fonts-h (&optional reload)
|
||||
"Loads `doom-font'."
|
||||
(dolist (map `((default . ,doom-font)
|
||||
(fixed-pitch . ,doom-font)
|
||||
(fixed-pitch-serif . ,doom-serif-font)
|
||||
(variable-pitch . ,doom-variable-pitch-font)))
|
||||
(when-let* ((face (car map))
|
||||
(font (cdr map)))
|
||||
(dolist (frame (frame-list))
|
||||
(when (display-multi-font-p frame)
|
||||
(set-face-attribute face frame
|
||||
:width 'normal :weight 'normal
|
||||
:slant 'normal :font font)))
|
||||
(let ((new-specs (doom--make-font-specs face font)))
|
||||
;; Don't save to `customized-face' so it's omitted from `custom-file'
|
||||
;;(put face 'customized-face new-specs)
|
||||
(custom-push-theme 'theme-face face 'user 'set new-specs)
|
||||
(put face 'face-modified nil))))
|
||||
(put face 'face-modified nil))
|
||||
('error
|
||||
(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)
|
||||
(let ((fn (doom-rpartial #'member (font-family-list))))
|
||||
(when-let (font (cl-find-if fn doom-symbol-fallback-font-families))
|
||||
(set-fontset-font t 'symbol font))
|
||||
(when-let (font (cl-find-if fn doom-emoji-fallback-font-families))
|
||||
(set-fontset-font t 'unicode font))
|
||||
(when doom-unicode-font
|
||||
(set-fontset-font t 'unicode doom-unicode-font))))
|
||||
(let* ((fn (doom-rpartial #'member (font-family-list)))
|
||||
(symbol-font (or doom-symbol-font
|
||||
(cl-find-if fn doom-symbol-fallback-font-families)))
|
||||
(emoji-font (or doom-emoji-font
|
||||
(cl-find-if fn doom-emoji-fallback-font-families))))
|
||||
(when symbol-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'
|
||||
(run-hooks 'after-setting-font-hook))
|
||||
|
||||
|
|
238
lisp/doom.el
238
lisp/doom.el
|
@ -59,9 +59,13 @@
|
|||
;; - On first switched-to buffer: `doom-first-buffer-hook'
|
||||
;; - On first opened file: `doom-first-file-hook'
|
||||
;;
|
||||
;; This is Doom's heart, where I define all its major constants and variables,
|
||||
;; set only its sanest global defaults, employ its hackiest (and least
|
||||
;; offensive) optimizations, and load the minimum for all Doom sessions.
|
||||
;; This file is Doom's heart, where I define all its major constants and
|
||||
;; variables, set only its sanest global defaults, employ its hackiest (and
|
||||
;; 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:
|
||||
|
||||
|
@ -99,7 +103,7 @@
|
|||
|
||||
;; 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
|
||||
;; 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.
|
||||
(let ((old-version (eval-when-compile emacs-version)))
|
||||
(unless (equal emacs-version old-version)
|
||||
|
@ -107,7 +111,31 @@
|
|||
"recompile it.")
|
||||
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
|
||||
;; claim `system-configuration-features' is not da way. Some features (that
|
||||
;; don't represent packages) can be found in `features' (which `featurep'
|
||||
|
@ -116,35 +144,40 @@
|
|||
(push 'dynamic-modules features))
|
||||
(if (fboundp #'json-parse-string)
|
||||
(push 'jansson features))
|
||||
(let ((inhibit-changing-match-data t))
|
||||
(if (string-match "HARFBUZZ" system-configuration-features) ; no alternative
|
||||
(push 'harfbuzz features)))
|
||||
;; `native-compile' exists whether or not it is functional (e.g. libgcc is
|
||||
;; available or not). This seems silly, so pretend it doesn't exist if it
|
||||
;; isn't available.
|
||||
(if (string-match-p "HARFBUZZ" system-configuration-features) ; no alternative
|
||||
(push 'harfbuzz features))
|
||||
|
||||
;; The `native-compile' feature exists whether or not it is functional (e.g.
|
||||
;; libgcc is available or not). This seems silly, so pretend it doesn't exist if
|
||||
;; it isn't functional.
|
||||
(if (featurep 'native-compile)
|
||||
(if (not (native-comp-available-p))
|
||||
(delq 'native-compile features)))
|
||||
|
||||
;;; Global constants
|
||||
;; DEPRECATED remove in v3
|
||||
(defconst IS-MAC (eq system-type 'darwin))
|
||||
(defconst IS-LINUX (memq system-type '(gnu gnu/linux gnu/kfreebsd berkeley-unix)))
|
||||
(defconst IS-WINDOWS (memq system-type '(cygwin windows-nt ms-dos)))
|
||||
(defconst IS-BSD (memq system-type '(darwin berkeley-unix gnu/kfreebsd)))
|
||||
(with-no-warnings
|
||||
(defconst IS-MAC doom--system-macos-p)
|
||||
(defconst IS-LINUX doom--system-linux-p)
|
||||
(defconst IS-WINDOWS doom--system-windows-p)
|
||||
(defconst IS-BSD (memq 'bsd doom-features))
|
||||
(defconst EMACS28+ (> emacs-major-version 27))
|
||||
(defconst EMACS29+ (> emacs-major-version 28))
|
||||
(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 'NATIVECOMP "Use (featurep 'native-compile) instead" "3.0.0"))
|
||||
|
||||
|
||||
;;; Fix $HOME on Windows
|
||||
;; $HOME isn't normally defined on Windows, but many unix tools expect it.
|
||||
(when IS-WINDOWS
|
||||
(when doom--system-windows-p
|
||||
(when-let (realhome
|
||||
(and (null (getenv-internal "HOME"))
|
||||
(getenv "USERPROFILE")))
|
||||
|
@ -168,7 +201,7 @@
|
|||
"Current version of Doom Emacs 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.")
|
||||
|
||||
(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")
|
||||
(defvar doom-data-dir
|
||||
(if doom-profile
|
||||
(if IS-WINDOWS
|
||||
(if doom--system-windows-p
|
||||
(expand-file-name "doomemacs/data/" (getenv-internal "APPDATA"))
|
||||
(expand-file-name "doom/" (or (getenv-internal "XDG_DATA_HOME") "~/.local/share")))
|
||||
;; 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
|
||||
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.
|
||||
|
||||
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
|
||||
(if doom-profile
|
||||
(if IS-WINDOWS
|
||||
(if doom--system-windows-p
|
||||
(expand-file-name "doomemacs/cache/" (getenv-internal "APPDATA"))
|
||||
(expand-file-name "doom/" (or (getenv-internal "XDG_CACHE_HOME") "~/.cache")))
|
||||
;; DEPRECATED: .local will be removed entirely in 3.0
|
||||
(file-name-concat doom-local-dir "cache/"))
|
||||
"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
|
||||
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,
|
||||
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
|
||||
(if doom-profile
|
||||
(if IS-WINDOWS
|
||||
(if doom--system-windows-p
|
||||
(expand-file-name "doomemacs/state/" (getenv-internal "APPDATA"))
|
||||
(expand-file-name "doom/" (or (getenv-internal "XDG_STATE_HOME") "~/.local/state")))
|
||||
;; DEPRECATED: .local will be removed entirely in 3.0
|
||||
(file-name-concat doom-local-dir "state/"))
|
||||
"Where Doom stores its global state files.
|
||||
|
||||
State files contain non-essential, unportable, but persistent data which, if
|
||||
lost won't cause breakage, but may be inconvenient as they cannot be
|
||||
automatically regenerated or restored. For example, a recently-opened file list
|
||||
is not essential, but losing it means losing this record, and restoring it
|
||||
requires revisiting all those files.
|
||||
State files contain unessential, unportable, but persistent data which, if lost
|
||||
won't cause breakage, but may be inconvenient as they cannot be automatically
|
||||
regenerated or restored. For example, a recently-opened file list is not
|
||||
essential, but losing it means losing this record, and restoring it requires
|
||||
revisiting all those files.
|
||||
|
||||
Use this for: history, logs, user-saved data, autosaves/backup files, known
|
||||
projects, recent files, bookmarks.
|
||||
|
@ -331,15 +364,16 @@ users).")
|
|||
;; `file-remote-p'). You get a noteable boost to startup time by unsetting
|
||||
;; or simplifying its value.
|
||||
(let ((old-value (default-toplevel-value 'file-name-handler-alist)))
|
||||
(setq file-name-handler-alist
|
||||
;; HACK: If the bundled elisp for this Emacs install isn't
|
||||
;; byte-compiled (but is compressed), then leave the gzip file
|
||||
;; handler there so Emacs won't forget how to read read them.
|
||||
(set-default-toplevel-value
|
||||
'file-name-handler-alist
|
||||
;; HACK: If the bundled elisp for this Emacs install isn't byte-compiled
|
||||
;; (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
|
||||
;; it uncompiled. This ensures that the only other, possible
|
||||
;; fallback would be calc-loaddefs.el.gz.
|
||||
;; calc-loaddefs.el is our heuristic for this because it is built-in to
|
||||
;; all supported versions of Emacs, and calc.el explicitly loads it
|
||||
;; uncompiled. This ensures that the only other, possible fallback would
|
||||
;; be calc-loaddefs.el.gz.
|
||||
(if (eval-when-compile
|
||||
(locate-file-internal "calc-loaddefs.el" load-path))
|
||||
nil
|
||||
|
@ -352,7 +386,8 @@ users).")
|
|||
;; needed for handling encrypted or compressed files, among other things.
|
||||
(add-hook! 'emacs-startup-hook :depth 101
|
||||
(defun doom--reset-file-handler-alist-h ()
|
||||
(setq file-name-handler-alist
|
||||
(set-default-toplevel-value
|
||||
'file-name-handler-alist
|
||||
;; Merge instead of overwrite because there may have been changes to
|
||||
;; `file-name-handler-alist' since startup we want to preserve.
|
||||
(delete-dups (append file-name-handler-alist old-value))))))
|
||||
|
@ -380,8 +415,9 @@ users).")
|
|||
|
||||
;; PERF: Shave seconds off startup time by starting the scratch buffer in
|
||||
;; `fundamental-mode', rather than, say, `org-mode' or `text-mode', which
|
||||
;; pull in a ton of packages. `doom/open-scratch-buffer' provides a better
|
||||
;; scratch buffer anyway.
|
||||
;; pull in a ton of packages. This buffer is created whether or not we're
|
||||
;; 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
|
||||
initial-scratch-message nil)
|
||||
|
||||
|
@ -397,54 +433,55 @@ users).")
|
|||
(doom-partial #'tty-run-terminal-initialization
|
||||
(selected-frame) nil t))))
|
||||
|
||||
(unless init-file-debug
|
||||
;; 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
|
||||
;; redisplay, which can be expensive during startup. This may also cause
|
||||
;; an flash of white when creating the first frame.
|
||||
;; an flash of white when creating the first frame. Needs to be undo
|
||||
;; later, though.
|
||||
(define-advice load-file (:override (file) silence)
|
||||
(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
|
||||
;; `require' and `load'. Doom won't load any dmodules this early, so omit
|
||||
;; .so for a small startup boost. This is later restored in doom-start.
|
||||
;; PERF: `load-suffixes' and `load-file-rep-suffixes' are consulted on
|
||||
;; each `require' and `load'. Doom won't load any modules this early, so
|
||||
;; 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-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-file-rep-suffixes '(""))
|
||||
;; COMPAT: Undo any problematic startup optimizations; from this point, I make
|
||||
;; no assumptions about what might be loaded in userland.
|
||||
;; COMPAT: Undo any problematic startup optimizations; from this point, I
|
||||
;; make no assumptions about what might be loaded in userland.
|
||||
(add-hook! 'doom-before-init-hook
|
||||
(defun doom--reset-load-suffixes-h ()
|
||||
(setq load-suffixes (get 'load-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
|
||||
;; to reconfigure. Trouble is it fires off initializers meant to
|
||||
;; accommodate any user attempts to configure them before they were
|
||||
;; defined. This is unnecessary before $DOOMDIR/init.el is loaded, so I
|
||||
;; disable them until it is.
|
||||
;; PERF: Doom uses `defcustom' to indicate variables that users are
|
||||
;; expected to reconfigure. Trouble is it fires off initializers meant
|
||||
;; to accommodate any user attempts to configure them before they were
|
||||
;; defined. This is unnecessary work before $DOOMDIR/init.el is loaded,
|
||||
;; so I disable them until it is.
|
||||
(setq custom-dont-initialize t)
|
||||
(add-hook! 'doom-before-init-hook
|
||||
(defun doom--reset-custom-dont-initialize-h ()
|
||||
(setq custom-dont-initialize nil)))
|
||||
|
||||
;; PERF: Doom disables the UI elements by default, so that there's less
|
||||
;; for the frame to initialize. However, the toolbar is still populated
|
||||
;; regardless, so I lazy load it until tool-bar-mode is actually used.
|
||||
(advice-add #'tool-bar-setup :override #'ignore)
|
||||
|
||||
;; PERF: The mode-line procs a couple dozen times during startup. This is
|
||||
;; normally quite fast, but disabling the default mode-line and reducing the
|
||||
;; update delay timer seems to stave off ~30-50ms.
|
||||
;; normally quite fast, but disabling the default mode-line and reducing
|
||||
;; the update delay timer seems to stave off ~30-50ms.
|
||||
(put 'mode-line-format 'initial-value (default-toplevel-value 'mode-line-format))
|
||||
(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.
|
||||
;; 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 it with advice, because `startup--load-user-init-file'
|
||||
;; 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 ()
|
||||
|
@ -453,26 +490,45 @@ users).")
|
|||
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
|
||||
|
||||
;; PERF,UX: An annoying aspect of site-lisp files is that they're often
|
||||
;; noisy (they emit load messages or other output to stdout). These
|
||||
;; queue unnecessary redraws at startup, cost startup time, and pollute
|
||||
;; the logs. I get around it by suppressing it until we can load it
|
||||
;; manually, later (in the `startup--load-user-init-file' advice below).
|
||||
(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: Doom disables the UI elements by default, so that there's less for
|
||||
;; the frame to initialize. However, the toolbar is still populated
|
||||
;; regardless, so I lazy load it until tool-bar-mode is actually used.
|
||||
(advice-add #'tool-bar-setup :override #'ignore)
|
||||
(define-advice startup--load-user-init-file (:before (&rest _) defer-tool-bar-setup)
|
||||
(advice-remove #'tool-bar-setup #'ignore)
|
||||
(add-transient-hook! 'tool-bar-mode (tool-bar-setup)))
|
||||
(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 our current OS, but `command-line-1' still processes.
|
||||
(unless IS-MAC
|
||||
;; 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)))))
|
||||
(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 'risky-local-variable t)
|
||||
|
||||
(defun doom-context--check (context)
|
||||
(defun doom-context--assert (context)
|
||||
(let ((valid (get 'doom-context 'valid-values)))
|
||||
(unless (memq context valid)
|
||||
(signal 'doom-context-error
|
||||
|
@ -512,7 +568,7 @@ All valid contexts:
|
|||
|
||||
Return non-nil if successful. Throws an error if CONTEXT is invalid."
|
||||
(unless (memq context doom-context)
|
||||
(doom-context--check context)
|
||||
(doom-context--assert context)
|
||||
(doom-log ":context: +%s %s" 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))))
|
||||
|
||||
(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))
|
||||
`(let ((doom-context doom-context))
|
||||
(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)
|
||||
(zerop native-comp-async-jobs-number)
|
||||
(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
|
||||
;; 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
|
||||
(when (boundp 'libgnutls-version)
|
||||
(concat "SECURE128:+SECURE192:-VERS-ALL"
|
||||
(if (and (not IS-WINDOWS)
|
||||
(if (and (not doom--system-windows-p)
|
||||
(>= libgnutls-version 30605))
|
||||
":+VERS-TLS1.3")
|
||||
":+VERS-TLS1.2"))
|
||||
|
@ -689,10 +753,22 @@ appropriately against `noninteractive' or the `cli' context."
|
|||
;;
|
||||
;;; 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
|
||||
(defun doom--begin-init-h ()
|
||||
"Begin the startup process."
|
||||
(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
|
||||
;; a later time, or consult them without fear of contamination.
|
||||
(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)
|
||||
(load-path
|
||||
(append (list doom-user-dir)
|
||||
doom-modules-dirs
|
||||
doom-module-load-path
|
||||
load-path)))
|
||||
(condition-case _
|
||||
(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))
|
||||
(doom-log "debug: enabled!")
|
||||
(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
|
||||
;; potentially define one of `doom-debug-variables'), in case some of them
|
||||
;; 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)
|
||||
(and (stringp emacs-repository-version)
|
||||
(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
|
||||
(if doom-profile
|
||||
(format "PROFILE=%s@%s"
|
||||
|
@ -300,7 +298,7 @@ ready to be pasted in a bug report on github."
|
|||
'compiled-user-config)
|
||||
(if (doom-files-in doom-core-dir :type 'files :match "\\.elc$")
|
||||
'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)))))
|
||||
(custom
|
||||
,@(when (and (stringp custom-file)
|
||||
|
|
|
@ -19,24 +19,24 @@
|
|||
(defvar doom-docs-header-specs
|
||||
'(("/docs/index\\.org$"
|
||||
(:label "FAQ"
|
||||
:icon "question_answer"
|
||||
:icon "nf-md-message_question_outline"
|
||||
:link "doom-faq:"
|
||||
:help-echo "Open the FAQ document"))
|
||||
(("/docs/[^/]+\\.org$" "/modules/README\\.org$")
|
||||
(:label "Back to index"
|
||||
:icon "arrow_back"
|
||||
:link ("doom-index" . "")
|
||||
:icon "nf-md-arrow_left"
|
||||
:link "doom-index"
|
||||
:help-echo "Navigate to the root index"))
|
||||
("/modules/[^/]+/README\\.org$"
|
||||
(:label "Back to module index"
|
||||
:icon "arrow_back"
|
||||
:icon "nf-md-arrow_left"
|
||||
:link "doom-module-index:"))
|
||||
("/modules/[^/]+/[^/]+/README\\.org$"
|
||||
(:label "Back to module index"
|
||||
:icon "arrow_back"
|
||||
:icon "nf-md-arrow_left"
|
||||
:link "doom-module-index:")
|
||||
(:label "History"
|
||||
:icon "history"
|
||||
:icon "nf-md-history"
|
||||
:icon-face font-lock-variable-name-face
|
||||
:link (lambda ()
|
||||
(cl-destructuring-bind (category . module) (doom-module-from-path (buffer-file-name))
|
||||
|
@ -44,7 +44,7 @@
|
|||
:help-echo "View the module history"
|
||||
:align right)
|
||||
(:label "Issues"
|
||||
:icon "error_outline"
|
||||
:icon "nf-md-flag"
|
||||
:icon-face error
|
||||
:link (lambda ()
|
||||
(cl-destructuring-bind (category . module) (doom-module-from-path (buffer-file-name))
|
||||
|
@ -52,12 +52,12 @@
|
|||
:align right))
|
||||
(t
|
||||
(:label "Suggest edits"
|
||||
:icon "edit"
|
||||
:icon "nf-md-account_edit"
|
||||
:icon-face warning
|
||||
:link "doom-suggest-edit"
|
||||
:align right)
|
||||
(:label "Help"
|
||||
:icon "help_outline"
|
||||
:icon "nf-md-timeline_help_outline"
|
||||
:icon-face font-lock-function-name-face
|
||||
:link (lambda ()
|
||||
(let ((title (cadar (org-collect-keywords '("TITLE")))))
|
||||
|
@ -101,9 +101,10 @@
|
|||
(defun doom-docs--make-header-link (spec)
|
||||
"Create a header link according to SPEC."
|
||||
(let ((icon (and (plist-get spec :icon)
|
||||
(with-demoted-errors "DOCS ERROR: %s"
|
||||
(funcall (or (plist-get spec :icon-function)
|
||||
#'all-the-icons-material)
|
||||
(plist-get spec :icon))))
|
||||
#'nerd-icons-mdicon)
|
||||
(plist-get spec :icon)))))
|
||||
(label (pcase (plist-get spec :label)
|
||||
((and (pred functionp) lab)
|
||||
(funcall lab))
|
||||
|
@ -239,11 +240,9 @@
|
|||
(beg (max (point-min) (1- (org-element-property :begin el))))
|
||||
(end (org-element-property :end el))
|
||||
((memq (org-element-type el) '(drawer property-drawer))))
|
||||
(when (org-current-level)
|
||||
(when (org-element-property-inherited :level el)
|
||||
(cl-decf end))
|
||||
(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)))))
|
||||
(org-fold-core-region beg end doom-docs-mode 'doom-doc-hidden))))
|
||||
;; FIX: If the cursor remains within a newly folded region, that folk will
|
||||
;; come undone, so we move it.
|
||||
(if pt (goto-char pt))))
|
||||
|
@ -373,7 +372,7 @@ depending.")
|
|||
(defvar doom-docs--cookies nil)
|
||||
;;;###autoload
|
||||
(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."
|
||||
:lighter " Doom Docs"
|
||||
:after-hook (org-restart-font-lock)
|
||||
|
@ -387,7 +386,7 @@ This primes `org-mode' for reading."
|
|||
(if doom-docs-mode
|
||||
(set (make-local-variable sym) t)
|
||||
(kill-local-variable sym)))
|
||||
`(org-pretty-entities
|
||||
'(org-pretty-entities
|
||||
org-hide-emphasis-markers
|
||||
org-hide-macro-markers))
|
||||
(when doom-docs-mode
|
||||
|
@ -428,13 +427,13 @@ This primes `org-mode' for reading."
|
|||
|
||||
(defvar doom-docs--id-locations nil)
|
||||
(defvar doom-docs--id-files nil)
|
||||
(defvar doom-docs--id-location-file (file-name-concat doom-cache-dir "doom-docs-org-ids"))
|
||||
;;;###autoload
|
||||
(defun doom/reload-docs (&optional force)
|
||||
"Reload the ID locations in Doom's documentation and open docs buffers."
|
||||
(interactive (list 'interactive))
|
||||
(with-temp-buffer
|
||||
(let ((org-id-locations-file
|
||||
(doom-path (file-truename doom-cache-dir) "doom-docs-org-ids"))
|
||||
(let ((org-id-locations-file doom-docs--id-location-file)
|
||||
(org-id-track-globally t)
|
||||
org-agenda-files
|
||||
org-id-extra-files
|
||||
|
@ -465,14 +464,26 @@ This primes `org-mode' for reading."
|
|||
(let ((org-id-link-to-org-use-id t)
|
||||
(org-id-method 'uuid)
|
||||
(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-files doom-docs--id-files))
|
||||
(doom/reload-docs)
|
||||
(when-let (fname (buffer-file-name (buffer-base-buffer)))
|
||||
(let ((id (org-id-new)))
|
||||
(org-id-add-location
|
||||
id (buffer-file-name (buffer-base-buffer)))
|
||||
id)))
|
||||
(org-id-add-location id fname)
|
||||
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
|
||||
(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
|
||||
`read-only-mode' is activated."
|
||||
:after-hook (visual-line-mode -1)
|
||||
(font-lock-add-keywords nil doom-docs-org-font-lock-keywords)
|
||||
(let ((gc-cons-threshold most-positive-fixnum)
|
||||
(gc-cons-percentage 1.0))
|
||||
(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
|
||||
org-id-method 'uuid
|
||||
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-files doom-docs--id-files
|
||||
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))
|
||||
(coding-system-for-read (or ,coding '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)
|
||||
(setq-local buffer-file-coding-system 'binary))
|
||||
,@body))
|
||||
|
@ -245,7 +245,8 @@ special values:
|
|||
'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.
|
||||
|
||||
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
|
||||
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
|
||||
`prin1'. BY is the function to use to emit
|
||||
|
||||
MODE dictates the permissions of the file. If FILE already exists, its
|
||||
permissions will be changed.
|
||||
MODE dictates the permissions of created file and directories. MODE is either an
|
||||
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').
|
||||
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,
|
||||
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."
|
||||
(doom--with-prepared-file-buffer file coding mode
|
||||
(let ((contents (ensure-list contents))
|
||||
(let ((mode (ensure-list mode))
|
||||
(contents (ensure-list contents))
|
||||
datum)
|
||||
(doom--with-prepared-file-buffer file coding (car mode)
|
||||
(while (setq datum (pop contents))
|
||||
(cond ((stringp datum)
|
||||
(funcall
|
||||
|
@ -325,15 +329,21 @@ ends. Set either APPEND or PREPEND to `noerror' to silently ignore read errors."
|
|||
((let ((standard-output (current-buffer))
|
||||
(print-quoted t)
|
||||
(print-level nil)
|
||||
(print-length nil))
|
||||
(funcall printfn datum))))))
|
||||
(print-length nil)
|
||||
;; Escape special chars to avoid any shenanigans
|
||||
(print-escape-newlines t)
|
||||
(print-escape-control-characters t)
|
||||
(print-escape-nonascii t)
|
||||
(print-escape-multibyte t))
|
||||
(funcall printfn datum)))))
|
||||
(let (write-region-annotate-functions
|
||||
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)))
|
||||
(eq mkdir 'parents))))
|
||||
(write-region nil nil buffer-file-name append :silent))
|
||||
buffer-file-name))
|
||||
buffer-file-name)))
|
||||
|
||||
;;;###autoload
|
||||
(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)
|
||||
"Open 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
|
||||
(defun doom/sudo-this-file ()
|
||||
|
@ -517,5 +527,77 @@ If FORCE-P, overwrite the destination file if it exists, without confirmation."
|
|||
(recentf-save-list)
|
||||
(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))
|
||||
;;; files.el ends here
|
||||
|
|
|
@ -168,7 +168,8 @@ selection of all minor-modes, active or not."
|
|||
(location
|
||||
(goto-char location)))
|
||||
(ignore-errors
|
||||
(when (outline-invisible-p)
|
||||
(when (memq (get-char-property (point) 'invisible)
|
||||
'(outline org-fold-outline))
|
||||
(save-excursion
|
||||
(outline-previous-visible-heading 1)
|
||||
(org-show-subtree))))))
|
||||
|
@ -575,7 +576,10 @@ If prefix arg is present, refresh the cache."
|
|||
(pp-to-string recipe))))
|
||||
|
||||
(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 ")
|
||||
(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))
|
||||
(user-error "Uneven number of packages being bumped"))
|
||||
(dolist (p1 before)
|
||||
(when (and (listp p1) (plist-get (cdr p1) :package))
|
||||
(cl-destructuring-bind (package &key plist _beg _end &allow-other-keys) p1
|
||||
(let ((p2 (cdr (assq package after))))
|
||||
(if (null p2)
|
||||
(push package errors)
|
||||
(let ((bstr1 (doom--package-to-bump-string package plist))
|
||||
(bstr2 (doom--package-to-bump-string package (plist-get p2 :plist))))
|
||||
(cl-pushnew (format "%s -> %s" bstr1 bstr2) lines :test #'equal))))))
|
||||
(cl-pushnew (format "%s -> %s" bstr1 bstr2) lines :test #'equal)))))))
|
||||
(if (null lines)
|
||||
(user-error "No bumps to bumpify")
|
||||
(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
|
||||
(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)
|
||||
(relpath . (lambda (str &optional dir)
|
||||
(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)
|
||||
#'counsel-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)
|
||||
(fboundp 'counsel-file-jump))
|
||||
(call-interactively #'counsel-file-jump))
|
||||
((project-current nil dir)
|
||||
(project-find-file-in nil nil dir))
|
||||
((when-let ((pr (project-current nil dir)))
|
||||
(project-find-file-in nil nil pr)))
|
||||
((and (bound-and-true-p helm-mode)
|
||||
(fboundp 'helm-find-files))
|
||||
(call-interactively #'helm-find-files))
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
(defun doom-system-distro ()
|
||||
"Return a symbol representing the installed distro."
|
||||
(with-memoization (get 'doom-system-distro 'cached-value)
|
||||
(cond (IS-WINDOWS 'windows)
|
||||
(IS-MAC 'macos)
|
||||
(cond (doom--system-windows-p 'windows)
|
||||
(doom--system-macos-p 'macos)
|
||||
((ignore-errors
|
||||
(with-file-contents! "/etc/os-release"
|
||||
(when (re-search-forward "^ID=\"?\\([^\"\n]+\\)\"?" nil t)
|
||||
|
@ -52,8 +52,8 @@
|
|||
(with-memoization (get 'doom-system-distro-icon 'cached-value)
|
||||
(propertize
|
||||
(pcase (doom-system-distro)
|
||||
(`windows (all-the-icons-faicon "windows"))
|
||||
(`macos (all-the-icons-faicon "apple"))
|
||||
(`windows (nerd-icons-faicon "nf-fa-windows"))
|
||||
(`macos (nerd-icons-faicon "nf-fa-apple"))
|
||||
(`arch "\uF303")
|
||||
(`debian "\uF306")
|
||||
(`raspbian "\uF315")
|
||||
|
@ -74,7 +74,7 @@
|
|||
(`devuan "\uF307")
|
||||
(`manjaro "\uF312")
|
||||
((or `void `artix) "\uF17c")
|
||||
(_ (all-the-icons-faicon "linux")))
|
||||
(_ (nerd-icons-faicon "nf-fa-linux")))
|
||||
'face '(:height 1)
|
||||
'display '(raise 0))))
|
||||
|
||||
|
|
|
@ -88,9 +88,10 @@ Uses `evil-visual-beginning' if available."
|
|||
"Return end position of selection.
|
||||
Uses `evil-visual-end' if available."
|
||||
(declare (side-effect-free t))
|
||||
(if (and (bound-and-true-p evil-local-mode)
|
||||
(evil-visual-state-p))
|
||||
evil-visual-end
|
||||
(or (and (bound-and-true-p evil-local-mode)
|
||||
(evil-visual-state-p)
|
||||
(markerp evil-visual-end)
|
||||
(marker-position evil-visual-end))
|
||||
(region-end)))
|
||||
|
||||
;;;###autoload
|
||||
|
|
|
@ -175,11 +175,18 @@ Use `winner-undo' to undo this. Alternatively, use
|
|||
"Interactively change the current frame's opacity.
|
||||
|
||||
OPACITY is an integer between 0 to 100, inclusive."
|
||||
(interactive
|
||||
(list (read-number "Opacity (0-100): "
|
||||
(or (frame-parameter nil 'alpha)
|
||||
100))))
|
||||
(set-frame-parameter nil 'alpha opacity))
|
||||
(interactive '(interactive))
|
||||
(let* ((parameter
|
||||
(if (eq window-system 'pgtk)
|
||||
'alpha-background
|
||||
'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)
|
||||
;;;###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).
|
||||
|
||||
Inspired from http://demonastery.org/2013/04/emacs-evil-narrow-region/"
|
||||
(interactive
|
||||
(list (or (bound-and-true-p evil-visual-beginning) (region-beginning))
|
||||
(or (bound-and-true-p evil-visual-end) (region-end))))
|
||||
(unless (region-active-p)
|
||||
(setq beg (line-beginning-position)
|
||||
end (line-end-position)))
|
||||
(interactive (if (region-active-p)
|
||||
(list (doom-region-beginning) (doom-region-end))
|
||||
(list (bol) (eol))))
|
||||
(deactivate-mark)
|
||||
(let ((orig-buffer (current-buffer)))
|
||||
(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
|
||||
(defun doom/toggle-narrow-buffer (beg end)
|
||||
"Narrow the buffer to BEG END. If narrowed, widen it."
|
||||
(interactive
|
||||
(list (or (bound-and-true-p evil-visual-beginning) (region-beginning))
|
||||
(or (bound-and-true-p evil-visual-end) (region-end))))
|
||||
(interactive (if (region-active-p)
|
||||
(list (doom-region-beginning) (doom-region-end))
|
||||
(list (bol) (eol))))
|
||||
(if (buffer-narrowed-p)
|
||||
(widen)
|
||||
(unless (region-active-p)
|
||||
(setq beg (line-beginning-position)
|
||||
end (line-end-position)))
|
||||
(narrow-to-region beg end)))
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
;;; lisp/packages.el
|
||||
|
||||
;; doom.el
|
||||
(package! auto-minor-mode :pin "17cfa1b54800fdef2975c0c0531dad34846a5065")
|
||||
(package! gcmh :pin "0089f9c3a6d4e9a310d0791cf6fa8f35642ecfd9")
|
||||
(package! explain-pause-mode
|
||||
:recipe (:host github
|
||||
:repo "lastquestion/explain-pause-mode")
|
||||
:pin "2356c8c3639cbeeb9751744dbe737267849b4b51")
|
||||
(package! auto-minor-mode
|
||||
:pin "17cfa1b54800fdef2975c0c0531dad34846a5065")
|
||||
(package! compat
|
||||
:recipe (:host github :repo "emacs-compat/compat")
|
||||
:pin "8d4e8a366681def88751f5e9975738ecd3180deb")
|
||||
(package! gcmh
|
||||
:pin "0089f9c3a6d4e9a310d0791cf6fa8f35642ecfd9")
|
||||
|
||||
;; doom-packages.el
|
||||
(package! straight
|
||||
|
@ -17,21 +18,21 @@
|
|||
:branch ,straight-repository-branch
|
||||
:local-repo "straight.el"
|
||||
:files ("straight*.el"))
|
||||
:pin "5e84c4e2cd8ca79560477782ee4c9e5187725def")
|
||||
:pin "b1062df10ba4c10ff7a3c61b9e124b3242b11bb2")
|
||||
|
||||
;; doom-ui.el
|
||||
(package! all-the-icons :pin "f491f39c21336d354e85bdb4cca281e0a0c2f880")
|
||||
(package! nerd-icons :pin "8095215a503d8048739de8b4ea4066598edb8cbb")
|
||||
(package! hide-mode-line :pin "bc5d293576c5e08c29e694078b96a5ed85631942")
|
||||
(package! highlight-numbers :pin "8b4744c7f46c72b1d3d599d4fb75ef8183dee307")
|
||||
(package! rainbow-delimiters :pin "a32b39bdfe6c61c322c37226d66e1b6d4f107ed0")
|
||||
(package! rainbow-delimiters :pin "f40ece58df8b2f0fb6c8576b527755a552a5e763")
|
||||
(package! restart-emacs :pin "1607da2bc657fe05ae01f7fdf26f716eafead02c")
|
||||
|
||||
;; doom-editor.el
|
||||
(package! better-jumper :pin "47622213783ece37d5337dc28d33b530540fc319")
|
||||
(package! dtrt-indent :pin "be07f4979a5b402a0cf5311c86c30b89ca0e1ee4")
|
||||
(package! helpful :pin "c57ff0d284b50ff430fe1f13fd48deaa0d1a910e")
|
||||
(package! pcre2el :pin "b941ed8a96299868171fac625ecffec77de3e986")
|
||||
(package! smartparens :pin "79a338db115f441cd47bb91e6f75816c5e78a772")
|
||||
(package! dtrt-indent :pin "5d1b44f9a1a484ca229cc14f8062609a10ef4891")
|
||||
(package! helpful :pin "a32a5b3d959a7fccf09a71d97b3d7c888ac31c69")
|
||||
(package! pcre2el :pin "380723b2701cceb75c266440fb8db918f3340d50")
|
||||
(package! smartparens :pin "ddc6233ea6fc2da7a3a8e44face465c15631b02b")
|
||||
(package! ws-butler
|
||||
;; Use my fork of ws-butler, which has a few choice improvements and
|
||||
;; optimizations (the original has been abandoned).
|
||||
|
@ -39,13 +40,9 @@
|
|||
:pin "572a10c11b6cb88293de48acbb59a059d36f9ba5")
|
||||
|
||||
;; doom-projects.el
|
||||
(package! projectile :pin "971cd5c4f25ff1f84ab7e8337ffc7f89f67a1b52")
|
||||
(package! project :pin "6c41ad68edf1f44110abe478d17c36f57a517e66")
|
||||
(package! projectile :pin "0163b335a18af0f077a474d4dc6b36e22b5e3274")
|
||||
(package! project :pin "b6989856abe9411872bdff5c8aa190bef4d86409")
|
||||
|
||||
;; doom-keybinds.el
|
||||
(package! general :pin "833dea2c4a60e06fcd552b653dfc8960935c9fb4")
|
||||
(package! which-key :pin "df6b0cb8449812e7fb200bc852107fa7eb708496")
|
||||
|
||||
(package! compat
|
||||
:recipe (:host github :repo "emacs-compat/compat")
|
||||
:pin "75d0b8527f51aae42d23eee4aeb263e19055747e")
|
||||
(package! general :pin "ced143c30de8e20f5a3761a465e684a1dc48471e")
|
||||
(package! which-key :pin "96911a1d3faf8426a33241f4821319e98421f380")
|
||||
|
|
|
@ -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]].
|
||||
|
||||
- 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).
|
||||
- Prettified =mu4e:main= view.
|
||||
- Cooperative locking of the =mu= process. Another Emacs instance may request
|
||||
|
@ -1153,7 +1153,7 @@ 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:
|
||||
|
||||
| Module | Major modes | Default language server |
|
||||
|------------------+---------------------------------------------------------+---------------------------------------------------------------|
|
||||
|----------------------------------+---------------------------------------------------------+---------------------------------------------------------------|
|
||||
| [[doom-module::lang cc]] | c-mode, c++-mode, objc-mode | ccls, clangd |
|
||||
| [[doom-module::lang clojure]] | clojure-mode | clojure-lsp |
|
||||
| [[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.
|
||||
|
||||
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.
|
||||
- The first time you run Emacs a unicode cache will be generated -- this will
|
||||
take a while!
|
||||
- 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
|
||||
configuration or the versions of relevant packages changes.
|
||||
|
||||
|
|
|
@ -34,12 +34,12 @@ This module requires:
|
|||
|
||||
* TODO Usage
|
||||
#+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
|
||||
|
||||
* TODO Configuration
|
||||
#+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
|
||||
|
||||
** Changing calendar sources
|
||||
|
@ -74,5 +74,5 @@ to link your calendar with Google calendars.
|
|||
|
||||
* TODO Appendix
|
||||
#+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
|
||||
|
|
|
@ -5,4 +5,4 @@
|
|||
(package! calfw-org :pin "03abce97620a4a7f7ec5f911e669da9031ab9088")
|
||||
(package! calfw-cal :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
|
||||
#+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
|
||||
|
||||
** Keybinds
|
||||
|
@ -56,7 +56,7 @@ These should be available through your OS package manager.
|
|||
|
||||
* TODO Configuration
|
||||
#+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
|
||||
|
||||
* Troubleshooting
|
||||
|
@ -70,5 +70,5 @@ Try [[kbd:][M-x +emms/mpd-restart-music-daemon]] then restart emacs.
|
|||
|
||||
* TODO Appendix
|
||||
#+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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; 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
|
||||
#+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
|
||||
|
|
|
@ -8,19 +8,23 @@
|
|||
:config
|
||||
(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
|
||||
;; this hook, which will rarely work well in emacs-everywhere's temporary
|
||||
;; buffers anyway.
|
||||
(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
|
||||
(doom-modeline-def-segment emacs-everywhere
|
||||
(concat
|
||||
(doom-modeline-spc)
|
||||
(when (emacs-everywhere-markdown-p)
|
||||
(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)))
|
||||
(propertize (emacs-everywhere-app-class emacs-everywhere-current-app)
|
||||
'face 'doom-modeline-project-dir)
|
||||
|
@ -32,7 +36,7 @@
|
|||
(doom-modeline-def-modeline 'emacs-everywhere
|
||||
'(bar modals emacs-everywhere buffer-position
|
||||
word-count parrot selection-info)
|
||||
'(input-method major-mode checker
|
||||
'(input-method major-mode check
|
||||
#(" " 0 1 ; "Exit to app" icon + a little padding
|
||||
(rear-nonsticky t
|
||||
display (raise -0.25)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
;;; app/everywhere/doctor.el -*- lexical-binding: t; -*-
|
||||
|
||||
(when IS-WINDOWS
|
||||
(when (featurep :system 'windows)
|
||||
(error! "emacs-everywhere package does not support windows."))
|
||||
|
||||
(when IS-LINUX
|
||||
(when (featurep :system 'linux)
|
||||
(let (unmet-deps)
|
||||
(dolist (dep '("xclip" "xdotool" "xprop" "xwininfo"))
|
||||
(unless (executable-find dep)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; app/everywhere/packages.el
|
||||
|
||||
(package! emacs-everywhere :pin "b461c4b42093abc42e5ec0f73cb7021c2915cea8")
|
||||
(package! emacs-everywhere :pin "fbeff19825336777dccaefedf3f376dd622cd294")
|
||||
|
|
|
@ -52,7 +52,7 @@ environment.systemPackages = [ pkgs.gnutls ];
|
|||
|
||||
* TODO Usage
|
||||
#+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
|
||||
|
||||
To connect to IRC use ~M-x =irc~.
|
||||
|
@ -70,7 +70,7 @@ When in a circe buffer these keybindings will be available:
|
|||
|
||||
* TODO Configuration
|
||||
#+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
|
||||
|
||||
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
|
||||
#+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
|
||||
|
||||
[[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
|
||||
#+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
|
||||
|
|
|
@ -55,7 +55,8 @@ workspace for it."
|
|||
circe-server-killed-confirmation)
|
||||
(when +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))
|
||||
(when (modulep! :ui workspaces)
|
||||
(when (equal (+workspace-current-name) +irc--workspace-name)
|
||||
|
|
|
@ -187,8 +187,8 @@ playback.")
|
|||
(setq circe-notifications-watch-strings +irc-notifications-watch-strings
|
||||
circe-notifications-emacs-focused nil
|
||||
circe-notifications-alert-style
|
||||
(cond (IS-MAC 'osx-notifier)
|
||||
(IS-LINUX 'libnotify)
|
||||
(cond ((featurep :system 'macos) 'osx-notifier)
|
||||
((featurep :system 'linux) 'libnotify)
|
||||
(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; -*-
|
||||
;;; app/irc/packages.el
|
||||
|
||||
(package! circe :pin "57fe189d7c0b98b9b1b5a59767cea1c7e2c22b13")
|
||||
(package! circe :pin "d374042741cfd0691135f215d311dca8b7a47d19")
|
||||
(package! circe-notifications :pin "291149ac12877bbd062da993479d3533a26862b0")
|
||||
|
|
|
@ -39,7 +39,7 @@ Read RSS feeds in the comfort of Emacs.
|
|||
|
||||
* TODO Usage
|
||||
#+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
|
||||
|
||||
- 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
|
||||
#+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
|
||||
|
||||
** 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]])
|
||||
and put name as you want into ~description~.
|
||||
- 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
|
||||
+ General
|
||||
|
@ -128,5 +128,5 @@ Hook ~elfeed-update~ to ~elfeed-search-mode-hook~:
|
|||
|
||||
* TODO Appendix
|
||||
#+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
|
||||
|
|
|
@ -14,8 +14,9 @@ easier to scroll through.")
|
|||
(defvar +rss-workspace-name "*rss*"
|
||||
"Name of the workspace that contains the elfeed buffer.")
|
||||
|
||||
|
||||
;;
|
||||
;; Packages
|
||||
;;; Packages
|
||||
|
||||
(use-package! elfeed
|
||||
:commands elfeed
|
||||
|
@ -83,6 +84,7 @@ easier to scroll through.")
|
|||
(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))))))
|
||||
|
||||
|
||||
(use-package! elfeed-goodies
|
||||
:after elfeed
|
||||
:config
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; app/rss/packages.el
|
||||
|
||||
(package! elfeed :pin "162d7d545ed41c27967d108c04aa31f5a61c8e16")
|
||||
(package! elfeed :pin "55fb162fa27e71b88effa59a83c57842e262b00f")
|
||||
(package! elfeed-goodies :pin "544ef42ead011d960a0ad1c1d34df5d222461a6b")
|
||||
(when (modulep! +org)
|
||||
(package! elfeed-org :pin "3242ec0519800a58f20480c8a6e3b3337d137084"))
|
||||
(package! elfeed-org :pin "d62d23e25c5e3be3d70b7fbe1eaeb6e43f93a061"))
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
#+created: October 11, 2019
|
||||
#+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:
|
||||
Enjoy twitter from emacs.
|
||||
|
||||
|
@ -48,12 +53,12 @@ This module requires:
|
|||
|
||||
* TODO Usage
|
||||
#+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
|
||||
|
||||
* TODO Configuration
|
||||
#+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
|
||||
|
||||
** Commands & Keybindings
|
||||
|
@ -96,6 +101,6 @@ key for evil users. To work around this issue you may use [[kbd:][M-SPC]] instea
|
|||
|
||||
* TODO Appendix
|
||||
#+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
|
||||
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
;;; app/twitter/packages.el
|
||||
|
||||
(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
|
||||
#+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
|
||||
|
||||
** 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+.
|
||||
|
||||
#+begin_quote
|
||||
🚧 This requires Java 1.8+
|
||||
This requires Java 1.8+
|
||||
#+end_quote
|
||||
|
||||
*** Commands
|
||||
|
@ -61,7 +61,7 @@ This minor mode highlights weasel words, duplication and passive voice.
|
|||
|
||||
* TODO Configuration
|
||||
#+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
|
||||
|
||||
* Troubleshooting
|
||||
|
@ -72,5 +72,5 @@ This minor mode highlights weasel words, duplication and passive voice.
|
|||
|
||||
* TODO Appendix
|
||||
#+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
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
(cond ((setq langtool-bin
|
||||
(or (executable-find "languagetool-commandline")
|
||||
(executable-find "languagetool")))) ; for nixpkgs.languagetool
|
||||
(IS-MAC
|
||||
((featurep :system 'macos)
|
||||
(cond
|
||||
;; is user using home brew?
|
||||
((file-directory-p "/usr/local/Cellar/languagetool")
|
||||
|
@ -25,7 +25,7 @@
|
|||
;; macports compatibility
|
||||
((file-directory-p "/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/*")))))
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; checkers/grammar/packages.el
|
||||
|
||||
(package! langtool :pin "8276eccc5587bc12fd205ee58a7a982f0a136e41")
|
||||
(package! writegood-mode :pin "ed42d918d98826ad88928b7af9f2597502afc6b0")
|
||||
(package! langtool :pin "d86101eafe9a994eb0425e08e7c1795e9cb0cd42")
|
||||
(package! writegood-mode :pin "d54eadeedb8bf3aa0e0a584c0a7373c69644f4b8")
|
||||
|
|
|
@ -58,7 +58,7 @@ your system and in your =$PATH=. They also need dictionaries for your
|
|||
language(s).
|
||||
|
||||
#+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
|
||||
because [[doom-package:spell-fu]] does not support generating the word list with anything
|
||||
other than =aspell= yet.
|
||||
|
@ -108,7 +108,7 @@ language(s).
|
|||
|
||||
* TODO Usage
|
||||
#+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
|
||||
|
||||
When using [[doom-module:+everywhere]], spell checking is performed for as many major modes as
|
||||
|
@ -117,7 +117,7 @@ major modes.
|
|||
|
||||
* TODO Configuration
|
||||
#+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
|
||||
|
||||
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
|
||||
#+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
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
;;; checkers/spell/packages.el
|
||||
|
||||
(if (not (modulep! +flyspell))
|
||||
(package! spell-fu :pin "aed6e87aa31013534b7a6cbedb26e4f29ccea735")
|
||||
(package! flyspell-correct :pin "7d7b6b01188bd28e20a13736ac9f36c3367bd16e")
|
||||
(package! spell-fu
|
||||
:recipe (:host github :repo "emacsmirror/spell-fu")
|
||||
:pin "e4031935803c66eca2f076dce72b0a6a770d026c")
|
||||
(package! flyspell-correct :pin "1e7a5a56362dd875dddf848b9a9e25d1395b9d37")
|
||||
(cond ((modulep! :completion ivy)
|
||||
(package! flyspell-correct-ivy))
|
||||
((modulep! :completion helm)
|
||||
|
|
|
@ -40,7 +40,7 @@ find out if you're missing any dependencies.
|
|||
|
||||
* TODO Usage
|
||||
#+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
|
||||
|
||||
Most of flycheck's features are under [[kbd:][C-c !]], regardless of whether evil mode is
|
||||
|
@ -67,7 +67,7 @@ Evil Specific:
|
|||
|
||||
* TODO Configuration
|
||||
#+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
|
||||
|
||||
* Troubleshooting
|
||||
|
@ -81,5 +81,5 @@ Evil Specific:
|
|||
|
||||
* TODO Appendix
|
||||
#+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
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
;;; checkers/syntax/packages.el
|
||||
|
||||
(unless (modulep! +flymake)
|
||||
(package! flycheck :pin "784f184cdd9f9cb4e3dbb997c09d93e954142842")
|
||||
(package! flycheck :pin "02148c6ce7edb0fd0986460db327cc9463939747")
|
||||
(package! flycheck-popup-tip :pin "ef86aad907f27ca076859d8d9416f4f7727619c6")
|
||||
(when (modulep! +childframe)
|
||||
(package! flycheck-posframe :pin "8f60c9bf124ab9597d681504a73fdf116a0bde12")))
|
||||
(package! flycheck-posframe :pin "19896b922c76a0f460bf3fe8d8ebc2f9ac9028d8")))
|
||||
|
||||
;; Flymake
|
||||
(when (modulep! +flymake)
|
||||
|
|
|
@ -44,7 +44,7 @@ find out if you're missing any dependencies.
|
|||
|
||||
* TODO Usage
|
||||
#+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
|
||||
|
||||
** Code completion
|
||||
|
@ -87,7 +87,7 @@ More information can be found [[https://github.com/oantolin/orderless#company][h
|
|||
|
||||
* TODO Configuration
|
||||
#+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
|
||||
|
||||
** Enable company backend(s) in certain modes
|
||||
|
@ -142,5 +142,5 @@ on changing what backends are available for that mode.
|
|||
|
||||
* TODO Appendix
|
||||
#+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
|
||||
|
|
|
@ -97,47 +97,46 @@
|
|||
:config
|
||||
(setq company-box-show-single-candidate t
|
||||
company-box-backends-colors nil
|
||||
company-box-max-candidates 50
|
||||
company-box-icons-alist 'company-box-icons-all-the-icons
|
||||
company-box-tooltip-limit 50
|
||||
company-box-icons-alist 'company-box-icons-nerd-icons
|
||||
;; Move company-box-icons--elisp to the end, because it has a catch-all
|
||||
;; clause that ruins icons from other backends in elisp buffers.
|
||||
company-box-icons-functions
|
||||
(cons #'+company-box-icons--elisp-fn
|
||||
(delq 'company-box-icons--elisp
|
||||
company-box-icons-functions))
|
||||
company-box-icons-all-the-icons
|
||||
(let ((all-the-icons-scale-factor 0.8))
|
||||
`((Unknown . ,(all-the-icons-material "find_in_page" :face 'all-the-icons-purple))
|
||||
(Text . ,(all-the-icons-material "text_fields" :face 'all-the-icons-green))
|
||||
(Method . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(Function . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(Constructor . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(Field . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(Variable . ,(all-the-icons-material "adjust" :face 'all-the-icons-blue))
|
||||
(Class . ,(all-the-icons-material "class" :face 'all-the-icons-red))
|
||||
(Interface . ,(all-the-icons-material "settings_input_component" :face 'all-the-icons-red))
|
||||
(Module . ,(all-the-icons-material "view_module" :face 'all-the-icons-red))
|
||||
(Property . ,(all-the-icons-material "settings" :face 'all-the-icons-red))
|
||||
(Unit . ,(all-the-icons-material "straighten" :face 'all-the-icons-red))
|
||||
(Value . ,(all-the-icons-material "filter_1" :face 'all-the-icons-red))
|
||||
(Enum . ,(all-the-icons-material "plus_one" :face 'all-the-icons-red))
|
||||
(Keyword . ,(all-the-icons-material "filter_center_focus" :face 'all-the-icons-red))
|
||||
(Snippet . ,(all-the-icons-material "short_text" :face 'all-the-icons-red))
|
||||
(Color . ,(all-the-icons-material "color_lens" :face 'all-the-icons-red))
|
||||
(File . ,(all-the-icons-material "insert_drive_file" :face 'all-the-icons-red))
|
||||
(Reference . ,(all-the-icons-material "collections_bookmark" :face 'all-the-icons-red))
|
||||
(Folder . ,(all-the-icons-material "folder" :face 'all-the-icons-red))
|
||||
(EnumMember . ,(all-the-icons-material "people" :face 'all-the-icons-red))
|
||||
(Constant . ,(all-the-icons-material "pause_circle_filled" :face 'all-the-icons-red))
|
||||
(Struct . ,(all-the-icons-material "streetview" :face 'all-the-icons-red))
|
||||
(Event . ,(all-the-icons-material "event" :face 'all-the-icons-red))
|
||||
(Operator . ,(all-the-icons-material "control_point" :face 'all-the-icons-red))
|
||||
(TypeParameter . ,(all-the-icons-material "class" :face 'all-the-icons-red))
|
||||
(Template . ,(all-the-icons-material "short_text" :face 'all-the-icons-green))
|
||||
(ElispFunction . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
|
||||
(ElispVariable . ,(all-the-icons-material "check_circle" :face 'all-the-icons-blue))
|
||||
(ElispFeature . ,(all-the-icons-material "stars" :face 'all-the-icons-orange))
|
||||
(ElispFace . ,(all-the-icons-material "format_paint" :face 'all-the-icons-pink)))))
|
||||
company-box-icons-nerd-icons
|
||||
`((Unknown . ,(nerd-icons-codicon "nf-cod-code" :face 'font-lock-warning-face))
|
||||
(Text . ,(nerd-icons-codicon "nf-cod-text_size" :face 'font-lock-doc-face))
|
||||
(Method . ,(nerd-icons-codicon "nf-cod-symbol_method" :face 'font-lock-function-name-face))
|
||||
(Function . ,(nerd-icons-codicon "nf-cod-symbol_method" :face 'font-lock-function-name-face))
|
||||
(Constructor . ,(nerd-icons-codicon "nf-cod-triangle_right" :face 'font-lock-function-name-face))
|
||||
(Field . ,(nerd-icons-codicon "nf-cod-symbol_field" :face 'font-lock-variable-name-face))
|
||||
(Variable . ,(nerd-icons-codicon "nf-cod-symbol_variable" :face 'font-lock-variable-name-face))
|
||||
(Class . ,(nerd-icons-codicon "nf-cod-symbol_class" :face 'font-lock-type-face))
|
||||
(Interface . ,(nerd-icons-codicon "nf-cod-symbol_interface" :face 'font-lock-type-face))
|
||||
(Module . ,(nerd-icons-codicon "nf-cod-file_submodule" :face 'font-lock-preprocessor-face))
|
||||
(Property . ,(nerd-icons-codicon "nf-cod-symbol_property" :face 'font-lock-variable-name-face))
|
||||
(Unit . ,(nerd-icons-codicon "nf-cod-symbol_ruler" :face 'font-lock-constant-face))
|
||||
(Value . ,(nerd-icons-codicon "nf-cod-symbol_field" :face 'font-lock-builtin-face))
|
||||
(Enum . ,(nerd-icons-codicon "nf-cod-symbol_enum" :face 'font-lock-builtin-face))
|
||||
(Keyword . ,(nerd-icons-codicon "nf-cod-symbol_keyword" :face 'font-lock-keyword-face))
|
||||
(Snippet . ,(nerd-icons-codicon "nf-cod-symbol_snippet" :face 'font-lock-string-face))
|
||||
(Color . ,(nerd-icons-codicon "nf-cod-symbol_color" :face 'success))
|
||||
(File . ,(nerd-icons-codicon "nf-cod-symbol_file" :face 'font-lock-string-face))
|
||||
(Reference . ,(nerd-icons-codicon "nf-cod-references" :face 'font-lock-variable-name-face))
|
||||
(Folder . ,(nerd-icons-codicon "nf-cod-folder" :face 'font-lock-variable-name-face))
|
||||
(EnumMember . ,(nerd-icons-codicon "nf-cod-symbol_enum_member" :face 'font-lock-builtin-face))
|
||||
(Constant . ,(nerd-icons-codicon "nf-cod-symbol_constant" :face 'font-lock-constant-face))
|
||||
(Struct . ,(nerd-icons-codicon "nf-cod-symbol_structure" :face 'font-lock-variable-name-face))
|
||||
(Event . ,(nerd-icons-codicon "nf-cod-symbol_event" :face 'font-lock-warning-face))
|
||||
(Operator . ,(nerd-icons-codicon "nf-cod-symbol_operator" :face 'font-lock-comment-delimiter-face))
|
||||
(TypeParameter . ,(nerd-icons-codicon "nf-cod-list_unordered" :face 'font-lock-type-face))
|
||||
(Template . ,(nerd-icons-codicon "nf-cod-symbol_snippet" :face 'font-lock-string-face))
|
||||
(ElispFunction . ,(nerd-icons-codicon "nf-cod-symbol_method" :face 'font-lock-function-name-face))
|
||||
(ElispVariable . ,(nerd-icons-codicon "nf-cod-symbol_variable" :face 'font-lock-variable-name-face))
|
||||
(ElispFeature . ,(nerd-icons-codicon "nf-cod-globe" :face 'font-lock-builtin-face))
|
||||
(ElispFace . ,(nerd-icons-codicon "nf-cod-symbol_color" :face 'success))))
|
||||
|
||||
;; HACK Fix oversized scrollbar in some odd cases
|
||||
;; REVIEW `resize-mode' is deprecated and may stop working in the future.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; completion/company/packages.el
|
||||
|
||||
(package! company :pin "2ca3e29abf87392714bc2b26e50e1c0f4b9f4e2c")
|
||||
(package! company :pin "02903bd7088d65a87df0ae0f0d0a7118de147b69")
|
||||
(package! company-dict :pin "cd7b8394f6014c57897f65d335d6b2bd65dab1f4")
|
||||
(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.
|
||||
- +icons ::
|
||||
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
|
||||
- [[doom-package:helm]]
|
||||
|
@ -40,7 +40,7 @@ For official documentation about Helm, see:
|
|||
|
||||
** TODO Hacks
|
||||
#+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
|
||||
|
||||
** TODO Changelog
|
||||
|
@ -75,7 +75,7 @@ its highlights will be covered here.
|
|||
Similar to Ivy, this module provides an interface to navigate within a project
|
||||
using [[doom-package:projectile]]:
|
||||
| Keybind | Description |
|
||||
|------------------+---------------------------------------------------------|
|
||||
|--------------------------------------+-------------------------------------------------------|
|
||||
| [[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 s i]] | Jump to symbol in file (~helm-semantic-or-imenu~) |
|
||||
|
@ -85,7 +85,7 @@ This module also provides interactive text search and replace using [[https://gi
|
|||
|
||||
*** Search
|
||||
| Keybind | Description |
|
||||
|---------+-----------------------------------------------------------|
|
||||
|-------------------+---------------------------------------------------------|
|
||||
| [[kbd:][SPC s p]] | Search project (~+default/search-project~) |
|
||||
| [[kbd:][SPC s P]] | Search another project (~+default/search-other-project~) |
|
||||
| [[kbd:][SPC s d]] | Search this directory (~+default/search-cwd~) |
|
||||
|
@ -97,7 +97,7 @@ search engine to include ignored files.
|
|||
|
||||
This module also provides Ex Commands for evil users:
|
||||
| Ex command | Description |
|
||||
|------------------------+------------------------------------------------------------------|
|
||||
|----------------------+----------------------------------------------------------------|
|
||||
| ~:pg[rep][!] [QUERY]~ | Search project (if ~!~, include hidden files) |
|
||||
| ~:pg[rep]d[!] [QUERY]~ | Search from current directory (if ~!~, don't search recursively) |
|
||||
|
||||
|
@ -107,7 +107,7 @@ commands.
|
|||
*** Replace
|
||||
These keybindings are available while a search is active:
|
||||
| Keybind | Description |
|
||||
|---------+-----------------------------------------------|
|
||||
|-------------------+-----------------------------------------------|
|
||||
| [[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-SPC]] | Preview the current candidate |
|
||||
|
@ -132,13 +132,13 @@ Helm also has a number of overrides for built-in functionality:
|
|||
|
||||
*** General
|
||||
| Keybind | Description |
|
||||
|------------+---------------------------|
|
||||
|--------------------------------+---------------------------|
|
||||
| [[kbd:][M-x]], [[kbd:][SPC :]] | Smarter, smex-powered M-x |
|
||||
| [[kbd:][SPC ']] | Resume last ivy session |
|
||||
|
||||
*** Jump to files, buffers or projects
|
||||
| Keybind | Description |
|
||||
|---------+----------------------------------------------------------------------|
|
||||
|-------------------+--------------------------------------------------------------------|
|
||||
| [[kbd:][SPC p t]] | List all TODO/FIXMEs in project |
|
||||
| [[kbd:][SPC s b]] | Search the current buffer (~+default/search-buffer~) |
|
||||
| [[kbd:][SPC s d]] | Search this directory (~+default/search-cwd~) |
|
||||
|
@ -150,7 +150,7 @@ Helm also has a number of overrides for built-in functionality:
|
|||
|
||||
*** Search
|
||||
| Keybind | Description |
|
||||
|---------+----------------------------------------------------------------------|
|
||||
|-------------------+--------------------------------------------------------------------|
|
||||
| [[kbd:][SPC p t]] | List all TODO/FIXMEs in project |
|
||||
| [[kbd:][SPC s b]] | Search the current buffer (~+default/search-buffer~) |
|
||||
| [[kbd:][SPC s d]] | Search this directory (~+default/search-cwd~) |
|
||||
|
@ -162,7 +162,7 @@ Helm also has a number of overrides for built-in functionality:
|
|||
|
||||
* TODO Configuration
|
||||
#+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
|
||||
|
||||
** helm-mode
|
||||
|
@ -182,9 +182,9 @@ makes sense to exempt ~foo~ with the following:
|
|||
|
||||
** Icons
|
||||
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,
|
||||
[[doom-package:all-the-icons]] is used. To change this:
|
||||
[[doom-package:nerd-icons]] is used. To change this:
|
||||
#+begin_src emacs-lisp
|
||||
;; add to $DOOMDIR/config.el
|
||||
(after! helm
|
||||
|
@ -202,5 +202,5 @@ See [[id:4f36ae11-1da8-4624-9c30-46b764e849fc][this answer]].
|
|||
|
||||
* TODO Appendix
|
||||
#+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
|
||||
|
|
|
@ -148,7 +148,7 @@ Can be negative.")
|
|||
|
||||
(defvar helm-generic-files-map (make-sparse-keymap))
|
||||
(after! helm-locate
|
||||
(when (and IS-MAC
|
||||
(when (and (featurep :system 'macos)
|
||||
(null helm-locate-command)
|
||||
(executable-find "mdfind"))
|
||||
(setq helm-locate-command "mdfind -name %s"))
|
||||
|
@ -195,7 +195,4 @@ Can be negative.")
|
|||
:when (modulep! +icons)
|
||||
:hook (helm-mode . helm-icons-enable)
|
||||
:init
|
||||
(setq helm-icons-provider 'all-the-icons)
|
||||
:config
|
||||
(when (eq helm-icons-provider 'all-the-icons)
|
||||
(setq helm-icons-mode->icon nil)))
|
||||
(setq helm-icons-provider 'nerd-icons))
|
||||
|
|
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; -*-
|
||||
;;; completion/helm/packages.el
|
||||
|
||||
(package! helm :pin "dfd6403947c5cd9f32afcd6bc92a1756cc958c82")
|
||||
(package! helm-company :pin "6eb5c2d730a60e394e005b47c1db018697094dde")
|
||||
(package! helm-c-yasnippet :pin "e214eec8b2875d8a7cd09006dfb6a8e15e9e4079")
|
||||
(package! helm :pin "f34ea6b702648e5c7535a704bdb6c4d7afb4b3b8")
|
||||
(package! helm-company :pin "4622b82353220ee6cc33468f710fa5b6b253b7f1")
|
||||
(package! helm-c-yasnippet :pin "c5880e740da101fde7a995e94a7b16c330e57583")
|
||||
(package! helm-descbinds :pin "b72515982396b6e336ad7beb6767e95a80fca192")
|
||||
(package! helm-describe-modes :pin "11fb36af119b784539d31c6160002de1957408aa")
|
||||
(package! helm-projectile :pin "35a2111d00c0c0c9d8743280d3f1243bb217118a")
|
||||
(package! helm-projectile :pin "e2e38825c975269a4971df25e79b2ae98929624e")
|
||||
(package! helm-rg :pin "ee0a3c09da0c843715344919400ab0a0190cc9dc")
|
||||
(package! swiper-helm :pin "93fb6db87bc6a5967898b5fd3286954cc72a0008")
|
||||
|
||||
(when (modulep! +childframe)
|
||||
(package! helm-posframe :pin "87461b52b6f3f378c63642a33f584d4a4ba28351"))
|
||||
(package! helm-posframe :pin "0b6bb016f0ff4980860a9d00574de311748c40b0"))
|
||||
(when (modulep! +fuzzy)
|
||||
(package! helm-flx :pin "5220099e695a3586dba2d59640217fe378e66310"))
|
||||
(when (modulep! +icons)
|
||||
(package! helm-icons :pin "8d2f5e705c8b78a390677cf242024739c932fc95"))
|
||||
(package! helm-icons :pin "0d113719ee72cb7b6bb7db29f7200d667bd86607"))
|
||||
(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
|
||||
#+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
|
||||
|
||||
* Configuration
|
||||
#+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
|
||||
|
||||
* Troubleshooting
|
||||
|
@ -52,5 +52,5 @@ See [[id:4f36ae11-1da8-4624-9c30-46b764e849fc][this answer]].
|
|||
|
||||
* Appendix
|
||||
#+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
|
||||
|
|
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; -*-
|
||||
;;; completion/ido/packages.el
|
||||
|
||||
(package! flx-ido :pin "7b44a5abb254bbfbeca7a29336f7f4ebd8aabbf2")
|
||||
(package! ido-completing-read+ :pin "49e7967ea8c0ab0a206b40d70fc19be115083fa1")
|
||||
(package! flx-ido :pin "4b1346eb9a8a76ee9c9dede69738c63ad97ac5b6")
|
||||
(package! ido-completing-read+ :pin "5995b4605b4f2d568489491704ef21bc49ddecd5")
|
||||
(package! ido-sort-mtime :pin "f638ff0c922af862f5211779f2311a27fde428eb")
|
||||
(package! ido-vertical-mode :pin "b1659e967da0687abceca733b389ace24004fa66")
|
||||
(package! crm-custom :pin "f1aaccf64306a5f99d9bf7ba815d7ea41c15518d")
|
||||
|
|
|
@ -27,7 +27,7 @@ lighter, simpler and faster in many cases.
|
|||
Enable prescient filtering and sorting for Ivy searches.
|
||||
|
||||
** 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:counsel]]
|
||||
- [[doom-package:counsel-projectile]]
|
||||
|
@ -64,7 +64,7 @@ use their associated Helm command or plugin.
|
|||
|
||||
* TODO Usage
|
||||
#+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
|
||||
|
||||
[[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
|
||||
#+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
|
||||
|
||||
** TODO Enable fuzzy/non-fuzzy search for specific commands
|
||||
** TODO Change the position of the ivy childframe
|
||||
|
||||
* 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
|
||||
[[doom-suggest-faq:][Ask a question?]]
|
||||
|
@ -186,5 +195,5 @@ See [[id:4f36ae11-1da8-4624-9c30-46b764e849fc][this answer]].
|
|||
|
||||
* TODO Appendix
|
||||
#+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
|
||||
|
|
|
@ -34,22 +34,6 @@ Buffers that are considered unreal (see `doom-real-buffer-p') are dimmed with
|
|||
(ivy-append-face candidate 'ivy-modified-buffer))
|
||||
(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
|
||||
(defun +ivy-rich-describe-variable-transformer (cand)
|
||||
"Previews the value of the variable in the minibuffer"
|
||||
|
|
|
@ -116,12 +116,6 @@ results buffer.")
|
|||
:config
|
||||
(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)
|
||||
(let ((filename (ivy-rich-bookmark-filename candidate)))
|
||||
(if (not filename) "" filename)))
|
||||
|
@ -155,25 +149,16 @@ results buffer.")
|
|||
(switch-buffer-alist (assq 'ivy-rich-candidate (plist-get plist :columns))))
|
||||
(setcar switch-buffer-alist '+ivy-rich-buffer-name))
|
||||
|
||||
(when (modulep! +icons)
|
||||
(nerd-icons-ivy-rich-mode +1))
|
||||
(ivy-rich-mode +1)
|
||||
(ivy-rich-project-root-cache-mode +1))
|
||||
|
||||
|
||||
(use-package! all-the-icons-ivy
|
||||
(use-package! nerd-icons-ivy-rich
|
||||
:when (modulep! +icons)
|
||||
:after ivy
|
||||
:config
|
||||
;; `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))))
|
||||
:commands (nerd-icons-ivy-rich-mode)
|
||||
:after counsel-projectile)
|
||||
|
||||
|
||||
(use-package! counsel
|
||||
|
@ -237,7 +222,6 @@ results buffer.")
|
|||
|
||||
;; 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 #'recenter)
|
||||
(ivy-add-actions
|
||||
'counsel-rg ; also applies to `counsel-rg'
|
||||
'(("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))
|
||||
|
||||
;; `counsel-locate'
|
||||
(when IS-MAC
|
||||
(when (featurep :system 'macos)
|
||||
;; Use spotlight on mac by default since it doesn't need any additional setup
|
||||
(setq counsel-locate-cmd #'counsel-locate-cmd-mdfind))
|
||||
|
||||
|
@ -292,13 +276,13 @@ results buffer.")
|
|||
(cl-loop for dir in projectile-globally-ignored-directories
|
||||
collect "--exclude"
|
||||
collect dir)
|
||||
(if IS-WINDOWS '("--path-separator=/")))))
|
||||
(if (featurep :system 'windows) '("--path-separator=/")))))
|
||||
((executable-find "rg" t)
|
||||
(append (list "rg" "--hidden" "--files" "--follow" "--color=never" "--no-messages")
|
||||
(cl-loop for dir in projectile-globally-ignored-directories
|
||||
collect "--glob"
|
||||
collect (concat "!" dir))
|
||||
(if IS-WINDOWS '("--path-separator=/"))))
|
||||
(if (featurep :system 'windows) '("--path-separator=/"))))
|
||||
((cons find-program args)))
|
||||
(unless (listp args)
|
||||
(user-error "`counsel-file-jump-args' is a list now, please customize accordingly."))
|
||||
|
@ -315,7 +299,7 @@ results buffer.")
|
|||
|
||||
|
||||
(use-package! counsel-projectile
|
||||
:defer t
|
||||
:after ivy-rich
|
||||
:init
|
||||
(define-key!
|
||||
[remap projectile-find-file] #'+ivy/projectile-find-file
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; 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; -*-
|
||||
;;; completion/ivy/packages.el
|
||||
|
||||
(package! swiper :pin "9d630d800e856a2c984c5a62a6f0ad313a9d2228")
|
||||
(package! swiper :pin "8c30f4cab5948aa8d942a3b2bbf5fb6a94d9441d")
|
||||
(package! ivy)
|
||||
(package! ivy-hydra)
|
||||
(package! ivy-avy)
|
||||
|
@ -10,15 +10,15 @@
|
|||
(package! amx :pin "5b3aa1aae84f4a225cb8d26ab79a32f97693f023")
|
||||
(package! counsel-projectile :pin "40d1e1d4bb70acb00fddd6f4df9778bf2c52734b")
|
||||
(package! ivy-rich :pin "aff9b6bd53e0fdcf350ab83c90e64e651b47dba4")
|
||||
(package! wgrep :pin "3132abd3750b8c87cbcf6942db952acfab5edccd")
|
||||
(package! wgrep :pin "208b9d01cfffa71037527e3a324684b3ce45ddc4")
|
||||
|
||||
(if (modulep! +prescient)
|
||||
(package! ivy-prescient :pin "d7cc55dad453c465af9ececbab94426202b5b32b")
|
||||
(package! ivy-prescient :pin "4b875be52e75f7b81e68a16b62cfbb2f2584042c")
|
||||
(when (modulep! +fuzzy)
|
||||
(package! flx :pin "7b44a5abb254bbfbeca7a29336f7f4ebd8aabbf2")))
|
||||
(package! flx :pin "4b1346eb9a8a76ee9c9dede69738c63ad97ac5b6")))
|
||||
|
||||
(when (modulep! +childframe)
|
||||
(package! ivy-posframe :pin "533a8e368fcabfd534761a5c685ce713376fa594"))
|
||||
|
||||
(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.
|
||||
|
||||
** 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-flycheck]] if [[doom-module::checkers syntax]]
|
||||
- [[doom-package:embark]]
|
||||
|
@ -63,7 +63,7 @@ intend to use their associated Helm command or plugin.
|
|||
|
||||
* TODO Usage
|
||||
#+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
|
||||
|
||||
The packages in this module modify and use the built-in ~completing-read~
|
||||
|
@ -77,7 +77,7 @@ When in an active Vertico completion session, the following doom added
|
|||
keybindings are available:
|
||||
|
||||
| Keybind | Description |
|
||||
|-------------------+----------------------------------------------------------------|
|
||||
|---------------------------------------+--------------------------------------------------------------|
|
||||
| [[kbd:][C-k]] | (evil) Go to previous candidate |
|
||||
| [[kbd:][C-j]] | (evil) Go to next candidate |
|
||||
| [[kbd:][C-M-k]] | (evil) Go to previous group |
|
||||
|
@ -100,7 +100,7 @@ This module provides an interface to navigate within a project using
|
|||
https://assets.doomemacs.org/completion/vertico/projectile.png
|
||||
|
||||
| Keybind | Description |
|
||||
|------------------+-------------------------------------|
|
||||
|--------------------------------------+-------------------------------------|
|
||||
| [[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 s i]] | Jump to symbol in file |
|
||||
|
@ -109,7 +109,7 @@ https://assets.doomemacs.org/completion/vertico/projectile.png
|
|||
This module provides interactive text search and replace using ripgrep.
|
||||
|
||||
| Keybind | Description |
|
||||
|---------+--------------------------|
|
||||
|------------------------+--------------------------|
|
||||
| [[kbd:][<leader> s p]] | Search project |
|
||||
| [[kbd:][<leader> s P]] | Search another project |
|
||||
| [[kbd:][<leader> s d]] | Search this directory |
|
||||
|
@ -154,13 +154,13 @@ An ~occur-edit~ buffer can be opened from ~consult-line~ with [[kbd:][C-c C-e]].
|
|||
** Vertico integration for various completing commands
|
||||
*** General
|
||||
| Keybind | Description |
|
||||
|------------+-----------------------------|
|
||||
|--------------------------------+-----------------------------|
|
||||
| [[kbd:][M-x]], [[kbd:][SPC :]] | Enhanced M-x |
|
||||
| [[kbd:][SPC ']] | Resume last Vertico session |
|
||||
|
||||
*** Jump to files, buffers or projects
|
||||
| Keybind | Description |
|
||||
|------------------+---------------------------------------|
|
||||
|--------------------------------------+---------------------------------------|
|
||||
| [[kbd:][SPC RET]] | Find bookmark |
|
||||
| [[kbd:][SPC f f]], [[kbd:][SPC .]] | Browse from current directory |
|
||||
| [[kbd:][SPC p f]], [[kbd:][SPC SPC]] | Find file in project |
|
||||
|
@ -178,7 +178,7 @@ the last workspace by typing [[kbd:][0 SPC]].
|
|||
|
||||
*** Search
|
||||
| Keybind | Description |
|
||||
|---------+-------------------------------------------|
|
||||
|-------------------+-------------------------------------------|
|
||||
| [[kbd:][SPC p t]] | List all TODO/FIXMEs in project |
|
||||
| [[kbd:][SPC s b]] | Search the current buffer |
|
||||
| [[kbd:][SPC s d]] | Search this directory |
|
||||
|
@ -201,7 +201,7 @@ to =~/=.
|
|||
This module modifies the default keybindings used in
|
||||
~consult-completing-read-multiple~:
|
||||
| Keybind | Description |
|
||||
|---------+-------------------------------------------------------------|
|
||||
|---------------+-------------------------------------------------------------|
|
||||
| [[kbd:][TAB]] | Select or deselect current candidate |
|
||||
| [[kbd:][RET]] | Enters selected candidates (also toggles current candidate) |
|
||||
|
||||
|
@ -227,7 +227,7 @@ For more information [[https://github.com/minad/consult#asynchronous-search][see
|
|||
|
||||
** Marginalia
|
||||
| Keybind | Description |
|
||||
|---------+---------------------------------|
|
||||
|---------------+---------------------------------|
|
||||
| [[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
|
||||
|
@ -260,7 +260,7 @@ you can use to further specify each space separated input in the following ways:
|
|||
|
||||
* TODO Configuration
|
||||
#+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
|
||||
|
||||
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
|
||||
#+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
|
||||
|
|
|
@ -13,7 +13,9 @@
|
|||
:in PATH
|
||||
Sets what directory to base the search out of. Defaults to the current project's root.
|
||||
: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))
|
||||
(unless (executable-find "rg")
|
||||
(user-error "Couldn't find ripgrep in your PATH"))
|
||||
|
@ -29,7 +31,7 @@
|
|||
"--path-separator / --smart-case --no-heading "
|
||||
"--with-filename --line-number --search-zip "
|
||||
"--hidden -g !.git -g !.svn -g !.hg "
|
||||
(mapconcat #'shell-quote-argument args " ")))
|
||||
(mapconcat #'identity args " ")))
|
||||
(prompt (if (stringp prompt) (string-trim prompt) "Search"))
|
||||
(query (or query
|
||||
(when (doom-region-active-p)
|
||||
|
@ -135,26 +137,6 @@ Supports exporting consult-grep to wgrep, file to wdeired, and consult-location
|
|||
(+vertico/embark-preview)
|
||||
(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
|
||||
(defun +vertico/jump-list (jump)
|
||||
"Go to an entry in evil's (or better-jumper's) jumplist."
|
||||
|
@ -227,27 +209,23 @@ targets."
|
|||
(not (string-suffix-p "-argument" (cdr binding))))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +vertico--consult--fd-make-builder ()
|
||||
(let ((cmd (split-string-and-unquote +vertico-consult-fd-args)))
|
||||
(lambda (input)
|
||||
(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)
|
||||
(defun +vertico/consult-fd-or-find (&optional dir initial)
|
||||
"Runs consult-fd if fd version > 8.6.0 exists, consult-find otherwise.
|
||||
See URL `https://github.com/minad/consult/issues/770'."
|
||||
(interactive "P")
|
||||
(if doom-projectile-fd-binary
|
||||
(pcase-let* ((`(,prompt ,paths ,dir) (consult--directory-prompt "Fd" dir))
|
||||
(default-directory dir)
|
||||
(builder (consult--find-make-builder paths)))
|
||||
(find-file (consult--find prompt builder initial)))
|
||||
;; TODO this condition was adapted from a similar one in lisp/doom-projects.el, to be replaced with a more robust check post v3
|
||||
(if (when-let*
|
||||
((bin (if (ignore-errors (file-remote-p default-directory nil t))
|
||||
(cl-find-if (doom-rpartial #'executable-find t)
|
||||
(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)))
|
||||
|
||||
;;;###autoload
|
||||
|
|
|
@ -86,8 +86,8 @@ buffer will be opened in the current workspace instead."
|
|||
(funcall consult--buffer-display (car buffer)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +vertico/embark-open-in-new-workspace (x)
|
||||
"Open X (a file) in a new workspace."
|
||||
(interactive)
|
||||
(defun +vertico/embark-open-in-new-workspace (file)
|
||||
"Open file in a new workspace."
|
||||
(interactive "GFile:")
|
||||
(+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
|
||||
overrides `completion-styles' during company completion sessions.")
|
||||
|
||||
(defvar +vertico-consult-fd-args nil
|
||||
"Shell command and arguments the vertico module uses for fd.")
|
||||
(defvar +vertico-consult-dir-container-executable "docker"
|
||||
"Command to call for listing container hosts.")
|
||||
|
||||
(defvar +vertico-consult-dir-container-args nil
|
||||
"Command to call for listing container hosts.")
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
@ -80,6 +83,9 @@ orderless."
|
|||
((string= "!" pattern) `(orderless-literal . ""))
|
||||
;; Without literal
|
||||
((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
|
||||
((string-prefix-p "%" pattern) `(char-fold-to-regexp . ,(substring pattern 1)))
|
||||
((string-suffix-p "%" pattern) `(char-fold-to-regexp . ,(substring pattern 0 -1)))
|
||||
|
@ -104,7 +110,7 @@ orderless."
|
|||
;; find-file etc.
|
||||
completion-category-overrides '((file (styles +vertico-basic-remote orderless partial-completion)))
|
||||
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
|
||||
(set-face-attribute 'completions-first-difference nil :inherit nil))
|
||||
|
||||
|
@ -130,25 +136,26 @@ orderless."
|
|||
[remap yank-pop] #'consult-yank-pop
|
||||
[remap persp-switch-to-buffer] #'+vertico/switch-workspace-buffer)
|
||||
:config
|
||||
(defadvice! +vertico--consult-recent-file-a (&rest _args)
|
||||
"`consult-recent-file' needs to have `recentf-mode' on to work correctly"
|
||||
:before #'consult-recent-file
|
||||
(defadvice! +vertico--consult-recentf-a (&rest _args)
|
||||
"`consult-recent-file' needs to have `recentf-mode' on to work correctly.
|
||||
`consult-buffer' needs `recentf-mode' to show file candidates."
|
||||
:before (list #'consult-recent-file #'consult-buffer)
|
||||
(recentf-mode +1))
|
||||
|
||||
(setq consult-project-root-function #'doom-project-root
|
||||
(setq consult-project-function #'doom-project-root
|
||||
consult-narrow-key "<"
|
||||
consult-line-numbers-widen t
|
||||
consult-async-min-input 2
|
||||
consult-async-refresh-delay 0.15
|
||||
consult-async-input-throttle 0.2
|
||||
consult-async-input-debounce 0.1)
|
||||
(unless +vertico-consult-fd-args
|
||||
(setq +vertico-consult-fd-args
|
||||
(if doom-projectile-fd-binary
|
||||
(format "%s --color=never -i -H -E .git --regex %s"
|
||||
doom-projectile-fd-binary
|
||||
(if IS-WINDOWS "--path-separator=/" ""))
|
||||
consult-find-args)))
|
||||
consult-async-input-debounce 0.1
|
||||
consult-fd-args
|
||||
'((if (executable-find "fdfind" 'remote) "fdfind" "fd")
|
||||
"--color=never"
|
||||
;; https://github.com/sharkdp/fd/issues/839
|
||||
"--full-path --absolute-path"
|
||||
"--hidden --exclude .git"
|
||||
(if (featurep :system 'windows) "--path-separator=/")))
|
||||
|
||||
(consult-customize
|
||||
consult-ripgrep consult-git-grep consult-grep
|
||||
|
@ -191,28 +198,42 @@ orderless."
|
|||
|
||||
|
||||
(use-package! consult-dir
|
||||
:bind (([remap list-directory] . consult-dir)
|
||||
:defer t
|
||||
:init
|
||||
(map! [remap list-directory] #'consult-dir
|
||||
(:after vertico
|
||||
:map vertico-map
|
||||
("C-x C-d" . consult-dir)
|
||||
("C-x C-j" . consult-dir-jump-file))
|
||||
"C-x C-d" #'consult-dir
|
||||
"C-x C-j" #'consult-dir-jump-file))
|
||||
:config
|
||||
(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 ()
|
||||
"Get a list of hosts from docker."
|
||||
(when (if (>= emacs-major-version 29)
|
||||
(require 'tramp-container nil t)
|
||||
(setq-local docker-tramp-use-names t)
|
||||
(require 'docker-tramp nil t))
|
||||
(let ((hosts)
|
||||
(docker-query-fn #'docker-tramp--parse-running-containers))
|
||||
(when (>= emacs-major-version 29)
|
||||
(setq docker-query-fn #'tramp-docker--completion-function))
|
||||
(dolist (cand (funcall docker-query-fn))
|
||||
(let ((user (unless (string-empty-p (car cand))
|
||||
(concat (car cand) "@")))
|
||||
(host (car (cdr cand))))
|
||||
(push (concat "/docker:" user host ":/") hosts)))
|
||||
hosts)))
|
||||
(let ((+vertico-consult-dir-container-executable "docker"))
|
||||
(+vertico--consult-dir-container-hosts "docker")))
|
||||
|
||||
(defvar +vertico--consult-dir-source-tramp-podman
|
||||
`(:name "Podman"
|
||||
:narrow ?p
|
||||
:category file
|
||||
:face consult-file
|
||||
:history file-name-history
|
||||
:items ,#'+vertico--consult-dir-podman-hosts)
|
||||
"Podman candidate source for `consult-dir'.")
|
||||
|
||||
(defvar +vertico--consult-dir-source-tramp-docker
|
||||
`(:name "Docker"
|
||||
|
@ -221,8 +242,9 @@ orderless."
|
|||
:face consult-file
|
||||
:history file-name-history
|
||||
: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 'consult-dir--source-tramp-ssh t)
|
||||
|
@ -233,6 +255,11 @@ orderless."
|
|||
(not (modulep! :checkers syntax +flymake)))
|
||||
:after (consult flycheck))
|
||||
|
||||
(use-package! consult-yasnippet
|
||||
:when (modulep! :editor snippets)
|
||||
:defer t
|
||||
:init (map! [remap yas-insert-snippet] #'consult-yasnippet))
|
||||
|
||||
|
||||
(use-package! embark
|
||||
:defer t
|
||||
|
@ -253,6 +280,7 @@ orderless."
|
|||
|
||||
(set-popup-rule! "^\\*Embark Export:" :size 0.35 :ttl 0 :quit nil)
|
||||
|
||||
(after! which-key
|
||||
(defadvice! +vertico--embark-which-key-prompt-a (fn &rest args)
|
||||
"Hide the which-key indicator immediately when using the completing-read prompter."
|
||||
:around #'embark-completing-read-prompter
|
||||
|
@ -260,7 +288,8 @@ orderless."
|
|||
(let ((embark-indicators
|
||||
(remq #'embark-which-key-indicator embark-indicators)))
|
||||
(apply fn args)))
|
||||
(cl-nsubstitute #'+vertico-embark-which-key-indicator #'embark-mixed-indicator embark-indicators)
|
||||
(cl-nsubstitute #'+vertico-embark-which-key-indicator #'embark-mixed-indicator embark-indicators))
|
||||
|
||||
;; add the package! target finder before the file target finder,
|
||||
;; so we don't get a false positive match.
|
||||
(let ((pos (or (cl-position
|
||||
|
@ -284,7 +313,8 @@ orderless."
|
|||
(:when (modulep! :tools magit)
|
||||
:desc "Open magit-status of target" "g" #'+vertico/embark-magit-status)
|
||||
(: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
|
||||
|
@ -294,7 +324,7 @@ orderless."
|
|||
:desc "Cycle marginalia views" "M-A" #'marginalia-cycle)
|
||||
:config
|
||||
(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)
|
||||
(pushnew! marginalia-command-categories
|
||||
'(+default/find-file-under-here . file)
|
||||
|
@ -320,3 +350,44 @@ orderless."
|
|||
:hook (vertico-mode . vertico-posframe-mode)
|
||||
:config
|
||||
(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)
|
||||
;; FIXME: This throws an error if grep is missing.
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; completion/vertico/packages.el
|
||||
|
||||
(package! vertico
|
||||
:recipe (:host github :repo "minad/vertico"
|
||||
:files ("*.el" "extensions/*.el"))
|
||||
:pin "a28370d07f35c5387c7a9ec2e5b67f0d4598058d")
|
||||
(package! vertico :pin "68cbd47589446e9674921bae0b98ff8fbe28be23")
|
||||
|
||||
(package! orderless :pin "e6784026717a8a6a7dcd0bf31fd3414f148c542e")
|
||||
(package! orderless :pin "dc7a781acf2e58ac7d20d1b522be0cde5213e057")
|
||||
|
||||
(package! consult :pin "fe49dedd71802ff97be7b89f1ec4bd61b98c2b13")
|
||||
(package! consult-dir :pin "ed8f0874d26f10f5c5b181ab9f2cf4107df8a0eb")
|
||||
(package! consult :pin "b48ff6bf0527baeb6bfd07c6da9d303ff0b79c3d")
|
||||
(package! consult-dir :pin "3f5f4b71ebe819392cb090cda71bd39a93bd830a")
|
||||
(when (and (modulep! :checkers syntax)
|
||||
(not (modulep! :checkers syntax +flymake)))
|
||||
(package! consult-flycheck :pin "3f2a7c17cc2fe64e0c07e3bf90e33c885c0d7062"))
|
||||
(package! embark :pin "9a44418c349e41020cdc5ad1bd21e8c77a429062")
|
||||
(package! embark-consult :pin "9a44418c349e41020cdc5ad1bd21e8c77a429062")
|
||||
(package! consult-flycheck :pin "754f5497d827f7d58009256a21af614cc44378a3"))
|
||||
(package! embark :pin "c93abadc8220c0caa6fea805f7a736c346d47e7e")
|
||||
(package! embark-consult :pin "c93abadc8220c0caa6fea805f7a736c346d47e7e")
|
||||
|
||||
(package! marginalia :pin "866e50aee4f066b0903752c69b33e9b7cab93f97")
|
||||
(package! marginalia :pin "f6fe86b989a177355ab3ff7e97a384e10a7b0bb1")
|
||||
|
||||
(package! wgrep :pin "3132abd3750b8c87cbcf6942db952acfab5edccd")
|
||||
(package! wgrep :pin "208b9d01cfffa71037527e3a324684b3ce45ddc4")
|
||||
|
||||
(when (modulep! +icons)
|
||||
(package! all-the-icons-completion :pin "8eb3e410d63f5d0657b41829e7898793e81f31c0"))
|
||||
(package! nerd-icons-completion :pin "c2db8557a3c1a9588d111f8c8e91cae96ee85010"))
|
||||
|
||||
(when (modulep! +childframe)
|
||||
(package! 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 "Locate file" "f" #'+lookup/file
|
||||
: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 link" "L" #'ffap-menu
|
||||
:desc "Jump to bookmark" "m" #'bookmark-jump
|
||||
|
@ -145,7 +148,10 @@
|
|||
|
||||
;;; <leader> 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 path" "F" (cmd!! #'+default/insert-file-path t)
|
||||
:desc "Snippet" "s" #'yas-insert-snippet
|
||||
|
@ -505,7 +511,7 @@
|
|||
"C-x C-b" #'ibuffer
|
||||
"C-x K" #'doom/kill-this-buffer-in-all-windows
|
||||
|
||||
;;; company-mode
|
||||
;;; completion (in-buffer)
|
||||
(:when (modulep! :completion company)
|
||||
"C-;" #'+company/complete
|
||||
(:after company
|
||||
|
|
|
@ -43,7 +43,10 @@
|
|||
#'yas-expand
|
||||
(and (bound-and-true-p company-mode)
|
||||
(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)
|
||||
(evil-visual-state-p)
|
||||
(or (eq evil-visual-selection 'line)
|
||||
|
@ -127,7 +130,7 @@
|
|||
;;
|
||||
;;; Module keybinds
|
||||
|
||||
;;; :completion
|
||||
;;; :completion (in-buffer)
|
||||
(map! (:when (modulep! :completion company)
|
||||
:i "C-@" (cmds! (not (minibufferp)) #'company-complete-common)
|
||||
:i "C-SPC" (cmds! (not (minibufferp)) #'company-complete-common)
|
||||
|
@ -156,7 +159,38 @@
|
|||
"C-s" #'company-filter-candidates
|
||||
[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
|
||||
:map ivy-minibuffer-map
|
||||
"C-SPC" #'ivy-call-and-recenter ; preview file
|
||||
|
@ -169,7 +203,8 @@
|
|||
[C-return] #'+ivy/git-grep-other-window-action))
|
||||
|
||||
(:when (modulep! :completion helm)
|
||||
(:after helm :map helm-map
|
||||
(:after helm
|
||||
:map helm-map
|
||||
[remap next-line] #'helm-next-line
|
||||
[remap previous-line] #'helm-previous-line
|
||||
[left] #'left-char
|
||||
|
@ -228,7 +263,7 @@
|
|||
:g "M-8" #'+workspace/switch-to-7
|
||||
:g "M-9" #'+workspace/switch-to-8
|
||||
:g "M-0" #'+workspace/switch-to-final
|
||||
(:when IS-MAC
|
||||
(:when (featurep :system 'macos)
|
||||
:g "s-t" #'+workspace/new
|
||||
:g "s-T" #'+workspace/display
|
||||
:n "s-1" #'+workspace/switch-to-0
|
||||
|
@ -373,6 +408,9 @@
|
|||
(:when (and (modulep! :tools lsp) (not (modulep! :tools lsp +eglot)))
|
||||
:desc "LSP Execute code action" "a" #'lsp-execute-code-action
|
||||
: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)
|
||||
: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)
|
||||
|
@ -386,10 +424,7 @@
|
|||
:desc "Errors list" "X" #'lsp-treemacs-errors-list
|
||||
:desc "Incoming call hierarchy" "y" #'lsp-treemacs-call-hierarchy
|
||||
:desc "Outgoing call hierarchy" "Y" (cmd!! #'lsp-treemacs-call-hierarchy 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)
|
||||
:desc "References tree" "R" (cmd!! #'lsp-treemacs-references t)))
|
||||
(:when (modulep! :tools lsp +eglot)
|
||||
:desc "LSP Execute code action" "a" #'eglot-code-actions
|
||||
:desc "LSP Rename" "r" #'eglot-rename
|
||||
|
@ -496,7 +531,10 @@
|
|||
|
||||
;;; <leader> 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 path" "F" (cmd!! #'+default/insert-file-path t)
|
||||
:desc "Evil ex path" "p" (cmd! (evil-ex "R!echo "))
|
||||
|
@ -674,7 +712,7 @@
|
|||
:desc "Configure project" "g" #'projectile-configure-project
|
||||
:desc "Invalidate project cache" "i" #'projectile-invalidate-cache
|
||||
: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 "Find recent project files" "r" #'projectile-recentf
|
||||
:desc "Run project" "R" #'projectile-run-project
|
||||
|
@ -736,6 +774,9 @@
|
|||
:desc "Search .emacs.d" "e" #'+default/search-emacsd
|
||||
:desc "Locate file" "f" #'locate
|
||||
: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 link" "L" #'ffap-menu
|
||||
:desc "Jump list" "j" #'evil-show-jumps
|
||||
|
@ -754,8 +795,9 @@
|
|||
((modulep! :completion helm) #'swiper-isearch-thing-at-point))
|
||||
:desc "Dictionary" "t" #'+lookup/dictionary-definition
|
||||
:desc "Thesaurus" "T" #'+lookup/synonyms
|
||||
(:when (fboundp 'vundo)
|
||||
:desc "Undo history" "u" #'vundo))
|
||||
:desc "Undo history" "u"
|
||||
(cond ((modulep! :emacs undo +tree) #'undo-tree-visualize)
|
||||
((modulep! :emacs undo) #'vundo)))
|
||||
|
||||
;;; <leader> t --- toggle
|
||||
(:prefix-map ("t" . "toggle")
|
||||
|
|
|
@ -43,12 +43,12 @@ This module provides a set of reasonable defaults, including:
|
|||
|
||||
* TODO Usage
|
||||
#+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
|
||||
|
||||
* TODO Configuration
|
||||
#+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
|
||||
|
||||
* Troubleshooting
|
||||
|
@ -59,7 +59,7 @@ This module provides a set of reasonable defaults, including:
|
|||
|
||||
* TODO Appendix
|
||||
#+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
|
||||
|
||||
** Commands
|
||||
|
|
|
@ -24,15 +24,16 @@ If ARG (universal argument), runs `compile' from the current directory."
|
|||
generate `completing-read' candidates."
|
||||
(interactive)
|
||||
(call-interactively
|
||||
(if (and (not IS-MAC) (executable-find "man"))
|
||||
#'man
|
||||
(if (and (not (featurep :system 'macos)) (executable-find "man"))
|
||||
(or (command-remapping #'man)
|
||||
#'man)
|
||||
#'woman)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +default/new-buffer ()
|
||||
"TODO"
|
||||
(interactive)
|
||||
(if (modulep! 'evil)
|
||||
(if (modulep! +evil)
|
||||
(call-interactively #'evil-buffer-new)
|
||||
(let ((buffer (generate-new-buffer "*new*")))
|
||||
(set-window-buffer nil buffer)
|
||||
|
@ -51,7 +52,7 @@ generate `completing-read' candidates."
|
|||
;;;###autoload
|
||||
(defun +default/diagnostics (&rest arg)
|
||||
"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"
|
||||
(interactive)
|
||||
(cond ((and (modulep! :completion vertico)
|
||||
|
|
|
@ -59,11 +59,16 @@
|
|||
(after! woman
|
||||
;; 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
|
||||
;; it's manpath.
|
||||
(when (executable-find "man")
|
||||
(setq woman-manpath
|
||||
;; its manpath.
|
||||
(let ((manpath (cond
|
||||
((executable-find "manpath")
|
||||
(split-string (cdr (doom-call-process "manpath"))
|
||||
path-separator t))
|
||||
((executable-find "man")
|
||||
(split-string (cdr (doom-call-process "man" "--path"))
|
||||
path-separator t))))
|
||||
path-separator t)))))
|
||||
(when manpath
|
||||
(setq woman-manpath manpath))))
|
||||
|
||||
|
||||
(use-package! drag-stuff
|
||||
|
@ -76,7 +81,7 @@
|
|||
|
||||
|
||||
;;;###package tramp
|
||||
(unless IS-WINDOWS
|
||||
(unless (featurep :system 'windows)
|
||||
(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))
|
||||
|
||||
;; OS specific fixes
|
||||
(when IS-MAC
|
||||
(when (featurep :system 'macos)
|
||||
;; Fix MacOS shift+tab
|
||||
(define-key key-translation-map [S-iso-lefttab] [backtab])
|
||||
;; Fix conventional OS keys in Emacs
|
||||
|
@ -453,6 +458,48 @@ Continues comments if executed from a commented line. Consults
|
|||
'(evil-ex-completion-map)))
|
||||
"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.
|
||||
;; 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.
|
||||
|
@ -482,7 +529,7 @@ Continues comments if executed from a commented line. Consults
|
|||
:gi "C-S-RET" #'+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-return] #'+default/newline-below
|
||||
: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