dev: merge branch 'master' of github.com:doomemacs
This commit is contained in:
commit
a2ae771393
36 changed files with 792 additions and 241 deletions
2
bin/doom
2
bin/doom
|
@ -164,7 +164,7 @@ EXIT CODES:
|
||||||
5 Invalid, missing, or extra options/arguments
|
5 Invalid, missing, or extra options/arguments
|
||||||
6-15 Reserved for Doom
|
6-15 Reserved for Doom
|
||||||
16-192 Reserved for the user's extensions
|
16-192 Reserved for the user's extensions
|
||||||
254 Successful run (but then execute `doom-cli-restart-script')
|
254 Successful run (then execute the dynamically generated after-script)
|
||||||
255 Uncaught critical errors
|
255 Uncaught critical errors
|
||||||
|
|
||||||
SEE ALSO:
|
SEE ALSO:
|
||||||
|
|
|
@ -22,7 +22,16 @@ fi
|
||||||
|
|
||||||
case "$EMACS" in
|
case "$EMACS" in
|
||||||
*term*) EMACS=emacs ;; # in {ansi-,v}term
|
*term*) EMACS=emacs ;; # in {ansi-,v}term
|
||||||
*) EMACS="${EMACS:-emacs}" ;;
|
*\ *) ;;
|
||||||
|
*) EMACS="${EMACS:-emacs}"
|
||||||
|
# Only sanity-check $EMACS if it's a path or executable
|
||||||
|
if ! type "$EMACS" >/dev/null 2>&1; then
|
||||||
|
echo "Error: failed to run Emacs with command '$EMACS'"
|
||||||
|
echo
|
||||||
|
echo "Are you sure Emacs is installed and in your \$PATH?"
|
||||||
|
exit 1
|
||||||
|
fi >&2
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# Careful not to use -Q! It implies --no-site-lisp, which omits the site-lisp
|
# Careful not to use -Q! It implies --no-site-lisp, which omits the site-lisp
|
||||||
|
@ -31,17 +40,6 @@ esac
|
||||||
# (like Snap or NixOS).
|
# (like Snap or NixOS).
|
||||||
emacs="$EMACS -q --no-site-file --batch"
|
emacs="$EMACS -q --no-site-file --batch"
|
||||||
|
|
||||||
# $TMPDIR (or $TEMP and $TMP on Windows) aren't guaranteed to have values, and
|
|
||||||
# mktemp isn't available on all systems, but you know what is? Emacs! So I rely
|
|
||||||
# on it to provide TMPDIR. And can second as a quick existence check for Emacs.
|
|
||||||
TMPDIR="${TMPDIR:-$($emacs --eval '(princ (temporary-file-directory))' 2>/dev/null)}"
|
|
||||||
if [ -z "$TMPDIR" ]; then
|
|
||||||
echo "Error: failed to run Emacs with command '$EMACS'"
|
|
||||||
echo
|
|
||||||
echo "Are you sure Emacs is installed and in your \$PATH?"
|
|
||||||
exit 1
|
|
||||||
fi >&2
|
|
||||||
|
|
||||||
# Doom respects $EMACSDIR to tell it where Doom lives. If it fails, then this is
|
# Doom respects $EMACSDIR to tell it where Doom lives. If it fails, then this is
|
||||||
# either isn't bash, or it's a posix shell being directly sourced with sh, which
|
# either isn't bash, or it's a posix shell being directly sourced with sh, which
|
||||||
# is unsupported.
|
# is unsupported.
|
||||||
|
@ -79,6 +77,11 @@ exit=$?
|
||||||
# To simulate execve syscalls (which replaces the running process), Doom
|
# To simulate execve syscalls (which replaces the running process), Doom
|
||||||
# generates a temporary exit-script if a Doomscript returns a 254 exit code.
|
# generates a temporary exit-script if a Doomscript returns a 254 exit code.
|
||||||
if [ "${exit:-0}" -eq 254 ]; then
|
if [ "${exit:-0}" -eq 254 ]; then
|
||||||
|
# $TMPDIR (or $TEMP and $TMP on Windows) aren't guaranteed to have values,
|
||||||
|
# and mktemp isn't available on all systems, but you know what is? Emacs! So
|
||||||
|
# I rely on it to provide TMPDIR.
|
||||||
|
export TMPDIR="${TMPDIR:-${TMP:-${TEMP:-$($emacs -Q --eval '(princ (temporary-file-directory))' 2>/dev/null)}}}"
|
||||||
|
|
||||||
# The user may have a noexec flag set on /tmp, so the exit-script should be
|
# The user may have a noexec flag set on /tmp, so the exit-script should be
|
||||||
# passed to /bin/sh rather than executed directly.
|
# passed to /bin/sh rather than executed directly.
|
||||||
sh "${TMPDIR}/doom.${__DOOMPID}.${__DOOMSTEP}.sh" "$0" "$@"
|
sh "${TMPDIR}/doom.${__DOOMPID}.${__DOOMSTEP}.sh" "$0" "$@"
|
||||||
|
|
|
@ -105,16 +105,15 @@
|
||||||
;; To reduce that burden -- and since Doom doesn't load any dynamic modules
|
;; To reduce that burden -- and since Doom doesn't load any dynamic modules
|
||||||
;; this early -- I remove `.so' from `load-suffixes' and pass the
|
;; this early -- I remove `.so' from `load-suffixes' and pass the
|
||||||
;; `must-suffix' arg to `load'. See the docs of `load' for details.
|
;; `must-suffix' arg to `load'. See the docs of `load' for details.
|
||||||
(if (let ((load-suffixes '(".elc" ".el")))
|
(if (let ((load-suffixes '(".elc" ".el"))
|
||||||
|
(doom-file (expand-file-name "lisp/doom" user-emacs-directory)))
|
||||||
;; I avoid `load's NOERROR argument because it suppresses other,
|
;; I avoid `load's NOERROR argument because it suppresses other,
|
||||||
;; legitimate errors (like permission or IO errors), which gets
|
;; legitimate errors (like permission or IO errors), which gets
|
||||||
;; incorrectly interpreted as "this is not a Doom config".
|
;; incorrectly interpreted as "this is not a Doom config".
|
||||||
(condition-case-unless-debug _
|
(if (file-exists-p (concat doom-file ".el"))
|
||||||
;; Load the heart of Doom Emacs.
|
;; Load the heart of Doom Emacs.
|
||||||
(load (expand-file-name "lisp/doom" user-emacs-directory)
|
(load doom-file nil (not init-file-debug) nil 'must-suffix)
|
||||||
nil (not init-file-debug) nil 'must-suffix)
|
;; Failing that, assume we're loading a non-Doom config...
|
||||||
;; Failing that, assume that we're loading a non-Doom config.
|
|
||||||
(file-missing
|
|
||||||
;; HACK: `startup--load-user-init-file' resolves $EMACSDIR from a
|
;; HACK: `startup--load-user-init-file' resolves $EMACSDIR from a
|
||||||
;; lexical (and so, not-trivially-modifiable)
|
;; lexical (and so, not-trivially-modifiable)
|
||||||
;; `startup-init-directory', so Emacs will fail to locate the
|
;; `startup-init-directory', so Emacs will fail to locate the
|
||||||
|
@ -122,21 +121,21 @@
|
||||||
(define-advice startup--load-user-init-file (:filter-args (args) reroute-to-profile)
|
(define-advice startup--load-user-init-file (:filter-args (args) reroute-to-profile)
|
||||||
(list (lambda () (expand-file-name "init.el" user-emacs-directory))
|
(list (lambda () (expand-file-name "init.el" user-emacs-directory))
|
||||||
nil (nth 2 args)))
|
nil (nth 2 args)))
|
||||||
;; (Re)set `user-init-file' for the `load' call further below, and
|
;; (Re)set `user-init-file' for the `load' call further below, and do
|
||||||
;; do so here while our `file-name-handler-alist' optimization is
|
;; so here while our `file-name-handler-alist' optimization is still
|
||||||
;; still effective (benefits `expand-file-name'). BTW: Emacs resets
|
;; effective (benefits `expand-file-name'). BTW: Emacs resets
|
||||||
;; `user-init-file' and `early-init-file' after this file is loaded.
|
;; `user-init-file' and `early-init-file' after this file is loaded.
|
||||||
(setq user-init-file (expand-file-name "early-init" user-emacs-directory))
|
(setq user-init-file (expand-file-name "early-init" user-emacs-directory))
|
||||||
;; COMPAT: I make no assumptions about the config we're going to
|
;; COMPAT: I make no assumptions about the config we're going to
|
||||||
;; load, so undo this file's global side-effects.
|
;; load, so undo this file's global side-effects.
|
||||||
(setq load-prefer-newer t)
|
(setq load-prefer-newer t)
|
||||||
;; PERF: But make an exception for `gc-cons-threshold', which I
|
;; PERF: But make an exception for `gc-cons-threshold', which I think
|
||||||
;; think all Emacs users and configs will benefit from. Still,
|
;; all Emacs users and configs will benefit from. Still, setting it
|
||||||
;; setting it to `most-positive-fixnum' is dangerous if downstream
|
;; to `most-positive-fixnum' is dangerous if downstream does not
|
||||||
;; does not reset it later to something reasonable, so I use 16mb
|
;; reset it later to something reasonable, so I use 16mb as a best
|
||||||
;; as a best fit guess. It's better than Emacs' 80kb default.
|
;; fit guess. It's better than Emacs' 80kb default.
|
||||||
(setq gc-cons-threshold (* 16 1024 1024))
|
(setq gc-cons-threshold (* 16 1024 1024))
|
||||||
nil)))
|
nil))
|
||||||
;; ...Otherwise, we're loading a Doom config, so continue as normal.
|
;; ...Otherwise, we're loading a Doom config, so continue as normal.
|
||||||
(doom-require (if noninteractive 'doom-cli 'doom-start))))
|
(doom-require (if noninteractive 'doom-cli 'doom-start))))
|
||||||
|
|
||||||
|
|
|
@ -51,18 +51,20 @@ performance, it is best to run Doom out of ~/.config/emacs or ~/.emacs.d."
|
||||||
;; configs, or binscripts, we symlink these to the sandbox.
|
;; configs, or binscripts, we symlink these to the sandbox.
|
||||||
;; REVIEW: Use `--init-directory' when we drop 29 support OR when Doom is
|
;; REVIEW: Use `--init-directory' when we drop 29 support OR when Doom is
|
||||||
;; in bootloader mode.
|
;; in bootloader mode.
|
||||||
(dolist (dir (list (or (getenv "XDG_DATA_HOME") "~/.local/share")
|
(dolist (dir (list (cons "XDG_DATA_HOME" ".local/share")
|
||||||
(or (getenv "XDG_BIN_HOME") "~/.local/bin")
|
(cons "XDG_STATE_HOME" ".local/state")
|
||||||
(or (getenv "XDG_CONFIG_HOME") "~/.config")
|
(cons "XDG_BIN_HOME" ".local/bin")
|
||||||
(or (getenv "XDG_CACHE_HOME") "~/.cache")))
|
(cons "XDG_CONFIG_HOME" ".config")
|
||||||
(let* ((xdg-dir (doom-path dir))
|
(cons "XDG_CACHE_HOME" ".cache")))
|
||||||
(target (doom-path tempdir (file-relative-name xdg-dir "~"))))
|
(let* ((source (expand-file-name (or (getenv (car dir)) (expand-file-name (cdr dir) "~"))))
|
||||||
(when (file-directory-p xdg-dir)
|
(target (expand-file-name (cdr dir) tempdir)))
|
||||||
|
(when (file-directory-p source)
|
||||||
(unless (file-symlink-p target)
|
(unless (file-symlink-p target)
|
||||||
(make-directory (file-name-directory target) t)
|
(make-directory (file-name-directory target) t)
|
||||||
(make-symbolic-link xdg-dir target)))))
|
(make-symbolic-link source target)))))
|
||||||
(with-temp-file (doom-path tempemacsdir "early-init.el")
|
(with-temp-file (doom-path tempemacsdir "early-init.el")
|
||||||
(prin1 `(progn
|
(prin1 `(progn
|
||||||
|
;; Restore sane values for these envvars
|
||||||
(setenv "HOME" ,(getenv "HOME"))
|
(setenv "HOME" ,(getenv "HOME"))
|
||||||
(setenv "EMACSDIR" ,doom-emacs-dir)
|
(setenv "EMACSDIR" ,doom-emacs-dir)
|
||||||
(setenv "DOOMDIR" ,doom-user-dir)
|
(setenv "DOOMDIR" ,doom-user-dir)
|
||||||
|
|
|
@ -361,6 +361,71 @@ Or to create aliases for functions that behave differently:
|
||||||
(:baz hello :boop nil)
|
(:baz hello :boop nil)
|
||||||
(:bar 42)))
|
(:bar 42)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
* letf!
|
||||||
|
:PROPERTIES:
|
||||||
|
:added: 3.0.0-pre
|
||||||
|
:END:
|
||||||
|
#+begin_src emacs-lisp :eval yes
|
||||||
|
(letf! (defun greet (name)
|
||||||
|
(message "Hello %s" name))
|
||||||
|
(greet "Doom")) ; #=> Hello Doom
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: Hello Doom
|
||||||
|
|
||||||
|
Multiple definitions:
|
||||||
|
#+begin_src emacs-lisp :eval yes :results output
|
||||||
|
(letf! ((defun greet (name)
|
||||||
|
(princ (format "Hello %s" name))
|
||||||
|
(terpri))
|
||||||
|
(defun destroy (name)
|
||||||
|
(princ (format "Blood for the %s god!" name))
|
||||||
|
(terpri)))
|
||||||
|
(greet "Doom")
|
||||||
|
(destroy "Doom"))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: Hello Doom
|
||||||
|
: Blood for the Doom god!
|
||||||
|
|
||||||
|
If defining an already-existing function, the old definition will be bound to a
|
||||||
|
variable by the same name:
|
||||||
|
#+begin_src emacs-lisp :eval yes :results output
|
||||||
|
(letf! (defun princ (str)
|
||||||
|
(funcall princ (format "[overwritten] %s" str)))
|
||||||
|
(princ "Doom Emacs"))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: [overwritten] Doom Emacs
|
||||||
|
|
||||||
|
Defining temporary advice:
|
||||||
|
#+begin_src emacs-lisp :eval yes
|
||||||
|
(letf! ((defun advised-message (fn message &rest args)
|
||||||
|
(apply fn (concat "[advised (1)] " message) args))
|
||||||
|
(defadvice #'message :around #'advised-message)
|
||||||
|
(defadvice message (:around (fn message &rest args))
|
||||||
|
(apply fn (concat "[advised (2)] " message) args)))
|
||||||
|
(message "Hello world"))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: [advised (1)] [advised (2)] Hello world
|
||||||
|
|
||||||
|
Calling "lexical" functions recursively:
|
||||||
|
#+begin_src emacs-lisp :eval yes
|
||||||
|
(letf! (defun* triangle (number)
|
||||||
|
(cond ((<= number 0) 0)
|
||||||
|
((= number 1) 1)
|
||||||
|
((> number 1)
|
||||||
|
(+ number (triangle (1- number))))))
|
||||||
|
(triangle 5))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: 15
|
||||||
|
|
||||||
* load!
|
* load!
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
|
|
|
@ -1877,7 +1877,6 @@ errors to `doom-cli-error-file')."
|
||||||
(error "Cannot nest `run!' calls"))
|
(error "Cannot nest `run!' calls"))
|
||||||
(doom-run-hooks 'doom-after-init-hook)
|
(doom-run-hooks 'doom-after-init-hook)
|
||||||
(doom-context-with 'cli
|
(doom-context-with 'cli
|
||||||
;; (doom-modules-initialize)
|
|
||||||
(let* ((args (flatten-list args))
|
(let* ((args (flatten-list args))
|
||||||
(context (make-doom-cli-context :prefix prefix :whole args))
|
(context (make-doom-cli-context :prefix prefix :whole args))
|
||||||
(doom-cli--context context)
|
(doom-cli--context context)
|
||||||
|
|
105
lisp/doom-lib.el
105
lisp/doom-lib.el
|
@ -7,6 +7,7 @@
|
||||||
(define-error 'doom-font-error "Could not find a font on your system" 'doom-error)
|
(define-error 'doom-font-error "Could not find a font on your system" 'doom-error)
|
||||||
(define-error 'doom-nosync-error "Doom hasn't been initialized yet; did you remember to run 'doom sync' in the shell?" 'doom-error)
|
(define-error 'doom-nosync-error "Doom hasn't been initialized yet; did you remember to run 'doom sync' in the shell?" 'doom-error)
|
||||||
(define-error 'doom-core-error "Unexpected error in Doom's core" 'doom-error)
|
(define-error 'doom-core-error "Unexpected error in Doom's core" 'doom-error)
|
||||||
|
(define-error 'doom-context-error "Incorrect context error" 'doom-error)
|
||||||
(define-error 'doom-hook-error "Error in a Doom startup hook" 'doom-error)
|
(define-error 'doom-hook-error "Error in a Doom startup hook" 'doom-error)
|
||||||
(define-error 'doom-autoload-error "Error in Doom's autoloads file" 'doom-error)
|
(define-error 'doom-autoload-error "Error in Doom's autoloads file" 'doom-error)
|
||||||
(define-error 'doom-user-error "Error caused by user's config or system" 'doom-error)
|
(define-error 'doom-user-error "Error caused by user's config or system" 'doom-error)
|
||||||
|
@ -19,10 +20,27 @@
|
||||||
;;; Logging
|
;;; Logging
|
||||||
|
|
||||||
(defvar doom-inhibit-log (not (or noninteractive init-file-debug))
|
(defvar doom-inhibit-log (not (or noninteractive init-file-debug))
|
||||||
"If non-nil, suppress `doom-log' output.")
|
"If non-nil, suppress `doom-log' output completely.")
|
||||||
|
|
||||||
(defun doom--log (text &rest args)
|
(defvar doom-log-level
|
||||||
(let ((inhibit-message (not init-file-debug))
|
(if init-file-debug
|
||||||
|
(if-let ((level (getenv-internal "DEBUG"))
|
||||||
|
(level (string-to-number level))
|
||||||
|
((not (zerop level))))
|
||||||
|
level
|
||||||
|
2)
|
||||||
|
0)
|
||||||
|
"How verbosely to log from `doom-log' calls.
|
||||||
|
|
||||||
|
0 -- No logging at all.
|
||||||
|
1 -- Only warnings.
|
||||||
|
2 -- Warnings and notices.
|
||||||
|
3 -- Debug info, warnings, and notices.")
|
||||||
|
|
||||||
|
(defun doom--log (level text &rest args)
|
||||||
|
(let ((inhibit-message (if noninteractive
|
||||||
|
(not init-file-debug)
|
||||||
|
(> level doom-log-level)))
|
||||||
(absolute? (string-prefix-p ":" text)))
|
(absolute? (string-prefix-p ":" text)))
|
||||||
(apply #'message
|
(apply #'message
|
||||||
(propertize (concat "* %.06f:%s" (if (not absolute?) ":") text)
|
(propertize (concat "* %.06f:%s" (if (not absolute?) ":") text)
|
||||||
|
@ -38,14 +56,19 @@
|
||||||
":")
|
":")
|
||||||
args)))
|
args)))
|
||||||
|
|
||||||
|
;; This is a macro instead of a function to prevent the potentially expensive
|
||||||
|
;; evaluation of its arguments when debug mode is off. Return non-nil.
|
||||||
(defmacro doom-log (message &rest args)
|
(defmacro doom-log (message &rest args)
|
||||||
"Log a message in *Messages*.
|
"Log a message to stderr or *Messages* (without displaying in the echo area)."
|
||||||
|
|
||||||
Does not emit the message in the echo area. This is a macro instead of a
|
|
||||||
function to prevent the potentially expensive evaluation of its arguments when
|
|
||||||
debug mode is off. Return non-nil."
|
|
||||||
(declare (debug t))
|
(declare (debug t))
|
||||||
`(unless doom-inhibit-log (doom--log ,message ,@args)))
|
(let ((level (if (integerp message)
|
||||||
|
(prog1 message
|
||||||
|
(setq message (pop args)))
|
||||||
|
2)))
|
||||||
|
`(when (and (not doom-inhibit-log)
|
||||||
|
(or (not noninteractive)
|
||||||
|
(<= ,level doom-log-level)))
|
||||||
|
(doom--log ,level ,message ,@args))))
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
@ -290,13 +313,12 @@ TRIGGER-HOOK is a list of quoted hooks and/or sharp-quoted functions."
|
||||||
|
|
||||||
(defmacro file! ()
|
(defmacro file! ()
|
||||||
"Return the file of the file this macro was called."
|
"Return the file of the file this macro was called."
|
||||||
(or
|
(or (bound-and-true-p byte-compile-current-file)
|
||||||
|
load-file-name
|
||||||
|
(buffer-file-name (buffer-base-buffer)) ; for `eval'
|
||||||
;; REVIEW: Use `macroexp-file-name' once 27 support is dropped.
|
;; REVIEW: Use `macroexp-file-name' once 27 support is dropped.
|
||||||
(let ((file (car (last current-load-list))))
|
(let ((file (car (last current-load-list))))
|
||||||
(if (stringp file) file))
|
(if (stringp file) file))
|
||||||
(bound-and-true-p byte-compile-current-file)
|
|
||||||
load-file-name
|
|
||||||
buffer-file-name ; for `eval'
|
|
||||||
(error "file!: cannot deduce the current file path")))
|
(error "file!: cannot deduce the current file path")))
|
||||||
|
|
||||||
(defmacro dir! ()
|
(defmacro dir! ()
|
||||||
|
@ -311,24 +333,26 @@ TRIGGER-HOOK is a list of quoted hooks and/or sharp-quoted functions."
|
||||||
"Temporarily rebind function, macros, and advice in BODY.
|
"Temporarily rebind function, macros, and advice in BODY.
|
||||||
|
|
||||||
Intended as syntax sugar for `cl-letf', `cl-labels', `cl-macrolet', and
|
Intended as syntax sugar for `cl-letf', `cl-labels', `cl-macrolet', and
|
||||||
temporary advice.
|
temporary advice (`define-advice').
|
||||||
|
|
||||||
BINDINGS is either:
|
BINDINGS is either:
|
||||||
|
|
||||||
A list of, or a single, `defun', `defun*', `defmacro', or `defadvice' forms.
|
|
||||||
A list of (PLACE VALUE) bindings as `cl-letf*' would accept.
|
A list of (PLACE VALUE) bindings as `cl-letf*' would accept.
|
||||||
|
A list of, or a single, `defun', `defun*', `defmacro', or `defadvice' forms.
|
||||||
|
|
||||||
TYPE is one of:
|
The def* forms accepted are:
|
||||||
|
|
||||||
`defun' (uses `cl-letf')
|
(defun NAME (ARGS...) &rest BODY)
|
||||||
`defun*' (uses `cl-labels'; allows recursive references),
|
Defines a temporary function with `cl-letf'
|
||||||
`defmacro' (uses `cl-macrolet')
|
(defun* NAME (ARGS...) &rest BODY)
|
||||||
`defadvice' (uses `defadvice!' before BODY, then `undefadvice!' after)
|
Defines a temporary function with `cl-labels' (allows recursive
|
||||||
|
definitions).
|
||||||
NAME, ARGLIST, and BODY are the same as `defun', `defun*', `defmacro', and
|
(defmacro NAME (ARGS...) &rest BODY)
|
||||||
`defadvice!', respectively.
|
Uses `cl-macrolet'.
|
||||||
|
(defadvice FUNCTION WHERE ADVICE)
|
||||||
\(fn ((TYPE NAME ARGLIST &rest BODY) ...) BODY...)"
|
Uses `advice-add' (then `advice-remove' afterwards).
|
||||||
|
(defadvice FUNCTION (HOW LAMBDA-LIST &optional NAME DEPTH) &rest BODY)
|
||||||
|
Defines temporary advice with `define-advice'."
|
||||||
(declare (indent defun))
|
(declare (indent defun))
|
||||||
(setq body (macroexp-progn body))
|
(setq body (macroexp-progn body))
|
||||||
(when (memq (car bindings) '(defun defun* defmacro defadvice))
|
(when (memq (car bindings) '(defun defun* defmacro defadvice))
|
||||||
|
@ -339,16 +363,33 @@ NAME, ARGLIST, and BODY are the same as `defun', `defun*', `defmacro', and
|
||||||
(setq
|
(setq
|
||||||
body (pcase type
|
body (pcase type
|
||||||
(`defmacro `(cl-macrolet ((,@rest)) ,body))
|
(`defmacro `(cl-macrolet ((,@rest)) ,body))
|
||||||
(`defadvice `(progn (defadvice! ,@rest)
|
(`defadvice
|
||||||
(unwind-protect ,body (undefadvice! ,@rest))))
|
(if (keywordp (cadr rest))
|
||||||
((or `defun `defun*)
|
(cl-destructuring-bind (target where fn) rest
|
||||||
|
`(when-let (fn ,fn)
|
||||||
|
(advice-add ,target ,where fn)
|
||||||
|
(unwind-protect ,body (advice-remove ,target fn))))
|
||||||
|
(let* ((fn (pop rest))
|
||||||
|
(argspec (pop rest)))
|
||||||
|
(when (< (length argspec) 3)
|
||||||
|
(setq argspec
|
||||||
|
(list (nth 0 argspec)
|
||||||
|
(nth 1 argspec)
|
||||||
|
(or (nth 2 argspec) (gensym (format "%s-a" (symbol-name fn)))))))
|
||||||
|
(let ((name (nth 2 argspec)))
|
||||||
|
`(progn
|
||||||
|
(define-advice ,fn ,argspec ,@rest)
|
||||||
|
(unwind-protect ,body
|
||||||
|
(advice-remove #',fn #',name)
|
||||||
|
,(if name `(fmakunbound ',name))))))))
|
||||||
|
(`defun
|
||||||
`(cl-letf ((,(car rest) (symbol-function #',(car rest))))
|
`(cl-letf ((,(car rest) (symbol-function #',(car rest))))
|
||||||
(ignore ,(car rest))
|
(ignore ,(car rest))
|
||||||
,(if (eq type 'defun*)
|
(cl-letf (((symbol-function #',(car rest))
|
||||||
`(cl-labels ((,@rest)) ,body)
|
|
||||||
`(cl-letf (((symbol-function #',(car rest))
|
|
||||||
(lambda! ,(cadr rest) ,@(cddr rest))))
|
(lambda! ,(cadr rest) ,@(cddr rest))))
|
||||||
,body))))
|
,body)))
|
||||||
|
(`defun*
|
||||||
|
`(cl-labels ((,@rest)) ,body))
|
||||||
(_
|
(_
|
||||||
(when (eq (car-safe type) 'function)
|
(when (eq (car-safe type) 'function)
|
||||||
(setq type (list 'symbol-function type)))
|
(setq type (list 'symbol-function type)))
|
||||||
|
|
|
@ -50,7 +50,7 @@ NOT IMPLEMENTED YET. This file contains a module's metadata: their version,
|
||||||
maintainers, checks, features, submodules, debug information, etc. And are used
|
maintainers, checks, features, submodules, debug information, etc. And are used
|
||||||
to locate modules in the user's file tree.")
|
to locate modules in the user's file tree.")
|
||||||
|
|
||||||
;; DEPRECATED: Module warnings will be rewritten in v3, and this variable will no longer be needed.
|
;; DEPRECATED: Remove in v3, as it will be handled in the CLI
|
||||||
(make-obsolete-variable 'doom-obsolete-modules nil "3.0.0")
|
(make-obsolete-variable 'doom-obsolete-modules nil "3.0.0")
|
||||||
(defconst doom-obsolete-modules
|
(defconst doom-obsolete-modules
|
||||||
'((:feature (version-control (:emacs vc) (:ui vc-gutter))
|
'((:feature (version-control (:emacs vc) (:ui vc-gutter))
|
||||||
|
|
|
@ -143,11 +143,6 @@
|
||||||
(setq selection-coding-system 'utf-8))
|
(setq selection-coding-system 'utf-8))
|
||||||
|
|
||||||
|
|
||||||
;;; Support for Doom-specific file extensions
|
|
||||||
(add-to-list 'auto-mode-alist '("/\\.doom\\(?:project\\|module\\|profile\\)\\'" . lisp-data-mode))
|
|
||||||
(add-to-list 'auto-mode-alist '("/\\.doomrc\\'" . emacs-lisp-mode))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;;; MODE-local-vars-hook
|
;;; MODE-local-vars-hook
|
||||||
|
|
||||||
|
@ -339,9 +334,8 @@ If RETURN-P, return the message as a string instead of displaying it."
|
||||||
;; TODO: Catch errors
|
;; TODO: Catch errors
|
||||||
(load! (string-remove-suffix ".el" doom-module-init-file) doom-user-dir t)
|
(load! (string-remove-suffix ".el" doom-module-init-file) doom-user-dir t)
|
||||||
|
|
||||||
;;; Load the rest of $DOOMDIR + modules if noninteractive
|
|
||||||
;; If the user is loading this file from a batch script, let's assume they want
|
;; If the user is loading this file from a batch script, let's assume they want
|
||||||
;; to load their userland config as well.
|
;; to load their userland config immediately.
|
||||||
(when noninteractive
|
(when noninteractive
|
||||||
(doom-require 'doom-profiles)
|
(doom-require 'doom-profiles)
|
||||||
(let ((init-file (doom-profile-init-file)))
|
(let ((init-file (doom-profile-init-file)))
|
||||||
|
@ -353,6 +347,7 @@ If RETURN-P, return the message as a string instead of displaying it."
|
||||||
(doom-load init-file 'noerror)
|
(doom-load init-file 'noerror)
|
||||||
(doom-initialize-packages))))
|
(doom-initialize-packages))))
|
||||||
|
|
||||||
|
|
||||||
;;; Entry point
|
;;; Entry point
|
||||||
;; HACK: This advice hijacks Emacs' initfile loader to accomplish the following:
|
;; HACK: This advice hijacks Emacs' initfile loader to accomplish the following:
|
||||||
;;
|
;;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;; doom-ui.el --- defaults for Doom's aesthetics -*- lexical-binding: t; -*-
|
;;; doom-ui.el --- defaults for Doom's aesthetics -*- lexical-binding: t; -*-
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
;;; Code;
|
;;; Code:
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;;; Variables
|
;;; Variables
|
||||||
|
@ -590,10 +590,18 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
||||||
(put 'doom-theme 'previous-themes (or last-themes 'none))
|
(put 'doom-theme 'previous-themes (or last-themes 'none))
|
||||||
;; DEPRECATED Hook into `enable-theme-functions' when we target 29
|
;; DEPRECATED Hook into `enable-theme-functions' when we target 29
|
||||||
(doom-run-hooks 'doom-load-theme-hook)
|
(doom-run-hooks 'doom-load-theme-hook)
|
||||||
(when-let* ((fg (face-foreground 'default nil t))
|
;; Fix incorrect fg/bg in new frames created after the initial frame
|
||||||
(bg (face-background 'default nil t)))
|
;; (which are reroneously displayed as black).
|
||||||
(setf (alist-get 'foreground-color default-frame-alist) fg
|
(pcase-dolist (`(,param ,fn ,face)
|
||||||
(alist-get 'background-color default-frame-alist) bg)))))))
|
'((foreground-color face-foreground default)
|
||||||
|
(background-color face-background default)
|
||||||
|
(cursor-color face-background cursor)
|
||||||
|
(border-color face-background border)
|
||||||
|
(mouse-color face-background mouse)))
|
||||||
|
(when-let* ((color (funcall fn face nil t))
|
||||||
|
((stringp color))
|
||||||
|
((not (string-prefix-p "unspecified-" color))))
|
||||||
|
(setf (alist-get param default-frame-alist) color))))))))
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
@ -657,11 +665,11 @@ triggering hooks during startup."
|
||||||
(fset 'set-fontset-font #'ignore))
|
(fset 'set-fontset-font #'ignore))
|
||||||
|
|
||||||
(after! whitespace
|
(after! whitespace
|
||||||
(defun doom-is-childframes-p ()
|
(defun doom--in-parent-frame-p ()
|
||||||
"`whitespace-mode' inundates child frames with whitespace markers, so
|
"`whitespace-mode' inundates child frames with whitespace markers, so
|
||||||
disable it to fix all that visual noise."
|
disable it to fix all that visual noise."
|
||||||
(null (frame-parameter nil 'parent-frame)))
|
(null (frame-parameter nil 'parent-frame)))
|
||||||
(add-function :before-while whitespace-enable-predicate #'doom-is-childframes-p))
|
(add-function :before-while whitespace-enable-predicate #'doom--in-parent-frame-p))
|
||||||
|
|
||||||
(provide 'doom-ui)
|
(provide 'doom-ui)
|
||||||
;;; doom-ui.el ends here
|
;;; doom-ui.el ends here
|
||||||
|
|
49
lisp/doom.el
49
lisp/doom.el
|
@ -54,7 +54,8 @@
|
||||||
;; - hook: `window-setup-hook'
|
;; - hook: `window-setup-hook'
|
||||||
;; - hook: `doom-init-ui-hook'
|
;; - hook: `doom-init-ui-hook'
|
||||||
;; - hook: `doom-after-init-hook'
|
;; - hook: `doom-after-init-hook'
|
||||||
;; > After startup is complete:
|
;; > After startup is complete (if file(s) have been opened from the command
|
||||||
|
;; line, these will trigger much earlier):
|
||||||
;; - On first input: `doom-first-input-hook'
|
;; - On first input: `doom-first-input-hook'
|
||||||
;; - On first switched-to buffer: `doom-first-buffer-hook'
|
;; - On first switched-to buffer: `doom-first-buffer-hook'
|
||||||
;; - On first opened file: `doom-first-file-hook'
|
;; - On first opened file: `doom-first-file-hook'
|
||||||
|
@ -374,13 +375,13 @@ users).")
|
||||||
(let ((old-value (default-toplevel-value 'file-name-handler-alist)))
|
(let ((old-value (default-toplevel-value 'file-name-handler-alist)))
|
||||||
(set-default-toplevel-value
|
(set-default-toplevel-value
|
||||||
'file-name-handler-alist
|
'file-name-handler-alist
|
||||||
;; HACK: The libraries bundled with Emacs can either be compiled,
|
;; HACK: The elisp libraries bundled with Emacs are either compressed or
|
||||||
;; compressed, or neither. We use calc-loaddefs.el as a heuristic to
|
;; not, never both. So if calc-loaddefs.el.gz exists, calc-loaddefs.el
|
||||||
;; guess what state all these libraries are in. If they're compressed, we
|
;; won't, and vice versa. This heuristic is used to guess the state of
|
||||||
;; need to leave the gzip file handler in `file-name-handler-alist' so
|
;; all other built-in (or site); if they're compressed, we must leave the
|
||||||
;; Emacs knows how to load them. If they're compiled or neither, we can
|
;; gzip file handler in `file-name-handler-alist' so Emacs knows how to
|
||||||
;; omit the gzip handler altogether (at least during startup) for a boost
|
;; load them. Otherwise, we can omit it (at least during startup) for a
|
||||||
;; in startup and package load time.
|
;; boost in package load time.
|
||||||
(if (eval-when-compile
|
(if (eval-when-compile
|
||||||
(locate-file-internal "calc-loaddefs.el" load-path))
|
(locate-file-internal "calc-loaddefs.el" load-path))
|
||||||
nil
|
nil
|
||||||
|
@ -469,12 +470,19 @@ users).")
|
||||||
(add-hook! 'doom-before-init-hook
|
(add-hook! 'doom-before-init-hook
|
||||||
(defun doom--reset-custom-dont-initialize-h ()
|
(defun doom--reset-custom-dont-initialize-h ()
|
||||||
(setq custom-dont-initialize nil)))
|
(setq custom-dont-initialize nil)))
|
||||||
|
(define-advice command-line-1 (:around (fn args-left) respect-defcustom-setters)
|
||||||
|
(let ((custom-dont-initialize nil))
|
||||||
|
(funcall fn args-left)))
|
||||||
|
|
||||||
;; PERF: The mode-line procs a couple dozen times during startup, before the
|
;; These optimizations are brittle, difficult to debug, and obscure other
|
||||||
;; user even sees the first mode-line. This is normally fast, but we can't
|
;; issues, so bow out when debug mode is on.
|
||||||
;; predict what the user (or packages) will put into the mode-line. Also,
|
(unless init-file-debug
|
||||||
;; mode-line packages have a bad habit of throwing performance to the
|
;; PERF: The mode-line procs a couple dozen times during startup, before
|
||||||
;; wind, so best we just disable the mode-line until we can see one.
|
;; the user even sees the first mode-line. This is normally fast, but we
|
||||||
|
;; can't predict what the user (or packages) will put into the
|
||||||
|
;; mode-line. Also, mode-line packages have a bad habit of throwing
|
||||||
|
;; performance to the wind, so best we just disable the mode-line until
|
||||||
|
;; we can see one.
|
||||||
(put 'mode-line-format 'initial-value (default-toplevel-value 'mode-line-format))
|
(put 'mode-line-format 'initial-value (default-toplevel-value 'mode-line-format))
|
||||||
(setq-default mode-line-format nil)
|
(setq-default mode-line-format nil)
|
||||||
(dolist (buf (buffer-list))
|
(dolist (buf (buffer-list))
|
||||||
|
@ -490,7 +498,7 @@ users).")
|
||||||
(setq-default inhibit-redisplay nil
|
(setq-default inhibit-redisplay nil
|
||||||
inhibit-message nil)
|
inhibit-message nil)
|
||||||
(remove-hook 'post-command-hook #'doom--reset-inhibited-vars-h))
|
(remove-hook 'post-command-hook #'doom--reset-inhibited-vars-h))
|
||||||
(add-hook 'post-command-hook #'doom--reset-inhibited-vars-h -100)
|
(add-hook 'post-command-hook #'doom--reset-inhibited-vars-h -100))
|
||||||
|
|
||||||
;; PERF: Doom disables the UI elements by default, so that there's less for
|
;; PERF: Doom disables the UI elements by default, so that there's less for
|
||||||
;; the frame to initialize. However, `tool-bar-setup' is still called and
|
;; the frame to initialize. However, `tool-bar-setup' is still called and
|
||||||
|
@ -515,10 +523,11 @@ users).")
|
||||||
(progn
|
(progn
|
||||||
(when (setq site-run-file (get 'site-run-file 'initial-value))
|
(when (setq site-run-file (get 'site-run-file 'initial-value))
|
||||||
(let ((inhibit-startup-screen inhibit-startup-screen))
|
(let ((inhibit-startup-screen inhibit-startup-screen))
|
||||||
(letf! ((defun load-file (file) (load file nil 'nomessage))
|
(letf! ((defun load-file (file)
|
||||||
|
(load file nil (not init-file-debug)))
|
||||||
(defun load (file &optional noerror _nomessage &rest args)
|
(defun load (file &optional noerror _nomessage &rest args)
|
||||||
(apply load file noerror t args)))
|
(apply load file noerror (not init-file-debug) args)))
|
||||||
(load site-run-file t t))))
|
(load site-run-file t))))
|
||||||
(apply fn args))
|
(apply fn args))
|
||||||
;; Now it's safe to be verbose.
|
;; Now it's safe to be verbose.
|
||||||
(setq-default inhibit-message nil)
|
(setq-default inhibit-message nil)
|
||||||
|
@ -762,7 +771,7 @@ appropriately against `noninteractive' or the `cli' context."
|
||||||
;;; Last minute initialization
|
;;; Last minute initialization
|
||||||
|
|
||||||
(when (daemonp)
|
(when (daemonp)
|
||||||
(message "Starting Doom Emacs in daemon mode!")
|
(message "Starting Doom Emacs in daemon mode...")
|
||||||
(unless doom-inhibit-log
|
(unless doom-inhibit-log
|
||||||
(add-hook! 'doom-after-init-hook :depth 106
|
(add-hook! 'doom-after-init-hook :depth 106
|
||||||
(unless doom-inhibit-log
|
(unless doom-inhibit-log
|
||||||
|
@ -783,8 +792,8 @@ appropriately against `noninteractive' or the `cli' context."
|
||||||
(when (doom-context-push 'init)
|
(when (doom-context-push 'init)
|
||||||
;; HACK: Ensure OS checks are as fast as possible (given their ubiquity).
|
;; HACK: Ensure OS checks are as fast as possible (given their ubiquity).
|
||||||
(setq features (cons :system (delq :system features)))
|
(setq features (cons :system (delq :system features)))
|
||||||
;; Remember these variables' initial values, so we can safely reset them at
|
;; Remember these variables' initial values, so we can safely reset them
|
||||||
;; a later time, or consult them without fear of contamination.
|
;; at a later time, or consult them without fear of contamination.
|
||||||
(dolist (var '(exec-path load-path process-environment))
|
(dolist (var '(exec-path load-path process-environment))
|
||||||
(put var 'initial-value (default-toplevel-value var))))))
|
(put var 'initial-value (default-toplevel-value var))))))
|
||||||
|
|
||||||
|
|
|
@ -511,8 +511,8 @@
|
||||||
:desc "Copy link to homepage" "Y" #'+vc/browse-at-remote-kill-homepage
|
:desc "Copy link to homepage" "Y" #'+vc/browse-at-remote-kill-homepage
|
||||||
:desc "Git time machine" "t" #'git-timemachine-toggle
|
:desc "Git time machine" "t" #'git-timemachine-toggle
|
||||||
(:when (modulep! :ui vc-gutter)
|
(:when (modulep! :ui vc-gutter)
|
||||||
:desc "Revert hunk at point" "r" #'+vc-gutter/revert-hunk
|
:desc "Revert hunk at point" "r" #'+vc-gutter/save-and-revert-hunk
|
||||||
:desc "stage hunk at point" "s" #'+vc-gutter/stage-hunk
|
:desc "Stage hunk at point" "s" #'+vc-gutter/stage-hunk
|
||||||
:desc "Jump to next hunk" "]" #'+vc-gutter/next-hunk
|
:desc "Jump to next hunk" "]" #'+vc-gutter/next-hunk
|
||||||
:desc "Jump to previous hunk" "[" #'+vc-gutter/previous-hunk)
|
:desc "Jump to previous hunk" "[" #'+vc-gutter/previous-hunk)
|
||||||
(:when (modulep! :tools magit)
|
(:when (modulep! :tools magit)
|
||||||
|
|
|
@ -181,8 +181,8 @@ This is performed with an asyncronous Emacs process, except when
|
||||||
(defun +literate-recompile-maybe-h ()
|
(defun +literate-recompile-maybe-h ()
|
||||||
"Recompile literate config to `doom-user-dir'.
|
"Recompile literate config to `doom-user-dir'.
|
||||||
|
|
||||||
We assume any org file in `doom-user-dir' is connected to your literate
|
We assume any org file in `doom-user-dir' is connected to your literate config,
|
||||||
config, and should trigger a recompile if changed."
|
and should trigger a recompile if changed."
|
||||||
(and (file-in-directory-p
|
(and (file-in-directory-p
|
||||||
(buffer-file-name (buffer-base-buffer))
|
(buffer-file-name (buffer-base-buffer))
|
||||||
(file-name-directory (file-truename +literate-config-file)))
|
(file-name-directory (file-truename +literate-config-file)))
|
||||||
|
|
|
@ -369,8 +369,7 @@ directives. By default, this only recognizes C directives.")
|
||||||
;;
|
;;
|
||||||
;;; Keybinds
|
;;; Keybinds
|
||||||
|
|
||||||
;; Keybinds that have no Emacs+evil analogues (i.e. don't exist):
|
;; TODO: zu{q,w} - undo last marking
|
||||||
;; zu{q,w} - undo last marking
|
|
||||||
|
|
||||||
(map! :v "@" #'+evil:apply-macro
|
(map! :v "@" #'+evil:apply-macro
|
||||||
:m [C-i] #'evil-jump-forward
|
:m [C-i] #'evil-jump-forward
|
||||||
|
@ -530,6 +529,7 @@ directives. By default, this only recognizes C directives.")
|
||||||
;; evil-easymotion
|
;; evil-easymotion
|
||||||
(:after evil-easymotion
|
(:after evil-easymotion
|
||||||
:m "gs" evilem-map
|
:m "gs" evilem-map
|
||||||
|
;; TODO: Use named functions
|
||||||
(:map evilem-map
|
(:map evilem-map
|
||||||
"a" (evilem-create #'evil-forward-arg)
|
"a" (evilem-create #'evil-forward-arg)
|
||||||
"A" (evilem-create #'evil-backward-arg)
|
"A" (evilem-create #'evil-backward-arg)
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#+title: `(+file-templates-module-for-path)`
|
#+title: `(+file-templates-module-for-path)`
|
||||||
#+subtitle: <A one-line quip about this module to display in init.example.el>
|
#+subtitle: <A one-line quip about this module to display in init.example.el>
|
||||||
#+created: `(format-time-string "%B %d, %Y")`
|
#+created: `(format-time-string "%B %d, %Y")`
|
||||||
#+since: `(car (split-string doom-version "-"))` (#COMMIT-OR-PR-REF)
|
#+since: `(car (split-string doom-modules-version "-"))` (#COMMIT-OR-PR-REF)
|
||||||
|
|
||||||
* Description :unfold:
|
* Description :unfold:
|
||||||
$0Replace this with a short (1-2 sentence) description of what this module does.
|
$0Replace this with a short (1-2 sentence) description of what this module does.
|
||||||
|
|
|
@ -38,9 +38,6 @@ this."
|
||||||
(after! org
|
(after! org
|
||||||
(setq org-ellipsis +fold-ellipsis))
|
(setq org-ellipsis +fold-ellipsis))
|
||||||
|
|
||||||
(after! mule-util
|
|
||||||
(setq truncate-string-ellipsis +fold-ellipsis))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;;; Packages
|
;;; Packages
|
||||||
|
|
55
modules/emacs/eww/README.org
Normal file
55
modules/emacs/eww/README.org
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
:PROPERTIES:
|
||||||
|
:ID: 4f6e0ee2-7837-4d15-853f-c8863d065f21
|
||||||
|
:END:
|
||||||
|
#+title: :emacs eww
|
||||||
|
#+subtitle: The internet is gross
|
||||||
|
#+created: September 11, 2024
|
||||||
|
#+since: 24.10
|
||||||
|
|
||||||
|
* Description :unfold:
|
||||||
|
This module augments eww (Emacs Web Wowser); Emacs' built-in web browser, with
|
||||||
|
some reasonable defaults and helper commands.
|
||||||
|
|
||||||
|
** Maintainers
|
||||||
|
/This module has no dedicated maintainers./ [[doom-contrib-maintainer:][Become a maintainer?]]
|
||||||
|
|
||||||
|
** Module flags
|
||||||
|
/This module has no flags./
|
||||||
|
|
||||||
|
** Packages
|
||||||
|
/This module doesn't install any packages./
|
||||||
|
|
||||||
|
** Hacks
|
||||||
|
- The buffer is renamed to match the current page's URL or title.
|
||||||
|
|
||||||
|
** TODO Changelog
|
||||||
|
# This section will be machine generated. Don't edit it by hand.
|
||||||
|
/This module does not have a changelog yet./
|
||||||
|
|
||||||
|
* Installation
|
||||||
|
[[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]]
|
||||||
|
|
||||||
|
/This module has no external requirements./
|
||||||
|
|
||||||
|
* Usage
|
||||||
|
#+begin_quote
|
||||||
|
/This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
|
||||||
|
#+end_quote
|
||||||
|
|
||||||
|
Type ~M-x eww~ and enter an URL.
|
||||||
|
|
||||||
|
* TODO Configuration
|
||||||
|
#+begin_quote
|
||||||
|
This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]]
|
||||||
|
#+end_quote
|
||||||
|
|
||||||
|
* Troubleshooting
|
||||||
|
/There are no known problems with this module./ [[doom-report:][Report one?]]
|
||||||
|
|
||||||
|
* 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
|
128
modules/emacs/eww/autoload.el
Normal file
128
modules/emacs/eww/autoload.el
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
;;; emacs/eww/autoload.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; NOTE: Many of these functions were adapted from Protesilaos Stavrou's
|
||||||
|
;; dotfiles. See https://protesilaos.com/codelog/2021-03-25-emacs-eww
|
||||||
|
|
||||||
|
;; Adapted from `prot-eww-jump-to-url-on-page'
|
||||||
|
(defun eww--capture-url-on-page (&optional position)
|
||||||
|
"Capture all the links on the current web page.
|
||||||
|
|
||||||
|
Return a list of strings. Strings are in the form LABEL @ URL.
|
||||||
|
When optional argument POSITION is non-nil, include position info in the strings
|
||||||
|
too, so strings take the form: LABEL @ URL ~ POSITION."
|
||||||
|
(let (links match)
|
||||||
|
(save-excursion
|
||||||
|
(goto-char (point-max))
|
||||||
|
;; NOTE 2021-07-25: The first clause in the `or' is meant to address a bug
|
||||||
|
;; where if a URL is in `point-min' it does not get captured.
|
||||||
|
(while (setq match (text-property-search-backward 'shr-url))
|
||||||
|
(let* ((raw-url (prop-match-value match))
|
||||||
|
(start-point-prop (prop-match-beginning match))
|
||||||
|
(end-point-prop (prop-match-end match))
|
||||||
|
(url (when (stringp raw-url)
|
||||||
|
(propertize raw-url 'face 'link)))
|
||||||
|
(label (replace-regexp-in-string
|
||||||
|
"\n" " " ; NOTE 2021-07-25: newlines break completion
|
||||||
|
(buffer-substring-no-properties
|
||||||
|
start-point-prop end-point-prop)))
|
||||||
|
(point start-point-prop)
|
||||||
|
(line (line-number-at-pos point t))
|
||||||
|
(column (save-excursion (goto-char point) (current-column)))
|
||||||
|
(coordinates (propertize
|
||||||
|
(format "%d,%d (%d)" line column point)
|
||||||
|
'face 'shadow)))
|
||||||
|
(when url
|
||||||
|
(push (if position
|
||||||
|
(format "%-15s ~ %s @ %s" coordinates label url)
|
||||||
|
(format "%s @ %s" label url))
|
||||||
|
links)))))
|
||||||
|
links))
|
||||||
|
|
||||||
|
;; Adapted from `prot-eww--rename-buffer'
|
||||||
|
(defun +eww-page-title-or-url (&rest _)
|
||||||
|
(let ((prop (if (string-empty-p (plist-get eww-data :title)) :url :title)))
|
||||||
|
(format "*%s # eww*" (plist-get eww-data prop))))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Commands
|
||||||
|
|
||||||
|
;; Adapted from `prot-eww-quit'
|
||||||
|
;;;###autoload
|
||||||
|
(defun +eww/quit ()
|
||||||
|
"Quit eww and kill all its buffers."
|
||||||
|
(interactive nil 'eww-mode)
|
||||||
|
(when (yes-or-no-p "Are you sure you want to quit eww?")
|
||||||
|
(save-match-data
|
||||||
|
(cl-loop with case-fold-search = t
|
||||||
|
for buf in (doom-buffer-list)
|
||||||
|
if (with-current-buffer buf
|
||||||
|
(or (eq major-mode 'eww-mode)
|
||||||
|
(and (derived-mode-p 'special-mode)
|
||||||
|
(string-match "\\*.*eww.*\\*" (buffer-name)))))
|
||||||
|
do (kill-buffer buf)))))
|
||||||
|
|
||||||
|
;; Adapted from `prot-eww-jump-to-url-on-page'
|
||||||
|
;;;###autoload
|
||||||
|
(defun +eww/jump-to-url-on-page (&optional arg)
|
||||||
|
"Jump to URL position on the page using completion.
|
||||||
|
|
||||||
|
When called without ARG (\\[universal-argument]) get URLs only
|
||||||
|
from the visible portion of the buffer. But when ARG is provided
|
||||||
|
consider whole buffer."
|
||||||
|
(interactive "P" 'eww-mode)
|
||||||
|
(unless (derived-mode-p 'eww-mode)
|
||||||
|
(user-error "Not in an eww buffer!"))
|
||||||
|
(let* ((links
|
||||||
|
(if arg
|
||||||
|
(eww--capture-url-on-page t)
|
||||||
|
(save-restriction
|
||||||
|
(if (use-region-p)
|
||||||
|
(narrow-to-region (region-beginning) (region-end))
|
||||||
|
(narrow-to-region (window-start) (window-end)))
|
||||||
|
(eww--capture-url-on-page t))))
|
||||||
|
(prompt-scope (if arg
|
||||||
|
(propertize "URL on the page" 'face 'warning)
|
||||||
|
"visible URL"))
|
||||||
|
(prompt (format "Jump to %s: " prompt-scope))
|
||||||
|
(selection (completing-read prompt links nil t))
|
||||||
|
(position (replace-regexp-in-string "^.*(\\([0-9]+\\))[\s\t]+~" "\\1" selection))
|
||||||
|
(point (string-to-number position)))
|
||||||
|
(goto-char point)
|
||||||
|
(recenter)))
|
||||||
|
|
||||||
|
;; Adapted from `prot-eww-open-in-other-window'
|
||||||
|
;;;###autoload
|
||||||
|
(defun +eww/open-in-other-window ()
|
||||||
|
"Use `eww-open-in-new-buffer' in another window."
|
||||||
|
(interactive nil 'ewe-mode)
|
||||||
|
(other-window-prefix)
|
||||||
|
(eww-open-in-new-buffer))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +eww/copy-current-url ()
|
||||||
|
"Copy the open page's URL to the kill ring."
|
||||||
|
(interactive nil 'eww-mode)
|
||||||
|
(let ((url (eww-current-url)))
|
||||||
|
(kill-new url)
|
||||||
|
(message url)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +eww/increase-font-size ()
|
||||||
|
"Increase the font size in `eww-mode'."
|
||||||
|
(interactive nil 'eww-mode)
|
||||||
|
(if shr-use-fonts
|
||||||
|
(let* ((cur (face-attribute 'shr-text :height nil))
|
||||||
|
(cur (if (floatp cur) cur 1.0)))
|
||||||
|
(set-face-attribute 'shr-text nil :height (+ cur 0.1)))
|
||||||
|
(text-scale-increase 0.5)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +eww/decrease-font-size ()
|
||||||
|
"Decrease the font size in `eww-mode'."
|
||||||
|
(interactive nil 'eww-mode)
|
||||||
|
(if shr-use-fonts
|
||||||
|
(let* ((cur (face-attribute 'shr-text :height nil))
|
||||||
|
(cur (if (floatp cur) cur 1.0)))
|
||||||
|
(set-face-attribute 'shr-text nil :height (- cur 0.1)))
|
||||||
|
(text-scale-decrease 0.5)))
|
48
modules/emacs/eww/config.el
Normal file
48
modules/emacs/eww/config.el
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
;;; emacs/eww/config.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
(use-package! eww
|
||||||
|
:defer t
|
||||||
|
:config
|
||||||
|
(map! :map eww-mode-map
|
||||||
|
[remap text-scale-increase] #'+eww/increase-font-size
|
||||||
|
[remap text-scale-decrease] #'+eww/decrease-font-size
|
||||||
|
[remap imenu] #'+eww/jump-to-url-on-page
|
||||||
|
[remap quit-window] #'+eww/quit
|
||||||
|
:ni [C-return] #'+eww/open-in-other-window
|
||||||
|
:n "yy" #'+eww/copy-current-url
|
||||||
|
:n "zk" #'text-scale-increase
|
||||||
|
:n "zj" #'text-scale-decrease
|
||||||
|
|
||||||
|
(:localleader
|
||||||
|
:desc "external browser" "e" #'eww-browse-with-external-browser
|
||||||
|
:desc "buffers" "b" #'eww-switch-to-buffer
|
||||||
|
|
||||||
|
(:prefix ("t" . "toggle")
|
||||||
|
:desc "readable" "r" #'eww-readable
|
||||||
|
:desc "colors" "c" #'eww-toggle-colors
|
||||||
|
:desc "fonts" "f" #'eww-toggle-fonts
|
||||||
|
:desc "images" "i" #'eww-toggle-images)
|
||||||
|
|
||||||
|
(:prefix ("y" . "copy")
|
||||||
|
:desc "copy url" "y" #'+eww/copy-current-url
|
||||||
|
:desc "copy for Org" "o" #'org-eww-copy-for-org-mode)))
|
||||||
|
|
||||||
|
;; HACK: There are packages that use eww to pop up html documentation; we want
|
||||||
|
;; those to open in a popup, but if the user calls `eww' directly, it should
|
||||||
|
;; open in the current window.
|
||||||
|
(defadvice! +eww-open-in-fullscreen-if-interactive-a (fn &rest args)
|
||||||
|
:around #'eww
|
||||||
|
(if (called-interactively-p 'any)
|
||||||
|
(apply fn args)
|
||||||
|
(let (display-buffer-alist)
|
||||||
|
(apply fn args))))
|
||||||
|
|
||||||
|
;; HACK: Rename the eww buffer to match the open page's title or URL.
|
||||||
|
(if (boundp 'eww-auto-rename-buffer)
|
||||||
|
(setq eww-auto-rename-buffer #'+eww-page-title-or-url) ; for >=29.1
|
||||||
|
;; REVIEW: Remove when we drop 28 support
|
||||||
|
(add-hook! 'eww-after-render-hook
|
||||||
|
(defun +eww--rename-buffer-to-page-title-or-url-h (&rest _)
|
||||||
|
(rename-buffer (+eww-page-title-or-url))))
|
||||||
|
(advice-add #'eww-back-url :after #'+eww--rename-buffer-to-page-title-or-url-h)
|
||||||
|
(advice-add #'eww-forward-url :after #'+eww--rename-buffer-to-page-title-or-url-h)))
|
4
modules/emacs/eww/packages.el
Normal file
4
modules/emacs/eww/packages.el
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
;; -*- no-byte-compile: t; -*-
|
||||||
|
;;; emacs/eww/packages.el
|
||||||
|
|
||||||
|
(package! eww :built-in t)
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
(defvar +mu4e-backend 'mbsync
|
(defvar +mu4e-backend 'mbsync
|
||||||
"Which backend to use. Can either be offlineimap, mbsync or nil (manual).")
|
"Which backend to use. Can either be offlineimap, mbsync or nil (manual).")
|
||||||
(make-obsolete-variable '+mu4e-backend "Use the :email mu4e module's +mbsync or +offlineimap flags instead" "3.0.0")
|
(make-obsolete-variable '+mu4e-backend "Use the :email mu4e module's +mbsync or +offlineimap flags instead" "24.09")
|
||||||
|
|
||||||
(defvar +mu4e-personal-addresses 'nil
|
(defvar +mu4e-personal-addresses 'nil
|
||||||
"Alternative to mu4e-personal-addresses that can be set for each account (mu4e context).")
|
"Alternative to mu4e-personal-addresses that can be set for each account (mu4e context).")
|
||||||
|
|
64
modules/lang/graphviz/README.org
Normal file
64
modules/lang/graphviz/README.org
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
:PROPERTIES:
|
||||||
|
:ID: 3efe8402-e4a1-41c3-ad1a-9aaa3783f68f
|
||||||
|
:END:
|
||||||
|
#+title: :lang graphviz
|
||||||
|
#+subtitle: Diagrams to confuse yourself even more
|
||||||
|
#+created: Nov 14, 2023
|
||||||
|
#+since: 23.09.0-pre
|
||||||
|
|
||||||
|
* Description :unfold:
|
||||||
|
This module adds graphviz support to Emacs, allowing you to generate diagrams
|
||||||
|
from plain text. Flycheck is supported.
|
||||||
|
|
||||||
|
** Maintainers
|
||||||
|
/This module has no dedicated maintainers./ [[doom-contrib-maintainer:][Become a maintainer?]]
|
||||||
|
|
||||||
|
** Module flags
|
||||||
|
/This module has no flags./
|
||||||
|
|
||||||
|
** Packages
|
||||||
|
- [[doom-package:graphviz-dot-mode]]
|
||||||
|
|
||||||
|
** 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
|
||||||
|
[[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]]
|
||||||
|
|
||||||
|
This module requires that the =graphviz= package be installed on your system to
|
||||||
|
build diagrams with. You can install it using:
|
||||||
|
#+begin_src shell
|
||||||
|
sudo dnf install graphviz # For fedora
|
||||||
|
sudo apt install graphviz # For debian/ubuntu
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* Usage
|
||||||
|
This module should configure "out-of-the-box" if you have installed graphviz on
|
||||||
|
your system.
|
||||||
|
|
||||||
|
With org-babel LaTeX/PDF-export, use a file naming ending with ".pdf", otherwise
|
||||||
|
LaTeX might complain about a non-existant ~\\includesvg~ command.
|
||||||
|
#+begin_src dot :file graph-1.pdf
|
||||||
|
digraph {
|
||||||
|
A -> B;
|
||||||
|
B -> D;
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* Configuration
|
||||||
|
There is nothing to configure. Just install dot and it should work.
|
||||||
|
|
||||||
|
* Troubleshooting
|
||||||
|
/There are no known problems with this module./ [[doom-report:][Report one?]]
|
||||||
|
|
||||||
|
* 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
|
19
modules/lang/graphviz/autoload.el
Normal file
19
modules/lang/graphviz/autoload.el
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
;;; lang/graphviz/autoload.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(cl-defun +graphviz-formatter (&key _buffer scratch callback &allow-other-keys)
|
||||||
|
"Format graphviz graphs."
|
||||||
|
(with-current-buffer scratch
|
||||||
|
(let ((inhibit-message t)
|
||||||
|
(message-log-max nil))
|
||||||
|
(goto-char (point-min))
|
||||||
|
(graphviz-dot-indent-graph))
|
||||||
|
(funcall callback)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +graphviz/toggle-preview ()
|
||||||
|
"Toggle `graphviz-dot-auto-preview-on-save'."
|
||||||
|
(interactive nil 'graphviz-dot-mode)
|
||||||
|
(if graphviz-dot-auto-preview-on-save
|
||||||
|
(graphviz-turn-off-live-preview)
|
||||||
|
(graphviz-turn-on-live-preview)))
|
37
modules/lang/graphviz/config.el
Normal file
37
modules/lang/graphviz/config.el
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
;;; lang/graphviz/config.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
(use-package! graphviz-dot-mode
|
||||||
|
:mode "\\.\\(?:nw\\|rack\\)diag\\'"
|
||||||
|
:init
|
||||||
|
(after! org-src
|
||||||
|
(add-to-list 'org-src-lang-modes '("dot" . graphviz-dot)))
|
||||||
|
:config
|
||||||
|
(set-company-backend! 'graphviz-dot-mode 'company-graphviz-dot-backend)
|
||||||
|
(set-formatter! 'graphviz-dot #'+graphviz-formatter :modes '(graphviz-dot-mode))
|
||||||
|
(set-tree-sitter-lang! 'graphviz-dot-mode 'dot)
|
||||||
|
|
||||||
|
(when (modulep! +tree-sitter)
|
||||||
|
(add-hook 'graphiz-dot-mode-hook #'tree-sitter!))
|
||||||
|
|
||||||
|
(after! dtrt-indent
|
||||||
|
(add-to-list 'dtrt-indent-hook-mapping-list '(graphviz-mode graphviz-dot-indent-width)))
|
||||||
|
|
||||||
|
(when (and (modulep! :checker syntax)
|
||||||
|
(not (modulep! :checker syntax +flymake)))
|
||||||
|
(after! flycheck
|
||||||
|
(flycheck-define-checker graphviz-dot
|
||||||
|
"A checker using graphviz dot."
|
||||||
|
:command ("dot")
|
||||||
|
:standard-input t
|
||||||
|
:error-patterns ((error line-start "Error: <stdin>: " (message "syntax error in line " line (* nonl)))
|
||||||
|
;; I have no idea if this can actually be printed
|
||||||
|
(error line-start "Error: <stdin>: " (message)))
|
||||||
|
:modes graphviz-dot-mode)
|
||||||
|
(add-to-list 'flycheck-checkers 'graphviz-dot)))
|
||||||
|
|
||||||
|
(map! :map graphviz-dot-mode-map
|
||||||
|
:localleader
|
||||||
|
:desc "External view" :nv "e" #'graphviz-dot-view
|
||||||
|
:desc "Preview" :nv "p" #'graphviz-dot-preview
|
||||||
|
:prefix ("t" . "toggle")
|
||||||
|
:desc "Preview" :nv "p" #'+graphviz/toggle-preview))
|
6
modules/lang/graphviz/doctor.el
Normal file
6
modules/lang/graphviz/doctor.el
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||||
|
;;; lang/graphviz/doctor.el
|
||||||
|
|
||||||
|
(when (require 'graphviz-dot-mode nil t)
|
||||||
|
(unless (executable-find graphviz-dot-dot-program)
|
||||||
|
(warn! "Couldn't find dot. Previewing and exporting will not work")))
|
4
modules/lang/graphviz/packages.el
Normal file
4
modules/lang/graphviz/packages.el
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
;; -*- no-byte-compile: t; -*-
|
||||||
|
;;; lang/graphviz/packages.el
|
||||||
|
|
||||||
|
(package! graphviz-dot-mode :pin "8ff793b13707cb511875f56e167ff7f980a31136")
|
|
@ -14,8 +14,12 @@ This module adds support for the [[https://www.racket-lang.org/][Racket programm
|
||||||
Enable support for ~racket-mode~. Requires [[doom-module::tools lsp]] and a langserver
|
Enable support for ~racket-mode~. Requires [[doom-module::tools lsp]] and a langserver
|
||||||
(supports [[https://github.com/jeapostrophe/racket-langserver][racket-langserver]]).
|
(supports [[https://github.com/jeapostrophe/racket-langserver][racket-langserver]]).
|
||||||
- +xp ::
|
- +xp ::
|
||||||
Enable the explore mode (~racket-xp-mode~), which "analyzes expanded code to
|
Enable the explore minor mode (~racket-xp-mode~), which "analyzes expanded
|
||||||
explain and explore."
|
code to explain and explore."
|
||||||
|
- +hash-lang ::
|
||||||
|
Enable the hash-lang major mode (~racket-hash-lang-mode~), which "uses
|
||||||
|
color-lexer, indent, and navigation supplied by a #lang." This flag can be
|
||||||
|
used along with the ~+xp~ flag.
|
||||||
|
|
||||||
** Packages
|
** Packages
|
||||||
- [[doom-package:racket-mode]]
|
- [[doom-package:racket-mode]]
|
||||||
|
|
|
@ -8,31 +8,49 @@
|
||||||
;;
|
;;
|
||||||
;;; Packages
|
;;; Packages
|
||||||
|
|
||||||
|
(let (mode
|
||||||
|
mode-map
|
||||||
|
mode-exts
|
||||||
|
mode-hook
|
||||||
|
mode-local-vars-hook)
|
||||||
|
(if (modulep! +hash-lang)
|
||||||
|
(setq mode 'racket-hash-lang-mode
|
||||||
|
mode-exts '("\\.rkt\\'" ; Racket
|
||||||
|
"\\.scrbl\\'" ; Scribble
|
||||||
|
"\\.rhm\\'")) ; Rhombus
|
||||||
|
(setq mode 'racket-mode
|
||||||
|
mode-exts `("\\.rkt\\'")))
|
||||||
|
(let ((mode-name (symbol-name mode)))
|
||||||
|
(setq mode-map (intern (format "%s-map" mode-name))
|
||||||
|
mode-hook (intern (format "%s-hook" mode-name))
|
||||||
|
mode-local-vars-hook (intern (format "%s-local-vars-hook" mode-name))))
|
||||||
|
|
||||||
(use-package! racket-mode
|
(use-package! racket-mode
|
||||||
:mode "\\.rkt\\'" ; give it precedence over :lang scheme
|
:defer t
|
||||||
|
:init
|
||||||
|
(dolist (entry mode-exts)
|
||||||
|
(add-to-list 'auto-mode-alist (cons entry mode)))
|
||||||
:config
|
:config
|
||||||
(set-repl-handler! 'racket-mode #'+racket/open-repl)
|
(set-repl-handler! mode #'+racket/open-repl)
|
||||||
(set-lookup-handlers! '(racket-mode racket-repl-mode)
|
(set-lookup-handlers! `(,mode racket-repl-mode)
|
||||||
:definition #'+racket-lookup-definition
|
:definition #'+racket-lookup-definition
|
||||||
:documentation #'+racket-lookup-documentation)
|
:documentation #'+racket-lookup-documentation)
|
||||||
(set-docsets! 'racket-mode "Racket")
|
(set-docsets! mode "Racket")
|
||||||
(set-ligatures! 'racket-mode
|
(set-ligatures! mode
|
||||||
:lambda "lambda"
|
:lambda "lambda"
|
||||||
:map "map"
|
:map "map"
|
||||||
:dot ".")
|
:dot ".")
|
||||||
(set-rotate-patterns! 'racket-mode
|
(set-rotate-patterns! mode :symbols '(("#true" "#false")))
|
||||||
:symbols '(("#true" "#false")))
|
(set-formatter! 'raco-fmt '("raco" "fmt") :modes (list mode))
|
||||||
(set-formatter! 'raco-fmt '("raco" "fmt") :modes '(racket-mode))
|
|
||||||
|
|
||||||
(add-hook! 'racket-mode-hook
|
(add-hook mode-hook #'rainbow-delimiters-mode)
|
||||||
#'rainbow-delimiters-mode
|
(add-hook mode-hook #'highlight-quoted-mode)
|
||||||
#'highlight-quoted-mode)
|
|
||||||
|
|
||||||
(when (modulep! +lsp)
|
(when (modulep! +lsp)
|
||||||
(add-hook 'racket-mode-local-vars-hook #'lsp! 'append))
|
(add-hook mode-local-vars-hook #'lsp! 'append))
|
||||||
|
|
||||||
(when (modulep! +xp)
|
(when (modulep! +xp)
|
||||||
(add-hook 'racket-mode-local-vars-hook #'racket-xp-mode)
|
(add-hook mode-local-vars-hook #'racket-xp-mode)
|
||||||
;; Both flycheck and racket-xp produce error popups, but racket-xp's are
|
;; Both flycheck and racket-xp produce error popups, but racket-xp's are
|
||||||
;; higher quality so disable flycheck's:
|
;; higher quality so disable flycheck's:
|
||||||
(when (modulep! :checkers syntax)
|
(when (modulep! :checkers syntax)
|
||||||
|
@ -42,7 +60,7 @@
|
||||||
|
|
||||||
(unless (or (modulep! :editor parinfer)
|
(unless (or (modulep! :editor parinfer)
|
||||||
(modulep! :editor lispy))
|
(modulep! :editor lispy))
|
||||||
(add-hook 'racket-mode-hook #'racket-smart-open-bracket-mode))
|
(add-hook mode-hook #'racket-smart-open-bracket-mode))
|
||||||
|
|
||||||
(map! (:map racket-xp-mode-map
|
(map! (:map racket-xp-mode-map
|
||||||
[remap racket-doc] #'racket-xp-documentation
|
[remap racket-doc] #'racket-xp-documentation
|
||||||
|
@ -50,7 +68,7 @@
|
||||||
[remap next-error] #'racket-xp-next-error
|
[remap next-error] #'racket-xp-next-error
|
||||||
[remap previous-error] #'racket-xp-previous-error)
|
[remap previous-error] #'racket-xp-previous-error)
|
||||||
(:localleader
|
(:localleader
|
||||||
:map racket-mode-map
|
:map ,mode-map
|
||||||
"a" #'racket-align
|
"a" #'racket-align
|
||||||
"A" #'racket-unalign
|
"A" #'racket-unalign
|
||||||
"f" #'racket-fold-all-tests
|
"f" #'racket-fold-all-tests
|
||||||
|
@ -92,4 +110,4 @@
|
||||||
(:prefix ("g" . "goto")
|
(:prefix ("g" . "goto")
|
||||||
"b" #'racket-unvisit
|
"b" #'racket-unvisit
|
||||||
"m" #'racket-visit-module
|
"m" #'racket-visit-module
|
||||||
"d" #'racket-repl-visit-definition))))
|
"d" #'racket-repl-visit-definition)))))
|
||||||
|
|
|
@ -91,6 +91,16 @@
|
||||||
"P" #'rubocop-autocorrect-project))
|
"P" #'rubocop-autocorrect-project))
|
||||||
|
|
||||||
|
|
||||||
|
(use-package! ruby-json-to-hash
|
||||||
|
:defer t
|
||||||
|
:init
|
||||||
|
(map! :after ruby-mode
|
||||||
|
:map ruby-mode-map
|
||||||
|
:localleader
|
||||||
|
"J" #'ruby-json-to-hash-parse-json
|
||||||
|
"j" #'ruby-json-to-hash-toggle-let))
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;;; Package & Ruby version management
|
;;; Package & Ruby version management
|
||||||
|
|
||||||
|
@ -182,6 +192,9 @@
|
||||||
"v" #'minitest-verify))
|
"v" #'minitest-verify))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Rails integration
|
||||||
|
|
||||||
(use-package! projectile-rails
|
(use-package! projectile-rails
|
||||||
:when (modulep! +rails)
|
:when (modulep! +rails)
|
||||||
:hook ((ruby-mode inf-ruby-mode projectile-rails-server-mode) . projectile-rails-mode)
|
:hook ((ruby-mode inf-ruby-mode projectile-rails-server-mode) . projectile-rails-mode)
|
||||||
|
@ -199,3 +212,29 @@
|
||||||
(map! :localleader
|
(map! :localleader
|
||||||
:map projectile-rails-mode-map
|
:map projectile-rails-mode-map
|
||||||
"r" #'projectile-rails-command-map))
|
"r" #'projectile-rails-command-map))
|
||||||
|
|
||||||
|
(use-package! rails-routes
|
||||||
|
:when (featurep! +rails)
|
||||||
|
:defer t
|
||||||
|
:init
|
||||||
|
(map! :after ruby-mode
|
||||||
|
:map ruby-mode-map
|
||||||
|
"C-c o" #'rails-routes-insert
|
||||||
|
"C-c C-o" #'rails-routes-insert-no-cache
|
||||||
|
"C-c ! o" #'rails-routes-jump)
|
||||||
|
(map! :after web-mode
|
||||||
|
:map web-mode-map
|
||||||
|
"C-c o" #'rails-routes-insert
|
||||||
|
"C-c C-o" #'rails-routes-insert-no-cache
|
||||||
|
"C-c ! o" #'rails-routes-jump))
|
||||||
|
|
||||||
|
(use-package! rails-i18n
|
||||||
|
:when (featurep! +rails)
|
||||||
|
:defer t
|
||||||
|
:init
|
||||||
|
(map! :after ruby-mode
|
||||||
|
:map ruby-mode-map
|
||||||
|
"C-c i" #'rails-i18n-insert-with-cache)
|
||||||
|
(map! :after web-mode
|
||||||
|
:map web-mode-map
|
||||||
|
"C-c i" #'rails-i18n-insert-with-cache))
|
||||||
|
|
|
@ -30,7 +30,12 @@
|
||||||
(package! rspec-mode :pin "29df3d081c6a1cbdf840cd13d45ea1c100c5bbaa")
|
(package! rspec-mode :pin "29df3d081c6a1cbdf840cd13d45ea1c100c5bbaa")
|
||||||
(package! minitest :pin "5999c45c047212cee15a2be67e78787776a79c35")
|
(package! minitest :pin "5999c45c047212cee15a2be67e78787776a79c35")
|
||||||
|
|
||||||
|
;; Refactoring
|
||||||
|
(package! ruby-json-to-hash :pin "383b22bb2e007289ac0dba146787d02ff99d4415")
|
||||||
|
|
||||||
;; Rails
|
;; Rails
|
||||||
(when (modulep! +rails)
|
(when (modulep! +rails)
|
||||||
|
(package! rails-routes :pin "eab995a9297ca5bd9bd4f4c2737f2fecfc36def0")
|
||||||
|
(package! rails-i18n :pin "8e87e4e48e31902b8259ded28a208c2e7efea6e9")
|
||||||
(package! projectile-rails :pin "701784df7befe17b861f1b53fe9cbc59d0b94b9f")
|
(package! projectile-rails :pin "701784df7befe17b861f1b53fe9cbc59d0b94b9f")
|
||||||
(package! inflections :pin "55caa66a7cc6e0b1a76143fd40eff38416928941"))
|
(package! inflections :pin "55caa66a7cc6e0b1a76143fd40eff38416928941"))
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
;; This file supplies some metadata about this module repo to Doom's module
|
|
||||||
;; manager. None of them are required, but it's a good idea to include them so
|
|
||||||
;; Doom can perform some sanity checks for you.
|
|
||||||
|
|
||||||
:root "./" ; where the module tree starts
|
|
||||||
:version "21.12" ; version of this repo
|
|
||||||
:requires "3.0.0" ; minimum supported version of Doom's core
|
|
|
@ -45,6 +45,8 @@ be enabled. If any function returns non-nil, the mode will not be activated."
|
||||||
;; TODO: Uncomment once we support treesit
|
;; TODO: Uncomment once we support treesit
|
||||||
;; (setq indent-bars-treesit-support (modulep! :tools tree-sitter))
|
;; (setq indent-bars-treesit-support (modulep! :tools tree-sitter))
|
||||||
|
|
||||||
|
;; indent-bars adds this to `enable-theme-functions', which was introduced in
|
||||||
|
;; 29.1, which will be redundant with `doom-load-theme-hook'.
|
||||||
(unless (boundp 'enable-theme-functions)
|
(unless (boundp 'enable-theme-functions)
|
||||||
(add-hook 'doom-load-theme-hook #'indent-bars-reset-styles))
|
(add-hook 'doom-load-theme-hook #'indent-bars-reset-styles))
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,11 @@ and cannot run in."
|
||||||
(setq prettify-symbols-unprettify-at-point 'right-edge)
|
(setq prettify-symbols-unprettify-at-point 'right-edge)
|
||||||
|
|
||||||
(when (modulep! +extra)
|
(when (modulep! +extra)
|
||||||
|
;; Lisp modes offer their own defaults for `prettify-symbols-mode' (just a
|
||||||
|
;; lambda symbol substitution), but this might be unexpected if the user
|
||||||
|
;; enables +extra but has unset `+ligatures-extra-symbols'.
|
||||||
|
(setq lisp-prettify-symbols-alist nil)
|
||||||
|
|
||||||
(add-hook 'after-change-major-mode-hook #'+ligatures-init-extra-symbols-h))
|
(add-hook 'after-change-major-mode-hook #'+ligatures-init-extra-symbols-h))
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
|
|
|
@ -69,6 +69,7 @@
|
||||||
:emacs
|
:emacs
|
||||||
dired ; making dired pretty [functional]
|
dired ; making dired pretty [functional]
|
||||||
electric ; smarter, keyword-based electric-indent
|
electric ; smarter, keyword-based electric-indent
|
||||||
|
;;eww ; the internet is gross
|
||||||
;;ibuffer ; interactive buffer management
|
;;ibuffer ; interactive buffer management
|
||||||
undo ; persistent, smarter undo for your inevitable mistakes
|
undo ; persistent, smarter undo for your inevitable mistakes
|
||||||
vc ; version-control and Emacs, sitting in a tree
|
vc ; version-control and Emacs, sitting in a tree
|
||||||
|
@ -154,6 +155,7 @@
|
||||||
org ; organize your plain life in plain text
|
org ; organize your plain life in plain text
|
||||||
;;php ; perl's insecure younger brother
|
;;php ; perl's insecure younger brother
|
||||||
;;plantuml ; diagrams for confusing people more
|
;;plantuml ; diagrams for confusing people more
|
||||||
|
;;graphviz ; diagrams for confusing yourself even more
|
||||||
;;purescript ; javascript, but functional
|
;;purescript ; javascript, but functional
|
||||||
;;python ; beautiful is better than ugly
|
;;python ; beautiful is better than ugly
|
||||||
;;qt ; the 'cutest' gui framework ever
|
;;qt ; the 'cutest' gui framework ever
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue