Merge remote-tracking branch 'upstream/develop' into develop

This commit is contained in:
Jeetaditya Chatterjee 2020-08-22 01:05:36 +01:00
commit 9500aedc35
31 changed files with 400 additions and 206 deletions

2
.gitignore vendored
View file

@ -8,6 +8,8 @@ modules/private
cask/
elpa/
test/.local*/
test/result
result
# emacs tempfiles that shouldn't be there
.mc-lists.el

View file

@ -30,6 +30,9 @@ shift $((OPTIND-1))
[ -t 0 ] && str="$*" || str=$(cat)
# Fix incompatible terminals that cause odd 'not a valid terminal' errors
[ $TERM -eq "alacritty" ] && export TERM=xterm-256color
if [ $daemon ]; then
emacsclient -a "" \
-c -F '((name . "doom-capture") (width . 70) (height . 25) (transient . t))' \

View file

@ -5,26 +5,62 @@
;;;###autoload
(defvar doom-debug-variables
'(doom-debug-p
init-file-debug
debug-on-error
'(debug-on-error
doom-debug-p
garbage-collection-messages
use-package-verbose
jka-compr-verbose
lsp-log-io
gcmh-verbose
magit-refresh-verbose
url-debug)
"A list of variable to toggle on `doom-debug-mode'.")
init-file-debug
jka-compr-verbose
url-debug
use-package-verbose)
"A list of variable to toggle on `doom-debug-mode'.
Each entry can be a variable symbol or a cons cell whose CAR is the variable
symbol and CDR is the value to set it to when `doom-debug-mode' is activated.")
(defvar doom--debug-vars-old-values nil)
(defvar doom--debug-vars-undefined nil)
(defun doom--watch-debug-vars-h (&rest _)
(when-let (bound-vars (cl-remove-if-not #'boundp doom--debug-vars-undefined))
(doom-log "New variables available: %s" bound-vars)
(let ((message-log-max nil))
(doom-debug-mode -1)
(doom-debug-mode +1))))
;;;###autoload
(define-minor-mode doom-debug-mode
"Toggle `debug-on-error' and `doom-debug-p' for verbose logging."
:init-value nil
:global t
(let ((value doom-debug-mode))
(mapc (doom-rpartial #'set value) doom-debug-variables)
(message "Debug mode %s" (if value "on" "off"))))
(let ((enabled doom-debug-mode))
(setq doom--debug-vars-undefined nil)
(dolist (var doom-debug-variables)
(cond ((listp var)
(cl-destructuring-bind (var . val) var
(if (not (boundp var))
(add-to-list 'doom--debug-vars-undefined var)
(set-default
var (if (not enabled)
(alist-get var doom--debug-vars-old-values)
(setf (alist-get var doom--debug-vars-old-values)
(symbol-value var))
val)))))
((if (boundp var)
(set-default var enabled)
(add-to-list 'doom--debug-vars-undefined var)))))
(when (fboundp 'explain-pause-mode)
(explain-pause-mode enabled))
;; 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.
(cond (enabled
(add-variable-watcher 'doom-debug-variables #'doom--watch-debug-vars-h)
(add-hook 'after-load-functions #'doom--watch-debug-vars-h))
(t
(remove-variable-watcher 'doom-debug-variables #'doom--watch-debug-vars-h)
(remove-hook 'after-load-functions #'doom--watch-debug-vars-h)))
(message "Debug mode %s" (if enabled "on" "off"))))
;;

View file

@ -321,7 +321,6 @@ files, so we replace calls to `pp' with the much faster `prin1'."
(use-package! better-jumper
:hook (doom-first-input . better-jumper-mode)
:hook (better-jumper-post-jump . recenter)
:commands doom-set-jump-a doom-set-jump-maybe-a doom-set-jump-h
:preface
;; REVIEW Suppress byte-compiler warning spawning a *Compile-Log* buffer at

View file

@ -369,7 +369,7 @@ config.el instead."
(defun doom-run-local-var-hooks-h ()
"Run MODE-local-vars-hook after local variables are initialized."
(unless doom-inhibit-local-var-hooks
(unless (or doom-inhibit-local-var-hooks revert-buffer-in-progress-p)
(set (make-local-variable 'doom-inhibit-local-var-hooks) t)
(run-hook-wrapped (intern-soft (format "%s-local-vars-hook" major-mode))
#'doom-try-run-hook)))

View file

@ -4,6 +4,10 @@
;; core.el
(package! auto-minor-mode :pin "17cfa1b54800fdef2975c0c0531dad34846a5065")
(package! gcmh :pin "b1bde5089169a74f62033d027e06e98cbeedd43f")
(package! explain-pause-mode
:recipe (:host github
:repo "lastquestion/explain-pause-mode")
:pin "2356c8c3639cbeeb9751744dbe737267849b4b51")
;; core-packages.el
(package! straight

View file

@ -155,8 +155,7 @@ pacman -S git emacs ripgrep
pacman -S fd
#+END_SRC
The above installs Emacs 26.3 (at the time of writing). To acquire Emacs 27
[[https://aur.archlinux.org/packages/emacs27-git/][emacs27-git]] is available on the AUR.
The above installs Emacs 27 (at the time of writing).
**** NixOS
On NixOS Emacs 26.3 can be installed via ~nix-env -Ai nixos.emacs~, or

View file

@ -154,7 +154,7 @@ Modules that bring support for a language or group of languages to Emacs.
* :os
Modules to improve integration into your OS, system, or devices.
+ [[file:/mnt/projects/conf/doom-emacs/modules/os/macos/README.org][macos]] - Improve Emacs' compatibility with macOS
+ [[file:../modules/os/macos/README.org][macos]] - Improve Emacs' compatibility with macOS
+ tty =+osc= - Improves the terminal Emacs experience.
* :term
@ -201,7 +201,7 @@ Aesthetic modules that affect the Emacs interface or user experience.
+ [[file:../modules/ui/hl-todo/README.org][hl-todo]] - TODO
+ [[file:../modules/ui/hydra/README.org][hydra]] - TODO
+ indent-guides - TODO
+ [[file:/mnt/projects/conf/doom-emacs/modules/ui/ligatures/README.org][ligatures]] =+extra +fira +hasklig +iosevka +pragmata-pro= - Ligature support for Emacs
+ [[file:../modules/ui/ligatures/README.org][ligatures]] =+extra +fira +hasklig +iosevka +pragmata-pro= - Ligature support for Emacs
+ [[file:../modules/ui/minimap/README.org][minimap]] - TODO
+ [[file:../modules/ui/modeline/README.org][modeline]] =+light= - TODO
+ [[file:../modules/ui/nav-flash/README.org][nav-flash]] - TODO

View file

@ -11,76 +11,79 @@
- [[#prerequisites][Prerequisites]]
- [[#features][Features]]
- [[#configuration][Configuration]]
- [[#changing-how-quickly-spell-fu-spellchecks-after-changes][Changing how quickly spell-fu spellchecks after changes]]
- [[#reducing-false-positives-by-disabling-spelling-on-certain-faces][Reducing false positives by disabling spelling on certain faces]]
- [[#adding-or-removing-words-to-your-personal-dictionary][Adding or removing words to your personal dictionary]]
- [[#troubleshooting][Troubleshooting]]
* Description
This modules provides spellchecking powered by =aspell= or =hunspell=.
Spellcheck is automatically loaded on the following modes:
+ org
+ markdown
+ TeX
+ rst
+ mu4e-compose
+ message
+ git-commit
Spellcheck is automatically loaded in all ~text-mode~ derivatives, which
includes ~org-mode~, ~markdown-mode~, the Git Commit buffer (from magit),
~mu4e-compose-mode~, and others.
** Maintainers
This module has no dedicated maintainers.
** Module Flags
+ =+aspell= Use =aspell= as a backend for spellchecking.
+ =+hunspell= Use =hunspell= as a backend for spellchecking.
+ =+everywhere= Use spellcheck in every mode.
+ =+aspell= Use =aspell= as a backend for correcting words.
+ =+hunspell= Use =hunspell= as a backend for correcting words.
+ =+everywhere= Use spellcheck in prog-mode and conf-mode derivatives as well as
text-mode. Basically, enable =spell-fu-mode= everywhere.
** Plugins
+ [[https://github.com/d12frosted/flyspell-correct][flyspell-correct]]
+ [[https://github.com/d12frosted/flyspell-correct#flyspell-correct-ivy-interface][flyspell-correct-ivy]] (=completion/ivy=)
+ [[https://github.com/d12frosted/flyspell-correct#flyspell-correct-helm-interface][flyspell-correct-helm]] (=completion/helm=)
+ [[https://github.com/d12frosted/flyspell-correct#flyspell-correct-popup-interface][flyspell-correct-popup]] (if *neither* =completion/ivy= or =completion/helm=)
+ [[https://github.com/rolandwalker/flyspell-lazy][flyspell-lazy]]
+ [[https://gitlab.com/ideasman42/emacs-spell-fu][spell-fu]]
* Prerequisites
This module requires either =aspell= or =hunspell= as backend. It will
automatically pick =aspell= if both are installed.
This module requires =aspell= to be installed, whether or not you intend to use
=hunspell= as the word correction backend. =spell-fu= does not yet support
generating the word list with a custom command or =hunspell=, but =hunspell= can
still be used to provide correction suggestions when invoking ~ispell-word~.
You can specify the backend with the =+aspell= or =+hunspell= flag.
You will need =hunspell= installed (via your OS package manager) to use it as a
correction backend.
* Features
+ Spellchecking and suggestions based on =aspell= or =hunspell=.
+ Choosing suggestions using completion interfaces (=ivy= or =helm=).
+ Lazily spellchecking recent changes only when idle.
+ Ignores source code inside org documents.
+ Spellchecking based on =aspell=.
+ Spell correction using =aspell= or =hunspell= (through ~M-x ispell-word~).
+ Ignores source code inside org or markdown files.
When using =+everywhere=, =flyspell-prog-mode= will be automatically loaded for
the following modes:
+ yaml-mode-hook
+ conf-mode-hook
+ prog-mode-hook
=flyspell-prog-mode= will only spellcheck comments.
When using =+everywhere=, ~spell-fu-mode~ is activated for as many major modes
as possible, and not only ~text-mode~ derivatives. =spell-fu= will only spell
check comments in programming major modes.
* Configuration
Dictionary is set by =ispell-dictionary= variable. Can be changed locally with
the function =ispell-change-dictionary=.
Lazy spellcheck is provided by =flyspell-lazy= package.
=flyspell-lazy-idle-seconds= sets how many idle seconds until spellchecking
recent changes (default as 1), while =flyspell-lazy-window-idle-seconds= sets
how many seconds until the whole window is spellchecked (default as 3).
If you want to add =flyspell-mode= or =flyspell-prog-mode= to a specific mode,
use =add-hook!=. To remove from a mode, use =remove-hook!=:
** Changing how quickly spell-fu spellchecks after changes
Adjust ~spell-fu-idle-delay~ to change how long spell-fu waits to spellcheck
after recent changes (its default value as ~0.25~).
#+BEGIN_SRC elisp
(add-hook! '(org-mode-hook markdown-mode-hook
git-commit-mode-hook) #'flyspell-mode)
(after! spell-fu
(setq spell-fu-idle-delay 0.5))
#+END_SRC
** Reducing false positives by disabling spelling on certain faces
Exclude what faces to not preform spellchecking on by setting
~spell-fu-faces-exclude~ in a buffer-local hook:
#+BEGIN_SRC elisp
(remove-hook! '(markdown-mode-hook git-commit-mode-hook)
#'flyspell-mode)
(setq-hook! 'markdown-mode-hook
spell-fu-faces-exclude '(markdown-code-face
markdown-reference-face
markdown-link-face
markdown-url-face
markdown-markup-face
markdown-html-attr-value-face
markdown-html-attr-name-face
markdown-html-tag-name-face))
#+END_SRC
* Troubleshooting
** Adding or removing words to your personal dictionary
Use ~M-x spell-fu-word-add~ and ~M-x spell-fu-word-remove~ to whitelist words
that you know are not misspellings.
* TODO Troubleshooting

View file

@ -1,27 +1,99 @@
;;; checkers/spell/autoload.el -*- lexical-binding: t; -*-
;;; checkers/spell/autoload/ivy.el -*- lexical-binding: t; -*-
;;;###autodef
(defalias 'flyspell-mode! #'flyspell-mode)
(defun +spell--correct (replace poss word orig-pt start end)
(cond ((eq replace 'ignore)
(goto-char orig-pt)
nil)
((eq replace 'save)
(goto-char orig-pt)
(ispell-send-string (concat "*" word "\n"))
(ispell-send-string "#\n")
(setq ispell-pdict-modified-p '(t)))
((or (eq replace 'buffer) (eq replace 'session))
(ispell-send-string (concat "@" word "\n"))
(add-to-list 'ispell-buffer-session-localwords word)
(or ispell-buffer-local-name ; session localwords might conflict
(setq ispell-buffer-local-name (buffer-name)))
(if (null ispell-pdict-modified-p)
(setq ispell-pdict-modified-p
(list ispell-pdict-modified-p)))
(goto-char orig-pt)
(if (eq replace 'buffer)
(ispell-add-per-file-word-list word)))
(replace
(let ((new-word (if (atom replace)
replace
(car replace)))
(orig-pt (+ (- (length word) (- end start))
orig-pt)))
(unless (equal new-word (car poss))
(delete-region start end)
(goto-char start)
(insert new-word))))
((goto-char orig-pt)
nil)))
(defvar +spell--flyspell-predicate-alist nil
"TODO")
(defun +spell-correct-ivy-fn (candidates word)
(ivy-read (format "Corrections for %S: " word) candidates))
;;;###autodef
(defun set-flyspell-predicate! (modes predicate)
"TODO"
(declare (indent defun))
(dolist (mode (doom-enlist modes) +spell--flyspell-predicate-alist)
(add-to-list '+spell--flyspell-predicate-alist (cons mode predicate))))
(defun +spell-correct-helm-fn (candidates word)
(helm :sources (helm-build-sync-source
"Ispell"
:candidates candidates)
:prompt (format "Corrections for %S: " word)))
(defun +spell-correct-generic-fn (candidates word)
(completing-read (format "Corrections for %S: " word) candidates))
;;;###autoload
(defun +spell-init-flyspell-predicate-h ()
"TODO"
(when-let (pred (assq major-mode +spell--flyspell-predicate-alist))
(setq-local flyspell-generic-check-word-predicate (cdr pred))))
;;;###autoload
(defun +spell-correction-at-point-p (&optional point)
"TODO"
(cl-loop for ov in (overlays-at (or point (point)))
if (overlay-get ov 'flyspell-overlay)
return t))
(defun +spell/correct ()
"Correct spelling of word at point."
(interactive)
(if (not (or (featurep! :completion ivy)
(featurep! :completion helm)))
(call-interactively #'ispell-word)
(cl-destructuring-bind (start . end)
(bounds-of-thing-at-point 'word)
(let ((word (thing-at-point 'word t))
(orig-pt (point))
poss ispell-filter)
(save-current-buffer
(ispell-accept-buffer-local-defs))
(ispell-send-string "%\n")
(ispell-send-string (concat "^" word "\n"))
(while (progn (accept-process-output ispell-process)
(not (string= "" (car ispell-filter)))))
;; Remove leading empty element
(setq ispell-filter (cdr ispell-filter))
;; ispell process should return something after word is sent. Tag word as
;; valid (i.e., skip) otherwise
(unless ispell-filter
(setq ispell-filter '(*)))
(when (consp ispell-filter)
(setq poss (ispell-parse-output (car ispell-filter))))
(cond
((or (eq poss t) (stringp poss))
;; don't correct word
(message "%s is correct" (funcall ispell-format-word-function word))
t)
((null poss)
;; ispell error
(error "Ispell: error in Ispell process"))
(t
;; The word is incorrect, we have to propose a replacement.
(setq res (funcall +spell-correct-interface (nth 2 poss) word))
;; Some interfaces actually eat 'C-g' so it's impossible to stop rapid
;; mode. So when interface returns nil we treat it as a stop.
(unless res (setq res (cons 'break word)))
(cond
((stringp res)
(+spell--correct res poss word orig-pt start end))
((let ((cmd (car res))
(wrd (cdr res)))
(unless (or (eq cmd 'skip)
(eq cmd 'break)
(eq cmd 'stop))
(+spell--correct cmd poss wrd orig-pt start end)
(unless (string-equal wrd word)
(+spell--correct wrd poss word orig-pt start end))))))
(ispell-pdict-save t)))))))

View file

@ -1,7 +1,54 @@
;;; checkers/spell/config.el -*- lexical-binding: t; -*-
(defvar ispell-dictionary "en_US")
(defvar +spell-correct-interface
(cond ((featurep! :completion ivy)
#'+spell-correct-ivy-fn)
((featurep! :completion helm)
#'+spell-correct-helm-fn)
(#'+spell-correct-generic-fn))
"Function to use to display corrections.")
(defvar +spell-excluded-faces-alist
'((markdown-mode
. (markdown-code-face
markdown-html-attr-name-face
markdown-html-attr-value-face
markdown-html-tag-name-face
markdown-link-face
markdown-markup-face
markdown-reference-face
markdown-url-face))
(org-mode
. (org-block
org-block-begin-line
org-block-end-line
org-code
org-date
org-formula
org-latex-and-related
org-link
org-meta-line
org-property-value
org-ref-cite-face
org-special-keyword
org-tag
org-todo
org-todo-keyword-done
org-todo-keyword-habt
org-todo-keyword-kill
org-todo-keyword-outd
org-todo-keyword-todo
org-todo-keyword-wait
org-verbatim)))
"Faces in certain major modes that spell-fu will not spellcheck.")
;;
;;; Packages
(global-set-key [remap ispell-word] #'+spell/correct)
(defvar ispell-dictionary "en_US")
(after! ispell
;; Don't spellcheck org blocks
(pushnew! ispell-skip-region-alist
@ -39,74 +86,21 @@
(_ (doom-log "Spell checker not found. Either install `aspell' or `hunspell'"))))
(use-package! flyspell ; built-in
:defer t
:preface
;; `flyspell' is loaded at startup. In order to lazy load its config we need
;; to pretend it isn't loaded.
(defer-feature! flyspell flyspell-mode flyspell-prog-mode)
(use-package! spell-fu
:hook (text-mode . spell-fu-mode)
:init
(add-hook! '(org-mode-hook
markdown-mode-hook
TeX-mode-hook
rst-mode-hook
mu4e-compose-mode-hook
message-mode-hook
git-commit-mode-hook)
#'flyspell-mode)
(setq spell-fu-directory (concat doom-etc-dir "spell-fu"))
(when (featurep! +everywhere)
(add-hook! '(yaml-mode-hook
conf-mode-hook
prog-mode-hook)
#'flyspell-prog-mode))
#'spell-fu-mode))
:config
(setq flyspell-issue-welcome-flag nil
;; Significantly speeds up flyspell, which would otherwise print
;; messages for every word when checking the entire buffer
flyspell-issue-message-flag nil)
(add-hook! 'spell-fu-mode-hook
(defun +spell-init-excluded-faces-h ()
(when-let (excluded (alist-get major-mode +spell-excluded-faces-alist))
(setq-local spell-fu-faces-exclude excluded))))
(add-hook! 'flyspell-mode-hook
(defun +spell-inhibit-duplicate-detection-maybe-h ()
"Don't mark duplicates when style/grammar linters are present.
e.g. proselint and langtool."
(and (or (and (bound-and-true-p flycheck-mode)
(executable-find "proselint"))
(featurep 'langtool))
(setq-local flyspell-mark-duplications-flag nil))))
;; Ensure mode-local predicates declared with `set-flyspell-predicate!' are
;; used in their respective major modes.
(add-hook 'flyspell-mode-hook #'+spell-init-flyspell-predicate-h)
(let ((flyspell-correct
(general-predicate-dispatch nil
(and (not (or mark-active (ignore-errors (evil-insert-state-p))))
(memq 'flyspell-incorrect (face-at-point nil t)))
#'flyspell-correct-at-point)))
(map! :map flyspell-mouse-map
"RET" flyspell-correct
[return] flyspell-correct
[mouse-1] #'flyspell-correct-at-point)))
(use-package! flyspell-correct
:commands flyspell-correct-previous
:general ([remap ispell-word] #'flyspell-correct-at-point)
:config
(cond ((and (featurep! :completion helm)
(require 'flyspell-correct-helm nil t)))
((and (featurep! :completion ivy)
(require 'flyspell-correct-ivy nil t)))
((require 'flyspell-correct-popup nil t)
(setq flyspell-popup-correct-delay 0.8)
(define-key popup-menu-keymap [escape] #'keyboard-quit))))
(use-package! flyspell-lazy
:after flyspell
:config
(setq flyspell-lazy-idle-seconds 1
flyspell-lazy-window-idle-seconds 3)
(flyspell-lazy-mode +1))
;; TODO custom `spell-fu-check-range' function to exclude URLs from links or
;; org-src blocks more intelligently.
)

View file

@ -1,11 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; checkers/spell/packages.el
(package! flyspell-correct :pin "dea1290a371c540dde7b8d0eef7a12d92f7a0b83")
(cond ((featurep! :completion ivy)
(package! flyspell-correct-ivy))
((featurep! :completion helm)
(package! flyspell-correct-helm))
((package! flyspell-correct-popup)))
(package! flyspell-lazy :pin "3ebf68cc9eb10c972a2de8d7861cbabbbce69570")
(package! spell-fu :pin "e94d01cdc822e02968971cde09276047a5d55772")

View file

@ -17,7 +17,7 @@
(package! flx :pin "17f5c9cb2af18aa6f52910ff4a5a63591261ced5")))
(when (featurep! +childframe)
(package! ivy-posframe :pin "82a63ae0fe1976d042ae41e6400c037193cfed8e"))
(package! ivy-posframe :pin "44749562a9e68bd43ccaa225b31311476fab1251"))
(when (featurep! +icons)
(package! all-the-icons-ivy :pin "a70cbfa1effe36efc946a823a580cec686d5e88d"))

View file

@ -204,7 +204,7 @@
(:when (featurep! :term eshell)
:desc "Toggle eshell popup" "e" #'+eshell/toggle
:desc "Open eshell here" "E" #'+eshell/here)
(:when (featurep! :tools macos)
(:when (featurep! :os macos)
:desc "Reveal in Finder" "o" #'+macos/reveal-in-finder
:desc "Reveal project in Finder" "O" #'+macos/reveal-project-in-finder
:desc "Send to Transmit" "u" #'+macos/send-to-transmit
@ -280,7 +280,7 @@
:desc "org-tree-slide mode" "p" #'org-tree-slide-mode)
:desc "Read-only mode" "r" #'read-only-mode
(:when (featurep! :checkers spell)
:desc "Flyspell" "s" #'flyspell-mode)
:desc "Spell checker" "s" #'spell-fu-mode)
(:when (featurep! :lang org +pomodoro)
:desc "Pomodoro timer" "t" #'org-pomodoro)
(:when (featurep! :ui zen)

View file

@ -541,7 +541,7 @@
(:when (featurep! :term eshell)
:desc "Toggle eshell popup" "e" #'+eshell/toggle
:desc "Open eshell here" "E" #'+eshell/here)
(:when (featurep! :tools macos)
(:when (featurep! :os macos)
:desc "Reveal in Finder" "o" #'+macos/reveal-in-finder
:desc "Reveal project in Finder" "O" #'+macos/reveal-project-in-finder
:desc "Send to Transmit" "u" #'+macos/send-to-transmit
@ -662,7 +662,7 @@
:desc "org-tree-slide mode" "p" #'org-tree-slide-mode)
:desc "Read-only mode" "r" #'read-only-mode
(:when (featurep! :checkers spell)
:desc "Flyspell" "s" #'flyspell-mode)
:desc "Spell checker" "s" #'spell-fu-mode)
(:when (featurep! :lang org +pomodoro)
:desc "Pomodoro timer" "t" #'org-pomodoro)
:desc "Soft line wrapping" "w" #'visual-line-mode

View file

@ -376,16 +376,17 @@ directives. By default, this only recognizes C directives.")
;;; Keybinds
;; Keybinds that have no Emacs+evil analogues (i.e. don't exist):
;; zq - mark word at point as good word
;; zw - mark word at point as bad
;; zu{q,w} - undo last marking
;; Keybinds that evil define:
;; z= - correct flyspell word at point
;; ]s - jump to previous spelling error
;; [s - jump to next spelling error
(map! :v "@" #'+evil:apply-macro
;; implement dictionary keybinds
;; evil already defines 'z=' to `ispell-word' = correct word at point
:n "zq" #'spell-fu-word-add
:n "zw" #'spell-fu-word-remove
:n "[s" #'spell-fu-goto-previous-error
:n "]s" #'spell-fu-goto-next-error
;; ported from vim-unimpaired
:n "] SPC" #'+evil/insert-newline-below
:n "[ SPC" #'+evil/insert-newline-above

View file

@ -33,6 +33,8 @@
#'yas-minor-mode-on)
:config
(add-to-list 'doom-debug-variables '(yas-verbosity . 3))
;; Allow private snippets in DOOMDIR/snippets
(add-to-list 'yas-snippet-dirs '+snippets-dir)

View file

@ -53,8 +53,6 @@ capture, the end position, and the output buffer.")
(add-to-list 'org-src-lang-modes '("md" . markdown)))
:config
(set-flyspell-predicate! '(markdown-mode gfm-mode)
#'+markdown-flyspell-word-p)
(set-lookup-handlers! '(markdown-mode gfm-mode)
;; `markdown-follow-thing-at-point' may open an external program or a
;; buffer. No good way to tell, so pretend it's async.

View file

@ -1,6 +1,8 @@
;;; lang/nim/config.el -*- lexical-binding: t; -*-
(after! nim-mode
(use-package! nim-mode
:defer t
:init
(add-hook! 'nim-mode-hook
(defun +nim-init-nimsuggest-mode-h ()
"Conditionally load `nimsuggest-mode', instead of clumsily erroring out if
@ -19,9 +21,16 @@ windows."
:filter-return #'nimsuggest--get-temp-file-name
(replace-regexp-in-string "[* |<>\"?*]" "" path)))
:config
(set-lookup-handlers! '(nim-mode nimsuggest-mode)
:definition #'+nimsuggest-find-definition
:documentation #'nimsuggest-show-doc)
(map! :localleader
:map nim-mode-map
"b" #'nim-compile))
"b" #'nim-compile
"h" #'nimsuggest-show-doc
"d" #'nimsuggest-find-definition))
(use-package! flycheck-nim

View file

@ -598,7 +598,10 @@ buffers."
(defadvice! +org--exclude-agenda-buffers-from-recentf-a (orig-fn file)
"Prevent temporarily opened agenda buffers from polluting recentf."
:around #'org-get-agenda-file-buffer
(let ((recentf-exclude (list (lambda (_file) t))))
(let ((recentf-exclude (list (lambda (_file) t)))
(doom-large-file-p t)
find-file-hook
org-mode-hook)
(funcall orig-fn file)))
;; HACK With https://code.orgmode.org/bzg/org-mode/commit/48da60f4, inline

View file

@ -12,10 +12,7 @@
(when (featurep! +lsp)
(unless (featurep! :tools lsp +eglot)
(if (featurep! +pyright)
(package! lsp-pyright
;; REVIEW Remove this when added to melpa
:recipe (:host github :repo "emacs-lsp/lsp-pyright")
:pin "9603dda12afaae9c82608c7d3762f98b24b8563f")
(package! lsp-pyright :pin "9603dda12afaae9c82608c7d3762f98b24b8563f")
(package! lsp-python-ms :pin "a884a9a4eb1a3acd3d70c776aec5e968bbdc1731"))))
;; Programming environment

View file

@ -10,7 +10,7 @@
:init
(setq geiser-active-implementations '(guile chicken mit chibi chez)
geiser-autodoc-identifier-format "%s → %s"
geiser-smart-tab-p t)
geiser-repl-current-project-function 'doom-project-root)
(unless (featurep! :lang racket)
(push 'racket geiser-active-implementations))
(after! scheme ; built-in

View file

@ -0,0 +1,5 @@
;; -*- no-byte-compile: t; -*-
;;; os/macos/packages.el
(package! osx-trash :pin "0f1dc052d0a750b8c75f14530a4897f5d4324b4e")
(package! ns-auto-titlebar :pin "60273e764bf8d95abc40dd2fdc23af87ea9ee33b")

View file

@ -120,8 +120,31 @@
(dap-mode 1)
(define-minor-mode +dap-running-session-mode
"A mode for adding keybindings to running sessions"
nil nil (make-sparse-keymap)
(when (bound-and-true-p evil-mode)
(evil-normalize-keymaps)) ; if you use evil, this is necessary to update the keymaps
;; The following code adds to the dap-terminated-hook so that this minor
;; mode will be deactivated when the debugger finishes
(when +dap-running-session-mode
(let ((session-at-creation (dap--cur-active-session-or-die)))
(add-hook 'dap-terminated-hook
(lambda (session)
(when (eq session session-at-creation)
(+dap-running-session-mode -1)))))))
;; Activate this minor mode when dap is initialized
(add-hook 'dap-session-created-hook #'+dap-running-session-mode)
;; Activate this minor mode when hitting a breakpoint in another file
(add-hook 'dap-stopped-hook #'+dap-running-session-mode)
;; Activate this minor mode when stepping into code in another file
(add-hook 'dap-stack-frame-changed-hook (lambda (session)
(when (dap--session-running session)
(+dap-running-session-mode 1))))
(map! :localleader
:map dap-mode-map
:map +dap-running-session-mode-map
"d" #'dap-hydra))

View file

@ -34,7 +34,7 @@ direnv and then made available to the current shell.
This module provides no flags.
** Plugins
+ [[https://github.com/wbolster/emacs-direnv][direnv]]
+ [[https://github.com/purcell/envrc][envrc]]
** Hacks
+ Normally, the direnv environment is updated on ~post-command-hook~. We've

View file

@ -5,30 +5,39 @@
"join_args" "expand_path" "dotenv" "user_rel_path" "find_up" "source_env"
"watch_file" "source_up" "direnv_load" "MANPATH_add" "load_prefix" "layout"
"use" "rvm" "use_nix" "use_guix")
"TODO")
"A list of direnv keywords, which are fontified when in `+direnv-rc-mode'.")
;;
;;; Packages
(use-package! direnv
:hook (before-hack-local-variables . direnv--maybe-update-environment)
:hook (flycheck-before-syntax-check . direnv--maybe-update-environment)
:hook (direnv-envrc-mode . +direnv-envrc-fontify-keywords-h)
(use-package! envrc
:when (executable-find "direnv")
:after-call doom-first-file
:mode ("\\.envrc\\'" . +direnv-rc-mode)
:config
(add-to-list 'direnv-non-file-modes 'vterm-mode)
(add-to-list 'doom-debug-variables 'envrc-debug)
(defun +direnv-envrc-fontify-keywords-h ()
"Fontify special .envrc keywords; it's a good indication of whether or not
we've typed them correctly."
;; I'm avoiding `global-envrc-mode' intentionally, because it has the
;; potential to run too late in the mode startup process (and after, say,
;; server hooks that may rely on that local direnv environment).
(add-hook! 'change-major-mode-after-body-hook
(defun +direnv-init-h ()
(unless (or envrc-mode
(minibufferp)
(file-remote-p default-directory))
(envrc-mode 1))))
(define-derived-mode +direnv-rc-mode sh-mode "envrc"
"Major mode for .envrc files."
;; Fontify .envrc keywords; it's a good indication of whether or not we've
;; typed them correctly, and that we're in the correct major mode.
(font-lock-add-keywords
nil `((,(regexp-opt +direnv-keywords 'symbols)
(0 font-lock-keyword-face)))))
(defadvice! +direnv--fail-gracefully-a (&rest _)
"Don't try to use direnv if the executable isn't present."
:before-while #'direnv-update-directory-environment
:before-while #'envrc-mode
(or (executable-find "direnv")
(ignore (doom-log "Couldn't find direnv executable"))))
(direnv-mode +1))
(ignore (doom-log "Couldn't find direnv executable")))))

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; tools/direnv/packages.el
(package! direnv :pin "f5484b0fc33d4e5116612626294efb362ff9ecd4")
(package! envrc :pin "1dc5aad14d2c27211c7c288d2d9dffeb2e27cb2d")

View file

@ -1,8 +1,5 @@
;;; tools/lsp/+eglot.el -*- lexical-binding: t; -*-
;; TODO set eglot-events-buffer-size to nil in doom-debug-mode
;; TODO Implement `+lsp-defer-shutdown'
(use-package! eglot
:commands eglot eglot-ensure
:hook (eglot-managed-mode . +lsp-init-optimizations-h)
@ -16,11 +13,32 @@
eglot-auto-display-help-buffer nil)
:config
(set-popup-rule! "^\\*eglot-help" :size 0.35 :quit t :select t)
(set-popup-rule! "^\\*eglot-help" :size 0.15 :quit t :select t)
(set-lookup-handlers! 'eglot--managed-mode
:implementations #'eglot-find-implementation
:type-definition #'eglot-find-typeDefinition
:documentation #'+eglot/documentation-lookup-handler)
:documentation #'+eglot-lookup-documentation)
(add-to-list 'doom-debug-variables '(eglot-events-buffer-size . 0))
(when (featurep! :checkers syntax)
(after! flycheck
(load! "autoload/flycheck-eglot"))))
(load! "autoload/flycheck-eglot")))
(defadvice! +lsp--defer-server-shutdown-a (orig-fn &optional server)
"Defer server shutdown for a few seconds.
This gives the user a chance to open other project files before the server is
auto-killed (which is a potentially expensive process). It also prevents the
server getting expensively restarted when reverting buffers."
:around #'eglot--managed-mode
(letf! (defun eglot-shutdown (server)
(if (or (null +lsp-defer-shutdown)
(eq +lsp-defer-shutdown 0))
(funcall eglot-shutdown server)
(run-at-time
(if (numberp +lsp-defer-shutdown) +lsp-defer-shutdown 3)
nil (lambda (server)
(unless (eglot--managed-buffers server)
(funcall eglot-shutdown server)))
server)))
(funcall orig-fn server))))

View file

@ -44,6 +44,8 @@ should be a deliberate act (as is flipping this variable).")
lsp-enable-on-type-formatting nil)
:config
(pushnew! doom-debug-variables 'lsp-log-io 'lsp-print-performance)
(setq lsp-intelephense-storage-path (concat doom-cache-dir "lsp-intelephense/")
lsp-vetur-global-snippets-dir (expand-file-name "vetur"
(or (bound-and-true-p +snippets-dir)

View file

@ -9,11 +9,31 @@ Example : (set-eglot-client! 'python-mode `(,(concat doom-etc-dir \"lsp/mspyls/M
(after! eglot
(add-to-list 'eglot-server-programs `(,mode . ,server-call))))
;; HACK Eglot removed `eglot-help-at-point' in joaotavora/eglot@a044dec for a
;; more problematic approach of deferred to eldoc. Here, I've restored it.
;; Doom's lookup handlers try to open documentation in a separate window
;; (so they can be copied or kept open), but doing so with an eldoc buffer
;; is difficult because a) its contents are generated asynchronously,
;; making them tough to scrape, and b) their contents change frequently
;; (every time you move your cursor).
(defvar +eglot--help-buffer nil)
;;;###autoload
(defun +eglot/documentation-lookup-handler ()
"Documentation lookup handler using eglot :document/hover handler.
Mostly a rewrite of `eglot-help-at-point', which should be used interactively."
(interactive)
(eglot-help-at-point)
(display-buffer eglot--help-buffer))
(defun +eglot-lookup-documentation (_identifier)
"Request documentation for the thing at point."
(eglot--dbind ((Hover) contents range)
(jsonrpc-request (eglot--current-server-or-lose) :textDocument/hover
(eglot--TextDocumentPositionParams))
(let ((blurb (and (not (seq-empty-p contents))
(eglot--hover-info contents range)))
(hint (thing-at-point 'symbol)))
(if blurb
(with-current-buffer
(or (and (buffer-live-p +eglot--help-buffer)
+eglot--help-buffer)
(setq +eglot--help-buffer (generate-new-buffer "*eglot-help*")))
(with-help-window (current-buffer)
(rename-buffer (format "*eglot-help for %s*" hint))
(with-current-buffer standard-output (insert blurb))
(setq-local nobreak-char-display nil)))
(display-local-help))))
'deferred)

View file

@ -18,6 +18,8 @@ For example, diffs and log buffers. Accepts `left', `right', `up', and `down'.")
transient-values-file (concat doom-etc-dir "transient/values")
transient-history-file (concat doom-etc-dir "transient/history"))
:config
(add-to-list 'doom-debug-variables 'magit-refresh-verbose)
(setq transient-default-level 5
magit-diff-refine-hunk t ; show granular diffs in selected hunk
;; Don't autosave repo buffers. This is too magical, and saving can