Merge branch 'develop' into fix/add-add-featurep-condition-to-global-bindings
This commit is contained in:
commit
a5d9079c43
184 changed files with 2868 additions and 1922 deletions
|
@ -10,9 +10,6 @@ before_install:
|
|||
- export PATH="/home/travis/.evm/bin:$PATH"
|
||||
- evm config path /tmp
|
||||
- evm install $EVM_EMACS --use --skip
|
||||
- mkdir -p ~/.config/doom
|
||||
- cp init.test.el ~/.config/doom/init.el
|
||||
- bin/doom -y -i install
|
||||
env:
|
||||
- EVM_EMACS=emacs-25.3-travis
|
||||
- EVM_EMACS=emacs-26.1-travis
|
||||
|
@ -22,5 +19,5 @@ matrix:
|
|||
- env: EVM_EMACS=emacs-git-snapshot-travis
|
||||
script:
|
||||
- bin/doom version
|
||||
- bin/doom -d test
|
||||
- bin/doom test
|
||||
- bin/doom -y compile
|
||||
|
|
15
bin/doom
15
bin/doom
|
@ -82,7 +82,7 @@
|
|||
|
||||
;; Bootstrap Doom
|
||||
(if (not noninteractive)
|
||||
(progn
|
||||
(let ((doom-interactive-mode t))
|
||||
(load (expand-file-name "init.el" user-emacs-directory)
|
||||
nil 'nomessage)
|
||||
(doom-run-all-startup-hooks-h))
|
||||
|
@ -91,14 +91,13 @@
|
|||
(doom-initialize 'force-p)
|
||||
(doom-initialize-modules)
|
||||
|
||||
(cond ((and (not (cdr args))
|
||||
(member (car args) '("help" "h")))
|
||||
(usage))
|
||||
((not args)
|
||||
(print! (error "No command detected.\n"))
|
||||
(cond ((or (not args)
|
||||
(and (not (cdr args))
|
||||
(member (car args) '("help" "h"))))
|
||||
(unless args
|
||||
(print! (error "No command detected.\n")))
|
||||
(usage))
|
||||
((require 'core-cli)
|
||||
(let ((default-directory user-emacs-directory))
|
||||
(setq argv nil)
|
||||
(condition-case e
|
||||
(doom-dispatch (car args) (cdr args))
|
||||
|
@ -119,4 +118,4 @@
|
|||
"Emacs outputs to standard error, so you'll need to redirect stderr to\n"
|
||||
"stdout to pipe this to a file or clipboard!\n\n"
|
||||
" e.g. doom -d install 2>&1 | clipboard-program"))
|
||||
(signal 'doom-error e)))))))))
|
||||
(signal 'doom-error e))))))))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env sh
|
||||
":"; command -v emacs >/dev/null || { >&2 echo "Emacs isn't installed"; exit 1; } # -*-emacs-lisp-*-
|
||||
":"; VERSION=$(emacs --version | head -n1)
|
||||
":"; case $VERSION in *\ 2[0-2].[0-1].[0-9]) echo "You're running $VERSION"; echo "That version is too old to run the doctor. Check your PATH"; echo; exit 2 ;; esac
|
||||
":"; case $VERSION in *\ 2[0-2].[0-1].[0-9]) echo "You're running $VERSION"; echo "That version is too old to run the doctor (25.3 minimum). Check your PATH"; echo; exit 2 ;; esac
|
||||
":"; exec emacs --quick --script "$0"; exit 0
|
||||
|
||||
;; The Doom doctor is essentially one big, self-contained elisp shell script
|
||||
|
@ -43,7 +43,7 @@
|
|||
(defun sh (cmd &rest args)
|
||||
(ignore-errors
|
||||
(string-trim-right
|
||||
(shell-command-to-string (apply #'format cmd args)))))
|
||||
(shell-command-to-string (if args (apply #'format cmd args) cmd)))))
|
||||
|
||||
(defun elc-check-dir (dir)
|
||||
(dolist (file (directory-files-recursively dir "\\.elc$"))
|
||||
|
@ -139,18 +139,6 @@
|
|||
(concat "\nMacOS users should use homebrew (https://brew.sh) to install Emacs\n"
|
||||
" brew install emacs --with-modules --with-imagemagick --with-cocoa"))))
|
||||
|
||||
(section! "Checking if your version of Emacs has changed recently...")
|
||||
(let ((version-file (expand-file-name ".local/emacs-version.el" user-emacs-directory))
|
||||
doom--last-emacs-version)
|
||||
(when (and (load version-file 'noerror 'nomessage 'nosuffix)
|
||||
(not (equal emacs-version doom--last-emacs-version)))
|
||||
(warn! "Your version of Emacs has changed from %S to %S. Recompile your packages!"
|
||||
doom--last-emacs-version
|
||||
emacs-version)
|
||||
(explain! "Byte-code compiled in one version of Emacs may not work in another version."
|
||||
"It is recommended that you reinstall your plugins or recompile them with"
|
||||
"`bin/doom rebuild'.")))
|
||||
|
||||
(section! "Checking for Emacs config conflicts...")
|
||||
(when (file-exists-p "~/.emacs")
|
||||
(warn! "Detected an ~/.emacs file, which may prevent Doom from loading")
|
||||
|
|
|
@ -16,7 +16,7 @@ IF NOT [%1]==[] (
|
|||
)
|
||||
|
||||
IF [%command%]==[run] (
|
||||
start runemacs -Q %args% -l ..\init.el -f "doom|run-all-startup-hooks"
|
||||
start runemacs -Q %args% -l ..\init.el -f "doom-run-all-startup-hooks-h"
|
||||
) ELSE (
|
||||
emacs --quick --script .\doom -- %*
|
||||
)
|
||||
|
|
|
@ -74,7 +74,7 @@ line."
|
|||
|
||||
Uses the same mechanism as 'bin/doom env reload'."
|
||||
(interactive)
|
||||
(compile (format "%s env refresh" (expand-file-name "bin/doom" doom-emacs-dir)))
|
||||
(compile (format "%s env" (expand-file-name "bin/doom" doom-emacs-dir)))
|
||||
(while compilation-in-progress
|
||||
(sit-for 1))
|
||||
(unless (file-readable-p doom-env-file)
|
||||
|
|
|
@ -39,7 +39,12 @@ ready to be pasted in a bug report on github."
|
|||
(version . ,emacs-version)
|
||||
(features ,@system-configuration-features)
|
||||
(build . ,(format-time-string "%b %d, %Y" emacs-build-time))
|
||||
(buildopts ,system-configuration-options))
|
||||
(buildopts ,system-configuration-options)
|
||||
(windowsys . ,(if noninteractive 'batch window-system))
|
||||
(daemonp . ,(cond ((daemonp) 'daemon)
|
||||
((and (require 'server)
|
||||
(server-running-p))
|
||||
'server-running))))
|
||||
(doom
|
||||
(version . ,doom-version)
|
||||
(build . ,(sh "git log -1 --format=\"%D %h %ci\"")))
|
||||
|
@ -63,11 +68,11 @@ ready to be pasted in a bug report on github."
|
|||
(modules
|
||||
,@(or (cl-loop with cat = nil
|
||||
for key being the hash-keys of doom-modules
|
||||
if (or (not cat) (not (eq cat (car key))))
|
||||
if (or (not cat)
|
||||
(not (eq cat (car key))))
|
||||
do (setq cat (car key))
|
||||
and collect cat
|
||||
and collect (cdr key)
|
||||
else collect
|
||||
collect
|
||||
(let ((flags (doom-module-get cat (cdr key) :flags)))
|
||||
(if flags
|
||||
`(,(cdr key) ,@flags)
|
||||
|
@ -75,18 +80,20 @@ ready to be pasted in a bug report on github."
|
|||
'("n/a")))
|
||||
(packages
|
||||
,@(or (ignore-errors
|
||||
(require 'core-packages)
|
||||
(doom-initialize-packages)
|
||||
(cl-loop for (name . plist) in doom-packages
|
||||
if (doom-package-private-p name)
|
||||
(let ((doom-interactive-mode t)
|
||||
doom-packages
|
||||
doom-disabled-packages)
|
||||
(doom--read-module-packages-file
|
||||
(doom-path doom-private-dir "packages.el")
|
||||
nil t)
|
||||
(cl-loop for (name . plist) in (nreverse doom-packages)
|
||||
collect
|
||||
(format
|
||||
"%s" (if-let (splist (doom-plist-delete (copy-sequence plist)
|
||||
(if-let (splist (doom-plist-delete (copy-sequence plist)
|
||||
:modules))
|
||||
(cons name splist)
|
||||
(prin1-to-string (cons name splist))
|
||||
name))))
|
||||
'("n/a")))
|
||||
(elpa-packages
|
||||
(elpa
|
||||
,@(or (ignore-errors
|
||||
(cl-loop for (name . _) in package-alist
|
||||
collect (format "%s" name)))
|
||||
|
@ -203,24 +210,23 @@ markdown and copies it to your clipboard, ready to be pasted into bug reports!"
|
|||
(setq-default buffer-undo-tree (make-undo-tree))))
|
||||
(pcase mode
|
||||
(`vanilla-doom+ ; Doom core + modules - private config
|
||||
`((setq doom-private-dir "/tmp/does/not/exist")
|
||||
`((setq doom-init-modules-p t)
|
||||
(load-file ,user-init-file)
|
||||
(setq doom-modules ',doom-modules)
|
||||
(maphash (lambda (key plist)
|
||||
(let ((doom--current-module key)
|
||||
(doom--current-flags (plist-get plist :flags)))
|
||||
(load! "init" (plist-get plist :path) t)))
|
||||
(load! "init" (doom-module-locate-path (car key) (cdr key)) t)))
|
||||
doom-modules)
|
||||
(maphash (lambda (key plist)
|
||||
(let ((doom--current-module key)
|
||||
(doom--current-flags (plist-get plist :flags)))
|
||||
(load! "config" (plist-get plist :path) t)))
|
||||
(load! "config" (doom-module-locate-path (car key) (cdr key)) t)))
|
||||
doom-modules)
|
||||
(run-hook-wrapped 'doom-init-modules-hook #'doom-try-run-hook)
|
||||
(doom-run-all-startup-hooks-h)))
|
||||
(`vanilla-doom ; only Doom core
|
||||
`((setq doom-private-dir "/tmp/does/not/exist"
|
||||
doom-init-modules-p t)
|
||||
`((setq doom-init-modules-p t)
|
||||
(load-file ,user-init-file)
|
||||
(doom-run-all-startup-hooks-h)))
|
||||
(`vanilla ; nothing loaded
|
||||
|
@ -378,42 +384,6 @@ will be automatically appended to the result."
|
|||
(profiler-stop))
|
||||
(setq doom--profiler (not doom--profiler)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/profile-emacs ()
|
||||
"Profile the startup time of Emacs in the background with ESUP.
|
||||
If INIT-FILE is non-nil, profile that instead of USER-INIT-FILE."
|
||||
(interactive)
|
||||
(require 'esup)
|
||||
(let ((init-file esup-user-init-file))
|
||||
(message "Starting esup...")
|
||||
(esup-reset)
|
||||
(setq esup-server-process (esup-server-create (esup-select-port)))
|
||||
(setq esup-server-port (process-contact esup-server-process :service))
|
||||
(message "esup process started on port %s" esup-server-port)
|
||||
(let ((process-args
|
||||
(append `("*esup-child*"
|
||||
"*esup-child*"
|
||||
,esup-emacs-path
|
||||
"-Q"
|
||||
"--eval=(setq after-init-time nil)"
|
||||
"-L" ,esup-load-path)
|
||||
(when (bound-and-true-p early-init-file)
|
||||
`("-l" ,early-init-file))
|
||||
`("-l" "esup-child"
|
||||
,(format "--eval=(let ((load-file-name \"%s\")) (esup-child-run \"%s\" \"%s\" %d))"
|
||||
init-file
|
||||
init-file
|
||||
esup-server-port
|
||||
esup-depth)
|
||||
"--eval=(doom-run-all-startup-hooks-h)"))))
|
||||
(when esup-run-as-batch-p
|
||||
(setq process-args (append process-args '("--batch"))))
|
||||
(setq esup-child-process (apply #'start-process process-args)))
|
||||
(set-process-sentinel esup-child-process 'esup-child-process-sentinel)))
|
||||
|
||||
;;;###autoload
|
||||
(advice-add #'esup :override #'doom/profile-emacs)
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/toggle-debug-mode (&optional arg)
|
||||
"Toggle `debug-on-error' and `doom-debug-mode' for verbose logging."
|
||||
|
|
|
@ -72,7 +72,8 @@ See `doom-init-fonts-h'."
|
|||
(interactive)
|
||||
(when doom-font
|
||||
(set-frame-font doom-font t))
|
||||
(mapc #'doom-init-fonts-h (frame-list)))
|
||||
(doom-init-fonts-h)
|
||||
(mapc #'doom-init-extra-fonts-h (frame-list)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/increase-font-size (count)
|
||||
|
|
|
@ -91,6 +91,7 @@ Accepts 'ansi and 'text-properties. nil means don't render colors.")
|
|||
;;
|
||||
;;; Library
|
||||
|
||||
;;;###autoload
|
||||
(defun doom--format (output)
|
||||
(if (string-empty-p (string-trim output))
|
||||
""
|
||||
|
@ -99,6 +100,7 @@ Accepts 'ansi and 'text-properties. nil means don't render colors.")
|
|||
"\n" (concat "\n" (make-string doom-format-indent 32))
|
||||
output t t))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom--format-print (output)
|
||||
(unless (string-empty-p output)
|
||||
(if (not noninteractive)
|
||||
|
@ -107,6 +109,7 @@ Accepts 'ansi and 'text-properties. nil means don't render colors.")
|
|||
(terpri)) ; newline
|
||||
t))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom--format-indent (width text &optional prefix)
|
||||
"Indent TEXT by WIDTH spaces. If ARGS, format TEXT with them."
|
||||
(with-temp-buffer
|
||||
|
@ -121,6 +124,7 @@ Accepts 'ansi and 'text-properties. nil means don't render colors.")
|
|||
(insert prefix)))
|
||||
(buffer-string)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom--format-autofill (&rest msgs)
|
||||
"Ensure MSG is split into lines no longer than `fill-column'."
|
||||
(with-temp-buffer
|
||||
|
@ -131,6 +135,7 @@ Accepts 'ansi and 'text-properties. nil means don't render colors.")
|
|||
(fill-region (point-min) (point-max))
|
||||
(buffer-string))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom--format-color (style format &rest args)
|
||||
"Apply STYLE to formatted MESSAGE with ARGS.
|
||||
|
||||
|
@ -159,6 +164,7 @@ Otherwise, it maps colors to a term-color-* face."
|
|||
((cddr (assq style doom-format-ansi-alist)))))))
|
||||
(_ message))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom--format-class (class format &rest args)
|
||||
"Apply CLASS to formatted format with ARGS.
|
||||
|
||||
|
@ -172,6 +178,7 @@ transformative logic."
|
|||
(args (apply #'format format args))
|
||||
(format))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom--format-apply (forms &optional sub)
|
||||
"Replace color-name functions with calls to `doom--format-color'."
|
||||
(cond ((null forms) nil)
|
||||
|
|
|
@ -147,7 +147,7 @@ selection of all minor-modes, active or not."
|
|||
(list (or (+org-get-property "TITLE")
|
||||
(file-relative-name buffer-file-name))))
|
||||
path
|
||||
(list (replace-regexp-in-string org-any-link-re "\\4" text)))
|
||||
(list (replace-regexp-in-string org-link-any-re "\\4" text)))
|
||||
" > ")
|
||||
tags)
|
||||
" ")
|
||||
|
@ -366,15 +366,6 @@ current file is in, or d) the module associated with the current major mode (see
|
|||
(recenter)
|
||||
(message "Couldn't find the config block"))))))))
|
||||
|
||||
(defvar doom--help-packages-list nil)
|
||||
(defun doom--help-packages-list (&optional refresh)
|
||||
(or (unless refresh
|
||||
doom--help-packages-list)
|
||||
(setq doom--help-packages-list
|
||||
(append (cl-loop for package in doom-core-packages
|
||||
collect (list package :modules '((:core internal))))
|
||||
(doom-package-list 'all)))))
|
||||
|
||||
(defun doom--help-package-configs (package)
|
||||
;; TODO Add git checks, in case ~/.emacs.d isn't a git repo
|
||||
(let ((default-directory doom-emacs-dir))
|
||||
|
@ -394,16 +385,16 @@ defined and configured.
|
|||
|
||||
If prefix arg is present, refresh the cache."
|
||||
(interactive
|
||||
(let* ((guess (or (function-called-at-point)
|
||||
(let ((guess (or (function-called-at-point)
|
||||
(symbol-at-point))))
|
||||
(require 'finder-inf nil t)
|
||||
(require 'package)
|
||||
(unless package--initialized
|
||||
(package-initialize t))
|
||||
(let ((packages (cl-delete-duplicates
|
||||
(append (mapcar 'car package-alist)
|
||||
(mapcar 'car package--builtins)
|
||||
(mapcar 'car (doom--help-packages-list))
|
||||
(require 'core-packages)
|
||||
(doom-initialize-packages)
|
||||
(let ((packages (delete-dups
|
||||
(append (mapcar #'car package-alist)
|
||||
(mapcar #'car package--builtins)
|
||||
(mapcar #'intern (hash-table-keys straight--build-cache))
|
||||
(mapcar #'car (doom-package-list 'all))
|
||||
nil))))
|
||||
(unless (memq guess packages)
|
||||
(setq guess nil))
|
||||
|
@ -415,6 +406,8 @@ If prefix arg is present, refresh the cache."
|
|||
"Describe package: ")
|
||||
packages nil t nil nil
|
||||
(if guess (symbol-name guess))))))))
|
||||
(require 'core-packages)
|
||||
(doom-initialize-packages)
|
||||
(if (or (package-desc-p package)
|
||||
(and (symbolp package)
|
||||
(or (assq package package-alist)
|
||||
|
@ -425,8 +418,7 @@ If prefix arg is present, refresh the cache."
|
|||
(with-help-window (help-buffer)))
|
||||
(save-excursion
|
||||
(with-current-buffer (help-buffer)
|
||||
(let ((doom-packages (doom--help-packages-list))
|
||||
(inhibit-read-only t)
|
||||
(let ((inhibit-read-only t)
|
||||
(indent (make-string 13 ? )))
|
||||
(goto-char (point-max))
|
||||
(if (re-search-forward "^ *Status: " nil t)
|
||||
|
@ -441,7 +433,10 @@ If prefix arg is present, refresh the cache."
|
|||
(package--print-help-section "Source")
|
||||
(insert (or (pcase (doom-package-backend package)
|
||||
(`straight
|
||||
(format! "Straight\n%s"
|
||||
(format! "Straight (%s)\n%s"
|
||||
(let ((default-directory (straight--build-dir (symbol-name package))))
|
||||
(string-trim
|
||||
(shell-command-to-string "git log -1 --format=\"%D %h %ci\"")))
|
||||
(indent
|
||||
13 (string-trim
|
||||
(pp-to-string
|
||||
|
@ -453,7 +448,7 @@ If prefix arg is present, refresh the cache."
|
|||
"unknown")
|
||||
"\n")
|
||||
|
||||
(when (assq package doom-packages)
|
||||
(when (gethash (symbol-name package) straight--build-cache)
|
||||
(package--print-help-section "Modules")
|
||||
(insert "Declared by the following Doom modules:\n")
|
||||
(dolist (m (doom-package-get package :modules))
|
||||
|
@ -548,7 +543,7 @@ If prefix arg is present, refresh the cache."
|
|||
|
||||
;;;###autoload
|
||||
(defun doom/help-package-config (package)
|
||||
"Jump to any `def-package!', `after!' or ;;;###package block for PACKAGE.
|
||||
"Jump to any `use-package!', `after!' or ;;;###package block for PACKAGE.
|
||||
|
||||
This only searches `doom-emacs-dir' (typically ~/.emacs.d) and does not include
|
||||
config blocks in your private config."
|
||||
|
|
|
@ -131,10 +131,10 @@ was installed with."
|
|||
;;
|
||||
;;; Package list getters
|
||||
|
||||
(defun doom--read-module-packages-file (file &optional eval noerror)
|
||||
(defun doom--read-module-packages-file (file &optional noeval noerror)
|
||||
(with-temp-buffer ; prevent buffer-local settings from propagating
|
||||
(condition-case e
|
||||
(if (not eval)
|
||||
(if (not noeval)
|
||||
(load file noerror t t)
|
||||
(when (file-readable-p file)
|
||||
(insert-file-contents file)
|
||||
|
@ -165,7 +165,7 @@ This excludes core packages listed in `doom-core-packages'.
|
|||
|
||||
If ALL-P, gather packages unconditionally across all modules, including disabled
|
||||
ones."
|
||||
(let ((noninteractive t)
|
||||
(let ((doom-interactive-mode t)
|
||||
(doom-modules (doom-modules))
|
||||
doom-packages
|
||||
doom-disabled-packages)
|
||||
|
|
|
@ -92,8 +92,8 @@
|
|||
(let ((session-file (doom-session-file)))
|
||||
(list (or (read-file-name "Session to restore: "
|
||||
(file-name-directory session-file)
|
||||
nil t
|
||||
(file-name-nondirectory session-file))
|
||||
(file-name-nondirectory session-file)
|
||||
t)
|
||||
(user-error "No session selected. Aborting")))))
|
||||
(unless file
|
||||
(error "No session file selected"))
|
||||
|
@ -107,7 +107,6 @@
|
|||
(let ((session-file (doom-session-file)))
|
||||
(list (or (read-file-name "Save session to: "
|
||||
(file-name-directory session-file)
|
||||
nil nil
|
||||
(file-name-nondirectory session-file))
|
||||
(user-error "No session selected. Aborting")))))
|
||||
(unless file
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
(cond ((listp (car spec))
|
||||
(cl-loop for face in (car spec)
|
||||
collect
|
||||
(doom--custom-theme-set-face `(,face ,(cdr spec)))))
|
||||
(car (doom--custom-theme-set-face (cons face (cdr spec))))))
|
||||
((keywordp (cadr spec))
|
||||
`((,(car spec) ((t ,(cdr spec))))))
|
||||
(`((,(car spec) ,(cdr spec))))))
|
||||
|
@ -44,7 +44,5 @@ face format."
|
|||
(let ((theme (or (car-safe custom-enabled-themes) doom-theme)))
|
||||
(when theme
|
||||
(mapc #'disable-theme custom-enabled-themes))
|
||||
(when (and doom-theme (not (memq doom-theme custom-enabled-themes)))
|
||||
(let (doom--prefer-theme-elc)
|
||||
(load-theme doom-theme t)))
|
||||
(doom-init-fonts-h)))
|
||||
(load-theme doom-theme 'noconfirm)
|
||||
(doom/reload-font)))
|
||||
|
|
|
@ -169,35 +169,67 @@ OPACITY is an integer between 0 to 100, inclusive."
|
|||
100))))
|
||||
(set-frame-parameter nil 'alpha opacity))
|
||||
|
||||
(defvar-local doom--buffer-narrowed-origin nil)
|
||||
(defvar-local doom--buffer-narrowed-window-start nil)
|
||||
(defvar doom--narrowed-base-buffer nil)
|
||||
;;;###autoload
|
||||
(defun doom/clone-and-narrow-buffer (beg end &optional clone-p)
|
||||
"Restrict editing in this buffer to the current region, indirectly. With CLONE-P,
|
||||
clone the buffer and hard-narrow the selection. If mark isn't active, then widen
|
||||
the buffer (if narrowed).
|
||||
(defun doom/narrow-buffer-indirectly (beg end)
|
||||
"Restrict editing in this buffer to the current region, indirectly.
|
||||
|
||||
This recursively creates indirect clones of the current buffer so that the
|
||||
narrowing doesn't affect other windows displaying the same buffer. Call
|
||||
`doom/widen-indirectly-narrowed-buffer' to undo it (incrementally).
|
||||
|
||||
Inspired from http://demonastery.org/2013/04/emacs-evil-narrow-region/"
|
||||
(interactive
|
||||
(list (or (bound-and-true-p evil-visual-beginning) (region-beginning))
|
||||
(or (bound-and-true-p evil-visual-end) (region-end))
|
||||
current-prefix-arg))
|
||||
(cond ((or (region-active-p)
|
||||
(not (buffer-narrowed-p)))
|
||||
(unless (region-active-p)
|
||||
(setq beg (line-beginning-position)
|
||||
end (line-end-position)))
|
||||
(setq deactivate-mark t)
|
||||
(when clone-p
|
||||
(let ((old-buf (current-buffer)))
|
||||
(switch-to-buffer (clone-indirect-buffer nil nil))
|
||||
(setq doom--buffer-narrowed-origin old-buf)))
|
||||
(setq doom--buffer-narrowed-window-start (window-start))
|
||||
(narrow-to-region beg end))
|
||||
(doom--buffer-narrowed-origin
|
||||
(kill-current-buffer)
|
||||
(switch-to-buffer doom--buffer-narrowed-origin)
|
||||
(setq doom--buffer-narrowed-origin nil))
|
||||
(t
|
||||
(deactivate-mark)
|
||||
(let ((orig-buffer (current-buffer)))
|
||||
(with-current-buffer (switch-to-buffer (clone-indirect-buffer nil nil))
|
||||
(narrow-to-region beg end)
|
||||
(setq-local doom--narrowed-base-buffer orig-buffer))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/widen-indirectly-narrowed-buffer (&optional arg)
|
||||
"Widens narrowed buffers.
|
||||
|
||||
This command will incrementally kill indirect buffers (under the assumption they
|
||||
were created by `doom/narrow-buffer-indirectly') and switch to their base
|
||||
buffer.
|
||||
|
||||
If ARG, then kill all indirect buffers, return the base buffer and widen it.
|
||||
|
||||
If the current buffer is not an indirect buffer, it is `widen'ed."
|
||||
(interactive "P")
|
||||
(unless (buffer-narrowed-p)
|
||||
(user-error "Buffer isn't narrowed"))
|
||||
(let ((orig-buffer (current-buffer))
|
||||
(base-buffer doom--narrowed-base-buffer))
|
||||
(cond ((or (not base-buffer)
|
||||
(not (buffer-live-p base-buffer)))
|
||||
(widen))
|
||||
(arg
|
||||
(let ((buffer orig-buffer)
|
||||
(buffers-to-kill (list orig-buffer)))
|
||||
(while (setq buffer (buffer-local-value 'doom--narrowed-base-buffer buffer))
|
||||
(push buffer buffers-to-kill))
|
||||
(switch-to-buffer (buffer-base-buffer))
|
||||
(mapc #'kill-buffer (remove (current-buffer) buffers-to-kill))))
|
||||
((switch-to-buffer base-buffer)
|
||||
(kill-buffer orig-buffer)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/toggle-narrow-buffer (beg end)
|
||||
"Narrow the buffer to BEG END. If narrowed, widen it."
|
||||
(interactive
|
||||
(list (or (bound-and-true-p evil-visual-beginning) (region-beginning))
|
||||
(or (bound-and-true-p evil-visual-end) (region-end))))
|
||||
(if (buffer-narrowed-p)
|
||||
(widen)
|
||||
(set-window-start nil doom--buffer-narrowed-window-start))))
|
||||
(unless (region-active-p)
|
||||
(setq beg (line-beginning-position)
|
||||
end (line-end-position)))
|
||||
(narrow-to-region beg end)))
|
||||
|
|
|
@ -27,6 +27,8 @@ byte-compiles `doom-autoload-file', as well as `doom-package-autoload-file'
|
|||
|
||||
It also caches `load-path', `Info-directory-list', `doom-disabled-packages',
|
||||
`package-activated-list' and `auto-mode-alist'."
|
||||
;; REVIEW Can we avoid calling `straight-check-all' everywhere?
|
||||
(straight-check-all)
|
||||
(doom-reload-autoloads nil 'force))
|
||||
|
||||
|
||||
|
@ -357,7 +359,7 @@ This should be run whenever your `doom!' block or update your packages."
|
|||
(print-group!
|
||||
(if (and (not force-p)
|
||||
(file-exists-p doom-package-autoload-file)
|
||||
(not (file-newer-than-file-p doom-elpa-dir doom-package-autoload-file))
|
||||
(not (file-newer-than-file-p package-user-dir doom-package-autoload-file))
|
||||
(not (cl-loop for dir in (straight--directory-files (straight--build-dir))
|
||||
if (cl-find-if
|
||||
(lambda (dir)
|
||||
|
@ -377,7 +379,7 @@ This should be run whenever your `doom!' block or update your packages."
|
|||
(noninteractive t)
|
||||
(backup-inhibited t)
|
||||
(version-control 'never)
|
||||
(case-fold-search nil) ; reduce magit
|
||||
(case-fold-search nil) ; reduce magic
|
||||
(autoload-timestamps nil))
|
||||
(print! (start "Regenerating package autoloads file"))
|
||||
|
||||
|
|
|
@ -92,10 +92,9 @@ If RECOMPILE-P is non-nil, only recompile out-of-date files."
|
|||
|
||||
;; But first we must be sure that Doom and your private config have been
|
||||
;; fully loaded. Which usually aren't so in an noninteractive session.
|
||||
(let (noninteractive)
|
||||
(let ((doom-interactive-mode 'byte-compile))
|
||||
(doom-initialize 'force)
|
||||
(doom-initialize-core)
|
||||
(doom-initialize-modules 'force))
|
||||
(doom-initialize-core))
|
||||
|
||||
;;
|
||||
(unless target-dirs
|
||||
|
|
|
@ -22,22 +22,23 @@ This file is automatically regenerated when you run this command or 'doom
|
|||
refresh'. However, 'doom refresh' will only regenerate this file if it exists.
|
||||
|
||||
Use the -c or --clear switch to delete your envvar file."
|
||||
(let ((default-directory doom-emacs-dir))
|
||||
(when (member "clear" args) ; DEPRECATED
|
||||
(message "'doom env clear' is deprecated. Use 'doom env -c' or 'doom env --clear' instead")
|
||||
(push "-c" args))
|
||||
|
||||
(let ((env-file (or (cadr (member "-o" args))
|
||||
doom-env-file)))
|
||||
(cond ((or (member "-c" args)
|
||||
(member "--clear" args))
|
||||
(unless (file-exists-p doom-env-file)
|
||||
(unless (file-exists-p env-file)
|
||||
(user-error! "%S does not exist to be cleared"
|
||||
(relpath doom-env-file)))
|
||||
(delete-file doom-env-file)
|
||||
(path env-file)))
|
||||
(delete-file env-file)
|
||||
(print! (success "Successfully deleted %S")
|
||||
(relpath doom-env-file)))
|
||||
(path env-file)))
|
||||
|
||||
((null args)
|
||||
(doom-reload-env-file 'force))
|
||||
((or (null args)
|
||||
(member "-o" args))
|
||||
(doom-reload-env-file 'force env-file))
|
||||
|
||||
((user-error "I don't understand 'doom env %s'"
|
||||
(string-join args " "))))))
|
||||
|
@ -58,6 +59,7 @@ Use the -c or --clear switch to delete your envvar file."
|
|||
"^INSECURE$"
|
||||
"^DEBUG$"
|
||||
"^YES$"
|
||||
"^TERM$"
|
||||
"^__")
|
||||
"Environment variables to not save in `doom-env-file'.
|
||||
|
||||
|
@ -79,21 +81,23 @@ It is rare that you'll need to change this.")
|
|||
This is a list of strings. Each entry is run separately and in sequence with
|
||||
`doom-env-executable' to scrape envvars from your shell environment.")
|
||||
|
||||
;; Borrows heavily from Spacemacs' `spacemacs//init-spacemacs-env'.
|
||||
(defun doom-reload-env-file (&optional force-p)
|
||||
(defun doom-reload-env-file (&optional force-p env-file)
|
||||
"Generates `doom-env-file', if it doesn't exist (or if FORCE-P).
|
||||
|
||||
This scrapes the variables from your shell environment by running
|
||||
`doom-env-executable' through `shell-file-name' with `doom-env-switches'. By
|
||||
default, on Linux, this is '$SHELL -ic /usr/bin/env'. Variables in
|
||||
`doom-env-ignored-vars' are removed."
|
||||
(when (or force-p (not (file-exists-p doom-env-file)))
|
||||
(with-temp-file doom-env-file
|
||||
(let ((env-file (if env-file
|
||||
(expand-file-name env-file)
|
||||
doom-env-file)))
|
||||
(when (or force-p (not (file-exists-p env-file)))
|
||||
(with-temp-file env-file
|
||||
(print! (start "%s envvars file at %S")
|
||||
(if (file-exists-p doom-env-file)
|
||||
(if (file-exists-p env-file)
|
||||
"Regenerating"
|
||||
"Generating")
|
||||
(relpath doom-env-file doom-emacs-dir))
|
||||
(path env-file))
|
||||
(let ((process-environment doom--initial-process-environment))
|
||||
(let ((shell-command-switch doom-env-switches)
|
||||
(error-buffer (get-buffer-create "*env errors*")))
|
||||
|
@ -106,7 +110,7 @@ default, on Linux, this is '$SHELL -ic /usr/bin/env'. Variables in
|
|||
(print-group!
|
||||
(let ((errors (with-current-buffer error-buffer (buffer-string))))
|
||||
(unless (string-empty-p errors)
|
||||
(print! (info "Error output:\n\n%s") (indent 4 errors))))
|
||||
(print! (info "Warnings:\n\n%s") (indent 4 errors))))
|
||||
;; Remove undesireable variables
|
||||
(insert
|
||||
(concat
|
||||
|
@ -121,8 +125,9 @@ default, on Linux, this is '$SHELL -ic /usr/bin/env'. Variables in
|
|||
"# in doom-env-ignored-vars).\n"
|
||||
"#\n"
|
||||
"# It is NOT safe to edit this file. Changes will be overwritten next time that\n"
|
||||
"# `doom refresh` is executed. Alternatively, create your own env file and load\n"
|
||||
"# it with `(doom-load-envvars-file FILE)` in your private config.el.\n"
|
||||
"# `doom refresh` is executed. Alternatively, create your own env file with\n"
|
||||
"# `doom env -o ~/.doom.d/myenv`, then load it with (doom-load-envvars-file FILE)\n"
|
||||
"# in your private config.el.\n"
|
||||
"# ---------------------------------------------------------------------------\n\n"))
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "\n\\([^= \n]+\\)=" nil t)
|
||||
|
@ -138,5 +143,5 @@ default, on Linux, this is '$SHELL -ic /usr/bin/env'. Variables in
|
|||
(print! (info "Ignoring %s") var)
|
||||
(delete-region (match-beginning 0) (1- valend)))))))
|
||||
(print! (success "Successfully generated %S")
|
||||
(relpath doom-env-file doom-emacs-dir))
|
||||
t)))))
|
||||
(path env-file))
|
||||
t))))))
|
||||
|
|
|
@ -8,15 +8,15 @@ See 'doom help install' instead."
|
|||
(apply #'doom-cli-install args))
|
||||
|
||||
(defcli! (install i) (&rest args)
|
||||
"A wizard for installing Doom for the first time.
|
||||
"Installs and sets up Doom Emacs for the first time.
|
||||
|
||||
This command does the following:
|
||||
|
||||
1. Creates DOOMDIR at ~/.doom.d,
|
||||
2. Copies ~/.emacs.d/init.example.el to DOOMDIR/init.el (if it doesn't exist),
|
||||
3. Creates dummy files for DOOMDIR/{config,packages}.el,
|
||||
4. Prompts you to generate an envvar file (via 'doom env refresh'),
|
||||
5. Installs any dependencies of enabled modules (specified by DOOMDIR/init.el),
|
||||
2. Copies ~/.emacs.d/init.example.el to $DOOMDIR/init.el (if it doesn't exist),
|
||||
3. Creates dummy files for $DOOMDIR/{config,packages}.el,
|
||||
4. Prompts you to generate an envvar file (same as 'doom env'),
|
||||
5. Installs any dependencies of enabled modules (specified by $DOOMDIR/init.el),
|
||||
6. And prompts to install all-the-icons' fonts
|
||||
|
||||
This command is idempotent and safe to reuse.
|
||||
|
@ -27,7 +27,7 @@ DOOMDIR environment variable. e.g.
|
|||
doom -p ~/.config/doom install
|
||||
DOOMDIR=~/.config/doom doom install
|
||||
|
||||
install understands the following switches:
|
||||
The following switches are recognized:
|
||||
|
||||
--no-config Don't create DOOMDIR or dummy files therein
|
||||
--no-install Don't auto-install packages
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
(defmacro doom--ensure-autoloads-while (&rest body)
|
||||
`(progn
|
||||
(straight-check-all)
|
||||
(doom-reload-core-autoloads)
|
||||
(when (progn ,@body)
|
||||
(doom-reload-package-autoloads 'force-p))
|
||||
|
@ -19,11 +20,16 @@ This works by fetching all installed package repos and checking the distance
|
|||
between HEAD and FETCH_HEAD. This can take a while.
|
||||
|
||||
This excludes packages whose `package!' declaration contains a non-nil :freeze
|
||||
or :ignore property."
|
||||
or :ignore property.
|
||||
|
||||
Switches:
|
||||
-t/--timeout TTL Seconds until a thread is timed out (default: 45)
|
||||
--threads N How many threads to use (default: 8)"
|
||||
(doom--ensure-autoloads-while
|
||||
(straight-check-all)
|
||||
(doom-packages-update
|
||||
doom-auto-accept
|
||||
(when-let (threads (cadr (member "--threads" args)))
|
||||
(string-to-number threads))
|
||||
(when-let (timeout (cadr (or (member "--timeout" args)
|
||||
(member "-t" args))))
|
||||
(string-to-number timeout)))))
|
||||
|
@ -32,26 +38,33 @@ or :ignore property."
|
|||
"Rebuilds all installed packages.
|
||||
|
||||
This ensures that all needed files are symlinked from their package repo and
|
||||
their elisp files are byte-compiled."
|
||||
their elisp files are byte-compiled.
|
||||
|
||||
Switches:
|
||||
-f Forcibly rebuild autoloads files, even if they're up-to-date"
|
||||
(doom--ensure-autoloads-while
|
||||
(doom-packages-rebuild doom-auto-accept (member "-f" args))))
|
||||
|
||||
(defcli! (purge p) (&rest args)
|
||||
"Deletes any unused ELPA packages, straight builds, and (optionally) repos.
|
||||
|
||||
By default, this does not purge repos.
|
||||
By default, this does not purge ELPA packages or repos. It is a good idea to run
|
||||
'doom purge --all' once in a while, to stymy build-up of repos and ELPA
|
||||
packages that could be taking up precious space.
|
||||
|
||||
Available options:
|
||||
|
||||
--no-elpa Don't purge ELPA packages
|
||||
Switches:
|
||||
--no-builds Don't purge unneeded (built) packages
|
||||
--repos Purge unused repos"
|
||||
-e / --elpa Don't purge ELPA packages
|
||||
-r / --repos Purge unused repos
|
||||
--all Purge builds, elpa packages and repos"
|
||||
(doom--ensure-autoloads-while
|
||||
(straight-check-all)
|
||||
(doom-packages-purge (not (member "--no-elpa" args))
|
||||
(doom-packages-purge (or (member "-e" args)
|
||||
(member "--elpa" args)
|
||||
(member "--all" args))
|
||||
(not (member "--no-builds" args))
|
||||
(or (member "-r" args)
|
||||
(member "--repos" args))
|
||||
(member "--repos" args)
|
||||
(member "--all" args))
|
||||
doom-auto-accept)))
|
||||
|
||||
;; (defcli! rollback () ; TODO rollback
|
||||
|
@ -147,12 +160,11 @@ a list of packages that will be installed."
|
|||
(condition-case e
|
||||
(let (packages errors)
|
||||
(load ,(concat doom-core-dir "core.el"))
|
||||
(doom-initialize 'force-p)
|
||||
(doom-initialize 'force)
|
||||
(dolist (recipe ',group)
|
||||
(when (straight--repository-is-available-p recipe)
|
||||
(straight-vc-git--destructure recipe
|
||||
(package local-repo nonrecursive upstream-remote upstream-repo upstream-host
|
||||
branch remote)
|
||||
(package local-repo nonrecursive upstream-remote upstream-repo upstream-host branch)
|
||||
(condition-case e
|
||||
(let ((default-directory (straight--repos-dir local-repo)))
|
||||
;; HACK We normalize packages to avoid certain scenarios
|
||||
|
@ -162,7 +174,7 @@ a list of packages that will be installed."
|
|||
;; can't use `straight-normalize-package' because could
|
||||
;; create popup prompts too, so we do it manually:
|
||||
(shell-command-to-string "git merge --abort")
|
||||
(straight--get-call "git" "reset" "--hard" (format "%s/%s" remote branch))
|
||||
(straight--get-call "git" "reset" "--hard" branch)
|
||||
(straight--get-call "git" "clean" "-ffd")
|
||||
(unless nonrecursive
|
||||
(shell-command-to-string "git submodule update --init --recursive"))
|
||||
|
@ -208,7 +220,7 @@ a list of packages that will be installed."
|
|||
(cons 'error e))))))
|
||||
|
||||
|
||||
(defun doom-packages-update (&optional auto-accept-p timeout)
|
||||
(defun doom-packages-update (&optional auto-accept-p threads timeout)
|
||||
"Updates packages.
|
||||
|
||||
Unless AUTO-ACCEPT-P is non-nil, this function will prompt for confirmation with
|
||||
|
@ -217,14 +229,17 @@ a list of packages that will be updated."
|
|||
(print-group!
|
||||
(when timeout
|
||||
(print! (info "Using %S as timeout value" timeout)))
|
||||
(when threads
|
||||
(print! (info "Limiting to %d thread(s)" threads)))
|
||||
;; REVIEW Does this fail gracefully enough? Is it error tolerant?
|
||||
;; TODO Add version-lock checks; don't want to spend all this effort on
|
||||
;; packages that shouldn't be updated
|
||||
(let* ((futures
|
||||
;; REVIEW We can do better "thread" management here
|
||||
(or (cl-loop for group
|
||||
in (seq-partition (hash-table-values straight--repo-cache)
|
||||
(/ (hash-table-count straight--repo-cache)
|
||||
16))
|
||||
(or threads 8)))
|
||||
for future = (doom--packages-remove-outdated-f group)
|
||||
if (processp future)
|
||||
collect (cons future group)
|
||||
|
@ -422,18 +437,21 @@ a list of packages that will be updated."
|
|||
(defun doom--packages-purge-elpa (&optional auto-accept-p)
|
||||
(unless (bound-and-true-p package--initialized)
|
||||
(package-initialize))
|
||||
(let ((packages (cl-loop for (package desc) in package-alist
|
||||
for dir = (package-desc-dir desc)
|
||||
if (file-in-directory-p dir package-user-dir)
|
||||
collect (cons package dir))))
|
||||
(if (not package-alist)
|
||||
(progn (print! (info "No ELPA packages to purge"))
|
||||
0)
|
||||
(doom--prompt-columns-p
|
||||
(lambda (p) (format " + %-20.20s" p))
|
||||
(mapcar #'car package-alist) nil
|
||||
(mapcar #'car packages) nil
|
||||
(format! "Found %d orphaned ELPA packages. Purge them?"
|
||||
(length package-alist)))
|
||||
(mapc (doom-rpartial #'delete-directory 'recursive)
|
||||
(mapcar #'package-desc-dir
|
||||
(mapcar #'cadr package-alist)))
|
||||
(length package-alist)))
|
||||
(mapcar #'cdr packages))
|
||||
(length packages))))
|
||||
|
||||
(defun doom-packages-purge (&optional elpa-p builds-p repos-p auto-accept-p)
|
||||
"Auto-removes orphaned packages and repos.
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
;;; core/cli/patch-macos.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defcli! patch-macos () ; DEPRECATED
|
||||
"Patches Emacs.app to respect your shell environment.
|
||||
|
||||
WARNING: This command is deprecated. Use 'doom env' instead.
|
||||
|
||||
A common issue with GUI Emacs on MacOS is that it launches in an environment
|
||||
independent of your shell configuration, including your PATH and any other
|
||||
utilities like rbenv, rvm or virtualenv.
|
||||
|
||||
This patch fixes this by patching Emacs.app (in /Applications or
|
||||
~/Applications). It will:
|
||||
|
||||
1. Move Contents/MacOS/Emacs to Contents/MacOS/RunEmacs
|
||||
2. And replace Contents/MacOS/Emacs with the following wrapper script:
|
||||
|
||||
#!/user/bin/env bash
|
||||
args=\"$@\"
|
||||
pwd=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\"; pwd -P)\"
|
||||
exec \"$SHELL\" -l -c \"$pwd/RunEmacs $args\"
|
||||
|
||||
This ensures that Emacs is always aware of your shell environment, regardless of
|
||||
how it is launched.
|
||||
|
||||
It can be undone with the --undo or -u options.
|
||||
|
||||
Alternatively, you can install the exec-path-from-shell Emacs plugin, which will
|
||||
scrape your shell environment remotely, at startup. However, this can be slow
|
||||
depending on your shell configuration and isn't always reliable."
|
||||
:hidden t
|
||||
(doom-patch-macos (or (member "--undo" args)
|
||||
(member "-u" args))
|
||||
(doom--find-emacsapp-path)))
|
||||
|
||||
|
||||
;;
|
||||
;; Library
|
||||
|
||||
(defun doom--find-emacsapp-path ()
|
||||
(or (getenv "EMACS_APP_PATH")
|
||||
(cl-loop for dir in (list "/usr/local/opt/emacs"
|
||||
"/usr/local/opt/emacs-plus"
|
||||
"/Applications"
|
||||
"~/Applications")
|
||||
for appdir = (concat dir "/Emacs.app")
|
||||
if (file-directory-p appdir)
|
||||
return appdir)
|
||||
(user-error "Couldn't find Emacs.app")))
|
||||
|
||||
(defun doom-patch-macos (undo-p appdir)
|
||||
"Patches Emacs.app to respect your shell environment."
|
||||
(unless IS-MAC
|
||||
(user-error "You don't seem to be running MacOS"))
|
||||
(unless (file-directory-p appdir)
|
||||
(user-error "Couldn't find '%s'" appdir))
|
||||
(let ((oldbin (expand-file-name "Contents/MacOS/Emacs" appdir))
|
||||
(newbin (expand-file-name "Contents/MacOS/RunEmacs" appdir)))
|
||||
(cond (undo-p
|
||||
(unless (file-exists-p newbin)
|
||||
(user-error "Emacs.app is not patched"))
|
||||
(copy-file newbin oldbin 'ok-if-already-exists nil nil 'preserve-permissions)
|
||||
(unless (file-exists-p oldbin)
|
||||
(error "Failed to copy %s to %s" newbin oldbin))
|
||||
(delete-file newbin)
|
||||
(message "%s successfully unpatched" appdir))
|
||||
|
||||
((file-exists-p newbin)
|
||||
(user-error "%s is already patched. Use 'doom patch-macos --undo' to unpatch it"
|
||||
appdir))
|
||||
|
||||
((user-error "patch-macos has been disabled. Please use 'doom env refresh' instead")))))
|
|
@ -1,5 +1,12 @@
|
|||
;;; core/cli/test.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defun doom--emacs-binary ()
|
||||
(let ((emacs-binary-path (doom-path invocation-directory invocation-name))
|
||||
(runemacs-binary-path (if IS-WINDOWS (doom-path invocation-directory "runemacs.exe"))))
|
||||
(if (and runemacs-binary-path (file-exists-p runemacs-binary-path))
|
||||
runemacs-binary-path
|
||||
emacs-binary-path)))
|
||||
|
||||
(defcli! test (&rest targets)
|
||||
"Run Doom unit tests."
|
||||
(let (files error)
|
||||
|
@ -14,6 +21,7 @@
|
|||
(cdr (doom-module-load-path)))))))
|
||||
(while targets
|
||||
(let ((target (pop targets)))
|
||||
;; FIXME Module targets don't work
|
||||
(cond ((equal target ":core")
|
||||
(appendq! files (nreverse (doom-glob doom-core-dir "test/test-*.el"))))
|
||||
((file-directory-p target)
|
||||
|
@ -21,23 +29,21 @@
|
|||
(appendq! files (nreverse (doom-glob target "test/test-*.el"))))
|
||||
((file-exists-p target)
|
||||
(push target files)))))
|
||||
(require 'restart-emacs)
|
||||
(with-temp-buffer
|
||||
(setenv "DOOMDIR" (concat doom-core-dir "test/"))
|
||||
(setenv "DOOMLOCALDIR" (concat doom-local-dir "test/"))
|
||||
(print! (start "Bootstrapping test environment, if necessary..."))
|
||||
(if (zerop
|
||||
(call-process
|
||||
(restart-emacs--get-emacs-binary)
|
||||
(doom--emacs-binary)
|
||||
nil t nil "--batch"
|
||||
"-l" (concat doom-core-dir "core.el")
|
||||
"--eval" (prin1-to-string
|
||||
`(progn (doom-initialize 'force)
|
||||
`(progn
|
||||
(setq doom-emacs-dir ,doom-emacs-dir
|
||||
doom-local-dir ,(concat doom-local-dir "test/")
|
||||
doom-private-dir ,(concat doom-core-dir "test/"))
|
||||
(require 'core ,(locate-library "core"))
|
||||
(doom-initialize 'force)
|
||||
(doom-initialize-modules)
|
||||
(require 'core-cli)
|
||||
(unless (package-installed-p 'buttercup)
|
||||
(package-refresh-contents)
|
||||
(package-install 'buttercup))
|
||||
(doom-reload-core-autoloads 'force)
|
||||
(when (doom-packages-install 'auto-accept)
|
||||
(doom-reload-package-autoloads 'force))))))
|
||||
|
@ -49,18 +55,21 @@
|
|||
(with-temp-buffer
|
||||
(unless
|
||||
(zerop
|
||||
(call-process
|
||||
(restart-emacs--get-emacs-binary)
|
||||
(apply #'call-process
|
||||
(doom--emacs-binary)
|
||||
nil t nil "--batch"
|
||||
"-l" (concat doom-core-dir "core.el")
|
||||
"-l" (concat doom-core-dir "test/helpers.el")
|
||||
"--eval" (prin1-to-string `(doom-initialize 'force))
|
||||
"-l" "buttercup"
|
||||
(append (list
|
||||
"-L" doom-core-dir
|
||||
"-l" "core"
|
||||
"-l" (concat doom-core-dir "test/helpers.el"))
|
||||
(when (file-in-directory-p file doom-modules-dir)
|
||||
(list "-f" "doom-initialize-core"))
|
||||
(list
|
||||
"-l" file
|
||||
"-f" "buttercup-run"))
|
||||
"-f" "buttercup-run"))))
|
||||
(setq error t))
|
||||
(message "%s" (buffer-string)))
|
||||
(print! (info "Ignoring %s" (relpath file)))))
|
||||
(if error
|
||||
(error "A test failed")
|
||||
(user-error "A test failed")
|
||||
t)))
|
||||
|
|
|
@ -10,15 +10,26 @@ following shell commands:
|
|||
git pull --rebase
|
||||
bin/doom clean
|
||||
bin/doom refresh
|
||||
bin/doom update"
|
||||
(and (doom-upgrade (or (member "-f" args)
|
||||
bin/doom update
|
||||
|
||||
Switches:
|
||||
-t/--timeout TTL Seconds until a thread is timed out (default: 45)
|
||||
--threads N How many threads to use (default: 8)"
|
||||
(and (doom-upgrade doom-auto-accept
|
||||
(or (member "-f" args)
|
||||
(member "--force" args)))
|
||||
(doom-packages-update doom-auto-accept)
|
||||
(doom-packages-update
|
||||
doom-auto-accept
|
||||
(when-let (threads (cadr (member "--threads" args)))
|
||||
(string-to-number threads))
|
||||
(when-let (timeout (cadr (or (member "--timeout" args)
|
||||
(member "-t" args))))
|
||||
(string-to-number timeout)))
|
||||
(doom-reload-package-autoloads 'force-p)))
|
||||
|
||||
|
||||
;;
|
||||
;;; Library
|
||||
;;; library
|
||||
|
||||
(defvar doom-repo-url "https://github.com/hlissner/doom-emacs"
|
||||
"The git repo url for Doom Emacs.")
|
||||
|
@ -33,7 +44,7 @@ following shell commands:
|
|||
(error "Failed to check working tree in %s" dir))))
|
||||
|
||||
|
||||
(defun doom-upgrade (&optional force-p)
|
||||
(defun doom-upgrade (&optional auto-accept-p force-p)
|
||||
"Upgrade Doom to the latest version non-destructively."
|
||||
(require 'vc-git)
|
||||
(let ((default-directory doom-emacs-dir)
|
||||
|
@ -82,12 +93,15 @@ following shell commands:
|
|||
(substring new-rev 0 10)
|
||||
(cdr (doom-sh "git" "log" "-1" "--format=%cr" target-remote))))
|
||||
|
||||
(when (y-or-n-p "View the comparison diff in your browser?")
|
||||
(when (and (not auto-accept-p)
|
||||
(y-or-n-p "View the comparison diff in your browser?"))
|
||||
(print! (info "Opened github in your browser."))
|
||||
(browse-url (format "https://github.com/hlissner/doom-emacs/compare/%s...%s"
|
||||
this-rev
|
||||
new-rev)))
|
||||
(if (not (y-or-n-p "Proceed with upgrade?"))
|
||||
|
||||
(if (not (or auto-accept-p
|
||||
(y-or-n-p "Proceed with upgrade?")))
|
||||
(ignore (print! (error "Aborted")))
|
||||
(print! (start "Upgrading Doom Emacs..."))
|
||||
(print-group!
|
||||
|
@ -97,6 +111,7 @@ following shell commands:
|
|||
(error "Failed to check out %s" (substring new-rev 0 10)))
|
||||
(print! (success "Finished upgrading Doom Emacs")))
|
||||
(doom-delete-autoloads-file doom-autoload-file)
|
||||
(doom-delete-autoloads-file doom-package-autoload-file)
|
||||
(doom-cli-refresh "-f")
|
||||
t)
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ stale."
|
|||
(setq success t))
|
||||
(and (doom-packages-rebuild doom-auto-accept)
|
||||
(setq success t))
|
||||
(and (doom-packages-purge 'elpa-p 'builds-p nil doom-auto-accept)
|
||||
(and (doom-packages-purge nil 'builds-p nil doom-auto-accept)
|
||||
(setq success t)))
|
||||
(doom-reload-package-autoloads (or success force-p))
|
||||
(doom-byte-compile nil 'recompile))
|
||||
|
@ -212,8 +212,7 @@ enabled modules.")
|
|||
(load! "cli/env")
|
||||
(load! "cli/upgrade")
|
||||
(load! "cli/packages")
|
||||
(load! "cli/autoloads")
|
||||
(load! "cli/patch-macos"))
|
||||
(load! "cli/autoloads"))
|
||||
|
||||
(defcligroup! "Byte compilation"
|
||||
"For byte-compiling Doom and your config"
|
||||
|
|
|
@ -111,8 +111,8 @@ successfully sets indent_style/indent_size.")
|
|||
;;
|
||||
;; This is because autorevert abuses the heck out of inotify handles which can
|
||||
;; grind Emacs to a halt if you do expensive IO (outside of Emacs) on the
|
||||
;; files you have open (like compression). We only really need revert changes
|
||||
;; when we switch to a buffer or when we focus the Emacs frame.
|
||||
;; files you have open (like compression). We only really need to revert
|
||||
;; changes when we switch to a buffer or when we focus the Emacs frame.
|
||||
(defun doom-auto-revert-buffer-h ()
|
||||
"Auto revert current buffer, if necessary."
|
||||
(unless auto-revert-mode
|
||||
|
@ -168,7 +168,7 @@ successfully sets indent_style/indent_size.")
|
|||
"Add dired directory to recentf file list."
|
||||
(recentf-add-file default-directory)))
|
||||
|
||||
(unless noninteractive
|
||||
(when doom-interactive-mode
|
||||
(add-hook 'kill-emacs-hook #'recentf-cleanup)
|
||||
(quiet! (recentf-mode +1))))
|
||||
|
||||
|
@ -198,12 +198,22 @@ successfully sets indent_style/indent_size.")
|
|||
:after-call after-find-file dired-initial-position-hook
|
||||
:config
|
||||
(setq save-place-file (concat doom-cache-dir "saveplace")
|
||||
save-place-forget-unreadable-files t
|
||||
save-place-limit 200)
|
||||
save-place-limit 100)
|
||||
|
||||
(defadvice! doom--recenter-on-load-saveplace-a (&rest _)
|
||||
"Recenter on cursor when loading a saved place."
|
||||
:after-while #'save-place-find-file-hook
|
||||
(if buffer-file-name (ignore-errors (recenter))))
|
||||
|
||||
(defadvice! doom--dont-prettify-saveplace-cache-a (orig-fn)
|
||||
"`save-place-alist-to-file' uses `pp' to prettify the contents of its cache.
|
||||
`pp' can be expensive for longer lists, and there's no reason to prettify cache
|
||||
files, so we replace calls to `pp' with the much faster `prin1'."
|
||||
:around #'save-place-alist-to-file
|
||||
(cl-letf (((symbol-function #'pp)
|
||||
(symbol-function #'prin1)))
|
||||
(funcall orig-fn)))
|
||||
|
||||
(save-place-mode +1))
|
||||
|
||||
|
||||
|
@ -223,6 +233,10 @@ successfully sets indent_style/indent_size.")
|
|||
|
||||
(use-package! better-jumper
|
||||
:after-call pre-command-hook
|
||||
:preface
|
||||
;; REVIEW Suppress byte-compiler warning spawning a *Compile-Log* buffer at
|
||||
;; startup. This can be removed once gilbertw1/better-jumper#2 is merged.
|
||||
(defvar better-jumper-local-mode nil)
|
||||
:init
|
||||
(global-set-key [remap evil-jump-forward] #'better-jumper-jump-forward)
|
||||
(global-set-key [remap evil-jump-backward] #'better-jumper-jump-backward)
|
||||
|
@ -259,18 +273,9 @@ successfully sets indent_style/indent_size.")
|
|||
nil))
|
||||
|
||||
|
||||
(use-package! command-log-mode
|
||||
:commands global-command-log-mode
|
||||
:config
|
||||
(setq command-log-mode-auto-show t
|
||||
command-log-mode-open-log-turns-on-mode nil
|
||||
command-log-mode-is-global t
|
||||
command-log-mode-window-size 50))
|
||||
|
||||
|
||||
(use-package! dtrt-indent
|
||||
;; Automatic detection of indent settings
|
||||
:unless noninteractive
|
||||
:when doom-interactive-mode
|
||||
:defer t
|
||||
:init
|
||||
(add-hook! '(change-major-mode-after-body-hook read-only-mode-hook)
|
||||
|
@ -389,8 +394,17 @@ successfully sets indent_style/indent_size.")
|
|||
(sp-local-pair 'minibuffer-inactive-mode "`" nil :actions nil)
|
||||
|
||||
;; Smartparens breaks evil-mode's replace state
|
||||
(add-hook 'evil-replace-state-entry-hook #'turn-off-smartparens-mode)
|
||||
(add-hook 'evil-replace-state-exit-hook #'turn-on-smartparens-mode)
|
||||
(defvar doom-buffer-smartparens-mode nil)
|
||||
(add-hook! 'evil-replace-state-exit-hook
|
||||
(defun doom-enable-smartparens-mode-maybe-h ()
|
||||
(when doom-buffer-smartparens-mode
|
||||
(turn-on-smartparens-mode)
|
||||
(kill-local-variable 'doom-buffer-smartparens-mode))))
|
||||
(add-hook! 'evil-replace-state-entry-hook
|
||||
(defun doom-disable-smartparens-mode-maybe-h ()
|
||||
(when smartparens-mode
|
||||
(setq-local doom-buffer-smartparens-mode t)
|
||||
(turn-off-smartparens-mode))))
|
||||
|
||||
(smartparens-global-mode +1))
|
||||
|
||||
|
@ -412,11 +426,20 @@ successfully sets indent_style/indent_size.")
|
|||
undo-tree-history-directory-alist
|
||||
`(("." . ,(concat doom-cache-dir "undo-tree-hist/"))))
|
||||
|
||||
;; Compress undo-tree history files with zstd, if available. File size isn't
|
||||
;; the (only) concern here: the file IO barrier is slow for Emacs to cross;
|
||||
;; reading a tiny file and piping it in-memory through zstd is *slightly*
|
||||
;; faster than Emacs reading the entire undo-tree file from the get go (on
|
||||
;; SSDs). Whether or not that's true in practice, we still enjoy zstd's ~80%
|
||||
;; file savings (these files add up over time and zstd is so incredibly fast).
|
||||
(when (executable-find "zstd")
|
||||
(defadvice! doom--undo-tree-make-history-save-file-name-a (file)
|
||||
:filter-return #'undo-tree-make-history-save-file-name
|
||||
(concat file ".zst")))
|
||||
|
||||
;; Strip text properties from undo-tree data to stave off bloat. File size
|
||||
;; isn't the concern here; undo cache files bloat easily, which can cause
|
||||
;; freezing, crashes, GC-induced stuttering or delays when opening files.
|
||||
(defadvice! doom--undo-tree-strip-text-properties-a (&rest _)
|
||||
:before #'undo-list-transfer-to-tree
|
||||
(dolist (item buffer-undo-list)
|
||||
|
|
|
@ -23,6 +23,14 @@ and Emacs states, and for non-evil users.")
|
|||
"An overriding keymap for <leader> keys.")
|
||||
|
||||
|
||||
;;
|
||||
;;; Keybind settings
|
||||
|
||||
(when IS-MAC
|
||||
(setq mac-command-modifier 'super
|
||||
mac-option-modifier 'meta))
|
||||
|
||||
|
||||
;;
|
||||
;;; Universal, non-nuclear escape
|
||||
|
||||
|
@ -411,18 +419,7 @@ Properties
|
|||
:unless [CONDITION] [...]
|
||||
|
||||
Any of the above properties may be nested, so that they only apply to a
|
||||
certain group of keybinds.
|
||||
|
||||
Example
|
||||
(map! :map magit-mode-map
|
||||
:m \"C-r\" 'do-something ; C-r in motion state
|
||||
:nv \"q\" 'magit-mode-quit-window ; q in normal+visual states
|
||||
\"C-x C-r\" 'a-global-keybind
|
||||
:g \"C-x C-r\" 'another-global-keybind ; same as above
|
||||
|
||||
(:when IS-MAC
|
||||
:n \"M-s\" 'some-fn
|
||||
:i \"M-o\" (lambda (interactive) (message \"Hi\"))))"
|
||||
certain group of keybinds."
|
||||
(doom--map-process rest))
|
||||
|
||||
(provide 'core-keybinds)
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
;;; core-lib.el -*- lexical-binding: t; -*-
|
||||
|
||||
(let ((load-path doom--initial-load-path))
|
||||
(require 'cl-lib)
|
||||
(require 'subr-x)
|
||||
(require 'cl-lib))
|
||||
|
||||
;; Polyfills
|
||||
(unless EMACS26+
|
||||
|
@ -175,7 +174,7 @@ at the values with which this function was called."
|
|||
"Push VALUES sequentially into PLACE, if they aren't already present.
|
||||
This is a variadic `cl-pushnew'."
|
||||
(let ((var (make-symbol "result")))
|
||||
`(dolist (,var (list ,@values))
|
||||
`(dolist (,var (list ,@values) (with-no-warnings ,place))
|
||||
(cl-pushnew ,var ,place :test #'equal))))
|
||||
|
||||
(defmacro prependq! (sym &rest lists)
|
||||
|
@ -243,7 +242,7 @@ This macro accepts, in order:
|
|||
3. The function(s) to be added: this can be one function, a list thereof, a
|
||||
list of `defun's, or body forms (implicitly wrapped in a closure).
|
||||
|
||||
\(fn [:append :local] HOOKS FUNCTIONS)"
|
||||
\(fn HOOKS [:append :local] FUNCTIONS)"
|
||||
(declare (indent (lambda (indent-point state)
|
||||
(goto-char indent-point)
|
||||
(when (looking-at-p "\\s-*(")
|
||||
|
@ -295,17 +294,13 @@ Takes the same arguments as `add-hook!'.
|
|||
|
||||
If N and M = 1, there's no benefit to using this macro over `remove-hook'.
|
||||
|
||||
\(fn [:append :local] HOOKS FUNCTIONS)"
|
||||
\(fn HOOKS [:append :local] FUNCTIONS)"
|
||||
(declare (indent defun) (debug t))
|
||||
`(add-hook! ,hooks :remove ,@rest))
|
||||
|
||||
(defmacro setq-hook! (hooks &rest var-vals)
|
||||
"Sets buffer-local variables on HOOKS.
|
||||
|
||||
(setq-hook! 'markdown-mode-hook
|
||||
line-spacing 2
|
||||
fill-column 80)
|
||||
|
||||
\(fn HOOKS &rest [SYM VAL]...)"
|
||||
(declare (indent 1))
|
||||
(macroexp-progn
|
||||
|
@ -338,7 +333,10 @@ If NOERROR is non-nil, don't throw an error if the file doesn't exist."
|
|||
(setq path (or (dir!)
|
||||
(error "Could not detect path to look for '%s' in"
|
||||
filename))))
|
||||
(let ((file (if path `(expand-file-name ,filename ,path) filename)))
|
||||
(let ((file (if path
|
||||
`(let (file-name-handler-alist)
|
||||
(expand-file-name ,filename ,path))
|
||||
filename)))
|
||||
`(condition-case e
|
||||
(load ,file ,noerror ,(not doom-debug-mode))
|
||||
((debug doom-error) (signal (car e) (cdr e)))
|
||||
|
@ -372,36 +370,37 @@ serve as a predicated alternative to `after!'."
|
|||
(put ',fn 'permanent-local-hook t)
|
||||
(add-hook 'after-load-functions #',fn)))))
|
||||
|
||||
(defmacro defer-feature! (feature &optional mode)
|
||||
"Pretend FEATURE hasn't been loaded yet, until FEATURE-hook is triggered.
|
||||
(defmacro defer-feature! (feature &optional fn)
|
||||
"Pretend FEATURE hasn't been loaded yet, until FEATURE-hook or FN runs.
|
||||
|
||||
Some packages (like `elisp-mode' and `lisp-mode') are loaded immediately at
|
||||
startup, which will prematurely trigger `after!' (and `with-eval-after-load')
|
||||
blocks. To get around this we make Emacs believe FEATURE hasn't been loaded yet,
|
||||
then wait until FEATURE-hook (or MODE-hook, if MODE is provided) is triggered to
|
||||
then wait until FEATURE-hook (or MODE-hook, if FN is provided) is triggered to
|
||||
reverse this and trigger `after!' blocks at a more reasonable time."
|
||||
(let ((advice-fn (intern (format "doom--defer-feature-%s-a" feature)))
|
||||
(mode (or mode feature)))
|
||||
(fn (or fn feature)))
|
||||
`(progn
|
||||
(setq features (delq ',feature features))
|
||||
(advice-add #',mode :before #',advice-fn)
|
||||
(advice-add #',fn :before #',advice-fn)
|
||||
(defun ,advice-fn (&rest _)
|
||||
;; Some plugins (like yasnippet) will invoke a mode early to parse
|
||||
;; Some plugins (like yasnippet) will invoke a fn early to parse
|
||||
;; code, which would prematurely trigger this. In those cases, well
|
||||
;; behaved plugins will use `delay-mode-hooks', which we can check for:
|
||||
(when (and ,(intern (format "%s-hook" mode))
|
||||
(when (and ,(intern (format "%s-hook" fn))
|
||||
(not delay-mode-hooks))
|
||||
;; ...Otherwise, announce to the world this package has been loaded,
|
||||
;; so `after!' handlers can react.
|
||||
(provide ',feature)
|
||||
(advice-remove #',mode #',advice-fn))))))
|
||||
(advice-remove #',fn #',advice-fn))))))
|
||||
|
||||
(defmacro quiet! (&rest forms)
|
||||
"Run FORMS without generating any output.
|
||||
|
||||
This silences calls to `message', `load-file', `write-region' and anything that
|
||||
writes to `standard-output'."
|
||||
`(cond (noninteractive
|
||||
`(cond (doom-debug-mode ,@forms)
|
||||
((not doom-interactive-mode)
|
||||
(let ((old-fn (symbol-function 'write-region)))
|
||||
(cl-letf ((standard-output (lambda (&rest _)))
|
||||
((symbol-function 'load-file) (lambda (file) (load file nil t)))
|
||||
|
@ -411,8 +410,6 @@ writes to `standard-output'."
|
|||
(unless visit (setq visit 'no-message))
|
||||
(funcall old-fn start end filename append visit lockname mustbenew))))
|
||||
,@forms)))
|
||||
((or doom-debug-mode debug-on-error debug-on-quit)
|
||||
,@forms)
|
||||
((let ((inhibit-message t)
|
||||
(save-silently t))
|
||||
(prog1 ,@forms (message ""))))))
|
||||
|
|
|
@ -48,7 +48,7 @@ syntax-checker modules obsolete. e.g. If :feature version-control is found in
|
|||
your `doom!' block, a warning is emitted before replacing it with :emacs vc and
|
||||
:ui vc-gutter.")
|
||||
|
||||
(defvar doom-inhibit-module-warnings (not noninteractive)
|
||||
(defvar doom-inhibit-module-warnings doom-interactive-mode
|
||||
"If non-nil, don't emit deprecated or missing module warnings at startup.")
|
||||
|
||||
;;; Custom hooks
|
||||
|
@ -84,7 +84,7 @@ non-nil."
|
|||
(load! "init" (plist-get plist :path) t)))
|
||||
doom-modules))
|
||||
(run-hook-wrapped 'doom-before-init-modules-hook #'doom-try-run-hook)
|
||||
(unless noninteractive
|
||||
(when doom-interactive-mode
|
||||
(when doom-modules
|
||||
(maphash (lambda (key plist)
|
||||
(let ((doom--current-module key)
|
||||
|
@ -224,7 +224,7 @@ those directories. The first returned path is always `doom-private-dir'."
|
|||
"Minimally initialize `doom-modules' (a hash table) and return it.
|
||||
This value is cached. If REFRESH-P, then don't use the cached value."
|
||||
(or (unless refresh-p doom-modules)
|
||||
(let ((noninteractive t)
|
||||
(let (doom-interactive-mode
|
||||
doom-modules
|
||||
doom-init-modules-p)
|
||||
(load! "init" doom-private-dir t)
|
||||
|
@ -243,30 +243,16 @@ This value is cached. If REFRESH-P, then don't use the cached value."
|
|||
(setq use-package-compute-statistics doom-debug-mode
|
||||
use-package-verbose doom-debug-mode
|
||||
use-package-minimum-reported-time (if doom-debug-mode 0 0.1)
|
||||
use-package-expand-minimally (not noninteractive)))
|
||||
use-package-expand-minimally doom-interactive-mode))
|
||||
|
||||
;; Adds four new keywords to `use-package' (and consequently, `use-package!') to
|
||||
;; expand its lazy-loading capabilities. They are:
|
||||
;;
|
||||
;; Check out `use-package!'s documentation for more about these two.
|
||||
;; :after-call SYMBOL|LIST
|
||||
;; :defer-incrementally SYMBOL|LIST|t
|
||||
;;
|
||||
;; Provided by `auto-minor-mode' package:
|
||||
;; :minor
|
||||
;; :magic-minor
|
||||
;;
|
||||
(defvar doom--deferred-packages-alist '(t))
|
||||
|
||||
(with-eval-after-load 'use-package-core
|
||||
;; Macros are already fontified, no need for this
|
||||
(font-lock-remove-keywords 'emacs-lisp-mode use-package-font-lock-keywords)
|
||||
|
||||
;; Register all new keywords
|
||||
(dolist (keyword '(:defer-incrementally :after-call))
|
||||
(push keyword use-package-deferring-keywords)
|
||||
(setq use-package-keywords
|
||||
(use-package-list-insert keyword use-package-keywords :after)))
|
||||
;; We define :minor and :magic-minor from the `auto-minor-mode' package here
|
||||
;; so we don't have to load `auto-minor-mode' so early.
|
||||
(dolist (keyword '(:minor :magic-minor))
|
||||
(setq use-package-keywords
|
||||
(use-package-list-insert keyword use-package-keywords :commands)))
|
||||
|
@ -279,6 +265,17 @@ This value is cached. If REFRESH-P, then don't use the cached value."
|
|||
(defun use-package-handler/:magic-minor (name _ arg rest state)
|
||||
(use-package-handle-mode name 'auto-minor-mode-magic-alist arg rest state))
|
||||
|
||||
;; Adds two keywords to `use-package' to expand its lazy-loading capabilities:
|
||||
;;
|
||||
;; :after-call SYMBOL|LIST
|
||||
;; :defer-incrementally SYMBOL|LIST|t
|
||||
;;
|
||||
;; Check out `use-package!'s documentation for more about these two.
|
||||
(dolist (keyword '(:defer-incrementally :after-call))
|
||||
(push keyword use-package-deferring-keywords)
|
||||
(setq use-package-keywords
|
||||
(use-package-list-insert keyword use-package-keywords :after)))
|
||||
|
||||
(defalias 'use-package-normalize/:defer-incrementally #'use-package-normalize-symlist)
|
||||
(defun use-package-handler/:defer-incrementally (name _keyword targets rest state)
|
||||
(use-package-concat
|
||||
|
@ -410,7 +407,7 @@ to least)."
|
|||
(if-let (path (doom-module-locate-path category module))
|
||||
(doom-module-set category module :flags flags :path path)
|
||||
(message "WARNING Couldn't find the %s %s module" category module)))))))
|
||||
(when noninteractive
|
||||
(unless doom-interactive-mode
|
||||
(setq doom-inhibit-module-warnings t))
|
||||
`(setq doom-modules ',doom-modules)))
|
||||
|
||||
|
@ -428,26 +425,17 @@ two extra properties:
|
|||
:after-call SYMBOL|LIST
|
||||
Takes a symbol or list of symbols representing functions or hook variables.
|
||||
The first time any of these functions or hooks are executed, the package is
|
||||
loaded. e.g.
|
||||
|
||||
(use-package! projectile
|
||||
:after-call (pre-command-hook after-find-file dired-before-readin-hook)
|
||||
...)
|
||||
loaded.
|
||||
|
||||
:defer-incrementally SYMBOL|LIST|t
|
||||
Takes a symbol or list of symbols representing packages that will be loaded
|
||||
incrementally at startup before this one. This is helpful for large packages
|
||||
like magit or org, which load a lot of dependencies on first load. This lets
|
||||
you load them piece-meal during idle periods, so that when you finally do need
|
||||
the package, it'll load quicker. e.g.
|
||||
the package, it'll load quicker.
|
||||
|
||||
NAME is implicitly added if this property is present and non-nil. No need to
|
||||
specify it. A value of `t' implies NAME, e.g.
|
||||
|
||||
(use-package! abc
|
||||
;; This is equivalent to :defer-incrementally (abc)
|
||||
:defer-incrementally t
|
||||
...)"
|
||||
specify it. A value of `t' implies NAME."
|
||||
(declare (indent 1))
|
||||
(unless (or (memq name doom-disabled-packages)
|
||||
;; At compile-time, use-package will forcibly load packages to
|
||||
|
@ -462,7 +450,8 @@ two extra properties:
|
|||
(defmacro use-package-hook! (package when &rest body)
|
||||
"Reconfigures a package's `use-package!' block.
|
||||
|
||||
Only use this macro in a module's init.el file.
|
||||
This macro must be used *before* PACKAGE's `use-package!' block. Often, this
|
||||
means using it from your DOOMDIR/init.el.
|
||||
|
||||
Under the hood, this uses use-package's `use-package-inject-hooks'.
|
||||
|
||||
|
@ -470,9 +459,13 @@ PACKAGE is a symbol; the package's name.
|
|||
WHEN should be one of the following:
|
||||
:pre-init :post-init :pre-config :post-config
|
||||
|
||||
WARNING: If :pre-init or :pre-config hooks return nil, the original
|
||||
`use-package!''s :init/:config block (respectively) is overwritten, so remember
|
||||
to have them return non-nil (or exploit that to overwrite Doom's config)."
|
||||
WARNINGS:
|
||||
- The use of this macro is more often than not a code smell. Use it as last
|
||||
resort. There is almost always a better alternative.
|
||||
- If you are using this solely for :post-config, stop! `after!' is much better.
|
||||
- If :pre-init or :pre-config hooks return nil, the original `use-package!''s
|
||||
:init/:config block (respectively) is overwritten, so remember to have them
|
||||
return non-nil (or exploit that to overwrite Doom's config)."
|
||||
(declare (indent defun))
|
||||
(unless (memq when '(:pre-init :post-init :pre-config :post-config))
|
||||
(error "'%s' isn't a valid hook for use-package-hook!" when))
|
||||
|
@ -493,7 +486,7 @@ CATEGORY is a keyword, MODULE is a symbol and FLAGS are symbols.
|
|||
|
||||
This is for testing and internal use. This is not the correct way to enable a
|
||||
module."
|
||||
`(let ((doom-modules ,doom-modules)
|
||||
`(let ((doom-modules (or ,doom-modules (doom-modules)))
|
||||
(module-path (doom-module-locate-path ,category ',module)))
|
||||
(doom-module-set
|
||||
,category ',module
|
||||
|
|
|
@ -74,8 +74,8 @@ missing) and shouldn't be deleted.")
|
|||
;; shouldn't be using it, but it may be convenient for quick package testing.
|
||||
(setq package--init-file-ensured t
|
||||
package-enable-at-startup nil
|
||||
package-user-dir doom-elpa-dir
|
||||
package-gnupghome-dir (expand-file-name "gpg" doom-elpa-dir)
|
||||
package-user-dir (concat doom-local-dir "elpa/")
|
||||
package-gnupghome-dir (expand-file-name "gpg" package-user-dir)
|
||||
;; I omit Marmalade because its packages are manually submitted rather
|
||||
;; than pulled, so packages are often out of date with upstream.
|
||||
package-archives
|
||||
|
@ -112,12 +112,6 @@ missing) and shouldn't be deleted.")
|
|||
;; we just don't have to deal with them at all.
|
||||
autoload-compute-prefixes nil)
|
||||
|
||||
;; Straight is hardcoded to operate out of ~/.emacs.d/straight. Not on my watch!
|
||||
(defadvice! doom--straight-use-local-dir-a (orig-fn &rest args)
|
||||
:around #'straight--emacs-dir
|
||||
(let ((user-emacs-directory doom-local-dir))
|
||||
(apply orig-fn args)))
|
||||
|
||||
(defun doom--finalize-straight ()
|
||||
(mapc #'funcall (delq nil (mapcar #'cdr straight--transaction-alist)))
|
||||
(setq straight--transaction-alist nil))
|
||||
|
@ -155,8 +149,6 @@ necessary package metadata is initialized and available for them."
|
|||
:branch ,straight-repository-branch
|
||||
:no-byte-compile t))
|
||||
(mapc #'straight-use-package doom-core-packages)
|
||||
(when noninteractive
|
||||
(add-hook 'kill-emacs-hook #'doom--finalize-straight)))
|
||||
(doom-log "Initializing doom-packages")
|
||||
(setq doom-disabled-packages nil
|
||||
doom-packages (doom-package-list))
|
||||
|
@ -171,7 +163,9 @@ necessary package metadata is initialized and available for them."
|
|||
(if-let (recipe (plist-get plist :recipe))
|
||||
(let ((plist (straight-recipes-retrieve pkg)))
|
||||
`(,pkg ,@(doom-plist-merge recipe (cdr plist))))
|
||||
pkg)))))
|
||||
pkg))))
|
||||
(unless doom-interactive-mode
|
||||
(add-hook 'kill-emacs-hook #'doom--finalize-straight))))
|
||||
|
||||
(defun doom-ensure-straight ()
|
||||
"Ensure `straight' is installed and was compiled with this version of Emacs."
|
||||
|
@ -214,7 +208,7 @@ Accepts the following properties:
|
|||
Takes a MELPA-style recipe (see `quelpa-recipe' in `quelpa' for an example);
|
||||
for packages to be installed from external sources.
|
||||
:disable BOOL
|
||||
Do not install or update this package AND disable all of its `def-package!'
|
||||
Do not install or update this package AND disable all of its `use-package!'
|
||||
blocks.
|
||||
:ignore FORM
|
||||
Do not install this package.
|
||||
|
|
|
@ -30,7 +30,7 @@ Emacs.")
|
|||
projectile-add-known-project) ; TODO PR autoload upstream
|
||||
:init
|
||||
(setq projectile-cache-file (concat doom-cache-dir "projectile.cache")
|
||||
projectile-enable-caching (not noninteractive)
|
||||
projectile-enable-caching doom-interactive-mode
|
||||
projectile-known-projects-file (concat doom-cache-dir "projectile.projects")
|
||||
projectile-require-project-root t
|
||||
projectile-globally-ignored-files '(".DS_Store" "Icon
" "TAGS")
|
||||
|
@ -51,6 +51,11 @@ Emacs.")
|
|||
(push ".project" projectile-project-root-files-bottom-up)
|
||||
(push (abbreviate-file-name doom-local-dir) projectile-globally-ignored-directories)
|
||||
|
||||
;; Disable commands that won't work, as is, and that Doom already provides a
|
||||
;; better alternative for.
|
||||
(put 'projectile-ag 'disabled "Use +{ivy,helm}/project-search or +{ivy,helm}/ag instead")
|
||||
(put 'projectile-ripgrep 'disabled "Use +{ivy,helm}/project-search or +{ivy,helm}/rg instead")
|
||||
|
||||
;; Treat current directory in dired as a "file in a project" and track it
|
||||
(add-hook 'dired-before-readin-hook #'projectile-track-known-projects-find-file-hook)
|
||||
|
||||
|
@ -67,7 +72,7 @@ b) represent blacklisted directories that are too big, change too often or are
|
|||
private. (see `doom-projectile-cache-blacklist'),
|
||||
c) are not valid projectile projects."
|
||||
(when (and (bound-and-true-p projectile-projects-cache)
|
||||
(not noninteractive))
|
||||
doom-interactive-mode)
|
||||
(cl-loop with blacklist = (mapcar #'file-truename doom-projectile-cache-blacklist)
|
||||
for proot in (hash-table-keys projectile-projects-cache)
|
||||
if (or (not (stringp proot))
|
||||
|
@ -239,6 +244,7 @@ Relevant: `doom-project-hook'."
|
|||
,(if (stringp (car files)) (cons 'and files) files))))
|
||||
,(or when t)
|
||||
(,name 1)))))
|
||||
(if modes
|
||||
`((dolist (mode ,modes)
|
||||
(let ((hook-name
|
||||
(intern (format "doom--enable-%s%s-h" ',name
|
||||
|
@ -246,7 +252,8 @@ Relevant: `doom-project-hook'."
|
|||
(fset hook-name #',fn)
|
||||
(if (eq mode t)
|
||||
(add-to-list 'auto-minor-mode-magic-alist (cons hook-name #',name))
|
||||
(add-hook (intern (format "%s-hook" mode)) hook-name)))))))
|
||||
(add-hook (intern (format "%s-hook" mode)) hook-name)))))
|
||||
`((add-hook 'change-major-mode-after-body-hook #',fn)))))
|
||||
(match
|
||||
`((add-to-list 'auto-minor-mode-alist (cons ,match #',name)))))))))
|
||||
|
||||
|
|
|
@ -344,7 +344,7 @@ treat Emacs as a non-application window."
|
|||
(setq mode-line-default-help-echo nil
|
||||
show-help-function nil)
|
||||
|
||||
;; y/n is easier to type than yes/no
|
||||
;; Typing yes/no is obnoxious when y/n will do
|
||||
(fset #'yes-or-no-p #'y-or-n-p)
|
||||
|
||||
;; Try really hard to keep the cursor from getting stuck in the read-only prompt
|
||||
|
@ -372,11 +372,11 @@ treat Emacs as a non-application window."
|
|||
|
||||
(use-package! ediff
|
||||
:defer t
|
||||
:init
|
||||
:config
|
||||
(setq ediff-diff-options "-w" ; turn off whitespace checking
|
||||
ediff-split-window-function #'split-window-horizontally
|
||||
ediff-window-setup-function #'ediff-setup-windows-plain)
|
||||
:config
|
||||
|
||||
(defvar doom--ediff-saved-wconf nil)
|
||||
;; Restore window config after quitting ediff
|
||||
(add-hook! 'ediff-before-setup-hook
|
||||
|
@ -579,12 +579,7 @@ character that looks like a space that `whitespace-mode' won't affect.")
|
|||
behavior). Do not set this directly, this is let-bound in `doom-init-theme-h'.")
|
||||
|
||||
(defun doom-init-fonts-h ()
|
||||
"Loads fonts.
|
||||
|
||||
Fonts are specified by `doom-font', `doom-variable-pitch-font',
|
||||
`doom-serif-font' and `doom-unicode-font'."
|
||||
(condition-case e
|
||||
(progn
|
||||
"Loads `doom-font'."
|
||||
(cond (doom-font
|
||||
(add-to-list
|
||||
'default-frame-alist
|
||||
|
@ -593,12 +588,17 @@ Fonts are specified by `doom-font', `doom-variable-pitch-font',
|
|||
((fontp doom-font) (font-xlfd-name doom-font))
|
||||
((signal 'wrong-type-argument (list '(fontp stringp) doom-font)))))))
|
||||
((display-graphic-p)
|
||||
(setq doom-font (face-attribute 'default :font))))
|
||||
(setq doom-font (face-attribute 'default :font)))))
|
||||
|
||||
(defun doom-init-extra-fonts-h (&optional frame)
|
||||
"Loads `doom-variable-pitch-font',`doom-serif-font' and `doom-unicode-font'."
|
||||
(condition-case e
|
||||
(with-selected-frame (or frame (selected-frame))
|
||||
(when doom-serif-font
|
||||
(set-face-attribute 'fixed-pitch-serif t :font doom-serif-font))
|
||||
(set-face-attribute 'fixed-pitch-serif nil :font doom-serif-font))
|
||||
(when doom-variable-pitch-font
|
||||
(set-face-attribute 'variable-pitch t :font doom-variable-pitch-font))
|
||||
(when doom-unicode-font
|
||||
(set-face-attribute 'variable-pitch nil :font doom-variable-pitch-font))
|
||||
(when (and doom-unicode-font (fboundp 'set-fontset-font))
|
||||
(set-fontset-font t 'unicode doom-unicode-font nil 'prepend)))
|
||||
((debug error)
|
||||
(if (string-prefix-p "Font not available: " (error-message-string e))
|
||||
|
@ -656,10 +656,15 @@ startup (or theme switch) time, so long as `doom--prefer-theme-elc' is non-nil."
|
|||
(dolist (fn '(switch-to-buffer display-buffer))
|
||||
(advice-add fn :around #'doom-run-switch-buffer-hooks-a)))
|
||||
|
||||
;; Apply `doom-theme'
|
||||
(add-hook 'doom-init-ui-hook #'doom-init-theme-h)
|
||||
;; Apply `doom-font' et co
|
||||
(add-hook 'doom-after-init-modules-hook #'doom-init-fonts-h)
|
||||
(add-hook 'doom-load-theme-hook #'doom-init-extra-fonts-h)
|
||||
|
||||
;; Apply `doom-theme'
|
||||
(add-hook (if (daemonp)
|
||||
'after-make-frame-functions
|
||||
'doom-init-ui-hook)
|
||||
#'doom-init-theme-h)
|
||||
|
||||
(add-hook 'window-setup-hook #'doom-init-ui-h)
|
||||
|
||||
|
@ -669,7 +674,7 @@ startup (or theme switch) time, so long as `doom--prefer-theme-elc' is non-nil."
|
|||
|
||||
;; doesn't exist in terminal Emacs; we define it to prevent errors
|
||||
(unless (fboundp 'define-fringe-bitmap)
|
||||
(defun define-fringe-bitmap (&rest _)))
|
||||
(fset 'define-fringe-bitmap #'ignore))
|
||||
|
||||
(after! whitespace
|
||||
(defun doom-disable-whitespace-mode-in-childframes-a (orig-fn)
|
||||
|
|
83
core/core.el
83
core/core.el
|
@ -1,5 +1,16 @@
|
|||
;;; core.el --- the heart of the beast -*- lexical-binding: t; -*-
|
||||
|
||||
(defconst doom-version "2.0.9"
|
||||
"Current version of Doom Emacs.")
|
||||
|
||||
(defconst EMACS26+ (> emacs-major-version 25))
|
||||
(defconst EMACS27+ (> emacs-major-version 26))
|
||||
(defconst IS-MAC (eq system-type 'darwin))
|
||||
(defconst IS-LINUX (eq system-type 'gnu/linux))
|
||||
(defconst IS-WINDOWS (memq system-type '(cygwin windows-nt ms-dos)))
|
||||
(defconst IS-BSD (or IS-MAC (eq system-type 'berkeley-unix)))
|
||||
|
||||
;;
|
||||
(defvar doom-init-p nil
|
||||
"Non-nil if Doom has been initialized.")
|
||||
|
||||
|
@ -12,22 +23,13 @@
|
|||
Use `doom/toggle-debug-mode' to toggle it. The --debug-init flag and setting the
|
||||
DEBUG envvar will enable this at startup.")
|
||||
|
||||
(defvar doom-interactive-mode (not noninteractive)
|
||||
"If non-nil, Emacs is in interactive mode.")
|
||||
|
||||
(defvar doom-gc-cons-threshold 16777216 ; 16mb
|
||||
"The default value to use for `gc-cons-threshold'. If you experience freezing,
|
||||
decrease this. If you experience stuttering, increase this.")
|
||||
|
||||
;;; Constants
|
||||
(defconst doom-version "2.0.9"
|
||||
"Current version of Doom Emacs.")
|
||||
|
||||
(defconst EMACS26+ (> emacs-major-version 25))
|
||||
(defconst EMACS27+ (> emacs-major-version 26))
|
||||
|
||||
(defconst IS-MAC (eq system-type 'darwin))
|
||||
(defconst IS-LINUX (eq system-type 'gnu/linux))
|
||||
(defconst IS-WINDOWS (memq system-type '(cygwin windows-nt ms-dos)))
|
||||
(defconst IS-BSD (or IS-MAC (eq system-type 'berkeley-unix)))
|
||||
|
||||
;;; Directories/files
|
||||
(defvar doom-emacs-dir
|
||||
(eval-when-compile (file-truename user-emacs-directory))
|
||||
|
@ -59,11 +61,6 @@ dependencies or long-term shared data. Must end with a slash.")
|
|||
|
||||
Use this for files that change often, like cache files. Must end with a slash.")
|
||||
|
||||
(defvar doom-elpa-dir (concat doom-local-dir "elpa/")
|
||||
"Where package.el and quelpa plugins (and their caches) are stored.
|
||||
|
||||
Must end with a slash.")
|
||||
|
||||
(defvar doom-docs-dir (concat doom-emacs-dir "docs/")
|
||||
"Where Doom's documentation files are stored. Must end with a slash.")
|
||||
|
||||
|
@ -146,9 +143,6 @@ users).")
|
|||
;; to, it's our (the user's) failure. One case for all!
|
||||
(setq auto-mode-case-fold nil)
|
||||
|
||||
;; Enable all disabled commands.
|
||||
(setq disabled-command-function nil)
|
||||
|
||||
;; Display the bare minimum at startup. We don't need all that noise. The
|
||||
;; dashboard/empty scratch buffer is good enough.
|
||||
(setq inhibit-startup-message t
|
||||
|
@ -202,6 +196,13 @@ users).")
|
|||
url-cache-directory (concat doom-cache-dir "url/")
|
||||
url-configuration-directory (concat doom-etc-dir "url/")
|
||||
gamegrid-user-score-file-directory (concat doom-etc-dir "games/"))
|
||||
;; HACK
|
||||
(with-eval-after-load 'x-win
|
||||
(defun emacs-session-filename (session-id)
|
||||
"Construct a filename to save a session based on SESSION-ID.
|
||||
Doom Emacs overrides this function to stop sessions from littering the user
|
||||
directory. The session files are placed by default in `doom-cache-dir'"
|
||||
(concat doom-cache-dir "emacs-session." session-id)))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -222,8 +223,8 @@ users).")
|
|||
(setq fast-but-imprecise-scrolling t)
|
||||
|
||||
;; Resizing the Emacs frame can be a terribly expensive part of changing the
|
||||
;; font. By inhibiting this, we easily halve startup times with fonts that are
|
||||
;; larger than the system default.
|
||||
;; font. By inhibiting this, we halve startup times, particularly when we use
|
||||
;; fonts that are larger than the system default (which would resize the frame).
|
||||
(setq frame-inhibit-implied-resize t)
|
||||
|
||||
;; Don't ping things that look like domain names.
|
||||
|
@ -320,7 +321,8 @@ This is already done by the lang/org module, however.
|
|||
|
||||
If you want to disable incremental loading altogether, either remove
|
||||
`doom-load-packages-incrementally-h' from `emacs-startup-hook' or set
|
||||
`doom-incremental-first-idle-timer' to nil.")
|
||||
`doom-incremental-first-idle-timer' to nil. Incremental loading does not occur
|
||||
in daemon sessions (they are loaded immediately at startup).")
|
||||
|
||||
(defvar doom-incremental-first-idle-timer 2
|
||||
"How long (in idle seconds) until incremental loading starts.
|
||||
|
@ -401,7 +403,8 @@ If RETURN-P, return the message as a string instead of displaying it."
|
|||
(- (length load-path) (length doom--initial-load-path))
|
||||
(if doom-modules (hash-table-count doom-modules) 0)
|
||||
(or doom-init-time
|
||||
(setq doom-init-time (float-time (time-subtract (current-time) before-init-time))))))
|
||||
(setq doom-init-time
|
||||
(float-time (time-subtract (current-time) before-init-time))))))
|
||||
|
||||
(defun doom-load-autoloads-file (file)
|
||||
"Tries to load FILE (an autoloads file). Return t on success, throws an error
|
||||
|
@ -410,7 +413,7 @@ in interactive sessions, nil otherwise (but logs a warning)."
|
|||
(let (command-switch-alist)
|
||||
(load (substring file 0 -3) 'noerror 'nomessage))
|
||||
((debug error)
|
||||
(if noninteractive
|
||||
(if doom-interactive-mode
|
||||
(message "Autoload file warning: %s -> %s" (car e) (error-message-string e))
|
||||
(signal 'doom-autoload-error (list (file-name-nondirectory file) e))))))
|
||||
|
||||
|
@ -419,25 +422,27 @@ in interactive sessions, nil otherwise (but logs a warning)."
|
|||
(if (not (file-readable-p file))
|
||||
(unless noerror
|
||||
(signal 'file-error (list "Couldn't read envvar file" file)))
|
||||
(let (vars)
|
||||
(with-temp-buffer
|
||||
(insert-file-contents file)
|
||||
(search-forward "\n\n" nil t)
|
||||
(while (re-search-forward "\n\\([^= \n]+\\)=" nil t)
|
||||
(while (re-search-forward "\n *\\([^#][^= \n]+\\)=" nil t)
|
||||
(save-excursion
|
||||
(let ((var (match-string 1))
|
||||
(let ((var (string-trim-left (match-string 1)))
|
||||
(value (buffer-substring-no-properties
|
||||
(point)
|
||||
(1- (or (when (re-search-forward "^\\([^= ]+\\)=" nil t)
|
||||
(line-beginning-position))
|
||||
(point-max))))))
|
||||
(push (cons var value) vars)
|
||||
(setenv var value)))))
|
||||
(when vars
|
||||
(setq-default
|
||||
exec-path (append (split-string (getenv "PATH")
|
||||
(if IS-WINDOWS ";" ":"))
|
||||
(list exec-directory))
|
||||
shell-file-name (or (getenv "SHELL")
|
||||
shell-file-name))
|
||||
t))
|
||||
(nreverse vars)))))
|
||||
|
||||
(defun doom-initialize (&optional force-p)
|
||||
"Bootstrap Doom, if it hasn't already (or if FORCE-P is non-nil).
|
||||
|
@ -495,7 +500,7 @@ to least)."
|
|||
;; `Info-directory-list', and `doom-disabled-packages'. A big
|
||||
;; reduction in startup time.
|
||||
(pkg-autoloads-p
|
||||
(unless noninteractive
|
||||
(when doom-interactive-mode
|
||||
(doom-load-autoloads-file doom-package-autoload-file))))
|
||||
|
||||
(if (and core-autoloads-p (not force-p))
|
||||
|
@ -507,17 +512,16 @@ to least)."
|
|||
(require 'core-packages)
|
||||
(doom-initialize-packages)))
|
||||
|
||||
;; Eagerly load these libraries because this module may be loaded in a session
|
||||
;; that hasn't been fully initialized (where autoloads files haven't been
|
||||
;; generated or `load-path' populated).
|
||||
;; Eagerly load these libraries because we may be in a session that
|
||||
;; hasn't been fully initialized (e.g. where autoloads files haven't
|
||||
;; been generated or `load-path' populated).
|
||||
(mapc (doom-rpartial #'load 'noerror 'nomessage)
|
||||
(file-expand-wildcards (concat doom-core-dir "autoload/*.el")))
|
||||
|
||||
;; Create all our core directories to quell file errors
|
||||
(dolist (dir (list doom-local-dir
|
||||
doom-etc-dir
|
||||
doom-cache-dir
|
||||
doom-elpa-dir))
|
||||
doom-cache-dir))
|
||||
(unless (file-directory-p dir)
|
||||
(make-directory dir 'parents)))
|
||||
|
||||
|
@ -528,12 +532,13 @@ to least)."
|
|||
|
||||
(unless (or (and core-autoloads-p pkg-autoloads-p)
|
||||
force-p
|
||||
noninteractive)
|
||||
(not doom-interactive-mode))
|
||||
(unless core-autoloads-p
|
||||
(message "Your Doom core autoloads file is missing"))
|
||||
(warn "Your Doom core autoloads file is missing"))
|
||||
(unless pkg-autoloads-p
|
||||
(message "Your package autoloads file is missing"))
|
||||
(user-error "Run `bin/doom refresh' to generate them")))))
|
||||
(warn "Your package autoloads file is missing"))
|
||||
(signal 'doom-autoload-error "Run `bin/doom refresh' to generate them")))
|
||||
t))
|
||||
|
||||
(defun doom-initialize-core ()
|
||||
"Load Doom's core files for an interactive session."
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
(package! all-the-icons)
|
||||
(package! hide-mode-line)
|
||||
(package! highlight-numbers)
|
||||
;; Some early 26.x builds of Emacs do not have `display-line-numbers' yet, so
|
||||
;; check for it instead of Emacs' version.
|
||||
(unless (locate-library "display-line-numbers")
|
||||
(package! nlinum)
|
||||
(package! nlinum-hl)
|
||||
|
@ -18,7 +20,6 @@
|
|||
|
||||
;; core-editor.el
|
||||
(package! better-jumper)
|
||||
(package! command-log-mode)
|
||||
(package! dtrt-indent)
|
||||
(package! helpful)
|
||||
(package! ns-auto-titlebar :ignore (not IS-MAC))
|
||||
|
@ -26,11 +27,14 @@
|
|||
(package! smartparens)
|
||||
(package! so-long
|
||||
:built-in 'prefer
|
||||
:recipe (:repo "https://git.savannah.gnu.org/git/so-long.git"))
|
||||
;; REVIEW so-long is slated to be published to ELPA eventually, but until then
|
||||
;; I've created my own mirror for it because git.savannah.gnu.org runs on a
|
||||
;; potato.
|
||||
:recipe (:host github :repo "hlissner/emacs-so-long"))
|
||||
(package! osx-clipboard :ignore (not IS-MAC))
|
||||
(package! undo-tree)
|
||||
(package! ws-butler)
|
||||
(package! xclip :ignore IS-LINUX)
|
||||
(package! xclip :ignore (not IS-LINUX))
|
||||
|
||||
;; core-projects.el
|
||||
(package! projectile)
|
||||
|
@ -38,6 +42,3 @@
|
|||
;; core-keybinds.el
|
||||
(package! general)
|
||||
(package! which-key)
|
||||
|
||||
;; autoload/debug.el
|
||||
(package! esup)
|
||||
|
|
|
@ -1,6 +1,64 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; core/test/helpers.el
|
||||
|
||||
(eval-and-compile
|
||||
(setq doom-interactive-mode 'test)
|
||||
(doom-initialize 'force)
|
||||
(require 'buttercup)
|
||||
(setq split-width-threshold 0
|
||||
split-height-threshold 0
|
||||
window-min-width 0
|
||||
window-min-height 0))
|
||||
|
||||
;;
|
||||
;;; Buttercup extensions
|
||||
|
||||
(buttercup-define-matcher :to-expand-into (form expected)
|
||||
(cl-destructuring-bind (form expected)
|
||||
(mapcar #'funcall (list form expected))
|
||||
(let ((expanded (macroexpand-1 form)))
|
||||
(if (equal expanded expected)
|
||||
(cons t (format "Expected `%S' to not expand to `%S'"
|
||||
form expected))
|
||||
(cons nil (format "Expected `%S' to not expand to `%S', but got `%S' instead"
|
||||
form expected expanded))))))
|
||||
|
||||
(buttercup-define-matcher :to-output (form &optional expected-output)
|
||||
(let ((expected-output (and (functionp expected-output)
|
||||
(funcall expected-output)))
|
||||
output)
|
||||
(with-current-buffer (get-buffer "*Messages*")
|
||||
(let ((standard-output (current-buffer))
|
||||
(start (point)))
|
||||
(let ((inhibit-message t))
|
||||
(funcall form))
|
||||
(setq output (buffer-substring-no-properties start (point-max)))
|
||||
(with-silent-modifications (erase-buffer))))
|
||||
(cond ((null expected-output)
|
||||
(if (string-empty-p output)
|
||||
(cons nil (format "Expected output %S, but got none"
|
||||
expected-output))
|
||||
(cons t (format "Expected no output, but got %S"
|
||||
output))))
|
||||
((not (equal expected-output output))
|
||||
(cons nil (format "Expected output %S, but got %S instead"
|
||||
expected-output output)))
|
||||
((cons t (format "Expected to not get %S as output"
|
||||
expected-output))))))
|
||||
|
||||
(buttercup-define-matcher :to-contain-items (items expected)
|
||||
(cl-destructuring-bind (items expected)
|
||||
(mapcar #'funcall (list items expected))
|
||||
(if-let (missing (cl-set-difference expected items))
|
||||
(cons nil (format "Expected list to contain %S, but it was missing %S"
|
||||
expected missing))
|
||||
(cons t (format "Expected list to not contain %S, but it did: %S"
|
||||
expected items)))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Helper macros
|
||||
|
||||
(defmacro insert!! (&rest text)
|
||||
"Insert TEXT in buffer, then move cursor to last {0} marker."
|
||||
`(progn
|
||||
|
|
4
core/test/packages.el
Normal file
4
core/test/packages.el
Normal file
|
@ -0,0 +1,4 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/test/packages.el
|
||||
|
||||
(package! buttercup)
|
|
@ -1,16 +1,12 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/test/test-autoload-buffers.el
|
||||
|
||||
(describe "core/autoload/buffers"
|
||||
:var (a b c d)
|
||||
|
||||
(require 'core-projects)
|
||||
(load! "autoload/buffers" doom-core-dir)
|
||||
|
||||
;;
|
||||
(describe "core/autoload/buffers"
|
||||
:var (a b c d)
|
||||
(before-all
|
||||
(spy-on 'buffer-list :and-call-fake
|
||||
(lambda (&optional _)
|
||||
(cl-remove-if-not #'buffer-live-p (list a b c d)))))
|
||||
(before-each
|
||||
(delete-other-windows)
|
||||
(setq a (switch-to-buffer (get-buffer-create "a"))
|
||||
|
@ -25,7 +21,7 @@
|
|||
|
||||
(describe "buffer-list"
|
||||
(it "should only see four buffers"
|
||||
(expect (doom-buffer-list) :to-have-same-items-as (list a b c d))))
|
||||
(expect (doom-buffer-list) :to-contain-items (list a b c d))))
|
||||
|
||||
(describe "project-buffer-list"
|
||||
:var (projectile-projects-cache-time projectile-projects-cache)
|
||||
|
@ -34,7 +30,7 @@
|
|||
|
||||
(before-each
|
||||
(with-current-buffer a (setq default-directory doom-emacs-dir))
|
||||
(with-current-buffer b (setq default-directory doom-emacs-dir))
|
||||
(with-current-buffer b (setq default-directory doom-core-dir))
|
||||
(with-current-buffer c (setq default-directory "/tmp/"))
|
||||
(with-current-buffer d (setq default-directory "~"))
|
||||
(projectile-mode +1))
|
||||
|
@ -44,7 +40,7 @@
|
|||
(it "returns buffers in the same project"
|
||||
(with-current-buffer a
|
||||
(expect (doom-project-buffer-list)
|
||||
:to-have-same-items-as (list a b))))
|
||||
:to-contain-items (list a b))))
|
||||
|
||||
(it "returns all buffers if not in a project"
|
||||
(with-current-buffer c
|
||||
|
@ -53,7 +49,10 @@
|
|||
|
||||
(describe "fallback-buffer"
|
||||
(it "returns a live buffer"
|
||||
(expect (buffer-live-p (doom-fallback-buffer)))))
|
||||
(expect (buffer-live-p (doom-fallback-buffer))))
|
||||
|
||||
(it "returns the scratch buffer"
|
||||
(expect (doom-fallback-buffer) :to-equal (get-buffer "*scratch*"))))
|
||||
|
||||
(describe "real buffers"
|
||||
(before-each
|
||||
|
@ -72,7 +71,7 @@
|
|||
|
||||
(describe "real-buffer-list"
|
||||
(it "returns only real buffers"
|
||||
(expect (doom-real-buffer-list) :to-have-same-items-as (list a b)))))
|
||||
(expect (doom-real-buffer-list) :to-contain-items (list a b)))))
|
||||
|
||||
(describe "buffer/window management"
|
||||
(describe "buffer search methods"
|
||||
|
@ -85,14 +84,17 @@
|
|||
|
||||
(it "can match buffers by regexp"
|
||||
(expect (doom-matching-buffers "^[ac]$") :to-have-same-items-as (list a c)))
|
||||
|
||||
(it "can match buffers by major-mode"
|
||||
(expect (doom-buffers-in-mode 'text-mode) :to-have-same-items-as (list b c)))
|
||||
|
||||
(it "can find all buried buffers"
|
||||
(expect (doom-buried-buffers)
|
||||
:to-have-same-items-as (list c d)))
|
||||
(expect (doom-buried-buffers) :to-contain-items (list c d)))
|
||||
|
||||
(it "can find all visible buffers"
|
||||
(expect (doom-visible-buffers)
|
||||
:to-have-same-items-as (list a b)))
|
||||
|
||||
(it "can find all visible windows"
|
||||
(expect (doom-visible-windows)
|
||||
:to-have-same-items-as
|
||||
|
@ -109,7 +111,7 @@
|
|||
(expect (length (doom-visible-windows)) :to-be 1)))
|
||||
|
||||
;; TODO
|
||||
(describe "kill-all-buffers")
|
||||
(describe "kill-other-buffers")
|
||||
(describe "kill-matching-buffers")
|
||||
(describe "cleanup-session")))
|
||||
(xdescribe "kill-all-buffers")
|
||||
(xdescribe "kill-other-buffers")
|
||||
(xdescribe "kill-matching-buffers")
|
||||
(xdescribe "cleanup-session")))
|
||||
|
|
|
@ -1,11 +1,109 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/test/test-autoload-files.el
|
||||
;;;
|
||||
|
||||
(describe "core/autoload/files"
|
||||
|
||||
(load! "autoload/files" doom-core-dir)
|
||||
|
||||
(xdescribe "doom-glob")
|
||||
(xdescribe "doom-path")
|
||||
(xdescribe "doom-dir")
|
||||
(xdescribe "doom-files-in")
|
||||
|
||||
(describe "library"
|
||||
(describe "file-exists-p!"
|
||||
(it "is a (quasi) drop-in replacement for `file-exists-p'"
|
||||
(let ((default-directory doom-emacs-dir)
|
||||
(init-file "init.el"))
|
||||
(expect (file-exists-p "init.el"))
|
||||
(expect (and (file-exists-p! "init.el")
|
||||
(file-exists-p "init.el")))
|
||||
(expect (and (file-exists-p! init-file)
|
||||
(file-exists-p init-file)))
|
||||
(expect (and (file-exists-p! doom-emacs-dir)
|
||||
(file-exists-p doom-emacs-dir)))
|
||||
(expect (and (not (file-exists-p! "/cant/possibly/exist/please/dont/exist"))
|
||||
(not (file-exists-p "/cant/possibly/exist/please/dont/exist"))))))
|
||||
|
||||
(it "returns the file path if it exists"
|
||||
(expect (file-exists-p! "init.example.el"
|
||||
doom-emacs-dir)
|
||||
:to-equal (expand-file-name "init.example.el" doom-emacs-dir)))
|
||||
|
||||
(it "understands compound statements"
|
||||
(let ((default-directory doom-emacs-dir))
|
||||
(expect (file-exists-p! (and "init.el" "init.example.el")))
|
||||
(expect (file-exists-p! (or "doesnotexist" "init.example.el")))
|
||||
(expect (not (file-exists-p! (or "doesnotexist" "DOESNOTEXIST")))))
|
||||
(expect (file-exists-p! (and "init.el" "init.example.el")
|
||||
doom-emacs-dir))
|
||||
(expect (file-exists-p! (and "init.el" "init.example.el")
|
||||
doom-emacs-dir))
|
||||
(expect (file-exists-p! (or "doesnotexist" "init.example.el")
|
||||
doom-emacs-dir))
|
||||
(expect (not (file-exists-p! (or "doesnotexist" "DOESNOTEXIST")
|
||||
doom-emacs-dir))))
|
||||
|
||||
(it "understands nested compound statements"
|
||||
(expect (file-exists-p! (and "init.el" "init.example.el"
|
||||
(or "doesnotexist" "LICENSE"))
|
||||
doom-emacs-dir))
|
||||
(expect (file-exists-p! (and "init.el" "init.example.el"
|
||||
(and "LICENSE" "README.md"
|
||||
(or "doesnotexist"
|
||||
"early-init.el")))
|
||||
doom-emacs-dir))
|
||||
(expect (file-exists-p! (and "init.el" "init.example.el"
|
||||
(or "edoesnotexist" "DOESNOTEXIST"
|
||||
(and "idontexist"
|
||||
"doanyofusexist?")))
|
||||
doom-emacs-dir)
|
||||
:to-be nil))
|
||||
|
||||
(it "returns the last form if a compound file check succeeds"
|
||||
(expect (file-exists-p! (and "init.el" "init.example.el"
|
||||
(or "doesnotexist" "LICENSE"))
|
||||
doom-emacs-dir)
|
||||
:to-equal (expand-file-name "LICENSE" doom-emacs-dir))
|
||||
(expect (file-exists-p! (and "init.el" "init.example.el"
|
||||
(or (or "doesnotexist" "DOESNOTEXIST")
|
||||
"doanyofusreallyexist"
|
||||
(or "cantexist" "LICENSE")))
|
||||
doom-emacs-dir)
|
||||
:to-equal (expand-file-name "LICENSE" doom-emacs-dir)))
|
||||
|
||||
(it "disregards the directory argument if given absolute path"
|
||||
(expect (file-exists-p! "/tmp" "/directory/that/doesnt/exist"))
|
||||
(expect (file-exists-p! doom-core-dir "/directory/that/doesnt/exist"))
|
||||
(expect (file-exists-p! (and "/tmp" doom-core-dir) "/directory/that/doesnt/exist"))
|
||||
(expect (file-exists-p! (or "/tmp" doom-core-dir) "/directory/that/doesnt/exist")))
|
||||
|
||||
(it "interpolates variables"
|
||||
(let ((file-1 "init.el")
|
||||
(file-2 "init.example.el")
|
||||
(file-3 "LICENSE")
|
||||
(file-404 "doesnotexistlikenoreally"))
|
||||
(expect (file-exists-p! file-1 doom-emacs-dir))
|
||||
(expect (file-exists-p! (and file-1 file-2) doom-emacs-dir))
|
||||
(expect (file-exists-p! (and file-1 (or file-404 file-2)) doom-emacs-dir))
|
||||
(expect (file-exists-p! (or (and file-404 file-2) (and file-3 file-1))
|
||||
doom-emacs-dir))))
|
||||
|
||||
(it "interpolates forms"
|
||||
(cl-letf (((symbol-function 'getfilename)
|
||||
(lambda () "init.example.el")))
|
||||
(expect (file-exists-p! (and (or (if nil "init.el" "doesnotexist")
|
||||
(getfilename))
|
||||
"LICENSE")
|
||||
doom-emacs-dir)
|
||||
:to-equal (expand-file-name "LICENSE" doom-emacs-dir))))))
|
||||
|
||||
(describe "interactive file operations"
|
||||
:var (src dest projectile-projects-cache-time projectile-projects-cache)
|
||||
|
||||
(require 'core-projects)
|
||||
(require 'projectile)
|
||||
|
||||
(describe "core/autoload/files"
|
||||
:var (src dest projectile-projects-cache-time projectile-projects-cache)
|
||||
(before-each
|
||||
(setq src (make-temp-file "test-src")
|
||||
existing (make-temp-file "test-existing")
|
||||
|
@ -51,4 +149,4 @@
|
|||
(expect (file-exists-p existing) :to-be nil))
|
||||
(it "prompts to delete any existing file"
|
||||
(quiet! (doom/delete-this-file existing))
|
||||
(expect 'y-or-n-p :to-have-been-called-times 1))))
|
||||
(expect 'y-or-n-p :to-have-been-called-times 1)))))
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/test/test-autoload-message.el
|
||||
|
||||
(describe "core/autoload/message"
|
||||
(describe "core/autoload/format"
|
||||
(describe "format!"
|
||||
:var (doom-message-backend)
|
||||
:var (doom-format-backend)
|
||||
(before-all
|
||||
(setq doom-message-backend 'ansi))
|
||||
(setq doom-format-backend 'ansi))
|
||||
|
||||
(it "should be a drop-in replacement for `format'"
|
||||
(expect (format! "Hello %s" "World")
|
||||
|
@ -16,7 +16,7 @@
|
|||
:to-equal "[31mHello World[0m"))
|
||||
|
||||
(it "supports text properties in interactive sessions"
|
||||
(let ((doom-message-backend 'text-properties))
|
||||
(let ((doom-format-backend 'text-properties))
|
||||
(expect (get-text-property 0 'face (format! (red "Hello %s") "World"))
|
||||
:to-equal (list :foreground (face-foreground 'term-color-red)))))
|
||||
|
||||
|
@ -35,4 +35,10 @@
|
|||
(expect (format! (color 'red "Hello %s") "World")
|
||||
:to-equal (format! (red "Hello %s") "World"))
|
||||
(expect (format! (color (if nil 'red 'blue) "Hello %s") "World")
|
||||
:to-equal (format! (blue "Hello %s") "World")))))
|
||||
:to-equal (format! (blue "Hello %s") "World"))))
|
||||
|
||||
(xdescribe "insert!")
|
||||
(xdescribe "print!")
|
||||
(xdescribe "print-group!")
|
||||
(xdescribe "error!")
|
||||
(xdescribe "user-error!"))
|
|
@ -1,10 +0,0 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/test/test-autoload-help.el
|
||||
|
||||
;; (load! "autoload/help" doom-core-dir)
|
||||
|
||||
;;
|
||||
;; (describe "core/autoload/help"
|
||||
;; :var (a)
|
||||
;; (before-each (setq a (switch-to-buffer (get-buffer-create "a"))))
|
||||
;; (after-each (kill-buffer a)))
|
|
@ -1,138 +1,5 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/test/test-autoload-package.el
|
||||
;;;###if nil
|
||||
|
||||
(describe "core/autoload/packages"
|
||||
:var (package-alist
|
||||
package-archive-contents
|
||||
package-selected-packages
|
||||
doom-packages
|
||||
quelpa-cache
|
||||
quelpa-initialized-p
|
||||
doom-packages-dir
|
||||
doom-core-packages
|
||||
package-user-dir
|
||||
quelpa-dir
|
||||
pkg)
|
||||
|
||||
(before-all
|
||||
(fset 'pkg
|
||||
(lambda (name version &optional reqs)
|
||||
(package-desc-create
|
||||
:name name :version version :reqs reqs
|
||||
:dir (expand-file-name (format "%s/" name) package-user-dir))))
|
||||
(require 'package)
|
||||
(require 'quelpa)
|
||||
(setq doom-packages-dir (expand-file-name "packages/" (file-name-directory load-file-name))
|
||||
package-user-dir (expand-file-name "elpa" doom-packages-dir)
|
||||
quelpa-dir (expand-file-name "quelpa" doom-packages-dir)
|
||||
quelpa-initialized-p t
|
||||
doom-core-packages nil)
|
||||
(spy-on #'package--user-installed-p :and-call-fake (lambda (_p) t))
|
||||
(spy-on #'doom-initialize-packages :and-call-fake (lambda (&optional _)))
|
||||
(spy-on #'package-refresh-contents :and-call-fake (lambda (&optional _)))
|
||||
(spy-on #'quelpa-checkout :and-call-fake
|
||||
(lambda (rcp _dir)
|
||||
(when (eq (car rcp) 'doom-quelpa-dummy)
|
||||
"20170405.1234"))))
|
||||
|
||||
(after-all
|
||||
(unload-feature 'package t)
|
||||
(unload-feature 'quelpa t))
|
||||
|
||||
(before-each
|
||||
(setq package-alist
|
||||
`((doom-dummy ,(pkg 'doom-dummy '(20160405 1234)))
|
||||
(doom-uptodate-dummy ,(pkg 'doom-uptodate-dummy '(20160605 1234)))
|
||||
(doom-unwanted-dummy ,(pkg 'doom-unwanted-dummy '(20160605 1234)))
|
||||
(doom-quelpa-dummy ,(pkg 'doom-quelpa-dummy '(20160405 1234)))
|
||||
(doom-noquelpa-dummy ,(pkg 'doom-noquelpa-dummy '(20160405 1234))))
|
||||
package-archive-contents
|
||||
`((doom-dummy ,(pkg 'doom-dummy '(20170405 1234)))
|
||||
(doom-uptodate-dummy ,(pkg 'doom-uptodate-dummy '(20160605 1234))))
|
||||
doom-packages
|
||||
'((doom-dummy)
|
||||
(doom-uptodate-dummy)
|
||||
(doom-missing-dummy)
|
||||
(doom-noquelpa-dummy)
|
||||
(doom-disabled-dummy :disable t)
|
||||
(doom-private-dummy :modules ((:private)))
|
||||
(doom-disabled-private-dummy :modules ((:private)) :disable t)
|
||||
(doom-quelpa-dummy :recipe (doom-quelpa-dummy :fetcher github :repo "hlissner/does-not-exist")))
|
||||
quelpa-cache
|
||||
'((doom-quelpa-dummy :fetcher github :repo "hlissner/does-not-exist")
|
||||
(doom-noquelpa-dummy :fetcher github :repo "hlissner/does-not-exist-3")
|
||||
(doom-new-quelpa-dummy :fetcher github :repo "hlissner/does-not-exist-2"))
|
||||
package-selected-packages (mapcar #'car doom-packages)))
|
||||
|
||||
(describe "package-backend"
|
||||
(it "determines the correct backend of a package"
|
||||
(expect (doom-package-backend 'doom-dummy) :to-be 'elpa)
|
||||
(expect (doom-package-backend 'doom-quelpa-dummy) :to-be 'quelpa)
|
||||
(expect (doom-package-backend 'org) :to-be 'emacs))
|
||||
(it "errors out if package isn't installed"
|
||||
(expect (doom-package-backend 'xyz) :to-throw)))
|
||||
|
||||
(describe "package-outdated-p (elpa)"
|
||||
(it "detects outdated ELPA packages and returns both versions"
|
||||
(expect (doom-package-outdated-p 'doom-dummy)
|
||||
:to-equal '(doom-dummy (20160405 1234) (20170405 1234))))
|
||||
(it "ignores up-to-date ELPA packages"
|
||||
(expect (doom-package-outdated-p 'doom-uptodate-dummy) :to-be nil))
|
||||
|
||||
(it "detects outdated QUELPA packages and returns both versions"
|
||||
(expect (doom-package-outdated-p 'doom-quelpa-dummy)
|
||||
:to-equal '(doom-quelpa-dummy (20160405 1234) (20170405 1234))))
|
||||
(it "ignores up-to-date QUELPA packages"
|
||||
(expect (doom-package-outdated-p 'doom-uptodate-dummy) :to-be nil))
|
||||
|
||||
(it "returns nil if package isn't installed"
|
||||
(expect (doom-package-outdated-p 'xyz) :to-be nil)))
|
||||
|
||||
(describe "get-packages"
|
||||
(before-all
|
||||
;; In addition to `package-installed-p', `doom-package-installed-p' does
|
||||
;; file existence checks which won't work here, so we simplify it
|
||||
(spy-on #'doom-package-installed-p :and-call-fake #'package-installed-p))
|
||||
|
||||
(it "returns all packages"
|
||||
(expect (mapcar #'car (doom-find-packages))
|
||||
:to-have-same-items-as
|
||||
(mapcar #'car doom-packages)))
|
||||
(it "returns only disabled packages"
|
||||
(expect (mapcar #'car (doom-find-packages :disabled t))
|
||||
:to-have-same-items-as
|
||||
'(doom-disabled-dummy doom-disabled-private-dummy)))
|
||||
(it "returns only non-disabled packages"
|
||||
(expect (mapcar #'car (doom-find-packages :disabled nil))
|
||||
:to-have-same-items-as
|
||||
'(doom-dummy doom-uptodate-dummy doom-quelpa-dummy doom-missing-dummy doom-noquelpa-dummy doom-private-dummy)))
|
||||
(it "returns only installed packages"
|
||||
(expect (mapcar #'car (doom-find-packages :disabled nil :installed t))
|
||||
:to-have-same-items-as
|
||||
'(doom-dummy doom-uptodate-dummy doom-quelpa-dummy doom-noquelpa-dummy)))
|
||||
(it "returns only non-installed packages"
|
||||
(expect (mapcar #'car (doom-find-packages :disabled nil :installed nil))
|
||||
:to-have-same-items-as
|
||||
'(doom-missing-dummy doom-private-dummy)))
|
||||
(it "returns only private packages"
|
||||
(expect (mapcar #'car (doom-find-packages :private t))
|
||||
:to-have-same-items-as
|
||||
'(doom-private-dummy doom-disabled-private-dummy)))
|
||||
(it "returns only disabled and private packages"
|
||||
(expect (mapcar #'car (doom-find-packages :disabled t :private t))
|
||||
:to-have-same-items-as
|
||||
'(doom-disabled-private-dummy))))
|
||||
|
||||
(describe "get-orphaned-packages"
|
||||
(it "returns orphaned packages"
|
||||
(expect (doom-get-orphaned-packages) :to-contain 'doom-unwanted-dummy))
|
||||
(it "returns packages that have changed backends"
|
||||
(expect (doom-get-orphaned-packages) :to-contain 'doom-noquelpa-dummy)))
|
||||
|
||||
(describe "get-missing-packages"
|
||||
(it "returns packages that haven't been installed"
|
||||
(expect (mapcar #'car (doom-get-missing-packages))
|
||||
:to-contain 'doom-missing-dummy))
|
||||
(it "returns packages that have changed backends"
|
||||
(expect (mapcar #'car (doom-get-missing-packages))
|
||||
:to-contain 'doom-noquelpa-dummy))))
|
||||
(xdescribe "core/autoload/packages")
|
||||
|
|
|
@ -1,21 +1,14 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/test/test-core-keybinds.el
|
||||
|
||||
(describe "core/keybinds"
|
||||
(require 'core-keybinds)
|
||||
|
||||
(buttercup-define-matcher :to-expand-into (src result)
|
||||
(let ((src (funcall src))
|
||||
(result (funcall result)))
|
||||
(or (equal (macroexpand-1 src) result)
|
||||
(error "'%s' expanded into '%s' instead of '%s'"
|
||||
src (macroexpand-1 src) result))))
|
||||
|
||||
(describe "core/keybinds"
|
||||
(describe "map!"
|
||||
:var (doom--map-evil-p doom-map-states)
|
||||
:var (doom--map-evil-p states-alist)
|
||||
(before-each
|
||||
(setq doom--map-evil-p t
|
||||
doom-map-states '((:n . normal)
|
||||
states-alist '((:n . normal)
|
||||
(:v . visual)
|
||||
(:i . insert)
|
||||
(:e . emacs)
|
||||
|
@ -25,16 +18,17 @@
|
|||
|
||||
(describe "Single keybinds"
|
||||
(it "binds a global key"
|
||||
(expect '(map! "C-." #'a) :to-expand-into '(general-define-key "C-." #'a)))
|
||||
(expect '(map! "C-." #'a)
|
||||
:to-expand-into '(general-define-key "C-." #'a)))
|
||||
|
||||
(it "binds a key in one evil state"
|
||||
(dolist (state doom-map-states)
|
||||
(dolist (state states-alist)
|
||||
(expect `(map! ,(car state) "C-." #'a)
|
||||
:to-expand-into
|
||||
`(general-define-key :states ',(cdr state) "C-." #'a))))
|
||||
|
||||
(it "binds a key in multiple evil states"
|
||||
(expect `(map! :nvi "C-." #'a)
|
||||
(expect '(map! :nvi "C-." #'a)
|
||||
:to-expand-into
|
||||
'(progn (general-define-key :states 'insert "C-." #'a)
|
||||
(general-define-key :states 'visual "C-." #'a)
|
||||
|
@ -54,7 +48,7 @@
|
|||
'(general-define-key "C-." #'a "C-," #'b "C-/" #'c)))
|
||||
|
||||
(it "binds multiple keybinds in an evil state and preserve order"
|
||||
(dolist (state doom-map-states)
|
||||
(dolist (state states-alist)
|
||||
(expect `(map! ,(car state) "a" #'a
|
||||
,(car state) "b" #'b
|
||||
,(car state) "c" #'c)
|
||||
|
|
|
@ -1,28 +1,130 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/test/test-core-lib.el
|
||||
|
||||
(require 'core-lib)
|
||||
(describe "core-lib"
|
||||
(before-all
|
||||
(require 'core-lib))
|
||||
|
||||
(describe "core/lib"
|
||||
;; --- Helpers ----------------------------
|
||||
(describe "doom-unquote"
|
||||
(it "unquotes a quoted form"
|
||||
(expect (doom-unquote '(quote hello)) :to-be 'hello))
|
||||
(it "unquotes nested-quoted forms"
|
||||
(it "unquotes nested quoted forms"
|
||||
(expect (doom-unquote '(quote (quote (a b c)))) :to-equal '(a b c)))
|
||||
(it "unquotes function-quoted forms"
|
||||
(expect (doom-unquote '(function a)) :to-be 'a))
|
||||
(it "does nothing to unquoted forms"
|
||||
(expect (doom-unquote 'hello) :to-be 'hello)))
|
||||
(expect (doom-unquote 'hello) :to-be 'hello)
|
||||
(expect (doom-unquote 5) :to-be 5)
|
||||
(expect (doom-unquote t) :to-be t)))
|
||||
|
||||
(describe "doom-enlist"
|
||||
(it "returns nil if given nil"
|
||||
(expect (doom-enlist nil) :to-be nil))
|
||||
(it "creates a list out of non-lists"
|
||||
(expect (doom-enlist 'a) :to-equal '(a)))
|
||||
(it "does nothing to lists"
|
||||
(it "returns lists as-is"
|
||||
(expect (doom-enlist '(a)) :to-equal '(a))))
|
||||
|
||||
(describe "doom-keyword-intern"
|
||||
(it "returns a keyword"
|
||||
(expect (doom-keyword-intern "test") :to-equal :test))
|
||||
(it "errors if given anything but a string"
|
||||
(expect (doom-keyword-intern t) :to-throw 'wrong-type-argument)))
|
||||
|
||||
(describe "doom-keyword-name"
|
||||
(it "returns the string name of a keyword"
|
||||
(expect (doom-keyword-name :test) :to-equal "test"))
|
||||
(it "errors if given anything but a keyword"
|
||||
(expect (doom-keyword-name "test") :to-throw 'wrong-type-argument)))
|
||||
|
||||
(describe "doom-partial"
|
||||
(it "returns a closure"
|
||||
(expect (functionp (doom-partial #'+ 1))))
|
||||
(it "returns a partial closure"
|
||||
(expect (funcall (doom-partial #'+ 1) 2) :to-be 3)))
|
||||
|
||||
(describe "doom-rpartial"
|
||||
(it "returns a closure"
|
||||
(expect (functionp (doom-rpartial #'+ 1))))
|
||||
(it "returns a partial closure with right-aligned arguments"
|
||||
(expect (funcall (doom-rpartial #'/ 2) 10) :to-be 5)))
|
||||
|
||||
|
||||
;; --- Sugars -----------------------------
|
||||
(describe "lambda!"
|
||||
(it "returns an interactive function"
|
||||
(expect (commandp (lambda!)))
|
||||
(expect (funcall (lambda! 5)) :to-equal 5)))
|
||||
|
||||
(describe "lambda!!"
|
||||
(it "returns an interactive function with a prefix argument"
|
||||
(expect (commandp (lambda! #'ignore t)))
|
||||
(expect (funcall (lambda!! (lambda (arg)
|
||||
(interactive "P")
|
||||
arg)
|
||||
5))
|
||||
:to-equal 5)))
|
||||
|
||||
(describe "file!"
|
||||
(it "returns the executing file"
|
||||
(expect (eval-and-compile (file!))
|
||||
:to-equal (expand-file-name "test/test-core-lib.el"
|
||||
doom-core-dir))))
|
||||
|
||||
(describe "dir!"
|
||||
(it "returns the executing directory"
|
||||
(expect (eval-and-compile (dir!))
|
||||
:to-equal (expand-file-name "test" doom-core-dir))))
|
||||
|
||||
(describe "pushnew!"
|
||||
(it "pushes values onto a list symbol, in order"
|
||||
(let ((a '(1 2 3)))
|
||||
(expect (pushnew! a 9 8 7)
|
||||
:to-equal '(7 8 9 1 2 3))))
|
||||
(it "only adds values that aren't already in the list"
|
||||
(let ((a '(1 symbol 3.14 "test")))
|
||||
(expect (pushnew! a "test" 'symbol 3.14 1)
|
||||
:to-equal '(1 symbol 3.14 "test")))))
|
||||
|
||||
(describe "prependq!"
|
||||
(it "prepends a list to a list symbol"
|
||||
(let ((list '(a b c)))
|
||||
(expect (prependq! list '(d e f))
|
||||
:to-equal '(d e f a b c)))))
|
||||
|
||||
(describe "append!"
|
||||
(it "appends a list to a list symbol"
|
||||
(let ((list '(a b c)))
|
||||
(expect (appendq! list '(d e f))
|
||||
:to-equal '(a b c d e f)))))
|
||||
|
||||
(describe "nconcq!"
|
||||
(it "nconc's a list to a list symbol"
|
||||
(let ((list '(a b c)))
|
||||
(expect (nconcq! list '(d e f))
|
||||
:to-equal '(a b c d e f)))))
|
||||
|
||||
(describe "delq!"
|
||||
(it "delete's a symbol from a list"
|
||||
(let ((list '(a b c)))
|
||||
(delq! 'b list)
|
||||
(expect list :to-equal '(a c))))
|
||||
(it "delete's an element from an alist by key"
|
||||
(let ((alist '((a 1) (b 2) (c 3))))
|
||||
(delq! 'b alist 'assq)
|
||||
(expect alist :to-equal '((a 1) (c 3))))))
|
||||
|
||||
(describe "delete!"
|
||||
(it "delete's a string from a list"
|
||||
(let ((list '("a" "b" "c")))
|
||||
(delete! "b" list)
|
||||
(expect list :to-equal '("a" "c"))))
|
||||
(it "delete's an element from an alist by key"
|
||||
(let ((alist '(("a" 1) ("b" 2) ("c" 3))))
|
||||
(delete! (assoc "b" alist) alist)
|
||||
(expect alist :to-equal '(("a" 1) ("c" 3))))))
|
||||
|
||||
;; --- Macros -----------------------------
|
||||
(describe "hooks"
|
||||
(describe "add-hook!"
|
||||
:var (fake-mode-hook other-mode-hook some-mode-hook)
|
||||
|
@ -31,15 +133,22 @@
|
|||
other-mode-hook nil
|
||||
some-mode-hook '(first-hook second-hook)))
|
||||
|
||||
(it "resolves quoted hooks literally"
|
||||
(expect '(add-hook! 'fake-mode-hook #'ignore) :to-expand-into
|
||||
`(add-hook 'fake-mode-hook #'ignore nil nil)))
|
||||
(it "resolves unquoted modes to their hook variables"
|
||||
(expect '(add-hook! fake-mode #'ignore) :to-expand-into
|
||||
`(add-hook 'fake-mode-hook #'ignore nil nil)))
|
||||
|
||||
(it "adds one-to-one hook"
|
||||
(add-hook! fake-mode #'hook-2)
|
||||
(add-hook! 'fake-mode-hook #'hook-1)
|
||||
(expect fake-mode-hook :to-equal '(hook-1 hook-2 first-hook)))
|
||||
|
||||
(it "adds many-to-one hook"
|
||||
(it "adds one-to-many hook"
|
||||
(add-hook! (fake-mode other-mode some-mode) #'hook-2)
|
||||
(add-hook! '(fake-mode-hook other-mode-hook some-mode-hook) #'hook-1)
|
||||
(add-hook! :append (fake-mode other-mode some-mode) #'last-hook)
|
||||
(add-hook! (fake-mode other-mode some-mode) :append #'last-hook)
|
||||
(expect fake-mode-hook :to-equal '(hook-1 hook-2 first-hook last-hook))
|
||||
(expect other-mode-hook :to-equal '(hook-1 hook-2 last-hook))
|
||||
(expect some-mode-hook :to-equal '(hook-1 hook-2 first-hook second-hook last-hook)))
|
||||
|
@ -47,7 +156,7 @@
|
|||
(it "adds many-to-many hooks and preserve provided order"
|
||||
(add-hook! (fake-mode other-mode some-mode) #'(hook-3 hook-4))
|
||||
(add-hook! '(fake-mode-hook other-mode-hook some-mode-hook) #'(hook-1 hook-2))
|
||||
(add-hook! :append '(fake-mode-hook other-mode-hook some-mode-hook) #'(last-hook-1 last-hook-2))
|
||||
(add-hook! '(fake-mode-hook other-mode-hook some-mode-hook) :append #'(last-hook-1 last-hook-2))
|
||||
(expect fake-mode-hook :to-equal '(hook-1 hook-2 hook-3 hook-4 first-hook last-hook-1 last-hook-2))
|
||||
(expect other-mode-hook :to-equal '(hook-1 hook-2 hook-3 hook-4 last-hook-1 last-hook-2))
|
||||
(expect some-mode-hook :to-equal '(hook-1 hook-2 hook-3 hook-4 first-hook second-hook last-hook-1 last-hook-2)))
|
||||
|
@ -55,10 +164,18 @@
|
|||
(it "adds implicit lambda to one hook"
|
||||
(add-hook! fake-mode (progn))
|
||||
(add-hook! 'other-mode-hook (ignore))
|
||||
(add-hook! :append 'some-mode-hook (ignore))
|
||||
(add-hook! 'some-mode-hook :append (ignore))
|
||||
(expect (caar fake-mode-hook) :to-be 'lambda)
|
||||
(expect (caar other-mode-hook) :to-be 'lambda)
|
||||
(expect (caar (last other-mode-hook)) :to-be 'lambda)))
|
||||
(expect (caar (last other-mode-hook)) :to-be 'lambda))
|
||||
|
||||
(it "handles inline defuns as hook symbols"
|
||||
(add-hook! fake-mode (defun hook-a ()))
|
||||
(add-hook! 'other-mode-hook
|
||||
(defun hook-b ())
|
||||
(defun hook-c ()))
|
||||
(expect (car fake-mode-hook) :to-be 'hook-a)
|
||||
(expect other-mode-hook :to-equal '(hook-b hook-c))))
|
||||
|
||||
(describe "remove-hook!"
|
||||
:var (fake-mode-hook)
|
||||
|
@ -71,7 +188,7 @@
|
|||
(it "removes multiple hooks"
|
||||
(remove-hook! fake-mode #'(first-hook third-hook))
|
||||
(remove-hook! 'fake-mode-hook #'(second-hook fourth-hook))
|
||||
(expect fake-mode-hook :to-be nil))))
|
||||
(expect fake-mode-hook :to-be nil)))
|
||||
|
||||
(describe "add-transient-hook!"
|
||||
(it "adds a transient function to hooks"
|
||||
|
@ -89,4 +206,74 @@
|
|||
(ignore t)
|
||||
(expect value))))
|
||||
|
||||
(xdescribe "associate!")) ; TODO
|
||||
(describe "(un)setq-hook!"
|
||||
:var (fake-hook x y z)
|
||||
(before-each
|
||||
(setq x 10 y 20 z 30))
|
||||
|
||||
(it "sets variables buffer-locally"
|
||||
(setq-hook! 'fake-hook x 1)
|
||||
(with-temp-buffer
|
||||
(run-hooks 'fake-hook)
|
||||
(expect (local-variable-p 'x))
|
||||
(expect (= x 1)))
|
||||
(expect (= x 10)))
|
||||
|
||||
(it "overwrites earlier hooks"
|
||||
(setq-hook! 'fake-hook x 1 y 0)
|
||||
(setq-hook! 'fake-hook x 5 y -1)
|
||||
(with-temp-buffer
|
||||
(run-hooks 'fake-hook)
|
||||
(expect (= x 5))
|
||||
(expect (= y -1))))
|
||||
|
||||
(it "unset setq hooks"
|
||||
(setq-hook! 'fake-hook x 1 y 0)
|
||||
(unsetq-hook! 'fake-hook y)
|
||||
(with-temp-buffer
|
||||
(run-hooks 'fake-hook)
|
||||
(expect (local-variable-p 'x))
|
||||
(expect (= x 1))
|
||||
(expect (not (local-variable-p 'y)))
|
||||
(expect (= y 20))))))
|
||||
|
||||
(describe "load!"
|
||||
(before-each
|
||||
(spy-on 'load :and-return-value t))
|
||||
|
||||
(it "loads a file relative to the current directory"
|
||||
(load! "path")
|
||||
(expect 'load :to-have-been-called)
|
||||
(expect 'load :to-have-been-called-with (expand-file-name "path" (eval-when-compile (dir!))) nil t))
|
||||
|
||||
(it "loads a file relative to a specified directory"
|
||||
(load! "path" doom-etc-dir)
|
||||
(expect 'load :to-have-been-called-with (expand-file-name "path" doom-etc-dir) nil t)))
|
||||
|
||||
(describe "quiet!"
|
||||
(it "suppresses output from message"
|
||||
(expect (message "hello world") :to-output "hello world\n")
|
||||
(expect (message "hello world") :to-output)
|
||||
(let (doom-interactive-mode)
|
||||
(expect (quiet! (message "hello world")) :not :to-output))
|
||||
(let ((doom-interactive-mode t))
|
||||
(expect (quiet! inhibit-message))
|
||||
(expect (quiet! save-silently))))
|
||||
|
||||
(it "suppresses load messages from `load' & `load-file'"
|
||||
(let ((tmpfile (make-temp-file "test" nil ".el")))
|
||||
(with-temp-file tmpfile)
|
||||
(let (doom-interactive-mode)
|
||||
(expect (load-file tmpfile) :to-output (format "Loading %s (source)...\n" tmpfile))
|
||||
(expect (quiet! (load-file tmpfile)) :not :to-output))
|
||||
(delete-file tmpfile)))
|
||||
|
||||
(it "won't suppress output in debug mode"
|
||||
(let ((doom-debug-mode t)
|
||||
(tmpfile (make-temp-file "test" nil ".el")))
|
||||
(dolist (doom-interactive-mode (list t nil))
|
||||
(expect (quiet! (message "hello world"))
|
||||
:to-output "hello world\n")
|
||||
(with-temp-file tmpfile)
|
||||
(expect (quiet! (load-file tmpfile))
|
||||
:to-output (format "Loading %s (source)...\n" tmpfile)))))))
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/test/test-core-modules.el
|
||||
;;;###if nil
|
||||
|
||||
;; (require 'core-modules)
|
||||
|
||||
(describe "core-modules")
|
||||
(xdescribe "core-modules")
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/test/test-core-packages.el
|
||||
;;;###if nil
|
||||
|
||||
(describe "core-packages")
|
||||
(xdescribe "core-packages")
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ../core/test/test-core-projects.el
|
||||
;;; core/test/test-core-projects.el
|
||||
|
||||
(describe "core/projects"
|
||||
:var (projectile-enable-caching)
|
||||
|
||||
(require 'core-projects)
|
||||
(require 'projectile)
|
||||
|
||||
(describe "core/projects"
|
||||
(before-each (projectile-mode +1))
|
||||
(after-each (projectile-mode -1))
|
||||
(before-each
|
||||
(setq projectile-enable-caching nil)
|
||||
(projectile-mode +1))
|
||||
(after-each
|
||||
(projectile-mode -1))
|
||||
|
||||
(describe "project-p"
|
||||
(it "Should detect when in a valid project"
|
||||
|
|
|
@ -1,17 +1,106 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ../core/test/test-core-ui.el
|
||||
|
||||
(require 'core-ui)
|
||||
|
||||
(describe "core/ui"
|
||||
(describe "doom|protect-fallback-buffer"
|
||||
:var (kill-buffer-query-functions a b)
|
||||
(before-all
|
||||
(setq kill-buffer-query-functions '(doom|protect-fallback-buffer)))
|
||||
(with-demoted-errors "Import error: %s"
|
||||
(require 'core-ui)))
|
||||
|
||||
(describe "doom-protect-fallback-buffer-h"
|
||||
:var (kill-buffer-query-functions)
|
||||
(before-all
|
||||
(setq kill-buffer-query-functions '(doom-protect-fallback-buffer-h)))
|
||||
|
||||
(it "should kill other buffers"
|
||||
(expect (kill-buffer (get-buffer-create "a"))))
|
||||
|
||||
(it "shouldn't kill the fallback buffer"
|
||||
(expect (not (kill-buffer (doom-fallback-buffer)))))))
|
||||
(expect (not (kill-buffer (doom-fallback-buffer))))))
|
||||
|
||||
(describe "custom hooks"
|
||||
(describe "switch hooks"
|
||||
:var (before-hook after-hook a b)
|
||||
(before-each
|
||||
(setq a (switch-to-buffer (get-buffer-create "a"))
|
||||
b (get-buffer-create "b"))
|
||||
(spy-on 'hook)
|
||||
(add-hook 'buffer-list-update-hook #'doom-run-switch-window-hooks-h)
|
||||
(add-hook 'focus-in-hook #'doom-run-switch-frame-hooks-h)
|
||||
(dolist (fn '(switch-to-buffer display-buffer))
|
||||
(advice-add fn :around #'doom-run-switch-buffer-hooks-a)))
|
||||
(after-each
|
||||
(remove-hook 'buffer-list-update-hook #'doom-run-switch-window-hooks-h)
|
||||
(remove-hook 'focus-in-hook #'doom-run-switch-frame-hooks-h)
|
||||
(dolist (fn '(switch-to-buffer display-buffer))
|
||||
(advice-remove fn #'doom-run-switch-buffer-hooks-a))
|
||||
(kill-buffer a)
|
||||
(kill-buffer b))
|
||||
|
||||
(describe "switch-buffer"
|
||||
:var (doom-switch-buffer-hook)
|
||||
(before-each
|
||||
(setq doom-switch-buffer-hook '(hook)))
|
||||
(after-each
|
||||
(setq doom-switch-buffer-hook nil))
|
||||
|
||||
(it "should trigger when switching buffers"
|
||||
(switch-to-buffer b)
|
||||
(switch-to-buffer a)
|
||||
(switch-to-buffer b)
|
||||
(expect 'hook :to-have-been-called-times 3))
|
||||
|
||||
(it "should trigger only once on the same buffer"
|
||||
(switch-to-buffer b)
|
||||
(switch-to-buffer b)
|
||||
(switch-to-buffer a)
|
||||
(expect 'hook :to-have-been-called-times 2)))
|
||||
|
||||
|
||||
(describe "switch-window"
|
||||
:var (doom-switch-window-hook x y)
|
||||
(before-each
|
||||
(delete-other-windows)
|
||||
(setq x (get-buffer-window a)
|
||||
y (save-selected-window (split-window)))
|
||||
(with-selected-window y
|
||||
(switch-to-buffer b))
|
||||
(select-window x)
|
||||
(spy-calls-reset 'hook)
|
||||
(setq doom-switch-window-hook '(hook)))
|
||||
|
||||
(it "should trigger when switching windows"
|
||||
(select-window y)
|
||||
(select-window x)
|
||||
(select-window y)
|
||||
(expect 'hook :to-have-been-called-times 3))
|
||||
|
||||
(it "should trigger only once on the same window"
|
||||
(select-window y)
|
||||
(select-window y)
|
||||
(select-window x)
|
||||
(expect 'hook :to-have-been-called-times 2)))
|
||||
|
||||
|
||||
(xdescribe "switch-frame"
|
||||
:var (doom-switch-frame-hook x y)
|
||||
(before-each
|
||||
(delete-other-windows)
|
||||
(setq x (get-buffer-window a)
|
||||
y (save-selected-window (split-window)))
|
||||
(with-selected-window y
|
||||
(switch-to-buffer b))
|
||||
(select-window x)
|
||||
(spy-calls-reset 'hook)
|
||||
(setq doom-switch-window-hook '(hook)))
|
||||
|
||||
(it "should trigger when switching windows"
|
||||
(select-window y)
|
||||
(select-window x)
|
||||
(select-window y)
|
||||
(expect 'hook :to-have-been-called-times 3))
|
||||
|
||||
(it "should trigger only once on the same window"
|
||||
(select-window y)
|
||||
(select-window y)
|
||||
(select-window x)
|
||||
(expect 'hook :to-have-been-called-times 2))))))
|
||||
|
|
|
@ -2,118 +2,116 @@
|
|||
;;; core/test/test-core.el
|
||||
|
||||
(describe "core"
|
||||
(xdescribe "initialize"
|
||||
:var (doom-init-p doom-init-modules-p doom-private-dir)
|
||||
:var (doom-interactive-mode)
|
||||
(before-each
|
||||
(setq doom-init-p nil
|
||||
doom-init-modules-p nil
|
||||
doom-private-dir doom-emacs-dir)
|
||||
(setq doom-interactive-mode nil))
|
||||
|
||||
(spy-on 'require)
|
||||
(spy-on 'load)
|
||||
(spy-on 'doom-reload-doom-autoloads)
|
||||
(spy-on 'doom-reload-package-autoloads)
|
||||
(spy-on 'doom-initialize-autoloads)
|
||||
(spy-on 'doom-ensure-core-directories)
|
||||
(spy-on 'doom-ensure-core-packages)
|
||||
(spy-on 'doom-ensure-packages-initialized)
|
||||
(spy-on 'doom-ensure-same-emacs-version-p))
|
||||
|
||||
(describe "in interactive session"
|
||||
:var (noninteractive)
|
||||
(before-each (setq noninteractive t))
|
||||
|
||||
(it "initializes once, unless forced")
|
||||
(it "does not initialize on consecutive invokations")
|
||||
(it "loads all core libraries" )
|
||||
(it "loads autoloads file" )
|
||||
(it "does not load autoloads file if forced" )
|
||||
(it "regenerates missing autoloads" ))
|
||||
|
||||
(describe "in non-interactive session"
|
||||
:var (noninteractive)
|
||||
(before-each (setq noninteractive nil))
|
||||
|
||||
(it "initializes once, unless forced")
|
||||
(it "does not initialize on consecutive invokations")
|
||||
(it "does not load all core libraries" )
|
||||
(it "loads autoloads file" )
|
||||
(it "does not load autoloads file if forced" )
|
||||
(it "does not regenerate missing autoloads" )))
|
||||
|
||||
(xdescribe "initialize-packages"
|
||||
(before-each (spy-on 'quelpa-setup-p))
|
||||
|
||||
(it "initializes package.el once, unless forced" )
|
||||
(it "initializes quelpa once, unless forced" )
|
||||
(it "initializes doom-packages once, unless forced" ))
|
||||
|
||||
(xdescribe "initialize-modules"
|
||||
(it "loads private init.el once, unless forced" ))
|
||||
|
||||
(xdescribe "initialize-autoloads"
|
||||
(it "loads autoloads file" )
|
||||
(it "ignores autoloads file if cleared" ))
|
||||
|
||||
(describe "custom hooks"
|
||||
(describe "switch hooks"
|
||||
:var (before-hook after-hook a b)
|
||||
(describe "initialization"
|
||||
(describe "doom-initialize"
|
||||
:var (doom-init-p)
|
||||
(before-each
|
||||
(setq a (switch-to-buffer (get-buffer-create "a"))
|
||||
b (get-buffer-create "b"))
|
||||
(spy-on 'hook)
|
||||
(add-hook 'buffer-list-update-hook #'doom-run-switch-window-hooks-h)
|
||||
(add-hook 'focus-in-hook #'doom-run-switch-frame-hooks-h)
|
||||
(dolist (fn '(switch-to-buffer display-buffer))
|
||||
(advice-add fn :around #'doom-run-switch-buffer-hooks-a)))
|
||||
(setq doom-init-p nil))
|
||||
|
||||
(it "initializes once"
|
||||
(expect (doom-initialize))
|
||||
(expect (not (doom-initialize)))
|
||||
(expect (not (doom-initialize)))
|
||||
(expect doom-init-p))
|
||||
|
||||
(it "initializes multiple times, if forced"
|
||||
(expect (doom-initialize))
|
||||
(expect (not (doom-initialize)))
|
||||
(expect (doom-initialize 'force)))
|
||||
|
||||
(describe "package initialization"
|
||||
(before-each
|
||||
(spy-on 'doom-initialize-packages :and-return-value t))
|
||||
|
||||
(it "initializes packages if core autoload file doesn't exist"
|
||||
(let ((doom-autoload-file "doesnotexist"))
|
||||
(doom-initialize))
|
||||
(expect 'doom-initialize-packages :to-have-been-called))
|
||||
|
||||
(it "doesn't initialize packages if core autoload file was loaded"
|
||||
(let ((doom-interactive-mode t))
|
||||
(spy-on 'doom-load-autoloads-file :and-return-value t)
|
||||
(doom-initialize)
|
||||
(expect 'doom-load-autoloads-file :to-have-been-called-with doom-package-autoload-file)
|
||||
(expect 'doom-initialize-packages :to-have-been-called)))
|
||||
|
||||
(it "initializes packages when forced"
|
||||
(doom-initialize 'force)
|
||||
(expect 'doom-initialize-packages :to-have-been-called)))
|
||||
|
||||
(describe "autoloads files"
|
||||
(before-each
|
||||
(spy-on 'doom-load-autoloads-file)
|
||||
(spy-on 'warn :and-return-value t))
|
||||
|
||||
(it "loads autoloads file"
|
||||
(let ((doom-interactive-mode t))
|
||||
(ignore-errors (doom-initialize)))
|
||||
(expect 'doom-load-autoloads-file
|
||||
:to-have-been-called-with doom-autoload-file)
|
||||
(expect 'doom-load-autoloads-file
|
||||
:to-have-been-called-with doom-package-autoload-file))
|
||||
|
||||
(it "does not load package autoloads file if noninteractive"
|
||||
(doom-initialize)
|
||||
(expect 'doom-load-autoloads-file
|
||||
:to-have-been-called-with doom-autoload-file)
|
||||
(expect 'doom-load-autoloads-file
|
||||
:not :to-have-been-called-with doom-package-autoload-file))
|
||||
|
||||
(it "throws doom-autoload-error in interactive session where autoload files don't exist"
|
||||
(let ((doom-interactive-mode t)
|
||||
(doom-autoload-file "doesnotexist")
|
||||
(doom-package-autoload-file "doesnotexist"))
|
||||
(expect (doom-initialize) :to-throw 'doom-autoload-error)))))
|
||||
|
||||
(describe "doom-initialize-core"
|
||||
(before-each
|
||||
(spy-on 'require))
|
||||
|
||||
(it "loads all doom core libraries"
|
||||
(doom-initialize-core)
|
||||
(expect 'require :to-have-been-called-with 'core-keybinds)
|
||||
(expect 'require :to-have-been-called-with 'core-ui)
|
||||
(expect 'require :to-have-been-called-with 'core-projects)
|
||||
(expect 'require :to-have-been-called-with 'core-editor))))
|
||||
|
||||
(describe "doom-load-autoloads-file"
|
||||
(before-each
|
||||
(spy-on 'load :and-return-value t))
|
||||
|
||||
(it "loads the autoloads file"
|
||||
(doom-load-autoloads-file doom-autoload-file)
|
||||
(expect 'load :to-have-been-called-with (file-name-sans-extension doom-autoload-file)
|
||||
'noerror 'nomessage)))
|
||||
|
||||
(describe "doom-load-envvars-file"
|
||||
:var (envvarfile process-environment)
|
||||
(before-each
|
||||
(setq process-environment (copy-sequence process-environment))
|
||||
(with-temp-file doom-env-file
|
||||
(insert "\n\n\nA=1\nB=2\nC=3\n")))
|
||||
(after-each
|
||||
(remove-hook 'buffer-list-update-hook #'doom-run-switch-window-hooks-h)
|
||||
(remove-hook 'focus-in-hook #'doom-run-switch-frame-hooks-h)
|
||||
(dolist (fn '(switch-to-buffer display-buffer))
|
||||
(advice-remove fn #'doom-run-switch-buffer-hooks-a))
|
||||
(kill-buffer a)
|
||||
(kill-buffer b))
|
||||
(delete-file doom-env-file))
|
||||
|
||||
(describe "switch-buffer"
|
||||
:var (doom-switch-buffer-hook)
|
||||
(before-each
|
||||
(setq doom-switch-buffer-hook '(hook)))
|
||||
(after-each
|
||||
(setq doom-switch-buffer-hook nil))
|
||||
(it "throws a file-error if file doesn't exist"
|
||||
(expect (doom-load-envvars-file "/tmp/envvardoesnotexist")
|
||||
:to-throw 'file-error))
|
||||
|
||||
(it "should trigger when switching buffers"
|
||||
(switch-to-buffer b)
|
||||
(switch-to-buffer a)
|
||||
(switch-to-buffer b)
|
||||
(expect 'hook :to-have-been-called-times 3))
|
||||
(it "to fail silently if NOERROR is non-nil"
|
||||
(expect (doom-load-envvars-file "/tmp/envvardoesnotexist" 'noerror)
|
||||
:not :to-throw))
|
||||
|
||||
(it "should trigger only once on the same buffer"
|
||||
(switch-to-buffer b)
|
||||
(switch-to-buffer b)
|
||||
(switch-to-buffer a)
|
||||
(expect 'hook :to-have-been-called-times 2)))
|
||||
(it "loads a well-formed envvar file"
|
||||
(expect (getenv "A") :not :to-be-truthy)
|
||||
(expect (doom-load-envvars-file doom-env-file)
|
||||
:to-equal '(("A" . "1") ("B" . "2") ("C" . "3")))
|
||||
(expect (getenv "A") :to-equal "1"))
|
||||
|
||||
|
||||
(describe "switch-window"
|
||||
:var (doom-switch-window-hook x y)
|
||||
(before-each
|
||||
(delete-other-windows)
|
||||
(setq x (get-buffer-window a)
|
||||
y (save-selected-window (split-window)))
|
||||
(with-selected-window y
|
||||
(switch-to-buffer b))
|
||||
(select-window x)
|
||||
(spy-calls-reset 'hook)
|
||||
(setq doom-switch-window-hook '(hook)))
|
||||
|
||||
(it "should trigger when switching windows"
|
||||
(select-window y)
|
||||
(select-window x)
|
||||
(select-window y)
|
||||
(expect 'hook :to-have-been-called-times 3))
|
||||
|
||||
(it "should trigger only once on the same window"
|
||||
(select-window y)
|
||||
(select-window y)
|
||||
(select-window x)
|
||||
(expect 'hook :to-have-been-called-times 2))))))
|
||||
(it "fails on an invalid envvar file"
|
||||
(with-temp-file doom-env-file (insert "A=1\nB=2\nC=3\n"))
|
||||
(expect (doom-load-envvars-file doom-env-file) :to-throw))))
|
||||
|
|
293
docs/api.org
293
docs/api.org
|
@ -1,9 +1,40 @@
|
|||
#+TITLE: API Demos
|
||||
#+PROPERTY: header-args:elisp :results pp
|
||||
|
||||
This appendix serves as a reference on how to use Doom Emacs' standard library.
|
||||
It is integrated into Helpful, in Doom.
|
||||
|
||||
* add-hook!
|
||||
* Table of Contents :TOC_3:
|
||||
- [[#examples-for-dooms-core-library][Examples for Doom's core library]]
|
||||
- [[#core-lib][core-lib]]
|
||||
- [[#add-hook][add-hook!]]
|
||||
- [[#add-transient-hook][add-transient-hook!]]
|
||||
- [[#after][after!]]
|
||||
- [[#custom-set-faces][custom-set-faces!]]
|
||||
- [[#custom-theme-set-faces][custom-theme-set-faces!]]
|
||||
- [[#defer-feature][defer-feature!]]
|
||||
- [[#defer-until][defer-until!]]
|
||||
- [[#disable-packages][disable-packages!]]
|
||||
- [[#doom][doom!]]
|
||||
- [[#file-exists-p][file-exists-p!]]
|
||||
- [[#lambda][lambda!]]
|
||||
- [[#lambda-1][lambda!!]]
|
||||
- [[#load][load!]]
|
||||
- [[#map][map!]]
|
||||
- [[#package][package!]]
|
||||
- [[#pushnew][pushnew!]]
|
||||
- [[#quiet][quiet!]]
|
||||
- [[#remove-hook][remove-hook!]]
|
||||
- [[#setq-hook][setq-hook!]]
|
||||
- [[#unsetq-hook][unsetq-hook!]]
|
||||
- [[#use-package][use-package!]]
|
||||
- [[#interesting-snippets][Interesting snippets]]
|
||||
- [[#persist-emacs-initial-frame-size-across-sessions][Persist Emacs' initial frame size across sessions]]
|
||||
- [[#persist-emacs-initial-frame-position-dimensions-andor-full-screen-state-across-sessions][Persist Emacs' initial frame position, dimensions and/or full-screen state across sessions]]
|
||||
|
||||
* Examples for Doom's core library
|
||||
** core-lib
|
||||
*** add-hook!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
;; With only one hook and one function, this is identical to `add-hook'. In that
|
||||
;; case, use that instead.
|
||||
|
@ -31,7 +62,69 @@ It is integrated into Helpful, in Doom.
|
|||
...))
|
||||
#+END_SRC
|
||||
|
||||
* custom-theme-set-faces!
|
||||
*** TODO add-transient-hook!
|
||||
*** after!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
;;; `after!' will take:
|
||||
|
||||
;; An unquoted package symbol (the name of a package)
|
||||
(after! helm ...)
|
||||
|
||||
;; An unquoted list of package symbols (i.e. BODY is evaluated once both magit
|
||||
;; and git-gutter have loaded)
|
||||
(after! (magit git-gutter) ...)
|
||||
|
||||
;; An unquoted, nested list of compound package lists, using any combination of
|
||||
;; :or/:any and :and/:all
|
||||
(after! (:or package-a package-b ...) ...)
|
||||
(after! (:and package-a package-b ...) ...)
|
||||
(after! (:and package-a (:or package-b package-c) ...) ...)
|
||||
;; (Without :or/:any/:and/:all, :and/:all are implied.)
|
||||
|
||||
;; A common mistake is to pass it the names of major or minor modes, e.g.
|
||||
(after! rustic-mode ...)
|
||||
(after! python-mode ...)
|
||||
;; But the code in them will never run! rustic-mode is in the `rustic' package
|
||||
;; and python-mode is in the `python' package. This is what you want:
|
||||
(after! rustic ...)
|
||||
(after! python ...)
|
||||
#+END_SRC
|
||||
|
||||
*** custom-set-faces!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
(custom-set-faces!
|
||||
'(outline-1 :weight normal)
|
||||
'(outline-2 :weight normal)
|
||||
'(outline-3 :weight normal)
|
||||
'(outline-4 :weight normal)
|
||||
'(outline-5 :weight normal)
|
||||
'(outline-6 :weight normal)
|
||||
'(default :background "red" :weight bold)
|
||||
'(region :background "red" :weight bold))
|
||||
|
||||
(custom-set-faces!
|
||||
'((outline-1 outline-2 outline-3 outline-4 outline-5 outline-6)
|
||||
:weight normal)
|
||||
'((default region)
|
||||
:background "red" :weight bold))
|
||||
|
||||
(let ((red-bg-faces '(default region)))
|
||||
(custom-set-faces!
|
||||
`(,(cl-loop for i from 0 to 6 collect (intern (format "outline-%d" i)))
|
||||
:weight normal)
|
||||
`(,red-bg-faces
|
||||
:background "red" :weight bold)))
|
||||
|
||||
;; If you want to make use of the `doom-themes' package API (e.g. `doom-color',
|
||||
;; `doom-lighten', `doom-darken', etc.), you must use `custom-set-faces!'
|
||||
;; *after* the theme has been loaded. e.g.
|
||||
(load-theme 'doom-one t)
|
||||
(custom-set-faces!
|
||||
`(outline-1 :foreground ,(doom-color 'red))
|
||||
`(outline-2 :background ,(doom-color 'blue)))
|
||||
#+END_SRC
|
||||
|
||||
*** custom-theme-set-faces!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
(custom-theme-set-faces! 'doom-one-theme
|
||||
'(outline-1 :weight normal)
|
||||
|
@ -55,35 +148,25 @@ It is integrated into Helpful, in Doom.
|
|||
:weight normal)
|
||||
`(,red-bg-faces
|
||||
:background "red" :weight bold)))
|
||||
|
||||
;; If you want to make use of the `doom-themes' package API (e.g. `doom-color',
|
||||
;; `doom-lighten', `doom-darken', etc.), you must use `custom-set-faces!'
|
||||
;; *after* the theme has been loaded. e.g.
|
||||
(load-theme 'doom-one t)
|
||||
(custom-theme-set-faces! 'doom-one
|
||||
`(outline-1 :foreground ,(doom-color 'red))
|
||||
`(outline-2 :background ,(doom-color 'blue)))
|
||||
#+END_SRC
|
||||
|
||||
* custom-set-faces!
|
||||
*** TODO defer-feature!
|
||||
*** TODO defer-until!
|
||||
*** disable-packages!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
(custom-set-faces!
|
||||
'(outline-1 :weight normal)
|
||||
'(outline-2 :weight normal)
|
||||
'(outline-3 :weight normal)
|
||||
'(outline-4 :weight normal)
|
||||
'(outline-5 :weight normal)
|
||||
'(outline-6 :weight normal)
|
||||
'(default :background "red" :weight bold)
|
||||
'(region :background "red" :weight bold))
|
||||
|
||||
(custom-set-faces!
|
||||
'((outline-1 outline-2 outline-3 outline-4 outline-5 outline-6)
|
||||
:weight normal)
|
||||
'((default region)
|
||||
:background "red" :weight bold))
|
||||
|
||||
(let ((red-bg-faces '(default region)))
|
||||
(custom-set-faces!
|
||||
`(,(cl-loop for i from 0 to 6 collect (intern (format "outline-%d" i)))
|
||||
:weight normal)
|
||||
`(,red-bg-faces
|
||||
:background "red" :weight bold)))
|
||||
;; Disable packages enabled by DOOM
|
||||
(disable-packages! some-package second-package)
|
||||
#+END_SRC
|
||||
|
||||
* doom!
|
||||
*** doom!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
(doom! :completion
|
||||
company
|
||||
|
@ -113,7 +196,7 @@ It is integrated into Helpful, in Doom.
|
|||
(default +bindings +smartparens))
|
||||
#+END_SRC
|
||||
|
||||
* file-exists-p!
|
||||
*** file-exists-p!
|
||||
#+BEGIN_SRC elisp
|
||||
(file-exists-p! "init.el" doom-emacs-dir)
|
||||
#+END_SRC
|
||||
|
@ -130,7 +213,86 @@ It is integrated into Helpful, in Doom.
|
|||
#+RESULTS:
|
||||
: /home/hlissner/.emacs.d/LICENSE
|
||||
|
||||
* remove-hook!
|
||||
*** TODO lambda!
|
||||
*** TODO lambda!!
|
||||
*** load!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
;;; Lets say we're in ~/.doom.d/config.el
|
||||
(load! "lisp/module") ; loads ~/.doom.d/lisp/module.el
|
||||
(load! "somefile" doom-emacs-dir) ; loads ~/.emacs.d/somefile.el
|
||||
(load! "anotherfile" doom-private-dir) ; loads ~/.doom.d/anotherfile.el
|
||||
|
||||
;; If you don't want a `load!' call to throw an error if the file doesn't exist:
|
||||
(load! "~/.maynotexist" nil t)
|
||||
#+END_SRC
|
||||
|
||||
*** map!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
(map! :map magit-mode-map
|
||||
:m "C-r" 'do-something ; C-r in motion state
|
||||
:nv "q" 'magit-mode-quit-window ; q in normal+visual states
|
||||
"C-x C-r" 'a-global-keybind
|
||||
:g "C-x C-r" 'another-global-keybind ; same as above
|
||||
|
||||
(:when IS-MAC
|
||||
:n "M-s" 'some-fn
|
||||
:i "M-o" (lambda (interactive) (message "Hi"))))
|
||||
|
||||
(map! (:when (featurep! :completion company) ; Conditional loading
|
||||
:i "C-@" #'+company/complete
|
||||
(:prefix "C-x" ; Use a prefix key
|
||||
:i "C-l" #'+company/whole-lines)))
|
||||
|
||||
(map! (:when (featurep! :lang latex) ; local conditional
|
||||
(:map LaTeX-mode-map
|
||||
:localleader ; Use local leader
|
||||
:desc "View" "v" #'TeX-view)) ; Add which-key description
|
||||
:leader ; Use leader key from now on
|
||||
:desc "Eval expression" ";" #'eval-expression)
|
||||
#+END_SRC
|
||||
|
||||
*** package!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
;; To install a package that can be found on ELPA or any of the sources
|
||||
;; specified in `doom-core-package-sources':
|
||||
(package! evil)
|
||||
(package! js2-mode)
|
||||
(package! rainbow-delimiters)
|
||||
|
||||
;; To disable a package included with Doom (which will no-op all its `after!'
|
||||
;; and `use-package!' blocks):
|
||||
(package! evil :disable t)
|
||||
(package! rainbow-delimiters :disable t)
|
||||
|
||||
;; To install a package from a github repo
|
||||
(package! so-long :recipe (:host github :repo "hlissner/emacs-so-long"))
|
||||
|
||||
;; If a package is particularly big and comes with submodules you don't need,
|
||||
;; you can tell the package manager not to clone the repo recursively:
|
||||
(package! ansible :recipe (:nonrecursive t))
|
||||
|
||||
;; To install a particular branch, commit or tag:
|
||||
(package! evil
|
||||
;; if :host and :fetcher aren't specified, the package manager will fall back
|
||||
;; to evil's default source provided by their (M)ELPA recipes:
|
||||
:recipe (:commit "e7bc39de2f961505e8e112da8c1b315ae8afce52"))
|
||||
|
||||
(package! evil :recipe (:branch "stable"))
|
||||
|
||||
(package! evil :recipe (:tag "1.2.9"))
|
||||
|
||||
;; If you share your config between two computers, and don't want bin/doom
|
||||
;; refresh to delete packages used only on one system, use :ignore
|
||||
(package! evil :ignore (not (equal system-name "my-desktop")))
|
||||
#+END_SRC
|
||||
|
||||
*** TODO pushnew!
|
||||
*** quiet!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
;; Enters recentf-mode without extra output
|
||||
(quiet! (recentf-mode +1))
|
||||
#+END_SRC
|
||||
*** remove-hook!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
;; With only one hook and one function, this is identical to `remove-hook'. In
|
||||
;; that case, use that instead.
|
||||
|
@ -148,3 +310,78 @@ It is integrated into Helpful, in Doom.
|
|||
;; Removing arbitrary forms (must be exactly the same as the definition)
|
||||
(remove-hook! (one-mode second-mode) (setq v 5) (setq a 2))
|
||||
#+END_SRC
|
||||
*** setq-hook!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
;; Set multiple variables after a hook
|
||||
(setq-hook! 'markdown-mode-hook
|
||||
line-spacing 2
|
||||
fill-column 80)
|
||||
|
||||
;; Set variables after multiple hooks
|
||||
(setq-hook! '(eshell-mode-hook term-mode-hook)
|
||||
hscroll-margin 0)
|
||||
#+END_SRC
|
||||
|
||||
*** unsetq-hook!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
(unsetq-hook! 'markdown-mode-hook line-spacing)
|
||||
|
||||
;; Removes the following variable hook
|
||||
(setq-hook! 'markdown-mode-hook line-spacing 2)
|
||||
|
||||
;; Removing N variables from M hooks
|
||||
(unsetq-hook! some-mode enable-something and-another)
|
||||
(unsetq-hook! some-mode (enable-something and-another))
|
||||
(unsetq-hook! '(one-mode-hook second-mode-hook) enable-something)
|
||||
(unsetq-hook! (one-mode second-mode) enable-something)
|
||||
#+END_SRC
|
||||
|
||||
*** use-package!
|
||||
#+BEGIN_SRC elisp :eval no
|
||||
;; Use after-call to load package before hook
|
||||
(use-package! projectile
|
||||
:after-call (pre-command-hook after-find-file dired-before-readin-hook))
|
||||
|
||||
;; defer recentf packages one by one
|
||||
(use-package! recentf
|
||||
:defer-incrementally easymenu tree-widget timer
|
||||
:after-call after-find-file)
|
||||
|
||||
;; This is equivalent to :defer-incrementally (abc)
|
||||
(use-package! abc
|
||||
:defer-incrementally t)
|
||||
#+END_SRC
|
||||
* Interesting snippets
|
||||
** Persist Emacs' initial frame size across sessions
|
||||
#+BEGIN_SRC elisp
|
||||
(let ((display-height (display-pixel-height))
|
||||
(display-width (display-pixel-width)))
|
||||
(add-to-list 'initial-frame-alist
|
||||
`((left . ,(/ new-frame-width 2))
|
||||
(top . ,(/ new-frame-height 2))
|
||||
(width . ,(/ display-width 2))
|
||||
(height . ,(/ display-height 2)))))
|
||||
#+END_SRC
|
||||
|
||||
** Persist Emacs' initial frame position, dimensions and/or full-screen state across sessions
|
||||
#+BEGIN_SRC elisp
|
||||
;; add to ~/.doom.d/config.el
|
||||
(when-let* ((dims (doom-cache-get 'last-frame-size)))
|
||||
(cl-destructuring-bind ((left . top) width height fullscreen) dims
|
||||
(setq initial-frame-alist
|
||||
(append initial-frame-alist
|
||||
`((left . ,left)
|
||||
(top . ,top)
|
||||
(width . ,width)
|
||||
(height . ,height)
|
||||
(fullscreen . ,fullscreen))))))
|
||||
|
||||
(defun save-frame-dimensions ()
|
||||
(doom-cache-set 'last-frame-size
|
||||
(list (frame-position)
|
||||
(frame-width)
|
||||
(frame-height)
|
||||
(frame-parameter nil 'fullscreen))))
|
||||
|
||||
(add-hook 'kill-emacs-hook #'save-frame-dimensions)
|
||||
#+END_SRC
|
||||
|
|
|
@ -20,3 +20,8 @@
|
|||
;; font. By inhibiting this, we easily halve startup times with fonts that are
|
||||
;; larger than the system default.
|
||||
(setq frame-inhibit-implied-resize t)
|
||||
|
||||
;; Ignore X resources; its settings would be redundant with the other settings
|
||||
;; in this file and can conflict with later config (particularly where the
|
||||
;; cursor color is concerned).
|
||||
(advice-add #'x-apply-session-resources :override #'ignore)
|
||||
|
|
18
init.el
18
init.el
|
@ -27,13 +27,6 @@
|
|||
;;
|
||||
;;; License: MIT
|
||||
|
||||
(when (version< emacs-version "25.3")
|
||||
(error "Detected Emacs %s. Doom only supports Emacs 25.3 and higher"
|
||||
emacs-version))
|
||||
|
||||
;; Ensure Doom is running out of this file's directory
|
||||
(setq user-emacs-directory (file-name-directory load-file-name))
|
||||
|
||||
;; A big contributor to startup times is garbage collection. We up the gc
|
||||
;; threshold to temporarily prevent it from running, then reset it later with
|
||||
;; `doom-restore-garbage-collection-h'. Not resetting it will cause
|
||||
|
@ -45,8 +38,17 @@
|
|||
;; to skip the mtime checks on every *.elc file we load.
|
||||
(setq load-prefer-newer noninteractive)
|
||||
|
||||
(let (file-name-handler-alist)
|
||||
(when (version< emacs-version "25.3")
|
||||
(error "Detected Emacs %s. Doom only supports Emacs 25.3 and higher"
|
||||
emacs-version))
|
||||
|
||||
;; Ensure Doom is running out of this file's directory
|
||||
(setq user-emacs-directory (file-name-directory load-file-name)))
|
||||
|
||||
;; Load the heart of Doom Emacs
|
||||
(require 'core (concat user-emacs-directory "core/core"))
|
||||
(load (concat user-emacs-directory "core/core")
|
||||
nil 'nomessage)
|
||||
|
||||
;; And let 'er rip!
|
||||
(add-hook 'window-setup-hook #'doom-display-benchmark-h)
|
||||
|
|
|
@ -118,6 +118,7 @@
|
|||
;;julia ; a better, faster MATLAB
|
||||
;;kotlin ; a better, slicker Java(Script)
|
||||
;;latex ; writing papers in Emacs has never been so fun
|
||||
;;lean
|
||||
;;ledger ; an accounting system in Emacs
|
||||
;;lua ; one-based indices? one-based indices
|
||||
markdown ; writing docs for people to ignore
|
||||
|
@ -125,10 +126,10 @@
|
|||
;;nix ; I hereby declare "nix geht mehr!"
|
||||
;;ocaml ; an objective camel
|
||||
(org ; organize your plain life in plain text
|
||||
+dragndrop ; file drag & drop support
|
||||
+ipython ; ipython support for babel
|
||||
+pandoc ; pandoc integration into org's exporter
|
||||
+present) ; using Emacs for presentations
|
||||
+dragndrop ; drag & drop files/images into org buffers
|
||||
+ipython ; ipython/jupyter support for babel
|
||||
+pandoc ; export-with-pandoc support
|
||||
+present) ; using org-mode for presentations
|
||||
;;perl ; write code no one else can comprehend
|
||||
;;php ; perl's insecure younger brother
|
||||
;;plantuml ; diagrams for confusing people more
|
||||
|
|
|
@ -42,7 +42,7 @@ Aesthetic modules that affect the Emacs interface or user experience.
|
|||
+ [[file:ui/unicode/README.org][unicode]]:
|
||||
+ vc-gutter:
|
||||
+ vi-tilde-fringe:
|
||||
+ [[file:ui/window-select/README.org][window-select]]:
|
||||
+ [[file:ui/window-select/README.org][window-select]] =+switch-window +numbers=:
|
||||
+ [[file:ui/workspaces/README.org][workspaces]]: Isolated workspaces
|
||||
|
||||
* :editor
|
||||
|
@ -64,7 +64,6 @@ Modules that reconfigure or augment packages or features built into Emacs.
|
|||
|
||||
+ dired =+ranger +icons=:
|
||||
+ electric:
|
||||
+ imenu:
|
||||
+ vc:
|
||||
|
||||
* :term
|
||||
|
|
|
@ -34,7 +34,7 @@ https://assets.doomemacs.org/completion/company/overlay.png
|
|||
+ [[https://github.com/company-mode/company-mode][company-mode]]
|
||||
+ [[https://github.com/hlissner/emacs-company-dict][company-dict]]
|
||||
+ [[https://github.com/raxod502/prescient.el][company-prescient]]
|
||||
+ [[https://github.com/sebastiencs/company-box][company-box]]
|
||||
+ [[https://github.com/sebastiencs/company-box][company-box]]* (=+childframe=)
|
||||
|
||||
* Prerequisites
|
||||
This module has no direct prerequisites.
|
||||
|
|
|
@ -41,6 +41,7 @@ be negative.")
|
|||
[remap bookmark-jump] #'helm-bookmarks
|
||||
[remap execute-extended-command] #'helm-M-x
|
||||
[remap find-file] #'helm-find-files
|
||||
[remap locate] #'helm-locate
|
||||
[remap imenu] #'helm-semantic-or-imenu
|
||||
[remap noop-show-kill-ring] #'helm-show-kill-ring
|
||||
[remap persp-switch-to-buffer] #'+helm/workspace-mini
|
||||
|
@ -158,7 +159,23 @@ be negative.")
|
|||
|
||||
;;;###package helm-locate
|
||||
(defvar helm-generic-files-map (make-sparse-keymap))
|
||||
(after! helm-locate (set-keymap-parent helm-generic-files-map helm-map))
|
||||
(after! helm-locate
|
||||
(when (and IS-MAC
|
||||
(null helm-locate-command)
|
||||
(executable-find "mdfind"))
|
||||
(setq helm-locate-command "mdfind -name %s"))
|
||||
(set-keymap-parent helm-generic-files-map helm-map))
|
||||
|
||||
|
||||
;;;###package helm-org
|
||||
(use-package! helm-org
|
||||
:when (featurep! :lang org)
|
||||
:defer t
|
||||
:init
|
||||
(after! helm-mode
|
||||
(pushnew! helm-completing-read-handlers-alist
|
||||
'(org-capture . helm-org-completing-read-tags)
|
||||
'(org-set-tags . helm-org-completing-read-tags))))
|
||||
|
||||
|
||||
;;;###package helm-projectile
|
||||
|
|
|
@ -12,3 +12,5 @@
|
|||
(package! helm-flx))
|
||||
(when (and EMACS26+ (featurep! +childframe))
|
||||
(package! posframe))
|
||||
(when (featurep! :lang org)
|
||||
(package! helm-org))
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
- [[#install][Install]]
|
||||
- [[#macos][MacOS]]
|
||||
- [[#arch-linux][Arch Linux]]
|
||||
- [[#opensuse][openSUSE]]
|
||||
- [[#features][Features]]
|
||||
- [[#jump-to-file-project-navigation][Jump-to-file project navigation]]
|
||||
- [[#project-search--replace][Project search & replace]]
|
||||
|
@ -90,6 +91,11 @@ brew install ripgrep the_silver_searcher
|
|||
sudo pacman --needed --noconfirm -S ripgrep the_silver_searcher
|
||||
#+END_SRC
|
||||
|
||||
*** openSUSE
|
||||
#+BEGIN_SRC sh :dir /sudo::
|
||||
sudo zypper install ripgrep the_silver_searcher
|
||||
#+END_SRC
|
||||
|
||||
* Features
|
||||
Ivy and its ilk are large plugins. Covering everything about them is outside of
|
||||
this documentation's scope, so only Doom-specific Ivy features are listed here:
|
||||
|
|
|
@ -214,7 +214,7 @@ If ARG (universal argument), open selection in other-window."
|
|||
|
||||
(defun +ivy--tasks-open-action (x)
|
||||
"Jump to the file and line of the current task."
|
||||
(cl-destructuring-bind (label type file line) x
|
||||
(cl-destructuring-bind (_label type file line) x
|
||||
(with-ivy-window
|
||||
(find-file (expand-file-name file (doom-project-root)))
|
||||
(goto-char (point-min))
|
||||
|
|
|
@ -62,8 +62,6 @@ immediately runs it on the current candidate (ending the ivy session)."
|
|||
projectile-completion-system 'ivy
|
||||
;; Don't use ^ as initial input
|
||||
ivy-initial-inputs-alist nil
|
||||
;; highlight til EOL
|
||||
ivy-format-function #'ivy-format-function-line
|
||||
;; disable magic slash on non-match
|
||||
ivy-magic-slash-non-match-action nil
|
||||
;; don't show recent files in switch-buffer
|
||||
|
@ -75,6 +73,9 @@ immediately runs it on the current candidate (ending the ivy session)."
|
|||
;; enable ability to select prompt (alternative to `ivy-immediate-done')
|
||||
ivy-use-selectable-prompt t)
|
||||
|
||||
(setf (alist-get 't ivy-format-functions-alist)
|
||||
#'ivy-format-function-line)
|
||||
|
||||
;; REVIEW Move this somewhere else and perhaps generalize this so both
|
||||
;; ivy/helm users can enjoy it.
|
||||
(defadvice! +ivy--counsel-file-jump-use-fd-rg-a (args)
|
||||
|
@ -220,10 +221,13 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
|
|||
[remap org-capture] #'counsel-org-capture
|
||||
[remap swiper] #'counsel-grep-or-swiper
|
||||
[remap evil-ex-registers] #'counsel-evil-registers
|
||||
[remap yank-pop] #'counsel-yank-pop)
|
||||
[remap yank-pop] #'counsel-yank-pop
|
||||
[remap locate] #'counsel-locate)
|
||||
:config
|
||||
(set-popup-rule! "^\\*ivy-occur" :size 0.35 :ttl 0 :quit nil)
|
||||
|
||||
(when IS-MAC
|
||||
(setq counsel-locate-cmd #'counsel-locate-cmd-mdfind))
|
||||
(setq counsel-find-file-ignore-regexp "\\(?:^[#.]\\)\\|\\(?:[#~]$\\)\\|\\(?:^Icon?\\)"
|
||||
counsel-describe-function-function #'helpful-callable
|
||||
counsel-describe-variable-function #'helpful-variable
|
||||
|
|
|
@ -20,20 +20,7 @@
|
|||
;;; Leader keys
|
||||
|
||||
(map! :leader
|
||||
:desc "Find file in project" "C-f" #'projectile-find-file
|
||||
:desc "Evaluate line/region" "e" #'+eval/line-or-region
|
||||
:desc "Open scratch buffer" "x" #'doom/open-scratch-buffer
|
||||
:desc "Open project scratch buffer" "X" #'doom/switch-to-scratch-buffer
|
||||
|
||||
(:when (featurep! :term term)
|
||||
:desc "Toggle term popup" "`" #'+term/toggle
|
||||
:desc "Open term here" "~" #'+term/here)
|
||||
(:when (featurep! :term vterm)
|
||||
:desc "Toggle vterm popup" "`" #'+vterm/toggle
|
||||
:desc "Open vterm here" "~" #'+vterm/here)
|
||||
(:when (featurep! :term eshell)
|
||||
:desc "Toggle eshell popup" "`" #'+eshell/toggle
|
||||
:desc "Open eshell here" "~" #'+eshell/here)
|
||||
|
||||
(:prefix ("l" . "<localleader>")) ; bound locally
|
||||
(:prefix ("!" . "checkers")) ; bound by flycheck
|
||||
|
@ -49,6 +36,8 @@
|
|||
:desc "Browse emacs.d" "E" #'+default/browse-emacsd
|
||||
:desc "Find file from here" "f" (if (fboundp 'counsel-file-jump) #'counsel-file-jump #'find-file)
|
||||
:desc "Find file in other project" "F" #'doom/browse-in-other-project
|
||||
:desc "Delete this file" "K" #'doom/delete-this-file
|
||||
:desc "Move this file" "m" #'doom/move-this-file
|
||||
:desc "Find file in project" "p" #'projectile-find-file
|
||||
:desc "Find file in other project" "P" #'doom/find-file-in-other-project
|
||||
:desc "Recent files" "r" #'recentf-open-files
|
||||
|
@ -56,11 +45,25 @@
|
|||
:desc "Sudo this file" "s" #'doom/sudo-this-file
|
||||
:desc "Sudo find file" "S" #'doom/sudo-find-file
|
||||
:desc "Yank filename" "y" #'+default/yank-buffer-filename
|
||||
:desc "Delete this file" "X" #'doom/delete-this-file)
|
||||
:desc "Open scratch buffer" "x" #'doom/open-scratch-buffer
|
||||
:desc "Open project scratch buffer" "X" #'doom/switch-to-scratch-buffer)
|
||||
|
||||
;;; <leader> g --- lookup
|
||||
(:when (featurep! :tools lookup)
|
||||
(:prefix-map ("g" . "lookup")
|
||||
"k" #'+lookup/documentation
|
||||
"d" #'+lookup/definition
|
||||
"D" #'+lookup/references
|
||||
"f" #'+lookup/file
|
||||
"o" #'+lookup/online-select
|
||||
"i" #'+lookup/in-docsets
|
||||
"I" #'+lookup/in-all-docsets))
|
||||
|
||||
;;; <leader> o --- org
|
||||
"o" nil ; we need to unbind it first as Org claims this
|
||||
(:prefix-map ("o". "org")
|
||||
:desc "Do what I mean" "o" #'+org/dwim-at-point
|
||||
:desc "Display inline images" "i" #'org-display-inline-images
|
||||
:desc "Search notes for symbol" "." #'+default/search-notes-for-symbol-at-point
|
||||
(:prefix ("a" . "org agenda")
|
||||
:desc "Agenda" "a" #'org-agenda
|
||||
|
@ -104,6 +107,17 @@
|
|||
:desc "Create Temp Template" "c" #'aya-create
|
||||
:desc "Use Temp Template" "e" #'aya-expand)
|
||||
|
||||
(:prefix-map ("t" . "terminal")
|
||||
(:when (featurep! :term term)
|
||||
:desc "Toggle term popup" "t" #'+term/toggle
|
||||
:desc "Open term here" "T" #'+term/here)
|
||||
(:when (featurep! :term vterm)
|
||||
:desc "Toggle vterm popup" "t" #'+vterm/toggle
|
||||
:desc "Open vterm here" "T" #'+vterm/here)
|
||||
(:when (featurep! :term eshell)
|
||||
:desc "Toggle eshell popup" "t" #'+eshell/toggle
|
||||
:desc "Open eshell here" "T" #'+eshell/here))
|
||||
|
||||
;;; <leader> v --- versioning
|
||||
(:prefix-map ("v" . "versioning")
|
||||
:desc "Git revert file" "R" #'vc-revert
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
[remap quit-window] #'kill-current-buffer)
|
||||
|
||||
(:map (help-mode-map helpful-mode-map)
|
||||
:n "o" 'ace-link-help)
|
||||
:n "o" #'ace-link-help)
|
||||
|
||||
;; misc
|
||||
:n "C-S-f" #'toggle-frame-fullscreen
|
||||
|
@ -116,6 +116,8 @@
|
|||
:v "g+" #'evil-numbers/inc-at-pt
|
||||
|
||||
;; custom evil keybinds
|
||||
:n "zn" #'+evil:narrow-buffer
|
||||
:n "zN" #'doom/widen-indirectly-narrowed-buffer
|
||||
:n "zx" #'kill-current-buffer
|
||||
:n "ZX" #'bury-buffer
|
||||
;; repeat in visual mode (FIXME buggy)
|
||||
|
@ -544,6 +546,7 @@
|
|||
:desc "Search buffer" "b" #'swiper
|
||||
:desc "Search current directory" "d" #'+default/search-cwd
|
||||
:desc "Search other directory" "D" #'+default/search-other-cwd
|
||||
:desc "Locate file" "f" #'locate
|
||||
:desc "Jump to symbol" "i" #'imenu
|
||||
:desc "Jump to link" "l" #'ace-link
|
||||
:desc "Look up online" "o" #'+lookup/online
|
||||
|
@ -581,7 +584,7 @@
|
|||
|
||||
;;; <leader> b --- buffer
|
||||
(:prefix-map ("b" . "buffer")
|
||||
:desc "Toggle narrowing" "-" #'doom/clone-and-narrow-buffer
|
||||
:desc "Toggle narrowing" "-" #'doom/toggle-narrow-buffer
|
||||
:desc "Previous buffer" "[" #'previous-buffer
|
||||
:desc "Next buffer" "]" #'next-buffer
|
||||
(:when (featurep! :ui workspaces)
|
||||
|
@ -594,7 +597,7 @@
|
|||
:desc "Switch to last buffer" "l" #'evil-switch-to-windows-last-buffer
|
||||
:desc "Next buffer" "n" #'next-buffer
|
||||
:desc "New empty buffer" "N" #'evil-buffer-new
|
||||
:desc "Kill other buffers" "o" #'doom/kill-other-buffers
|
||||
:desc "Kill other buffers" "O" #'doom/kill-other-buffers
|
||||
:desc "Previous buffer" "p" #'previous-buffer
|
||||
:desc "Save buffer" "s" #'save-buffer
|
||||
:desc "Sudo edit this file" "S" #'doom/sudo-this-file
|
||||
|
@ -615,7 +618,9 @@
|
|||
:desc "Delete trailing whitespace" "w" #'delete-trailing-whitespace
|
||||
:desc "Delete trailing newlines" "W" #'doom/delete-trailing-newlines
|
||||
(:when (featurep! :tools flycheck)
|
||||
:desc "List errors" "x" #'flycheck-list-errors))
|
||||
:desc "List errors" "x" #'flycheck-list-errors)
|
||||
(:unless (featurep! :tools flycheck)
|
||||
:desc "List errors" "x" #'flymake-show-diagnostics-buffer))
|
||||
|
||||
;;; <leader> f --- file
|
||||
(:prefix-map ("f" . "file")
|
||||
|
@ -629,6 +634,7 @@
|
|||
:desc "Find file in emacs.d" "e" #'+default/find-in-emacsd
|
||||
:desc "Browse emacs.d" "E" #'+default/browse-emacsd
|
||||
:desc "Find file from here" "f" #'find-file
|
||||
:desc "Locate file" "l" #'locate
|
||||
:desc "Move/rename file" "m" #'doom/move-this-file
|
||||
:desc "Find file in private config" "p" #'doom/find-file-in-private-config
|
||||
:desc "Browse private config" "P" #'doom/open-private-config
|
||||
|
@ -642,6 +648,8 @@
|
|||
;;; <leader> g --- git
|
||||
(:prefix-map ("g" . "git")
|
||||
:desc "Git revert file" "R" #'vc-revert
|
||||
:desc "Copy git link" "y" #'git-link
|
||||
:desc "Copy git link to homepage" "Y" #'git-link-homepage
|
||||
(:when (featurep! :ui vc-gutter)
|
||||
:desc "Git revert hunk" "r" #'git-gutter:revert-hunk
|
||||
:desc "Git stage hunk" "s" #'git-gutter:stage-hunk
|
||||
|
@ -667,7 +675,7 @@
|
|||
:desc "Find issue" "i" #'forge-visit-issue
|
||||
:desc "Find pull request" "p" #'forge-visit-pullreq)
|
||||
(:prefix ("o" . "open in browser")
|
||||
:desc "Browse region or line" "." #'+vc/git-browse-region-or-line
|
||||
:desc "Browse region or line" "o" #'+vc/git-browse-region-or-line
|
||||
:desc "Browse remote" "r" #'forge-browse-remote
|
||||
:desc "Browse commit" "c" #'forge-browse-commit
|
||||
:desc "Browse an issue" "i" #'forge-browse-issue
|
||||
|
@ -707,7 +715,12 @@
|
|||
:desc "Search org agenda headlines" "h" #'+default/org-notes-headlines
|
||||
:desc "Find file in notes" "n" #'+default/find-in-notes
|
||||
:desc "Browse notes" "N" #'+default/browse-notes
|
||||
:desc "Org store link" "l" #'org-store-link)
|
||||
:desc "Org store link" "l" #'org-store-link
|
||||
|
||||
(:when (featurep! :lang org +journal)
|
||||
(:prefix ("j" . "journal")
|
||||
:desc "New Entry" "j" #'org-journal-new-entry
|
||||
:desc "Search Forever" "s" #'org-journal-search-forever)))
|
||||
|
||||
;;; <leader> o --- open
|
||||
(:prefix-map ("o" . "open")
|
||||
|
@ -813,6 +826,10 @@
|
|||
;;; <leader> t --- toggle
|
||||
(:prefix-map ("t" . "toggle")
|
||||
:desc "Big mode" "b" #'doom-big-font-mode
|
||||
(:when (featurep! :tools flycheck)
|
||||
:desc "Flycheck" "f" #'flycheck-mode)
|
||||
(:unless (featurep! :tools flycheck)
|
||||
:desc "Flymake" "f" #'flymake-mode)
|
||||
:desc "Frame fullscreen" "F" #'toggle-frame-fullscreen
|
||||
:desc "Evil goggles" "g" #'evil-goggles-mode
|
||||
:desc "Indent style" "I" #'doom/toggle-indent-style
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
;;; config/default/+evil.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defun +default|disable-delete-selection-mode ()
|
||||
(defun +default-disable-delete-selection-mode-h ()
|
||||
(delete-selection-mode -1))
|
||||
(add-hook 'evil-insert-state-entry-hook #'delete-selection-mode)
|
||||
(add-hook 'evil-insert-state-exit-hook #'+default|disable-delete-selection-mode)
|
||||
(add-hook 'evil-insert-state-exit-hook #'+default-disable-delete-selection-mode-h)
|
||||
|
||||
|
||||
;;
|
||||
|
|
|
@ -109,7 +109,7 @@ If ARG (universal argument), runs `compile' from the current directory."
|
|||
((error "No kill-ring search backend available. Enable ivy or helm!")))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +default*newline-indent-and-continue-comments ()
|
||||
(defun +default--newline-indent-and-continue-comments-a ()
|
||||
"A replacement for `newline-and-indent'.
|
||||
|
||||
Continues comments if executed from a commented line, with special support for
|
||||
|
@ -159,7 +159,7 @@ possible, or just one char if that's not possible."
|
|||
((delete-char -1)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +default*delete-backward-char (n &optional killflag)
|
||||
(defun +default--delete-backward-char-a (n &optional killflag)
|
||||
"Same as `delete-backward-char', but preforms these additional checks:
|
||||
|
||||
+ If point is surrounded by (balanced) whitespace and a brace delimiter ({} []
|
||||
|
@ -283,11 +283,11 @@ If prefix ARG is set, prompt for a known project to search from."
|
|||
((rgrep (regexp-quote symbol))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +default/search-notes-for-symbol-at-point (&optional arg symbol)
|
||||
(defun +default/search-notes-for-symbol-at-point (&optional symbol)
|
||||
"Conduct a text search in the current project for symbol at point. If prefix
|
||||
ARG is set, prompt for a known project to search from."
|
||||
(interactive
|
||||
(list current-prefix-arg (thing-at-point 'symbol t)))
|
||||
(list (thing-at-point 'symbol t)))
|
||||
(require 'org)
|
||||
(let ((default-directory org-directory))
|
||||
(+default/search-project-for-symbol-at-point
|
||||
|
|
|
@ -34,6 +34,10 @@
|
|||
;; prompt for the key passphrase.
|
||||
epa-pinentry-mode 'loopback))
|
||||
|
||||
;;;###package tramp
|
||||
(unless IS-WINDOWS
|
||||
(setq tramp-default-method "ssh")) ; faster than the default scp
|
||||
|
||||
|
||||
;;
|
||||
;;; Smartparens config
|
||||
|
@ -195,10 +199,10 @@
|
|||
;; e) properly delete smartparen pairs when they are encountered, without
|
||||
;; the need for strict mode.
|
||||
;; f) do none of this when inside a string
|
||||
(advice-add #'delete-backward-char :override #'+default*delete-backward-char))
|
||||
(advice-add #'delete-backward-char :override #'+default--delete-backward-char-a))
|
||||
|
||||
;; Makes `newline-and-indent' continue comments (and more reliably)
|
||||
(advice-add #'newline-and-indent :override #'+default*newline-indent-and-continue-comments))
|
||||
(advice-add #'newline-and-indent :override #'+default--newline-indent-and-continue-comments-a))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -260,7 +264,6 @@
|
|||
(define-key! help-map
|
||||
;; new keybinds
|
||||
"'" #'describe-char
|
||||
"B" #'doom/open-bug-report
|
||||
"D" #'doom/help
|
||||
"E" #'doom/sandbox
|
||||
"M" #'doom/describe-active-minor-mode
|
||||
|
@ -312,8 +315,6 @@
|
|||
"F" #'describe-face
|
||||
;; replaces `view-hello-file' b/c annoying
|
||||
"h" #'doom/help
|
||||
;; replaces `describe-language-environment' b/c remapped to C-l
|
||||
"L" #'global-command-log-mode
|
||||
;; replaces `view-emacs-news' b/c it's on C-n too
|
||||
"n" #'doom/help-news
|
||||
;; replaces `finder-by-keyword'
|
||||
|
|
|
@ -53,7 +53,12 @@ variable for an explanation of the defaults (in comments). See
|
|||
;; (url-retrieve-synchronously "https://raw.githubusercontent.com/emacs-evil/evil-collection/master/evil-collection.el" t t)
|
||||
;; (goto-char (point-min))
|
||||
;; (when (re-search-forward "^(defcustom evil-collection-mode-list\n[^(]+")
|
||||
;; (kill-new (thing-at-point 'sexp t))))
|
||||
;; (let ((list (sexp-at-point)))
|
||||
;; ;; Fixes
|
||||
;; (when (assq 'pdf list)
|
||||
;; (setf (alist-get 'pdf list) '(pdf-tools)))
|
||||
;; (kill-new (prin1-to-string list)))))
|
||||
|
||||
(defvar evil-collection-mode-list
|
||||
`(2048-game
|
||||
ag
|
||||
|
@ -143,7 +148,7 @@ variable for an explanation of the defaults (in comments). See
|
|||
p4
|
||||
(package-menu package)
|
||||
pass
|
||||
(pdf pdf-view)
|
||||
(pdf pdf-tools)
|
||||
popup
|
||||
proced
|
||||
process-menu
|
||||
|
|
|
@ -135,10 +135,18 @@ integration."
|
|||
|
||||
;;;###autoload (autoload '+evil:narrow-buffer "editor/evil/autoload/evil" nil t)
|
||||
(evil-define-operator +evil:narrow-buffer (beg end &optional bang)
|
||||
"Wrapper around `doom/clone-and-narrow-buffer'."
|
||||
"Narrow the buffer to region between BEG and END.
|
||||
|
||||
Widens narrowed buffers first. If BANG, use indirect buffer clones instead."
|
||||
:move-point nil
|
||||
(interactive "<r><!>")
|
||||
(doom/clone-and-narrow-buffer beg end bang))
|
||||
(if (not bang)
|
||||
(if (buffer-narrowed-p)
|
||||
(widen)
|
||||
(narrow-to-region beg end))
|
||||
(when (buffer-narrowed-p)
|
||||
(doom/widen-indirectly-narrowed-buffer t))
|
||||
(doom/narrow-buffer-indirectly beg end)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil/next-beginning-of-method (count)
|
||||
|
@ -192,13 +200,13 @@ See `+evil/next-preproc-directive' for details."
|
|||
(dotimes (_ (abs count))
|
||||
(cond ((> count 0)
|
||||
(while (and (not (eobp)) (sp-point-in-comment))
|
||||
(next-line))
|
||||
(forward-line 1))
|
||||
(unless (comment-search-forward (point-max) 'noerror)
|
||||
(goto-char orig-pt)
|
||||
(user-error "No comment after point")))
|
||||
(t
|
||||
(while (and (not (bobp)) (sp-point-in-comment))
|
||||
(previous-line))
|
||||
(forward-line -1))
|
||||
(unless (comment-search-backward nil 'noerror)
|
||||
(goto-char orig-pt)
|
||||
(user-error "No comment before point")))))))
|
||||
|
|
|
@ -177,7 +177,7 @@ If BANG, search Doom documentation."
|
|||
'module (list cat mod))))
|
||||
(module (completing-read "Describe module: " modules nil t query))
|
||||
(key (get-text-property 0 'module module)))
|
||||
(doom/help-modules key)))
|
||||
(doom/help-modules (car key) (cdr key))))
|
||||
((and (string-match-p "\\(?:SPC\\|[CMsSH]-[^ ]\\|<[^>]+>\\)" query)
|
||||
(helpful-key (kbd (string-trim query)))))
|
||||
((apropos query t)))))
|
||||
|
|
|
@ -85,31 +85,31 @@
|
|||
|
||||
;;; ]u / [u
|
||||
;;;###autoload (autoload '+evil:url-encode "editor/evil/autoload/unimpaired" nil t)
|
||||
(evil-define-operator +evil:url-encode (count &optional beg end type)
|
||||
(evil-define-operator +evil:url-encode (_count &optional beg end)
|
||||
"TODO"
|
||||
(interactive "<c><R>")
|
||||
(interactive "<c><r>")
|
||||
(+evil--encode beg end #'url-encode-url))
|
||||
|
||||
;;;###autoload (autoload '+evil:url-decode "editor/evil/autoload/unimpaired" nil t)
|
||||
(evil-define-operator +evil:url-decode (count &optional beg end type)
|
||||
(evil-define-operator +evil:url-decode (_count &optional beg end)
|
||||
"TODO"
|
||||
(interactive "<c><R>")
|
||||
(interactive "<c><r>")
|
||||
(+evil--encode beg end #'url-unhex-string))
|
||||
|
||||
;;; ]y / [y
|
||||
;;;###autoload (autoload '+evil:c-string-encode "editor/evil/autoload/unimpaired" nil t)
|
||||
(evil-define-operator +evil:c-string-encode (count &optional beg end type)
|
||||
(evil-define-operator +evil:c-string-encode (_count &optional beg end)
|
||||
"TODO"
|
||||
(interactive "<c><R>")
|
||||
(interactive "<c><r>")
|
||||
(+evil--encode
|
||||
beg end
|
||||
(lambda (text)
|
||||
(replace-regexp-in-string "[\"\\]" (lambda (ch) (concat "\\" ch)) text))))
|
||||
|
||||
;;;###autoload (autoload '+evil:c-string-decode "editor/evil/autoload/unimpaired" nil t)
|
||||
(evil-define-operator +evil:c-string-decode (count &optional beg end type)
|
||||
(evil-define-operator +evil:c-string-decode (_count &optional beg end)
|
||||
"TODO"
|
||||
(interactive "<c><R>")
|
||||
(interactive "<c><r>")
|
||||
(+evil--encode
|
||||
beg end
|
||||
(lambda (text)
|
||||
|
|
|
@ -257,12 +257,12 @@ directives. By default, this only recognizes C directives.")
|
|||
|
||||
(use-package! evil-escape
|
||||
:commands evil-escape
|
||||
:after-call evil-normal-state-exit-hook
|
||||
:after-call pre-command-hook
|
||||
:init
|
||||
(setq evil-escape-excluded-states '(normal visual multiedit emacs motion)
|
||||
evil-escape-excluded-major-modes '(neotree-mode treemacs-mode vterm-mode)
|
||||
evil-escape-key-sequence "jk"
|
||||
evil-escape-delay 0.25)
|
||||
evil-escape-delay 0.15)
|
||||
(evil-define-key* '(insert replace visual operator) 'global "\C-g" #'evil-escape)
|
||||
:config
|
||||
;; no `evil-escape' in minibuffer
|
||||
|
|
|
@ -3,12 +3,11 @@
|
|||
|
||||
(describe "feature/evil"
|
||||
:var (resv project-root)
|
||||
(before-all
|
||||
|
||||
(require! :editor evil)
|
||||
(require 'evil)
|
||||
(load! "../autoload/evil"))
|
||||
(after-all
|
||||
(unload-feature 'evil t))
|
||||
(load! "../autoload/evil")
|
||||
|
||||
(before-each
|
||||
(fset 'resv #'+evil-resolve-vim-path-a)
|
||||
(spy-on 'doom-project-root :and-call-fake (lambda () project-root)))
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
(defun +multiple-cursors/evil-mc-toggle-cursors ()
|
||||
"Toggle frozen state of evil-mc cursors."
|
||||
(interactive)
|
||||
(unless (evil-mc-has-cursors-p)
|
||||
(user-error "No cursors exist to be toggled"))
|
||||
(setq evil-mc-frozen (not (and (evil-mc-has-cursors-p)
|
||||
evil-mc-frozen)))
|
||||
(if evil-mc-frozen
|
||||
|
@ -45,12 +47,14 @@ pauses cursors."
|
|||
(evil-mc-make-cursor-here))))
|
||||
|
||||
;;;###autoload (autoload '+multiple-cursors:evil-mc "editor/multiple-cursors/autoload/evil-mc" nil t)
|
||||
(evil-define-command +multiple-cursors:evil-mc (beg end type pattern &optional bang)
|
||||
"Create mc cursors at each match of PATTERN within BEG and END, and leave the
|
||||
cursor at the final match. If BANG, then treat PATTERN as literal."
|
||||
(evil-define-command +multiple-cursors:evil-mc (beg end type pattern &optional flags bang)
|
||||
"Create mc cursors at each match of PATTERN within BEG and END.
|
||||
|
||||
This leaves the cursor at the final match. If BANG, then treat PATTERN as
|
||||
literal. PATTERN is a delimited regexp (the same that :g or :s uses)."
|
||||
:move-point nil
|
||||
:evil-mc t
|
||||
(interactive "<R><//g><!>")
|
||||
(interactive "<R><//!><!>")
|
||||
(unless (and (stringp pattern)
|
||||
(not (string-empty-p pattern)))
|
||||
(user-error "A regexp pattern is required"))
|
||||
|
@ -59,9 +63,19 @@ cursor at the final match. If BANG, then treat PATTERN as literal."
|
|||
(cons (evil-ex-make-search-pattern
|
||||
(if bang (regexp-quote pattern) pattern))
|
||||
(list beg end type)))
|
||||
(save-excursion
|
||||
(evil-with-restriction beg end
|
||||
(evil-mc-make-cursors-for-all)))
|
||||
(let ((point (point)))
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(while (eq (evil-ex-find-next (evil-mc-get-pattern) 'forward t) t)
|
||||
(goto-char (1- (point)))
|
||||
(when (/= point (point))
|
||||
(evil-mc-run-cursors-before)
|
||||
(evil-mc-make-cursor-at-pos (point)))
|
||||
(goto-char
|
||||
(if (memq ?g flags)
|
||||
(line-beginning-position 2)
|
||||
(1+ (point))))))))
|
||||
(evil-exit-visual-state)
|
||||
(evil-mc-goto-cursor
|
||||
(if (= (evil-visual-direction) 1)
|
||||
|
|
|
@ -59,11 +59,7 @@
|
|||
;; Forward declare these so that ex completion and evil-mc support is
|
||||
;; recognized before the autoloaded functions are loaded.
|
||||
(evil-add-command-properties '+evil:align :evil-mc t)
|
||||
(evil-set-command-properties '+multiple-cursors:evil-mc
|
||||
:move-point nil
|
||||
:ex-arg 'global-match
|
||||
:ex-bang t
|
||||
:evil-mc t))
|
||||
(evil-add-command-properties '+multiple-cursors:evil-mc :evil-mc t))
|
||||
|
||||
|
||||
(after! multiple-cursors-core
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
"Register minor MODES (one mode symbol or a list of them) with yasnippet so it
|
||||
can have its own snippets category, if the folder exists."
|
||||
(dolist (mode (doom-enlist modes))
|
||||
(let ((fn (intern (format "+snippets|register-%s" mode))))
|
||||
(let ((fn (intern (format "+snippets-register-%s-h" mode))))
|
||||
(fset fn (lambda () (yas-activate-extra-mode mode)))
|
||||
(add-hook (intern (format "%s-hook" mode)) fn))))
|
||||
|
|
|
@ -225,7 +225,7 @@ You will be prompted for a snippet to alias."
|
|||
"# condition: t}\n"
|
||||
"# type: command\n"
|
||||
"# --\n"
|
||||
"(%alias \"${4:" (or template "uuid") "}\")"))
|
||||
"(%alias \"${4:" (or template-uuid "uuid") "}\")"))
|
||||
(when (bound-and-true-p evil-local-mode)
|
||||
(evil-insert-state)))))
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
;; Use GNU ls as `gls' from `coreutils' if available. Add `(setq
|
||||
;; dired-use-ls-dired nil)' to your config to suppress the Dired warning
|
||||
;; when not using GNU ls.
|
||||
(if-let* ((gls (executable-find "gls")))
|
||||
(if-let (gls (executable-find "gls"))
|
||||
(setq insert-directory-program gls)
|
||||
;; BSD ls doesn't support --group-directories-first
|
||||
(setq args (delete "--group-directories-first" args))))
|
||||
|
@ -45,30 +45,12 @@
|
|||
:hook (dired-mode . diredfl-mode))
|
||||
|
||||
|
||||
(use-package! dired-k
|
||||
:hook (dired-initial-position . dired-k)
|
||||
:hook (dired-after-readin . dired-k-no-revert)
|
||||
(use-package! diff-hl
|
||||
:hook (dired-mode . diff-hl-dired-mode)
|
||||
:hook (magit-post-refresh . diff-hl-magit-post-refresh)
|
||||
:config
|
||||
(setq dired-k-style 'git
|
||||
dired-k-padding 1)
|
||||
|
||||
;; Don't highlight based on mtime, this interferes with diredfl and is more
|
||||
;; confusing than helpful.
|
||||
(advice-add #'dired-k--highlight-by-file-attribyte :override #'ignore)
|
||||
|
||||
(defadvice! +dired--interrupt-process-a (orig-fn &rest args)
|
||||
"Fixes dired-k killing git processes too abruptly, leaving behind disruptive
|
||||
.git/index.lock files."
|
||||
:around #'dired-k--start-git-status
|
||||
(cl-letf (((symbol-function #'kill-process)
|
||||
(symbol-function #'interrupt-process)))
|
||||
(apply orig-fn args)))
|
||||
|
||||
(defadvice! +dired--dired-k-highlight-a (orig-fn &rest args)
|
||||
"Butt out if the requested directory is remote (i.e. through tramp)."
|
||||
:around #'dired-k--highlight
|
||||
(unless (file-remote-p default-directory)
|
||||
(apply orig-fn args))))
|
||||
;; use margin instead of fringe
|
||||
(diff-hl-margin-mode))
|
||||
|
||||
|
||||
(use-package! ranger
|
||||
|
@ -117,6 +99,7 @@ we have to clean it up ourselves."
|
|||
|
||||
|
||||
(use-package! dired-x
|
||||
:unless (featurep! +ranger)
|
||||
:hook (dired-mode . dired-omit-mode)
|
||||
:config
|
||||
(setq dired-omit-verbose nil)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
;;; emacs/dired/packages.el
|
||||
|
||||
(package! diredfl)
|
||||
(package! dired-k)
|
||||
(package! diff-hl)
|
||||
(package! dired-rsync)
|
||||
(when (featurep! +ranger)
|
||||
(package! ranger))
|
||||
|
|
|
@ -4,16 +4,18 @@
|
|||
#+STARTUP: inlineimages
|
||||
|
||||
* Table of Contents :TOC:
|
||||
- [[Description][Description]]
|
||||
- [[Module Flags][Module Flags]]
|
||||
- [[Plugins][Plugins]]
|
||||
- [[Prerequisites][Prerequisites]]
|
||||
- [[MacOS][MacOS]]
|
||||
- [[Arch Linux][Arch Linux]]
|
||||
- [[Features][Features]]
|
||||
- [[Configuration][Configuration]]
|
||||
- [[offlineimap][offlineimap]]
|
||||
- [[mbsync][mbsync]]
|
||||
- [[#description][Description]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#macos][MacOS]]
|
||||
- [[#arch-linux][Arch Linux]]
|
||||
- [[#nixos][NixOS]]
|
||||
- [[#opensuse][openSUSE]]
|
||||
- [[#features][Features]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#offlineimap][offlineimap]]
|
||||
- [[#mbsync][mbsync]]
|
||||
|
||||
* Description
|
||||
This module makes Emacs an email client, using ~mu4e~.
|
||||
|
@ -66,6 +68,15 @@ environment.systemPackages = with pkgs; [
|
|||
|
||||
[[https://github.com/Emiller88/dotfiles/blob/master/modules/shell/mail.nix][An example of setting up mbsync with home-manager]]
|
||||
|
||||
** openSUSE
|
||||
|
||||
Remove ~#~ in ~#sync_program=offlineimap~ to choose ~offlineimap~ instead of ~mbsync~.
|
||||
#+BEGIN_SRC sh :dir /sudo::
|
||||
sync_program=isync # mbsync
|
||||
#sync_program=offlineimap
|
||||
sudo zypper install maildir-utils $sync_programm
|
||||
#+END_SRC
|
||||
|
||||
* TODO Features
|
||||
|
||||
* Configuration
|
||||
|
|
|
@ -36,15 +36,15 @@
|
|||
when exporting org-mode to html."
|
||||
:filter-args #'org-html-paragraph
|
||||
(cl-destructuring-bind (paragraph contents info) args
|
||||
(let* ((fix-regexp "[[:multibyte:]a-zA-Z0-9]")
|
||||
(origin-contents contents)
|
||||
(let* ((fix-regexp "[[:multibyte:]]")
|
||||
(origin-contents
|
||||
(replace-regexp-in-string
|
||||
"<[Bb][Rr] */>"
|
||||
""
|
||||
contents))
|
||||
(fixed-contents
|
||||
(replace-regexp-in-string
|
||||
(concat "\\("
|
||||
fix-regexp
|
||||
"\\) *\\(<[Bb][Rr] */>\\)?\n *\\("
|
||||
fix-regexp
|
||||
"\\)")
|
||||
"\\1\\3"
|
||||
(concat "\\(" fix-regexp "\\) *\n *\\(" fix-regexp "\\)")
|
||||
"\\1\\2"
|
||||
origin-contents)))
|
||||
(list paragraph fixed-contents info))))
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
(after! helm (helm-migemo-mode +1)))))
|
||||
|
||||
|
||||
(use-package pangu-spacing
|
||||
(use-package! pangu-spacing
|
||||
:hook (text-mode . pangu-spacing-mode)
|
||||
:init
|
||||
;; replacing `chinese-two-byte' by `japanese'
|
||||
|
@ -46,15 +46,15 @@
|
|||
when exporting org-mode to html."
|
||||
:filter-args #'org-html-paragraph
|
||||
(cl-destructuring-bind (paragraph contents info) args
|
||||
(let* ((fix-regexp "[[:multibyte:]a-zA-Z0-9]")
|
||||
(origin-contents contents)
|
||||
(let* ((fix-regexp "[[:multibyte:]]")
|
||||
(origin-contents
|
||||
(replace-regexp-in-string
|
||||
"<[Bb][Rr] */>"
|
||||
""
|
||||
contents))
|
||||
(fixed-contents
|
||||
(replace-regexp-in-string
|
||||
(concat "\\("
|
||||
fix-regexp
|
||||
"\\) *\\(<[Bb][Rr] */>\\)?\n *\\("
|
||||
fix-regexp
|
||||
"\\)")
|
||||
"\\1\\3"
|
||||
(concat "\\(" fix-regexp "\\) *\n *\\(" fix-regexp "\\)")
|
||||
"\\1\\2"
|
||||
origin-contents)))
|
||||
(list paragraph fixed-contents info))))
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
#+TITLE: :lang agda
|
||||
|
||||
This module adds support for the [[http://wiki.portal.chalmers.se/agda/pmwiki.php][agda]] programming language.
|
||||
|
||||
Emacs support is included in the agda release (you can find installation
|
||||
instructions [[https://agda.readthedocs.io/en/latest/getting-started/installation.html][here]]). This module attempts to find the location of ~agda2.el~ via
|
||||
the ~agda-mode locate~ command that comes with the agda release. Users can set
|
||||
this manually by setting the ~+agda2-dir~ variable.
|
||||
|
||||
This module adds support for the [[http://wiki.portal.chalmers.se/agda/pmwiki.php][agda]] programming language. The Emacs support
|
||||
exists directly in the agda repository but not in melpa.
|
||||
|
|
|
@ -1,17 +1,7 @@
|
|||
;;; lang/agda/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +agda-dir
|
||||
(when (executable-find "agda-mode")
|
||||
(file-name-directory (shell-command-to-string "agda-mode locate"))))
|
||||
|
||||
(use-package! agda2
|
||||
:when +agda-dir
|
||||
:load-path +agda-dir)
|
||||
|
||||
(use-package! agda2-mode
|
||||
:defer t
|
||||
:config
|
||||
(map! :map agda2-mode-map
|
||||
(map! :after agda2-mode
|
||||
:map agda2-mode-map
|
||||
:localleader
|
||||
"?" #'agda2-show-goals
|
||||
"." #'agda2-goal-and-context-and-inferred
|
||||
|
@ -38,4 +28,4 @@
|
|||
"d" #'agda2-remove-annotations
|
||||
"h" #'agda2-display-implicit-arguments
|
||||
"q" #'agda2-quit
|
||||
"r" #'agda2-restart)))
|
||||
"r" #'agda2-restart))
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; lang/agda/doctor.el
|
||||
|
||||
(unless (executable-find "agda-mode")
|
||||
(warn! "Couldn't find agda-mode. Agda support won't work"))
|
15
modules/lang/agda/packages.el
Normal file
15
modules/lang/agda/packages.el
Normal file
|
@ -0,0 +1,15 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/agda/packages.el
|
||||
|
||||
|
||||
(package! agda-input
|
||||
:recipe
|
||||
(:host github :repo "agda/agda"
|
||||
:files ("src/data/emacs-mode/agda-input.el")))
|
||||
|
||||
(package! agda2-mode
|
||||
:recipe
|
||||
(:host github :repo "agda/agda"
|
||||
:files
|
||||
("src/data/emacs-mode/*.el"
|
||||
(:exclude "agda-input.el"))))
|
|
@ -11,6 +11,7 @@
|
|||
- [[#irony-server][irony-server]]
|
||||
- [[#macos][MacOS]]
|
||||
- [[#arch-linux][Arch Linux]]
|
||||
- [[#opensuse][openSUSE]]
|
||||
- [[#rtags][rtags]]
|
||||
- [[#configure][Configure]]
|
||||
- [[#project-compile-settings][Project compile settings]]
|
||||
|
@ -93,6 +94,11 @@ rm -rf irony-mode
|
|||
pacman -S clang cmake
|
||||
#+END_SRC
|
||||
|
||||
*** openSUSE
|
||||
#+BEGIN_SRC sh :dir /sudo::
|
||||
sudo zypper install clang cmake
|
||||
#+END_SRC
|
||||
|
||||
** rtags
|
||||
Code navigation requires an [[https://github.com/Andersbakken/rtags][rtags]] server (~rdm~) installed. This should be
|
||||
available through your OS's package manager.
|
||||
|
|
|
@ -103,7 +103,7 @@ simpler."
|
|||
(rtags-call-rc :silent t "-J" (or (doom-project-root) default-directory))))
|
||||
;; then irony
|
||||
(when (and (featurep 'irony) irony-mode)
|
||||
(+cc|irony-init-compile-options)))
|
||||
(+cc-init-irony-compile-options-h)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +cc/imenu ()
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
;;; lang/clojure/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###package clojure-mode
|
||||
(after! clojure-mode
|
||||
(add-hook 'clojure-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
(set-repl-handler! 'clojure-mode #'+clojure/repl)
|
||||
(set-eval-handler! 'clojure-mode #'cider-eval-region))
|
||||
|
||||
|
||||
(use-package! cider
|
||||
;; NOTE: if you don't have an org directory set (the dir doesn't exist),
|
||||
;; cider jack in won't work.
|
||||
:commands (cider-jack-in cider-jack-in-clojurescript)
|
||||
:commands cider-jack-in cider-jack-in-clojurescript
|
||||
:hook (clojure-mode-local-vars . cider-mode)
|
||||
:init
|
||||
(set-repl-handler! 'clojure-mode #'+clojure/repl)
|
||||
(set-eval-handler! 'clojure-mode #'cider-eval-region)
|
||||
:config
|
||||
(add-hook 'cider-mode-hook #'eldoc-mode)
|
||||
(set-lookup-handlers! 'cider-mode
|
||||
:definition #'+clojure-cider-lookup-definition
|
||||
:documentation #'cider-doc)
|
||||
(add-hook 'cider-mode-hook #'eldoc-mode)
|
||||
:config
|
||||
(set-popup-rules!
|
||||
'(("^\\*cider-error*" :ignore t)
|
||||
("^\\*cider-repl" :quit nil)
|
||||
|
@ -134,10 +134,9 @@
|
|||
|
||||
(use-package! clj-refactor
|
||||
:hook (clojure-mode . clj-refactor-mode)
|
||||
:init
|
||||
:config
|
||||
(set-lookup-handlers! 'clj-refactor-mode
|
||||
:references #'cljr-find-usages)
|
||||
:config
|
||||
(map! :map clojure-mode-map
|
||||
:localleader
|
||||
:desc "refactor" "R" #'hydra-cljr-help-menu/body))
|
||||
|
|
|
@ -1,4 +1,15 @@
|
|||
;;; lang/coq/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; HACK `proof-general' ascertains its own library path at compile time in its
|
||||
;; autoloads file using `byte-compile-current-file' (and stores it in
|
||||
;; `pg-init--script-full-path'). This means that when
|
||||
;; `doom-package-autoload-file' is created and byte-compiled,
|
||||
;; `pg-init--script-full-path' will be wrong, causing file-missing errors as it
|
||||
;; tries to load `proof-site'. We prevent this by defining these two variables
|
||||
;; early, in our own autoloads file.
|
||||
;;;###autoload
|
||||
(setq pg-init--script-full-path (locate-library "proof-general")
|
||||
pg-init--pg-root (file-name-directory pg-init--script-full-path))
|
||||
|
||||
;;;###autoload
|
||||
(add-hook 'coq-mode-hook #'company-coq-mode)
|
||||
|
|
|
@ -7,6 +7,45 @@
|
|||
;; library included with Doom).
|
||||
(setq coq-mode-abbrev-table '())
|
||||
|
||||
(map! :after coq-mode
|
||||
:map coq-mode-map
|
||||
:localleader
|
||||
"]" #'proof-assert-next-command-interactive
|
||||
"[" #'proof-undo-last-successful-command
|
||||
"." #'proof-goto-point
|
||||
(:prefix ("l" . "layout")
|
||||
"c" #'pg-response-clear-displays
|
||||
"l" #'proof-layout-windows
|
||||
"p" #'proof-prf)
|
||||
(:prefix ("p" . "proof")
|
||||
"i" #'proof-interrupt-process
|
||||
"p" #'proof-process-buffer
|
||||
"q" #'proof-shell-exit
|
||||
"r" #'proof-retract-buffer)
|
||||
(:prefix ("a" . "about/print/check")
|
||||
"a" #'coq-Print
|
||||
"A" #'coq-Print-with-all
|
||||
"b" #'coq-About
|
||||
"B" #'coq-About-with-all
|
||||
"c" #'coq-Check
|
||||
"C" #'coq-Check-show-all
|
||||
"f" #'proof-find-theorems
|
||||
(:prefix ("i" . "implicits")
|
||||
"b" #'coq-About-with-implicits
|
||||
"c" #'coq-Check-show-implicits
|
||||
"i" #'coq-Print-with-implicits))
|
||||
(:prefix ("g" . "goto")
|
||||
"e" #'proof-goto-command-end
|
||||
"l" #'proof-goto-end-of-locked
|
||||
"s" #'proof-goto-command-start)
|
||||
(:prefix ("i" . "insert")
|
||||
"c" #'coq-insert-command
|
||||
"e" #'coq-end-Section
|
||||
"i" #'coq-insert-intros
|
||||
"r" #'coq-insert-requires
|
||||
"s" #'coq-insert-section-or-module
|
||||
"t" #'coq-insert-tactic
|
||||
"T" #'coq-insert-tactical))
|
||||
|
||||
(after! company-coq
|
||||
(set-popup-rule! "^\\*\\(?:response\\|goals\\)\\*" :ignore t)
|
||||
|
@ -15,4 +54,15 @@
|
|||
:references #'company-coq-grep-symbol
|
||||
:documentation #'company-coq-doc)
|
||||
(unless (featurep! :completion company)
|
||||
(setq company-coq-disabled-features '(company company-defaults))))
|
||||
(setq company-coq-disabled-features '(company company-defaults)))
|
||||
|
||||
(map! :map coq-mode-map
|
||||
:localleader
|
||||
(:prefix ("i" . "insert")
|
||||
"l" #'company-coq-lemma-from-goal
|
||||
"m" #'company-coq-insert-match-construct)
|
||||
"ao" #'company-coq-occur
|
||||
(:prefix ("h" . "help")
|
||||
"e" #'company-coq-document-error
|
||||
"E" #'company-coq-browse-error-messages
|
||||
"h" #'company-coq-doc)))
|
||||
|
|
|
@ -1,28 +1,39 @@
|
|||
#+TITLE: :lang csharp
|
||||
|
||||
This module adds C# support to Emacs.
|
||||
|
||||
#+begin_quote
|
||||
I don't use C# for much else than Unity3D and, seldomly, for Mono game
|
||||
development on Linux.
|
||||
#+end_quote
|
||||
|
||||
* Table of Contents :TOC:
|
||||
- [[Install][Install]]
|
||||
- [[MacOS][MacOS]]
|
||||
- [[Arch Linux][Arch Linux]]
|
||||
- [[#description][Description]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#macos][MacOS]]
|
||||
- [[#arch-linux][Arch Linux]]
|
||||
- [[#nixos][NixOS]]
|
||||
|
||||
* Install
|
||||
* Description
|
||||
This module adds C# support to Emacs. Powered by omnisharp (directly or through
|
||||
LSP).
|
||||
|
||||
** Module Flags
|
||||
+ =+lsp= Enables omnisharp through LSP support (requires omnisharp).
|
||||
+ =+unity= Enables special support for the [[https://unity.com/][Unity game engine]] (particularly,
|
||||
support for HLSL shaders).
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/josteink/csharp-mode][csharp-mode]]
|
||||
+ [[https://github.com/OmniSharp/omnisharp-emacs][omnisharp]]* (not =+lsp=)
|
||||
+ [[https://github.com/midnightSuyama/shader-mode][shader-mode]]* (=+unity=)
|
||||
|
||||
* Prerequisites
|
||||
This module needs:
|
||||
|
||||
+ omnisharp-roslyn (install with ~M-x omnisharp-install-server~)
|
||||
+ omnisharp (with the ~+lsp~ flag, this must be installed externally. Without
|
||||
it, use ~M-x omnisharp-install-server~)
|
||||
+ .NET SDKs (on Windows)
|
||||
+ Mono (on UNIX platforms)
|
||||
|
||||
** MacOS
|
||||
=TODO=
|
||||
|
||||
** TODO MacOS
|
||||
** Arch Linux
|
||||
#+BEGIN_SRC sh :dir /sudo:: :tangle (if (doom-system-os 'arch) "yes")
|
||||
#+BEGIN_SRC sh
|
||||
sudo pacman --needed --noconfirm -S mono
|
||||
#+END_SRC
|
||||
** TODO NixOS
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
(after! csharp-mode
|
||||
(add-hook 'csharp-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
(when (featurep! +lsp)
|
||||
(add-hook 'csharp-mode-local-vars-hook #'lsp!))
|
||||
|
||||
(set-electric! 'csharp-mode :chars '(?\n ?\}))
|
||||
(set-rotate-patterns! 'csharp-mode
|
||||
:symbols '(("public" "protected" "private")
|
||||
|
@ -13,6 +16,7 @@
|
|||
|
||||
|
||||
(use-package! omnisharp
|
||||
:unless (featurep! +lsp)
|
||||
:hook (csharp-mode . omnisharp-mode)
|
||||
:commands omnisharp-install-server
|
||||
:preface
|
||||
|
@ -56,9 +60,10 @@
|
|||
"b" #'omnisharp-unit-test-buffer)))
|
||||
|
||||
|
||||
;;;###package shader-mode
|
||||
(when (featurep! +unity)
|
||||
;; `shader-mode' --- unity shaders
|
||||
(add-to-list 'auto-mode-alist '("\\.shader$" . shader-mode))
|
||||
;; Unity shaders
|
||||
(add-to-list 'auto-mode-alist '("\\.shader\\'" . shader-mode))
|
||||
|
||||
(def-project-mode! +csharp-unity-mode
|
||||
:modes '(csharp-mode shader-mode)
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
;;; lang/csharp/packages.el
|
||||
|
||||
(package! csharp-mode)
|
||||
(package! omnisharp)
|
||||
|
||||
(unless (featurep! +lsp)
|
||||
(package! omnisharp))
|
||||
|
||||
(when (featurep! +unity)
|
||||
(package! shader-mode))
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
;;
|
||||
;;; Third-party plugins
|
||||
|
||||
;; `csv-mode'
|
||||
;;;###package csv-mode
|
||||
(map! :after csv-mode
|
||||
:localleader
|
||||
:map csv-mode-map
|
||||
|
@ -37,13 +37,12 @@
|
|||
:config
|
||||
(set-electric! 'json-mode :chars '(?\n ?: ?{ ?})))
|
||||
|
||||
(use-package! jsonnet-mode
|
||||
:defer t
|
||||
:config
|
||||
(after! jsonnet-mode
|
||||
(set-electric! 'jsonnet-mode :chars '(?\n ?: ?{ ?})))
|
||||
|
||||
|
||||
;;
|
||||
;; Frameworks
|
||||
;;; Frameworks
|
||||
|
||||
(def-project-mode! +data-vagrant-mode
|
||||
:files ("Vagrantfile"))
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
- [[#with-asdf][With ~asdf~]]
|
||||
- [[#arch-linux][Arch Linux]]
|
||||
- [[#gentoo-linux][Gentoo Linux]]
|
||||
- [[#opensuse][openSUSE]]
|
||||
- [[#features][Features]]
|
||||
|
||||
* Description
|
||||
|
@ -47,6 +48,11 @@ sudo pacman -S elixir
|
|||
#+BEGIN_SRC sh :dir /sudo::
|
||||
sudo emerge -v dev-lang/elixir
|
||||
#+END_SRC
|
||||
|
||||
*** openSUSE
|
||||
#+BEGIN_SRC sh :dir /sudo::
|
||||
sudo zypper install elixir
|
||||
#+END_SRC
|
||||
* Features
|
||||
- Code completion (~:completion company~)
|
||||
- Documentation lookup (~:tools lookup~)
|
||||
|
|
|
@ -32,18 +32,6 @@
|
|||
(when (featurep! +lsp)
|
||||
(add-hook 'elixir-mode-local-vars-hook #'lsp!))
|
||||
|
||||
(use-package! alchemist-company
|
||||
:when (featurep! :completion company)
|
||||
:commands alchemist-company
|
||||
:init
|
||||
(set-company-backend! 'elixir-mode '(alchemist-company company-yasnippet))
|
||||
:config
|
||||
;; Alchemist doesn't use hook symbols to add these backends, so we have to
|
||||
;; use the entire closure to get rid of it.
|
||||
(let ((fn (byte-compile (lambda () (add-to-list (make-local-variable 'company-backends) 'alchemist-company)))))
|
||||
(remove-hook 'alchemist-mode-hook fn)
|
||||
(remove-hook 'alchemist-iex-mode-hook fn)))
|
||||
|
||||
(use-package! flycheck-credo
|
||||
:when (featurep! :tools flycheck)
|
||||
:config (flycheck-credo-setup)))
|
||||
|
@ -51,9 +39,24 @@
|
|||
|
||||
(use-package! alchemist
|
||||
:hook (elixir-mode . alchemist-mode)
|
||||
:config
|
||||
:init
|
||||
(after! elixir-mode
|
||||
(set-lookup-handlers! 'elixir-mode
|
||||
:definition #'alchemist-goto-definition-at-point
|
||||
:documentation #'alchemist-help-search-at-point)
|
||||
(set-eval-handler! 'elixir-mode #'alchemist-eval-region)
|
||||
(set-repl-handler! 'elixir-mode #'alchemist-iex-project-run))
|
||||
(set-repl-handler! 'elixir-mode #'alchemist-iex-project-run)))
|
||||
|
||||
|
||||
(use-package! alchemist-company
|
||||
:when (featurep! :completion company)
|
||||
:commands alchemist-company
|
||||
:init
|
||||
(after! elixir-mode
|
||||
(set-company-backend! 'elixir-mode '(alchemist-company company-yasnippet)))
|
||||
:config
|
||||
;; Alchemist doesn't use hook symbols to add these backends, so we have to use
|
||||
;; the entire closure to get rid of it.
|
||||
(let ((fn (byte-compile (lambda () (add-to-list (make-local-variable 'company-backends) 'alchemist-company)))))
|
||||
(remove-hook 'alchemist-mode-hook fn)
|
||||
(remove-hook 'alchemist-iex-mode-hook fn)))
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
;;; lang/elm/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; `elm-mode'
|
||||
(setq elm-format-on-save t)
|
||||
|
||||
(after! elm-mode
|
||||
(add-hook 'elm-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ if it's callable, `apropos' otherwise."
|
|||
`(("Section" "^[ \t]*;;;;*[ \t]+\\([^\n]+\\)" 1)
|
||||
("Evil commands" "^\\s-*(evil-define-\\(?:command\\|operator\\|motion\\) +\\(\\_<[^ ()\n]+\\_>\\)" 1)
|
||||
("Unit tests" "^\\s-*(\\(?:ert-deftest\\|describe\\) +\"\\([^\")]+\\)\"" 1)
|
||||
("Package" "^\\s-*(\\(?:;;;###package\\|def-package!\\|package!\\|use-package\\|after!\\) +\\(\\_<[^ ()\n]+\\_>\\)" 1)
|
||||
("Package" "^\\s-*(\\(?:;;;###package\\|package!\\|use-package!?\\|after!\\) +\\(\\_<[^ ()\n]+\\_>\\)" 1)
|
||||
("Major modes" "^\\s-*(define-derived-mode +\\([^ ()\n]+\\)" 1)
|
||||
("Minor modes" "^\\s-*(define-\\(?:global\\(?:ized\\)?-minor\\|generic\\|minor\\)-mode +\\([^ ()\n]+\\)" 1)
|
||||
("Modelines" "^\\s-*(def-modeline! +\\([^ ()\n]+\\)" 1)
|
||||
|
@ -174,3 +174,15 @@ verbosity when editing a file in `doom-private-dir' or `doom-emacs-dir'."
|
|||
" "
|
||||
(default-value 'flycheck-emacs-lisp-check-form)
|
||||
")"))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp/edebug-instrument-defun-on ()
|
||||
"Toggle on instrumentalisation for the function under `defun'."
|
||||
(interactive)
|
||||
(eval-defun 'edebugit))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp/edebug-instrument-defun-off ()
|
||||
"Toggle off instrumentalisation for the function under `defun'."
|
||||
(interactive)
|
||||
(eval-defun nil))
|
||||
|
|
|
@ -77,8 +77,10 @@ This marks a foldable marker for `outline-minor-mode' in elisp buffers.")
|
|||
|
||||
(map! :localleader
|
||||
:map emacs-lisp-mode-map
|
||||
"e" #'macrostep-expand))
|
||||
|
||||
"e" #'macrostep-expand
|
||||
(:prefix ("d" . "debug")
|
||||
("f" #'+emacs-lisp/edebug-instrument-defun-on)
|
||||
("F" #'+emacs-lisp/edebug-instrument-defun-off))))
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
@ -112,8 +114,20 @@ This marks a foldable marker for `outline-minor-mode' in elisp buffers.")
|
|||
"Add Doom's own demos to help buffers."
|
||||
:around #'elisp-demos--search
|
||||
(or (funcall orig-fn symbol)
|
||||
(when-let* ((elisp-demos--elisp-demos.org (doom-glob doom-docs-dir "api.org")))
|
||||
(funcall orig-fn symbol)))))
|
||||
(when-let (demos-file (doom-glob doom-docs-dir "api.org"))
|
||||
(with-temp-buffer
|
||||
(insert-file-contents demos-file)
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward
|
||||
(format "^\\*\\*\\* %s$" (regexp-quote (symbol-name symbol)))
|
||||
nil t)
|
||||
(let (beg end)
|
||||
(forward-line 1)
|
||||
(setq beg (point))
|
||||
(if (re-search-forward "^\\*" nil t)
|
||||
(setq end (line-beginning-position))
|
||||
(setq end (point-max)))
|
||||
(string-trim (buffer-substring-no-properties beg end)))))))))
|
||||
|
||||
|
||||
(use-package! buttercup
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
;;; lang/erlang/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package! erlang
|
||||
:mode ("\\.erlang$" . erlang-mode)
|
||||
:mode ("/rebar\\.config\\(?:\\.script\\)?$" . erlang-mode)
|
||||
:mode ("/\\(?:app\\|sys\\)\\.config$" . erlang-mode))
|
||||
:mode ("\\.erlang\\'" . erlang-mode)
|
||||
:mode ("/rebar\\.config\\(?:\\.script\\)?\\'" . erlang-mode)
|
||||
:mode ("/\\(?:app\\|sys\\)\\.config\\'" . erlang-mode))
|
||||
|
||||
|
||||
(use-package! flycheck-rebar3
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
;;; lang/ess/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package! ess
|
||||
:commands (stata SAS)
|
||||
:commands stata SAS
|
||||
:init
|
||||
(setq ess-smart-S-assign-key nil)
|
||||
(unless (featurep! :lang julia)
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
#+STARTUP: inlineimages
|
||||
|
||||
* Table of Contents :TOC:
|
||||
- [[Description][Description]]
|
||||
- [[Module Flags][Module Flags]]
|
||||
- [[Plugins][Plugins]]
|
||||
- [[Prerequisites][Prerequisites]]
|
||||
- [[Go][Go]]
|
||||
- [[Dependencies][Dependencies]]
|
||||
- [[Features][Features]]
|
||||
- [[Configuration][Configuration]]
|
||||
- [[Troubleshooting][Troubleshooting]]
|
||||
- [[#description][Description]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#go][Go]]
|
||||
- [[#dependencies][Dependencies]]
|
||||
- [[#features][Features]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#troubleshooting][Troubleshooting]]
|
||||
|
||||
* Description
|
||||
This module adds [[https://golang.org][Go]] support.
|
||||
|
@ -35,6 +35,7 @@ This module provides no flags.
|
|||
+ [[https://github.com/syohex/emacs-go-eldoc][go-eldoc]]
|
||||
+ [[https://github.com/dominikh/go-mode.el][go-guru]]
|
||||
+ [[https://github.com/manute/gorepl-mode][gorepl-mode]]
|
||||
+ [[https://github.com/syohex/emacs-go-add-tags][go-add-tags]]
|
||||
+ [[https://github.com/mdempsky/gocode][company-go]]*
|
||||
|
||||
* Prerequisites
|
||||
|
@ -51,6 +52,11 @@ brew install go
|
|||
sudo pacman -S go
|
||||
#+END_SRC
|
||||
|
||||
*** openSUSE
|
||||
#+BEGIN_SRC sh :dir /sudo::
|
||||
sudo zypper install go
|
||||
#+END_SRC
|
||||
|
||||
** Dependencies
|
||||
This module requires a valid ~GOPATH~, and the following Go packages:
|
||||
|
||||
|
|
|
@ -6,17 +6,21 @@
|
|||
(defvar +go-test-last nil
|
||||
"The last test run.")
|
||||
|
||||
(defun +go--run-tests (args)
|
||||
(require 'async)
|
||||
(defun +go--spawn (cmd)
|
||||
(save-selected-window
|
||||
(async-shell-command (concat "go test " args))))
|
||||
(compile cmd)))
|
||||
|
||||
(defun +go--run-tests (args)
|
||||
(let ((cmd (concat "go test " args)))
|
||||
(setq +go-test-last (concat "cd " default-directory ";" cmd))
|
||||
(+go--spawn cmd)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +go/test-rerun ()
|
||||
(interactive)
|
||||
(if +go-test-last
|
||||
(funcall +go-test-last)
|
||||
(+go/run-all-tests)))
|
||||
(+go--spawn +go-test-last)
|
||||
(+go/test-all)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +go/test-all ()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
;;; lang/go/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;
|
||||
;; Packages
|
||||
;;; Packages
|
||||
|
||||
(after! go-mode
|
||||
(set-docsets! 'go-mode "Go")
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
(map! :map go-mode-map
|
||||
:localleader
|
||||
"a" #'go-add-tags
|
||||
"e" #'+go/play-buffer-or-region
|
||||
"i" #'go-goto-imports ; Go to imports
|
||||
(:prefix ("h" . "help")
|
||||
|
@ -58,8 +59,8 @@
|
|||
|
||||
|
||||
(use-package! company-go
|
||||
:when (and (featurep! :completion company)
|
||||
(not (featurep! +lsp)))
|
||||
:when (featurep! :completion company)
|
||||
:unless (featurep! +lsp)
|
||||
:after go-mode
|
||||
:config
|
||||
(set-company-backend! 'go-mode 'company-go)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
(package! go-guru)
|
||||
(package! go-mode)
|
||||
(package! gorepl-mode)
|
||||
(package! go-add-tags)
|
||||
|
||||
(when (featurep! :completion company)
|
||||
(package! company-go))
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue