From 68e56025bcb9c1fc14ddc840e103806b104db4e9 Mon Sep 17 00:00:00 2001 From: Ralf Beckmann Date: Sun, 3 Nov 2019 02:00:04 +0100 Subject: [PATCH 001/129] Fixed sudo edit on remote files The previous implementation failed, if the remote user was given only implicitly. --- core/autoload/files.el | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/core/autoload/files.el b/core/autoload/files.el index 7365641f6..9555efe89 100644 --- a/core/autoload/files.el +++ b/core/autoload/files.el @@ -319,9 +319,14 @@ file if it exists, without confirmation." (interactive "FOpen file as root: ") (when (file-writable-p file) (user-error "File is user writeable, aborting sudo")) - (find-file (if (file-remote-p file) - (concat "/" (file-remote-p file 'method) ":" (file-remote-p file 'user) "@" (file-remote-p file 'host) "|sudo:root@" (file-remote-p file 'host) ":" (file-remote-p file 'localname)) - (concat "/sudo:root@localhost:" file)))) + (let* ((host (or (file-remote-p file 'host) "localhost")) + (user-host (if-let (( user (file-remote-p file 'user))) + (concat user "@" host) + host)) + (hop1 (when (file-remote-p file) (concat "/" (file-remote-p file 'method) ":" user-host))) + (sep (if hop1 "|" "/")) + (hop2 (concat "sudo:root@" host ":" (or (file-remote-p file 'localname) file)))) + (find-file (concat hop1 sep hop2)))) ;;;###autoload (defun doom/sudo-this-file () From 7a810d53a0d27467e7ae69f0c9453fe065963c79 Mon Sep 17 00:00:00 2001 From: Ralf Beckmann Date: Sun, 3 Nov 2019 14:25:10 +0100 Subject: [PATCH 002/129] Consider current buffer's file when sudo-editing If doom/sudo-find-file is invoked with a file that is equal to the current buffer's file, kill that buffer since it is probably not needed anymore. --- core/autoload/files.el | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/core/autoload/files.el b/core/autoload/files.el index 9555efe89..9a9b21bfc 100644 --- a/core/autoload/files.el +++ b/core/autoload/files.el @@ -317,16 +317,19 @@ file if it exists, without confirmation." (defun doom/sudo-find-file (file) "Open FILE as root." (interactive "FOpen file as root: ") - (when (file-writable-p file) - (user-error "File is user writeable, aborting sudo")) (let* ((host (or (file-remote-p file 'host) "localhost")) - (user-host (if-let (( user (file-remote-p file 'user))) - (concat user "@" host) - host)) - (hop1 (when (file-remote-p file) (concat "/" (file-remote-p file 'method) ":" user-host))) - (sep (if hop1 "|" "/")) - (hop2 (concat "sudo:root@" host ":" (or (file-remote-p file 'localname) file)))) - (find-file (concat hop1 sep hop2)))) + (f (concat "/" (when (file-remote-p file) + (concat (file-remote-p file 'method) ":" + (if-let (user (file-remote-p file 'user)) + (concat user "@" host) + host) + "|")) + "sudo:root@" host + ":" (or (file-remote-p file 'localname) + file)))) + (if (and buffer-file-name (equal file (file-truename buffer-file-name))) + (find-alternate-file f) + (find-file f)))) ;;;###autoload (defun doom/sudo-this-file () From 280da152807460f92cc57983a60d02a849c91805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benno=20F=C3=BCnfst=C3=BCck?= Date: Sun, 3 Nov 2019 23:04:06 +0100 Subject: [PATCH 003/129] Avoid nav-flash after each hydra action Hydra displays the hints in a buffer created by lv-window, which triggers nav-flash. By advicing lv-window, we can inhibit the nav-flash hook. --- modules/ui/hydra/config.el | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/ui/hydra/config.el b/modules/ui/hydra/config.el index b8bfe3f79..ce36937cc 100644 --- a/modules/ui/hydra/config.el +++ b/modules/ui/hydra/config.el @@ -8,3 +8,9 @@ ;;;###package hydra (setq lv-use-separator t) + +(after! hydra + (defadvice! +hydra/inhibit-window-switch-hooks-a (orig-fn) + :around #'lv-window + (let ((doom-inhibit-switch-window-hooks t)) + (funcall orig-fn)))) From d05c97070876a4a3e58ff27786d4f15e66f1f097 Mon Sep 17 00:00:00 2001 From: Danny Navarro Date: Mon, 4 Nov 2019 10:48:06 +0000 Subject: [PATCH 004/129] Add org archive keybinding --- modules/lang/org/config.el | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/lang/org/config.el b/modules/lang/org/config.el index b77fca444..24e726452 100644 --- a/modules/lang/org/config.el +++ b/modules/lang/org/config.el @@ -633,6 +633,7 @@ between the two." (:when (featurep! :completion helm) "." #'helm-org-in-buffer-headings "/" #'helm-org-agenda-files-headings) + "A" #'org-archive-subtree "d" #'org-deadline "e" #'org-export-dispatch "f" #'org-footnote-new From 31b2a5a19e0dd84a480fee283dccf2b1d502e352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benno=20F=C3=BCnfst=C3=BCck?= Date: Mon, 4 Nov 2019 11:57:52 +0100 Subject: [PATCH 005/129] Fix nil error in +ivy/jump-list for empty buffers For empty buffers which don't have any lines, `(thing-at-point 'line)` will return `nil`. This broke `+ivy/jump-list`. --- modules/completion/ivy/autoload/ivy.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/completion/ivy/autoload/ivy.el b/modules/completion/ivy/autoload/ivy.el index c264f8337..27a358f5a 100644 --- a/modules/completion/ivy/autoload/ivy.el +++ b/modules/completion/ivy/autoload/ivy.el @@ -513,7 +513,7 @@ If ALL-FILES-P, search compressed and hidden files as well." (cons (format "%s:%d: %s" (buffer-name) (line-number-at-pos) - (string-trim-right (thing-at-point 'line))) + (string-trim-right (or (thing-at-point 'line) ""))) (point-marker))))))) (cddr (better-jumper-jump-list-struct-ring (better-jumper-get-jumps (better-jumper--get-current-context)))))))) From 9b831d8ae7d30a32322dd48c042ff4de0bec8b3f Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Wed, 6 Nov 2019 16:57:35 +0900 Subject: [PATCH 006/129] Add rst module Uses sphinx-mode and adds a few common bindings Signed-off-by: Rudi Grinberg --- modules/lang/rst/config.el | 16 ++++++++++++++++ modules/lang/rst/packages.el | 1 + 2 files changed, 17 insertions(+) create mode 100644 modules/lang/rst/config.el create mode 100644 modules/lang/rst/packages.el diff --git a/modules/lang/rst/config.el b/modules/lang/rst/config.el new file mode 100644 index 000000000..1b076cdef --- /dev/null +++ b/modules/lang/rst/config.el @@ -0,0 +1,16 @@ +(use-package! sphinx-mode + :init + (add-hook! 'rst-mode-hook #'sphinx-mode)) + +(use-package! rst + :config + (map! :localleader + :map rst-mode-map + (:prefix ("a" . "adjust") + ("a" #'rst-adjust + "r" #'rst-adjust-region)) + (:prefix ("t" . "table of contents") + ("t" #'rst-toc + "i" #'rst-toc-insert + "u" #'rst-toc-update + "f" #'rst-toc-follow-link)))) diff --git a/modules/lang/rst/packages.el b/modules/lang/rst/packages.el new file mode 100644 index 000000000..ff9563aa7 --- /dev/null +++ b/modules/lang/rst/packages.el @@ -0,0 +1 @@ +(package! sphinx-mode) From 1fcf210bd4af3bb34f2ac5dce9fdfb3515866da5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastien=20Rivi=C3=A8re?= Date: Wed, 6 Nov 2019 14:22:24 +0100 Subject: [PATCH 007/129] replace go-add-tags with go-tag go-add-tags isn't maintained and has a few issues. This library will fix those issues by using a binary intended for this. --- modules/lang/go/README.org | 4 +++- modules/lang/go/config.el | 3 ++- modules/lang/go/doctor.el | 3 +++ modules/lang/go/packages.el | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/lang/go/README.org b/modules/lang/go/README.org index 9c33d6738..c1a2f91e7 100644 --- a/modules/lang/go/README.org +++ b/modules/lang/go/README.org @@ -36,7 +36,7 @@ This module adds [[https://golang.org][Go]] support. + [[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/brantou/emacs-go-tag][go-tag]] + [[https://github.com/mdempsky/gocode][company-go]]* + [[https://github.com/s-kostyaev/go-gen-test][go-gen-test]] @@ -69,6 +69,7 @@ This module requires a valid ~GOPATH~, and the following Go packages: + ~guru~ (for code navigation & refactoring commands) + ~goimports~ (optional: for auto-formatting code on save & fixing imports) + ~gotests~ (for generate test code) ++ ~gomodifytags~ (for manipulating tags) #+BEGIN_SRC sh export GOPATH=~/work/go @@ -80,6 +81,7 @@ go get -u golang.org/x/tools/cmd/goimports go get -u golang.org/x/tools/cmd/gorename go get -u golang.org/x/tools/cmd/guru go get -u github.com/cweill/gotests/... +go get -u github.com/fatih/gomodifytags #+END_SRC * TODO Features diff --git a/modules/lang/go/config.el b/modules/lang/go/config.el index 0c13afd68..2f656f590 100644 --- a/modules/lang/go/config.el +++ b/modules/lang/go/config.el @@ -25,7 +25,8 @@ (map! :map go-mode-map :localleader - "a" #'go-add-tags + "a" #'go-tag-add + "d" #'go-tag-remove "e" #'+go/play-buffer-or-region "i" #'go-goto-imports ; Go to imports (:prefix ("h" . "help") diff --git a/modules/lang/go/doctor.el b/modules/lang/go/doctor.el index 37d002263..a179fb5c9 100644 --- a/modules/lang/go/doctor.el +++ b/modules/lang/go/doctor.el @@ -14,6 +14,9 @@ (unless (executable-find "gotests") (warn! "Couldn't find gotests. Generating tests will not work")) +(unless (executable-find "gomodifytags") + (warn! "Couldn't find gomodifytags. Manipulating struct tags will not work")) + (when (featurep! :completion company) (require 'company-go) (unless (executable-find company-go-gocode-command) diff --git a/modules/lang/go/packages.el b/modules/lang/go/packages.el index bbf22ba0b..ab3c2b8c1 100644 --- a/modules/lang/go/packages.el +++ b/modules/lang/go/packages.el @@ -5,7 +5,7 @@ (package! go-guru) (package! go-mode) (package! gorepl-mode) -(package! go-add-tags) +(package! go-tag) (package! go-gen-test) (when (featurep! :completion company) From fe464910d2483fededed361b556c4fe38aa4f43e Mon Sep 17 00:00:00 2001 From: vikigenius Date: Thu, 7 Nov 2019 14:09:30 -0500 Subject: [PATCH 008/129] Fixes:2023, added racket-smart-open-bracket-mode --- modules/lang/racket/config.el | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/lang/racket/config.el b/modules/lang/racket/config.el index 40b2048df..894eb3b39 100644 --- a/modules/lang/racket/config.el +++ b/modules/lang/racket/config.el @@ -24,10 +24,8 @@ (add-hook! 'racket-mode-hook #'rainbow-delimiters-mode - #'highlight-quoted-mode) - - (map! :map (racket-mode-map racket-repl-mode-map) - :i "[" #'racket-smart-open-bracket) + #'highlight-quoted-mode + #'racket-smart-open-bracket-mode) (map! :localleader :map racket-mode-map From 45f8972cdc327c28cc445a39485fcb385b1d5529 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Fri, 8 Nov 2019 12:50:38 +0900 Subject: [PATCH 009/129] add headers Signed-off-by: Rudi Grinberg --- modules/lang/rst/config.el | 2 ++ modules/lang/rst/packages.el | 3 +++ 2 files changed, 5 insertions(+) diff --git a/modules/lang/rst/config.el b/modules/lang/rst/config.el index 1b076cdef..2460ac74a 100644 --- a/modules/lang/rst/config.el +++ b/modules/lang/rst/config.el @@ -1,3 +1,5 @@ +;;; lang/rst/config.el -*- lexical-binding: t; -*- + (use-package! sphinx-mode :init (add-hook! 'rst-mode-hook #'sphinx-mode)) diff --git a/modules/lang/rst/packages.el b/modules/lang/rst/packages.el index ff9563aa7..b4f32ff0b 100644 --- a/modules/lang/rst/packages.el +++ b/modules/lang/rst/packages.el @@ -1 +1,4 @@ +;; -*- no-byte-compile: t; -*- +;;; lang/rst/packages.el + (package! sphinx-mode) From b1341f5668a4fe54ea45bbaa772dbb03da2bd709 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Fri, 8 Nov 2019 12:50:44 +0900 Subject: [PATCH 010/129] Use use-package's :hook Signed-off-by: Rudi Grinberg --- modules/lang/rst/config.el | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/lang/rst/config.el b/modules/lang/rst/config.el index 2460ac74a..87ec00a63 100644 --- a/modules/lang/rst/config.el +++ b/modules/lang/rst/config.el @@ -1,8 +1,7 @@ ;;; lang/rst/config.el -*- lexical-binding: t; -*- (use-package! sphinx-mode - :init - (add-hook! 'rst-mode-hook #'sphinx-mode)) + :hook (rst-mode . sphinx-mode)) (use-package! rst :config From 487b53ab5d26152beb4d17403723ff21e7f20942 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Fri, 8 Nov 2019 12:51:57 +0900 Subject: [PATCH 011/129] remove unnecessary parens Signed-off-by: Rudi Grinberg --- modules/lang/rst/config.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/lang/rst/config.el b/modules/lang/rst/config.el index 87ec00a63..25a58b029 100644 --- a/modules/lang/rst/config.el +++ b/modules/lang/rst/config.el @@ -8,8 +8,8 @@ (map! :localleader :map rst-mode-map (:prefix ("a" . "adjust") - ("a" #'rst-adjust - "r" #'rst-adjust-region)) + "a" #'rst-adjust + "r" #'rst-adjust-region) (:prefix ("t" . "table of contents") ("t" #'rst-toc "i" #'rst-toc-insert From ba11f046bfca4e7360d2dd38be712fa45168f925 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Fri, 8 Nov 2019 12:54:10 +0900 Subject: [PATCH 012/129] Use ox-rst when :lang rst is enabled Signed-off-by: Rudi Grinberg --- modules/lang/org/packages.el | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/lang/org/packages.el b/modules/lang/org/packages.el index 6e04f10b8..f4f4cd52a 100644 --- a/modules/lang/org/packages.el +++ b/modules/lang/org/packages.el @@ -58,3 +58,5 @@ (when (featurep! +hugo) (package! ox-hugo :recipe (:host github :repo "kaushalmodi/ox-hugo" :nonrecursive t))) +(when (featurep! :lang rst) + (package! ox-rst)) From 1f53ee92cb9c3843c6027b7e6642ccf28276203b Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Fri, 8 Nov 2019 12:56:14 +0900 Subject: [PATCH 013/129] lazy load rst Signed-off-by: Rudi Grinberg --- modules/lang/rst/config.el | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/lang/rst/config.el b/modules/lang/rst/config.el index 25a58b029..77cec504d 100644 --- a/modules/lang/rst/config.el +++ b/modules/lang/rst/config.el @@ -4,6 +4,7 @@ :hook (rst-mode . sphinx-mode)) (use-package! rst + :defer t :config (map! :localleader :map rst-mode-map From 99cd52e70fac33b46c7ef3ab868ef4ccf19ba4ce Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 7 Nov 2019 12:49:30 -0500 Subject: [PATCH 014/129] :boom: Drop Emacs 25.x support Emacs 26.1 is Doom's new minimum supported version Closes #2026 --- .github/workflows/test.yml | 2 +- README.md | 2 +- core/autoload/line-numbers.el | 92 ------------------------ core/autoload/projects.el | 3 +- core/autoload/ui.el | 11 +-- core/core-lib.el | 35 ---------- core/core-ui.el | 73 -------------------- core/core.el | 5 +- core/packages.el | 6 -- modules/completion/company/config.el | 2 +- modules/completion/company/packages.el | 2 +- modules/completion/helm/config.el | 2 +- modules/completion/helm/packages.el | 2 +- modules/completion/ivy/config.el | 2 +- modules/completion/ivy/doctor.el | 2 - modules/completion/ivy/packages.el | 2 +- modules/editor/evil/+everywhere.el | 2 +- modules/emacs/ibuffer/config.el | 2 +- modules/emacs/vc/config.el | 11 --- modules/lang/data/packages.el | 7 +- modules/lang/rust/config.el | 77 ++++++--------------- modules/lang/rust/packages.el | 4 +- modules/lang/web/+css.el | 6 -- modules/lang/web/+html.el | 7 +- modules/lang/web/packages.el | 2 +- modules/tools/flycheck/config.el | 1 - modules/tools/flycheck/packages.el | 2 +- modules/tools/lsp/config.el | 3 +- modules/tools/pass/config.el | 2 +- modules/ui/doom/config.el | 4 +- modules/ui/modeline/autoload.el | 4 +- modules/ui/popup/autoload/popup.el | 96 -------------------------- modules/ui/popup/config.el | 1 - 33 files changed, 48 insertions(+), 426 deletions(-) delete mode 100644 core/autoload/line-numbers.el diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7d04c1f39..65dbb2818 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,8 +16,8 @@ jobs: strategy: matrix: emacs_version: - - 25.3 - 26.1 + - 26.3 - snapshot include: - emacs_version: 26.3 diff --git a/README.md b/README.md index 7645d96e9..4ad52f31c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Made with Doom Emacs - Made for Emacs 25.3+ + Made for Emacs 26.1+ Build status: develop diff --git a/core/autoload/line-numbers.el b/core/autoload/line-numbers.el deleted file mode 100644 index df144180a..000000000 --- a/core/autoload/line-numbers.el +++ /dev/null @@ -1,92 +0,0 @@ -;;; core/autoload/line-numbers.el -*- lexical-binding: t; -*- -;;;###if (version< emacs-version "26.1") - -;; DEPRECATED This was lifted out of the display-line-numbers library in Emacs -;; 26.1 and modified to use nlinum for Emacs 25.x users. It should be removed -;; should Emacs 25 support be removed. - -;;;###autoload -(defvar display-line-numbers t - "Non-nil means display line numbers. - -If the value is t, display the absolute number of each line of a buffer -shown in a window. Absolute line numbers count from the beginning of -the current narrowing, or from buffer beginning. If the value is -relative, display for each line not containing the window's point its -relative number instead, i.e. the number of the line relative to the -line showing the window's point. - -In either case, line numbers are displayed at the beginning of each -non-continuation line that displays buffer text, i.e. after each newline -character that comes from the buffer. The value visual is like -relative but counts screen lines instead of buffer lines. In practice -this means that continuation lines count as well when calculating the -relative number of a line. - -Lisp programs can disable display of a line number of a particular -buffer line by putting the display-line-numbers-disable text property -or overlay property on the first visible character of that line.") - -(defgroup display-line-numbers nil "Display line number preferences" - :group 'emacs) - -;;;###autoload -(defcustom display-line-numbers-type t - "The default type of line numbers to use in `display-line-numbers-mode'. -See `display-line-numbers' for value options." - :type '(choice (const :tag "Relative line numbers" relative) - (const :tag "Relative visual line numbers" visual) - (other :tag "Absolute line numbers" t))) - -;;;###autoload -(defcustom display-line-numbers-grow-only nil - "If non-nil, do not shrink line number width." - :type 'boolean) - -;;;###autoload -(defcustom display-line-numbers-width-start nil - "If non-nil, count number of lines to use for line number width. -When `display-line-numbers-mode' is turned on, -`display-line-numbers-width' is set to the minimum width necessary -to display all line numbers in the buffer." - :type 'boolean) - -;;;###autoload -(defun line-number-display-width (&optional _) - "Return the width used for displaying line numbers in the -selected window." - (length (save-excursion (goto-char (point-max)) - (format-mode-line "%l")))) - -(defun display-line-numbers-update-width () - "Prevent the line number width from shrinking." - (let ((width (line-number-display-width))) - (when (> width (or display-line-numbers-width 1)) - (setq display-line-numbers-width width)))) - -;;;###autoload -(define-minor-mode display-line-numbers-mode - "Toggle display of line numbers in the buffer. -This uses `display-line-numbers' internally. - -To change the type of line numbers displayed by default, -customize `display-line-numbers-type'. To change the type while -the mode is on, set `display-line-numbers' directly." - :lighter nil - (cond ((null display-line-numbers-type)) - ((eq display-line-numbers-type 'relative) - (if display-line-numbers-mode - (nlinum-relative-off) - (nlinum-relative-on))) - ((nlinum-mode (if display-line-numbers-mode +1 -1))))) - -(defun display-line-numbers--turn-on () - "Turn on `display-line-numbers-mode'." - (unless (or (minibufferp) - ;; taken from linum.el - (and (daemonp) (null (frame-parameter nil 'client)))) - (display-line-numbers-mode))) - -;;;###autoload -(define-globalized-minor-mode global-display-line-numbers-mode - display-line-numbers-mode display-line-numbers--turn-on) diff --git a/core/autoload/projects.el b/core/autoload/projects.el index 364941ab5..6decf3501 100644 --- a/core/autoload/projects.el +++ b/core/autoload/projects.el @@ -117,8 +117,7 @@ If DIR is not a project, it will be indexed (but not cached)." #'projectile-find-file))) ((fboundp 'counsel-file-jump) ; ivy only (call-interactively #'counsel-file-jump)) - ((and (fboundp 'project-find-file-in) ; emacs 26.1+ only - (project-current)) + ((project-current) (project-find-file-in nil (list default-directory) nil)) ((fboundp 'helm-find-files) (call-interactively #'helm-find-files)) diff --git a/core/autoload/ui.el b/core/autoload/ui.el index f5a8ba544..7a0b8a447 100644 --- a/core/autoload/ui.el +++ b/core/autoload/ui.el @@ -72,21 +72,14 @@ visual-line-mode is on, this skips relative and uses visual instead. See `display-line-numbers' for what these values mean." (interactive) (defvar doom--line-number-style display-line-numbers-type) - ;; DEPRECATED - (let* ((styles `(t ,(if (and EMACS26+ visual-line-mode) 'visual 'relative) nil)) + (let* ((styles `(t ,(if visual-line-mode 'visual 'relative) nil)) (order (cons display-line-numbers-type (remq display-line-numbers-type styles))) (queue (memq doom--line-number-style order)) (next (if (= (length queue) 1) (car order) (car (cdr queue))))) (setq doom--line-number-style next) - ;; DEPRECATED - (if EMACS26+ - (setq display-line-numbers next) - (pcase next - (`t (nlinum-relative-off) (nlinum-mode +1)) - (`relative (nlinum-relative-on)) - (`nil (nlinum-mode -1)))) + (setq display-line-numbers next) (message "Switched to %s line numbers" (pcase next (`t "normal") diff --git a/core/core-lib.el b/core/core-lib.el index f605a626c..caed77b53 100644 --- a/core/core-lib.el +++ b/core/core-lib.el @@ -3,41 +3,6 @@ (require 'cl-lib) (require 'subr-x) -;; DEPRECATED Polyfills -(unless EMACS26+ - (with-no-warnings - ;; `kill-current-buffer' was introduced in Emacs 26 - (defalias 'kill-current-buffer #'kill-this-buffer) - ;; if-let and when-let were moved to (if|when)-let* in Emacs 26+ so we alias - ;; them for 25 users. - (defalias 'if-let* #'if-let) - (defalias 'when-let* #'when-let) - - ;; `mapcan' was introduced in 26.1. `cl-mapcan' isn't a perfect replacement, - ;; but it's close enough. - (defalias 'mapcan #'cl-mapcan) - - (defun alist-get (key alist &optional default remove testfn) - "Return the value associated with KEY in ALIST. -If KEY is not found in ALIST, return DEFAULT. -Use TESTFN to lookup in the alist if non-nil. Otherwise, use `assq'. - -This is a generalized variable suitable for use with `setf'. -When using it to set a value, optional argument REMOVE non-nil -means to remove KEY from ALIST if the new value is `eql' to DEFAULT." - (ignore remove) ;;Silence byte-compiler. - (let ((x (if (not testfn) - (assq key alist) - ;; In Emacs<26, `assoc' has no testfn arg, so we have to - ;; implement it ourselves - (if testfn - (cl-loop for entry in alist - if (funcall testfn key entry) - return entry) - (assoc key alist))))) - (if x (cdr x) default))))) - - ;; ;;; Helpers diff --git a/core/core-ui.el b/core/core-ui.el index eb82cb3e5..620feb24b 100644 --- a/core/core-ui.el +++ b/core/core-ui.el @@ -512,79 +512,6 @@ treat Emacs as a non-application window." (defun doom-enable-line-numbers-h () (display-line-numbers-mode +1)) (defun doom-disable-line-numbers-h () (display-line-numbers-mode -1)) -;; DEPRECATED `nlinum' is used for Emacs 25 users; 26+ has native line numbers. -(use-package! nlinum - ;; Line number column. A faster (or equivalent, in the worst case) line number - ;; plugin than `linum-mode'. - :unless EMACS26+ - :defer t - :init - (defvar doom-line-number-lpad 4 - "How much padding to place before line numbers.") - (defvar doom-line-number-rpad 1 - "How much padding to place after line numbers.") - (defvar doom-line-number-pad-char 32 - "Character to use for padding line numbers. - -By default, this is a space character. If you use `whitespace-mode' with -`space-mark', the whitespace in line numbers will be affected (this can look -ugly). In this case, you can change this to ?\u2002, which is a unicode -character that looks like a space that `whitespace-mode' won't affect.") - :config - (setq nlinum-highlight-current-line t) - - ;; Fix lingering hl-line overlays (caused by nlinum) - (add-hook! 'hl-line-mode-hook - (remove-overlays (point-min) (point-max) 'face 'hl-line)) - - (defun doom-nlinum-format-fn (line _width) - "A more customizable `nlinum-format-function'. See `doom-line-number-lpad', -`doom-line-number-rpad' and `doom-line-number-pad-char'. Allows a fix for -`whitespace-mode' space-marks appearing inside the line number." - (let ((str (number-to-string line))) - (setq str (concat (make-string (max 0 (- doom-line-number-lpad (length str))) - doom-line-number-pad-char) - str - (make-string doom-line-number-rpad doom-line-number-pad-char))) - (put-text-property 0 (length str) 'face - (if (and nlinum-highlight-current-line - (= line nlinum--current-line)) - 'nlinum-current-line - 'linum) - str) - str)) - (setq nlinum-format-function #'doom-nlinum-format-fn) - - (add-hook! 'nlinum-mode-hook - (defun doom-init-nlinum-width-h () - "Calculate line number column width beforehand (optimization)." - (setq nlinum--width - (length (save-excursion (goto-char (point-max)) - (format-mode-line "%l"))))))) - -(use-package! nlinum-hl - ;; Fixes disappearing line numbers in nlinum and other quirks - :unless EMACS26+ - :after nlinum - :config - ;; With `markdown-fontify-code-blocks-natively' enabled in `markdown-mode', - ;; line numbers tend to vanish next to code blocks. - (advice-add #'markdown-fontify-code-block-natively - :after #'nlinum-hl-do-markdown-fontify-region) - ;; When using `web-mode's code-folding an entire range of line numbers will - ;; vanish in the affected area. - (advice-add #'web-mode-fold-or-unfold :after #'nlinum-hl-do-generic-flush) - ;; Changing fonts can leave nlinum line numbers in their original size; this - ;; forces them to resize. - (add-hook 'after-setting-font-hook #'nlinum-hl-flush-all-windows)) - -(use-package! nlinum-relative - :unless EMACS26+ - :defer t - :config - (setq nlinum-format " %d ") - (add-hook 'evil-mode-hook #'nlinum-relative-setup-evil)) - ;; ;;; Theme & font diff --git a/core/core.el b/core/core.el index 5321799fd..81762e1ed 100644 --- a/core/core.el +++ b/core/core.el @@ -1,13 +1,12 @@ ;;; core.el --- the heart of the beast -*- lexical-binding: t; -*- -(when (version< emacs-version "25.3") - (error "Detected Emacs %s. Doom only supports Emacs 25.3 and higher" +(when (version< emacs-version "26.1") + (error "Detected Emacs %s. Doom only supports Emacs 26.1 and higher" emacs-version)) (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)) diff --git a/core/packages.el b/core/packages.el index 84504da62..ff2ee9115 100644 --- a/core/packages.el +++ b/core/packages.el @@ -9,12 +9,6 @@ (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) - (package! nlinum-relative)) (package! rainbow-delimiters) (package! restart-emacs) diff --git a/modules/completion/company/config.el b/modules/completion/company/config.el index ef84516a1..a98bcca9c 100644 --- a/modules/completion/company/config.el +++ b/modules/completion/company/config.el @@ -62,7 +62,7 @@ (use-package! company-box - :when (and EMACS26+ (featurep! +childframe)) + :when (featurep! +childframe) :hook (company-mode . company-box-mode) :config (setq company-box-show-single-candidate t diff --git a/modules/completion/company/packages.el b/modules/completion/company/packages.el index 1e2b7a64b..91b9e88a7 100644 --- a/modules/completion/company/packages.el +++ b/modules/completion/company/packages.el @@ -4,5 +4,5 @@ (package! company) (package! company-dict) (package! company-prescient) -(when (and EMACS26+ (featurep! +childframe)) +(when (featurep! +childframe) (package! company-box)) diff --git a/modules/completion/helm/config.el b/modules/completion/helm/config.el index b559b34d7..1753c416f 100644 --- a/modules/completion/helm/config.el +++ b/modules/completion/helm/config.el @@ -82,7 +82,7 @@ be negative.") (setq helm-default-prompt-display-function #'+helm--set-prompt-display)) :init - (when (and EMACS26+ (featurep! +childframe)) + (when (featurep! +childframe) (setq helm-display-function #'+helm-posframe-display-fn)) (let ((fuzzy (featurep! +fuzzy))) diff --git a/modules/completion/helm/packages.el b/modules/completion/helm/packages.el index 870759b66..eb343b566 100644 --- a/modules/completion/helm/packages.el +++ b/modules/completion/helm/packages.el @@ -10,7 +10,7 @@ (package! swiper-helm) (when (featurep! +fuzzy) (package! helm-flx)) -(when (and EMACS26+ (featurep! +childframe)) +(when (featurep! +childframe) (package! posframe)) (when (featurep! :lang org) (package! helm-org)) diff --git a/modules/completion/ivy/config.el b/modules/completion/ivy/config.el index 17ad1c5a6..f12ddf55d 100644 --- a/modules/completion/ivy/config.el +++ b/modules/completion/ivy/config.el @@ -324,7 +324,7 @@ evil-ex-specific constructs, so we disable it solely in evil-ex." (use-package! ivy-posframe - :when (and EMACS26+ (featurep! +childframe)) + :when (featurep! +childframe) :hook (ivy-mode . ivy-posframe-mode) :config (setq ivy-fixed-height-minibuffer nil diff --git a/modules/completion/ivy/doctor.el b/modules/completion/ivy/doctor.el index d730f1552..a79d37c56 100644 --- a/modules/completion/ivy/doctor.el +++ b/modules/completion/ivy/doctor.el @@ -1,5 +1,3 @@ ;; -*- lexical-binding: t; no-byte-compile: t; -*- ;;; completion/ivy/doctor.el -(when (and (not EMACS26+) (featurep! +childframe)) - (error! "The +childframe feature requires Emacs 26+")) diff --git a/modules/completion/ivy/packages.el b/modules/completion/ivy/packages.el index e804e9ead..5571641fd 100644 --- a/modules/completion/ivy/packages.el +++ b/modules/completion/ivy/packages.el @@ -15,7 +15,7 @@ (when (featurep! +fuzzy) (package! flx))) -(when (and EMACS26+ (featurep! +childframe)) +(when (featurep! +childframe) (package! ivy-posframe)) (when (featurep! +icons) diff --git a/modules/editor/evil/+everywhere.el b/modules/editor/evil/+everywhere.el index ea8ba4ddc..c5e1312eb 100644 --- a/modules/editor/evil/+everywhere.el +++ b/modules/editor/evil/+everywhere.el @@ -220,7 +220,7 @@ and complains if a module is loaded too early (during startup)." (add-transient-hook! 'emacs-lisp-mode (+evil-collection-init 'elisp-mode)) (add-transient-hook! 'occur-mode - (+evil-collection-init (if EMACS26+ 'replace "replace"))) + (+evil-collection-init 'replace)) (evil-define-key* 'normal process-menu-mode-map "q" #'kill-current-buffer diff --git a/modules/emacs/ibuffer/config.el b/modules/emacs/ibuffer/config.el index e928358d7..72755c9d3 100644 --- a/modules/emacs/ibuffer/config.el +++ b/modules/emacs/ibuffer/config.el @@ -6,7 +6,7 @@ (setq ibuffer-show-empty-filter-groups nil ibuffer-filter-group-name-face '(:inherit (success bold)) ibuffer-formats - `((mark modified read-only ,(if EMACS26+ 'locked "") + `((mark modified read-only locked ,@(if (featurep! +icons) `(;; Here you may adjust by replacing :right with :center ;; or :left According to taste, if you want the icon diff --git a/modules/emacs/vc/config.el b/modules/emacs/vc/config.el index 68cfe853c..a8a595052 100644 --- a/modules/emacs/vc/config.el +++ b/modules/emacs/vc/config.el @@ -66,14 +66,3 @@ otherwise in default state." (when (and (bound-and-true-p evil-mode) (bobp) (eolp)) (evil-insert-state))))) - - -(after! smerge-mode - (unless EMACS26+ - (with-no-warnings - (defalias #'smerge-keep-upper #'smerge-keep-mine) - (defalias #'smerge-keep-lower #'smerge-keep-other) - (defalias #'smerge-diff-base-upper #'smerge-diff-base-mine) - (defalias #'smerge-diff-upper-lower #'smerge-diff-mine-other) - (defalias #'smerge-diff-base-lower #'smerge-diff-base-other)))) - diff --git a/modules/lang/data/packages.el b/modules/lang/data/packages.el index 8feed097b..9cb3322eb 100644 --- a/modules/lang/data/packages.el +++ b/modules/lang/data/packages.el @@ -7,8 +7,5 @@ (package! yaml-mode) (package! csv-mode) (package! dhall-mode) -(package! protobuf-mode :recipe (:host github :repo "emacsmirror/protobuf-mode" :files (:defaults "*"))) - -;; DEPRECATED `conf-toml-mode' exists in Emacs 26+ -(unless (fboundp 'conf-toml-mode) - (package! toml-mode)) +(package! protobuf-mode + :recipe (:host github :repo "emacsmirror/protobuf-mode" :files (:defaults "*"))) diff --git a/modules/lang/rust/config.el b/modules/lang/rust/config.el index 6bbe39b04..87f8bb602 100644 --- a/modules/lang/rust/config.el +++ b/modules/lang/rust/config.el @@ -7,43 +7,13 @@ ;; ;;; Packages -(use-package! rust-mode - :defer t - :config - (setq rust-indent-method-chain t) - (add-hook 'rust-mode-hook #'rainbow-delimiters-mode) - - ;; This is necessary because both plugins are fighting for supremacy in - ;; `auto-mode-alist', so rustic-mode *must* load second. It only needs to - ;; happen once. - ;; - ;; rust-mode is still required for `racer'. - (add-hook! 'rust-mode-hook - (defun +rust-init-h () - "Switch to `rustic-mode', if it's available." - (when (require 'rustic nil t) - (rustic-mode)))) - - (set-docsets! '(rust-mode rustic-mode) "Rust") - (when (featurep! +lsp) - (add-hook 'rust-mode-local-vars-hook #'lsp!))) - - -(use-package! racer - :unless (featurep! +lsp) - :hook ((rust-mode rustic-mode) . racer-mode) - :config - (set-lookup-handlers! 'rust-mode - :definition '(racer-find-definition :async t) - :documentation '+rust-racer-lookup-documentation)) - - (use-package! rustic - :when EMACS26+ - :after rust-mode + :mode ("\\.rs$" . rustic-mode) :preface (setq rustic-rls-pkg (if (featurep! +lsp) 'lsp-mode)) :config + (set-docsets! 'rustic-mode "Rust") + (setq rustic-indent-method-chain t rustic-flycheck-setup-mode-line-p nil ;; use :editor format instead @@ -52,38 +22,35 @@ ;; buffers, so we disable it, but only for evil users, because it ;; affects `forward-sexp' and its ilk. See ;; https://github.com/rust-lang/rust-mode/issues/288. - rustic-match-angle-brackets (not (featurep! :editor evil))) + rustic-match-angle-brackets (not (featurep! :editor evil)) + ;; `rustic-setup-rls' uses `package-installed-p' to determine if + ;; lsp-mode/elgot are available. This breaks because Doom doesn't use + ;; package.el to begin with (and lazy loads it). This is already handled + ;; by the :tools lsp module, so... + rustic-lsp-setup-p nil) (add-hook 'rustic-mode-hook #'rainbow-delimiters-mode) - (defadvice! +rust--dont-install-packages-p (orig-fn &rest args) - :around #'rustic-setup-rls - (cl-letf (;; `rustic-setup-rls' uses `package-installed-p' to determine if - ;; lsp-mode/elgot are available. This breaks because Doom doesn't - ;; use package.el to begin with (and lazy loads it). - ((symbol-function #'package-installed-p) - (lambda (pkg) - (require pkg nil t))) - ;; If lsp/elgot isn't available, it attempts to install lsp-mode - ;; via package.el. Doom manages its own dependencies so we disable - ;; that behavior. - ((symbol-function #'rustic-install-rls-client-p) - (lambda (&rest _) - (message "No RLS server running")))) - (apply orig-fn args)))) + (when (featurep! +lsp) + (add-hook 'rustic-mode-local-vars-hook #'lsp!))) + + +(use-package! racer + :unless (featurep! +lsp) + :hook (rustic-mode . racer-mode) + :config + (set-lookup-handlers! 'rustic-mode + :definition '(racer-find-definition :async t) + :documentation '+rust-racer-lookup-documentation)) ;; ;;; Tools (use-package! cargo - :after rust-mode + :after rustic-mode :config - (defvar +rust-keymap - (if (boundp 'rustic-mode-map) - rustic-mode-map - rust-mode-map)) - (map! :map +rust-keymap + (map! :map rustic-mode-map :localleader (:prefix ("b" . "build") :desc "cargo add" "a" #'cargo-process-add diff --git a/modules/lang/rust/packages.el b/modules/lang/rust/packages.el index 250637459..05fab0577 100644 --- a/modules/lang/rust/packages.el +++ b/modules/lang/rust/packages.el @@ -1,9 +1,7 @@ ;; -*- no-byte-compile: t; -*- ;;; lang/rust/packages.el -(when EMACS26+ - (package! rustic)) -(package! rust-mode) +(package! rustic) (unless (featurep! +lsp) (package! racer)) diff --git a/modules/lang/web/+css.el b/modules/lang/web/+css.el index 1ef7b6d03..7f8162814 100644 --- a/modules/lang/web/+css.el +++ b/modules/lang/web/+css.el @@ -28,12 +28,6 @@ (after! css-mode ;; css-mode hooks apply to scss and less-css modes (add-hook 'css-mode-hook #'rainbow-delimiters-mode) - (set-company-backend! '(css-mode scss-mode) - (if EMACS26+ - ;; DEPRECATED css-mode's built in completion is superior in 26+ - 'company-capf - 'company-css)) - (map! :localleader :map scss-mode-map "b" #'+css/scss-build diff --git a/modules/lang/web/+html.el b/modules/lang/web/+html.el index 0444fb481..6869b89c0 100644 --- a/modules/lang/web/+html.el +++ b/modules/lang/web/+html.el @@ -41,12 +41,7 @@ (setcdr alist (cl-loop for pair in (cdr alist) unless (string-match-p "^[a-z-]" (cdr pair)) - collect (cons (car pair) - ;; TODO Replace with `string-trim-right' (Emacs 26+) - (let ((string (cdr pair))) - (if (string-match "\\(?:>\\|]\\|}\\)+\\'" string) - (replace-match "" t t string) - string)))))) + collect (cons (car pair) (string-trim-right (cdr pair)))))) (delq! nil web-mode-engines-auto-pairs)) (map! :map web-mode-map diff --git a/modules/lang/web/packages.el b/modules/lang/web/packages.el index 2efb16915..d0933030a 100644 --- a/modules/lang/web/packages.el +++ b/modules/lang/web/packages.el @@ -12,7 +12,7 @@ ;; +css.el (package! css-mode :built-in t) -(package! less-css-mode :built-in (not (version< emacs-version "26.1"))) +(package! less-css-mode :built-in t) (package! sass-mode) (package! stylus-mode) diff --git a/modules/tools/flycheck/config.el b/modules/tools/flycheck/config.el index 1c9fb0f5a..dc77b4790 100644 --- a/modules/tools/flycheck/config.el +++ b/modules/tools/flycheck/config.el @@ -63,7 +63,6 @@ errors.") (use-package! flycheck-posframe - :when EMACS26+ :when (featurep! +childframe) :defer t :init (add-hook 'flycheck-mode-hook #'+flycheck-init-popups-h) diff --git a/modules/tools/flycheck/packages.el b/modules/tools/flycheck/packages.el index e5e2f0885..b9bcdfd82 100644 --- a/modules/tools/flycheck/packages.el +++ b/modules/tools/flycheck/packages.el @@ -3,5 +3,5 @@ (package! flycheck) (package! flycheck-popup-tip) -(when (and EMACS26+ (featurep! +childframe)) +(when (featurep! +childframe) (package! flycheck-posframe)) diff --git a/modules/tools/lsp/config.el b/modules/tools/lsp/config.el index e37dcf8dd..c31591ff9 100644 --- a/modules/tools/lsp/config.el +++ b/modules/tools/lsp/config.el @@ -106,8 +106,7 @@ Also logs the resolved project root, if found." (defun +lsp-init-ui-flycheck-or-flymake-h () "Sets up flymake-mode or flycheck-mode, depending on `lsp-prefer-flymake'." (cond ((eq :none lsp-prefer-flymake)) - ((and (not (version< emacs-version "26.1")) - lsp-prefer-flymake) + (lsp-prefer-flymake (lsp--flymake-setup)) ((require 'flycheck nil t) (require 'lsp-ui-flycheck) diff --git a/modules/tools/pass/config.el b/modules/tools/pass/config.el index 59094000b..4017d6f56 100644 --- a/modules/tools/pass/config.el +++ b/modules/tools/pass/config.el @@ -36,5 +36,5 @@ ;; Is built into Emacs 26+ -(when (and EMACS26+ (featurep! +auth)) +(when (featurep! +auth) (auth-source-pass-enable)) diff --git a/modules/ui/doom/config.el b/modules/ui/doom/config.el index 749757728..f95c73a0d 100644 --- a/modules/ui/doom/config.el +++ b/modules/ui/doom/config.el @@ -61,8 +61,8 @@ ;; On Emacs 26+, when point is on the last line and solaire-mode is remapping ;; the hl-line face, hl-line's highlight bleeds into the rest of the window - ;; after eob. - (when EMACS26+ + ;; after eob. On Emacs 27 this no longer happens. + (unless EMACS27+ (defun +doom--line-range-fn () (cons (line-beginning-position) (cond ((let ((eol (line-end-position))) diff --git a/modules/ui/modeline/autoload.el b/modules/ui/modeline/autoload.el index 514a6d245..7162bd069 100644 --- a/modules/ui/modeline/autoload.el +++ b/modules/ui/modeline/autoload.el @@ -28,9 +28,7 @@ Meant for `doom-change-font-size-hook'." xlfd-regexp-pixelsize-subnum))) (scale (frame-parameter nil 'font-scale))) (setq doom-modeline-height (+ default-height (* scale doom-font-increment)))) - (setq doom-modeline-height default-height)) - ;; already has a variable watcher in Emacs 26+ - (unless EMACS26+ (doom-modeline-refresh-bars)))) + (setq doom-modeline-height default-height)))) ;;;###autoload (defun +modeline-update-env-in-all-windows-h (&rest _) diff --git a/modules/ui/popup/autoload/popup.el b/modules/ui/popup/autoload/popup.el index 24202a760..30159d815 100644 --- a/modules/ui/popup/autoload/popup.el +++ b/modules/ui/popup/autoload/popup.el @@ -139,11 +139,6 @@ default window parameters for popup windows, clears leftover transient timers and enables `+popup-buffer-mode'." (with-selected-window window (setq alist (delq (assq 'actions alist) alist)) - (when (and alist +popup--populate-wparams) - ;; Emacs 26+ will automatically map the window-parameters alist entry to - ;; the popup window, so we need this for Emacs 25.x users - (dolist (param (cdr (assq 'window-parameters alist))) - (set-window-parameter window (car param) (cdr param)))) (set-window-parameter window 'popup t) (set-window-parameter window 'split-window #'+popup--split-window) (set-window-parameter window 'delete-window #'+popup--delete-window) @@ -617,94 +612,3 @@ This advice ensures backwards compatibility for Emacs <= 26 users." (when (and (windowp window) display-buffer-mark-dedicated) (set-window-dedicated-p window display-buffer-mark-dedicated)) window)) - -;; DEPRECATED -(unless EMACS26+ - (defvar window-sides-reversed nil) - - (defun window--sides-reverse-on-frame-p (frame) - "Return non-nil when side windows should appear reversed on FRAME. -This uses some heuristics to guess the user's intentions when the -selected window of FRAME is a side window ." - (cond - ;; Reverse when `window-sides-reversed' is t. Do not reverse when - ;; `window-sides-reversed' is nil. - ((memq window-sides-reversed '(nil t)) - window-sides-reversed) - ;; Reverse when FRAME's selected window shows a right-to-left buffer. - ((let ((window (frame-selected-window frame))) - (when (and (not (window-parameter window 'window-side)) - (or (not (window-minibuffer-p window)) - (setq window (minibuffer-selected-window)))) - (with-current-buffer (window-buffer window) - (eq bidi-paragraph-direction 'right-to-left))))) - ;; Reverse when FRAME's `window-sides-main-selected-window' parameter - ;; specifies a live window showing a right-to-left buffer. - ((let ((window (frame-parameter - frame 'window-sides-main-selected-window))) - (when (window-live-p window) - (with-current-buffer (window-buffer window) - (eq bidi-paragraph-direction 'right-to-left))))) - ;; Reverse when all windows in FRAME's main window show right-to-left - ;; buffers. - (t - (catch 'found - (walk-window-subtree - (lambda (window) - (with-current-buffer (window-buffer window) - (when (eq bidi-paragraph-direction 'left-to-right) - (throw 'found nil)))) - (window-main-window frame)) - t)))) - - (defun window--make-major-side-window (buffer side slot &optional alist) - "Display BUFFER in a new major side window on the selected frame. -SIDE must be one of `left', `top', `right' or `bottom'. SLOT -specifies the slot to use. ALIST is an association list of -symbols and values as passed to `display-buffer-in-side-window'. -Return the new window, nil if its creation failed. - -This is an auxiliary function of `display-buffer-in-side-window' -and may be called only if no window on SIDE exists yet." - (let* ((left-or-right (memq side '(left right))) - (next-to (window--make-major-side-window-next-to side)) - (on-side (cond - ((eq side 'top) 'above) - ((eq side 'bottom) 'below) - (t side))) - (window--sides-inhibit-check t) - ;; The following two bindings will tell `split-window' to take - ;; the space for the new window from the selected frame's main - ;; window and not make a new parent window unless needed. - (window-combination-resize 'side) - (window-combination-limit nil) - (window (ignore-errors (split-window next-to nil on-side)))) - (when window - ;; Initialize `window-side' parameter of new window to SIDE and - ;; make that parameter persistent. - (set-window-parameter window 'window-side side) - (add-to-list 'window-persistent-parameters '(window-side . writable)) - ;; Install `window-slot' parameter of new window and make that - ;; parameter persistent. - (set-window-parameter window 'window-slot slot) - (add-to-list 'window-persistent-parameters '(window-slot . writable)) - ;; Auto-adjust height/width of new window unless a size has been - ;; explicitly requested. - (unless (if left-or-right - (cdr (assq 'window-width alist)) - (cdr (assq 'window-height alist))) - (setq alist - (cons - (cons - (if left-or-right 'window-width 'window-height) - (/ (window-total-size (frame-root-window) left-or-right) - ;; By default use a fourth of the size of the frame's - ;; root window. - 4)) - alist))) - (with-current-buffer buffer - (setq window--sides-shown t)) - ;; Install BUFFER in new window and return WINDOW. - (window--display-buffer buffer window 'window alist 'side)))) - - (advice-add #'window--sides-check :override #'ignore)) diff --git a/modules/ui/popup/config.el b/modules/ui/popup/config.el index 3381554ee..f34a49835 100644 --- a/modules/ui/popup/config.el +++ b/modules/ui/popup/config.el @@ -24,7 +24,6 @@ Modifying this has no effect, unless done before ui/popup loads.") "Size of the margins to give popup windows. Set this to nil to disable margin adjustment.") -(defvar +popup--populate-wparams (not EMACS26+)) (defvar +popup--inhibit-transient nil) (defvar +popup--inhibit-select nil) (defvar +popup--old-display-buffer-alist nil) From 873fc5c0db4876d9e1f347fa6cbd2a3a1933df69 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 7 Nov 2019 15:59:56 -0500 Subject: [PATCH 015/129] Rewrite core-cli Highlights: - 'doom purge' now purges builds, elpa packages, and repos by default. Regrafting repos is now opt-in with the -g/--regraft switches. Negation flags have been added for elpa/repos: -e/--no-elpa and -r/--no-repos. - Removed 'doom rebuild' (it is now just 'doom build' or 'doom b'). - Removed 'doom build's -f flag, this is now the default. Added the -r flag instead, which only builds packages that need rebuilding. - 'doom update' now updates packages synchronously, but produces more informative output about the updating process. - Straight can now prompt in batch mode, which resolves a lot of issues with 'doom update' (and 'doom upgrade') freezing indefinitely or throwing repo branch errors. - 'bin/doom's switches are now positional. Switches aimed at `bin/doom` must precede any subcommands. e.g. Do: 'doom -yd upgrade' Don't do: 'doom upgrade -yd' - Moved 'doom doctor' from bin/doom-doctor to core/cli/doctor, and integrated core/doctor.el into it, as to avoid naming conflicts between it and Emacs doctor. - The defcli! macro now has a special syntax for declaring flags, their arguments and descriptions. Addresses #1981, #1925, #1816, #1721, #1322 --- bin/doom | 171 +++++++-------- bin/doom-doctor | 257 ---------------------- core/autoload/cli.el | 86 -------- core/cli/autoloads.el | 149 ++++++------- core/cli/byte-compile.el | 15 +- core/cli/debug.el | 21 +- core/cli/doctor.el | 209 ++++++++++++++++++ core/cli/env.el | 145 ++++++------ core/cli/help.el | 101 +++++++++ core/cli/install.el | 62 +++--- core/cli/packages.el | 464 ++++++++++++--------------------------- core/cli/test.el | 115 ++++++---- core/cli/upgrade.el | 31 +-- core/core-cli.el | 342 +++++++++++++++++------------ core/core.el | 33 ++- core/doctor.el | 61 ----- 16 files changed, 996 insertions(+), 1266 deletions(-) delete mode 100755 bin/doom-doctor create mode 100644 core/cli/doctor.el create mode 100644 core/cli/help.el delete mode 100644 core/doctor.el diff --git a/bin/doom b/bin/doom index bd381e5ab..834e56afd 100755 --- a/bin/doom +++ b/bin/doom @@ -1,105 +1,79 @@ #!/usr/bin/env sh -":"; ( echo "$EMACS" | grep -q "term" ) && EMACS=emacs || EMACS=${EMACS:-emacs} # -*-emacs-lisp-*- -":"; command -v $EMACS >/dev/null || { >&2 echo "Emacs isn't installed"; exit 1; } -":"; 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 Doom. Check your PATH"; echo; exit 2 ;; esac -":"; DOOMBASE=$(dirname "$0")/.. -":"; [ "$1" = -d ] || [ "$1" = --debug ] && { shift; export DEBUG=1; } -":"; [ "$1" = doc ] || [ "$1" = doctor ] && { cd "$DOOMBASE"; shift; exec $EMACS --script bin/doom-doctor "$@"; exit 0; } -":"; [ "$1" = run ] && { cd "$DOOMBASE"; shift; exec $EMACS -q --no-splash -l bin/doom "$@"; exit 0; } -":"; exec $EMACS --script "$0" -- "$@" -":"; exit 0 +:; ( echo "$EMACS" | grep -q "term" ) && EMACS=emacs || EMACS=${EMACS:-emacs} # -*-emacs-lisp-*- +:; command -v $EMACS >/dev/null || { >&2 echo "Can't find emacs in your PATH"; exit 1; } +:; VERSION=$($EMACS --version | head -n1) +:; case "$VERSION" in *\ 2[0-5].[0-9]) echo "Detected Emacs $VERSION"; echo "Doom only supports Emacs 26.1 and newer"; echo; exit 2 ;; esac +:; DOOMBASE="$(dirname "$0")/.." +:; [ "$1" = -d ] || [ "$1" = --debug ] && { shift; export DEBUG=1; } +:; [ "$1" = run ] && { cd "$DOOMBASE"; shift; exec $EMACS -q --no-splash -l bin/doom "$@"; exit 0; } +:; exec $EMACS --script "$0" -- "$@" +:; exit 0 -(defconst user-emacs-directory - (or (getenv "EMACSDIR") - (expand-file-name "../" (file-name-directory (file-truename load-file-name))))) +(let* ((loaddir (file-name-directory (file-truename load-file-name))) + (emacsdir (getenv "EMACSDIR")) + (user-emacs-directory (or emacsdir (expand-file-name "../" loaddir))) + (load-prefer-newer t)) -(defun usage () - (with-temp-buffer - (insert (format! "%s %s [COMMAND] [ARGS...]\n" - (bold "Usage:") - (file-name-nondirectory load-file-name)) - "\n" - "A command line interface for managing Doom Emacs; including\n" - "package management, diagnostics, unit tests, and byte-compilation.\n" - "\n" - "This tool also makes it trivial to launch Emacs out of a different\n" - "folder or with a different private module.\n" - "\n" - (format! (bold "Example:\n")) - " doom install\n" - " doom help update\n" - " doom compile :core lang/php lang/python\n" - " doom run\n" - " doom run -nw file.txt file2.el\n" - " doom run -p ~/.other.doom.d -e ~/.other.emacs.d -nw file.txt\n" - "\n" - (format! (bold "Options:\n")) - " -h --help\t\tSame as help command\n" - " -d --debug\t\tTurns on doom-debug-mode (and debug-on-error)\n" - " -e --emacsd DIR\tUse the emacs config at DIR (e.g. ~/.emacs.d)\n" - " -i --insecure\t\tDisable TLS/SSL validation (not recommended)\n" - " -l --local DIR\tUse DIR as your local storage directory\n" - " -p --private DIR\tUse the private module at DIR (e.g. ~/.doom.d)\n" - " -y --yes\t\tAuto-accept all confirmation prompts\n\n") - (princ (buffer-string))) - (doom--dispatch-help)) + (push (expand-file-name "core" user-emacs-directory) load-path) + (require 'core) + (require 'core-cli) -;; -(let ((args (cdr (cdr (cdr command-line-args))))) - ;; Parse options - (while (ignore-errors (string-prefix-p "-" (car args))) - (pcase (pop args) - ((or "-h" "--help") - (push "help" args)) - ((or "-d" "--debug") - (setenv "DEBUG" "1") - (message "Debug mode on")) - ((or "-i" "--insecure") - (setenv "INSECURE" "1") - (message "Insecure mode on")) - ((or "-p" "--private") - (setq doom-private-dir (expand-file-name (concat (pop args) "/"))) - (setenv "DOOMDIR" doom-private-dir) - (message "DOOMDIR changed to %s" doom-private-dir) - (or (file-directory-p doom-private-dir) - (message "Warning: %s does not exist" - (abbreviate-file-name doom-private-dir)))) - ((or "-l" "--local") - (setq doom-local-dir (expand-file-name (concat (pop args) "/"))) - (setenv "DOOMLOCALDIR" doom-local-dir) - (message "DOOMLOCALDIR changed to %s" doom-local-dir)) - ((or "-e" "--emacsd") - (setq user-emacs-directory (expand-file-name (concat (pop args) "/"))) - (message "Emacs directory changed to %s" user-emacs-directory)) - ((or "-y" "--yes") - (setenv "YES" "1") - (message "Auto-yes mode on")))) + (defcli! :main + ((help-p ["-h" "--help"] "Same as help command") + (debug-p ["-d" "--debug"] "Turns on doom-debug-mode (and debug-on-error)") + (yes-p ["-y" "--yes"] "Auto-accept all confirmation prompts") + (emacsdir ["--emacsdir" dir] "Use the emacs config at DIR (e.g. ~/.emacs.d)") + (doomdir ["--doomdir" dir] "Use the private module at DIR (e.g. ~/.doom.d)") + (localdir ["--localdir" dir] "Use DIR as your local storage directory") + &optional command &rest args) + "A command line interface for managing Doom Emacs. - (unless (file-directory-p user-emacs-directory) - (error "%s does not exist" user-emacs-directory)) +Includes package management, diagnostics, unit tests, and byte-compilation. - ;; Bootstrap Doom - (if (not noninteractive) - (let ((doom-interactive-mode t)) - (load (expand-file-name "init.el" user-emacs-directory) - nil 'nomessage) - (doom-run-all-startup-hooks-h)) - (load (expand-file-name "core/core.el" user-emacs-directory) - nil 'nomessage) - (doom-initialize 'force-p) - (doom-initialize-modules) +This tool also makes it trivial to launch Emacs out of a different folder or +with a different private module." + :bare t + (when emacsdir + (setq user-emacs-directory (file-name-as-directory emacsdir)) + (print! (info "EMACSDIR=%s") localdir)) + (when doomdir + (setenv "DOOMDIR" doomdir) + (print! (info "DOOMDIR=%s") localdir)) + (when localdir + (setenv "DOOMLOCALDIR" localdir) + (print! (info "DOOMLOCALDIR=%s") localdir)) + (when debug-p + (setenv "DEBUG" "1") + (setq doom-debug-mode t) + (print! (info "Debug mode on"))) + (when yes-p + (setenv "YES" "1") + (setq doom-auto-accept t) + (print! (info "Auto-yes on"))) + (when help-p + (push command args) + (setq command "help")) - (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) - (setq argv nil) - (condition-case e - (doom-dispatch (car args) (cdr args)) + ;; Reload core in case any of the directories were changed. + (when (or emacsdir doomdir localdir) + (load! "core/core.el" user-emacs-directory)) + + (cond ((not noninteractive) + (print! "Doom launched out of %s (test mode)" (path user-emacs-directory)) + (load! "init.el" user-emacs-directory) + (doom-run-all-startup-hooks-h)) + + ((null command) + (doom-cli-execute "help")) + + ((condition-case e + (let ((start-time (current-time))) + (and (doom-cli-execute command args) + (terpri) + (print! (success "Finished! (%.4fs)") + (float-time + (time-subtract (current-time) + start-time))))) (user-error (print! (error "%s\n") (error-message-string e)) (print! (yellow "See 'doom help %s' for documentation on this command.") (car args))) @@ -116,5 +90,8 @@ "report, please include it!\n\n" "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)))))))) + " e.g. doom -d install 2>&1 | clipboard-program\n")) + (signal 'doom-error e))))))) + + (doom-cli-execute :main (cdr (member "--" argv))) + (setq argv nil)) diff --git a/bin/doom-doctor b/bin/doom-doctor deleted file mode 100755 index 701c22707..000000000 --- a/bin/doom-doctor +++ /dev/null @@ -1,257 +0,0 @@ -#!/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 (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 -;; that uses a series of simple heuristics to diagnose common issues on your -;; system. Issues that could intefere with Doom Emacs. -;; -;; Doom modules may optionally have a doctor.el file to run their own heuristics -;; in. Doctor scripts may run in versions of Emacs as old as Emacs 23, so make -;; no assumptions about what's available in the standard library (e.g. avoid -;; cl/cl-lib, subr-x, map, seq, etc). - - -;; Ensure Doom doctor always runs out of the current Emacs directory (optionally -;; specified by the EMACSDIR envvar) -(setq user-emacs-directory - (or (getenv "EMACSDIR") - (expand-file-name "../" (file-name-directory (file-truename load-file-name)))) - default-directory user-emacs-directory) - -(unless (file-directory-p user-emacs-directory) - (error "Couldn't find a Doom config!")) -(unless noninteractive - (error "This script must not be run from an interactive session.")) -(when (getenv "DEBUG") - (setq debug-on-error t)) - -(require 'subr-x) -(require 'pp) -(load (expand-file-name "core/autoload/format" user-emacs-directory) nil t) - - -(defvar doom-init-p nil) -(defvar doom-warnings 0) -(defvar doom-errors 0) - - -;;; Helpers - -(defun sh (cmd &rest args) - (ignore-errors - (string-trim-right - (shell-command-to-string (if args (apply #'format cmd args) cmd))))) - -(defun elc-check-dir (dir) - (dolist (file (directory-files-recursively dir "\\.elc$")) - (when (file-newer-than-file-p (concat (file-name-sans-extension file) ".el") - file) - (warn! "%s is out-of-date" (abbreviate-file-name file))))) - -(defmacro assert! (condition message &rest args) - `(unless ,condition - (error! ,message ,@args))) - - -;;; Logging - -(defvar indent 0) -(defvar prefix "") - -(defmacro msg! (msg &rest args) - `(print! - (indent indent - (format (concat prefix ,msg) - ,@args)))) - -(defmacro error! (&rest args) - `(progn (msg! (red ,@args)) - (setq doom-errors (+ doom-errors 1)))) -(defmacro warn! (&rest args) - `(progn (msg! (yellow ,@args)) - (setq doom-warnings (+ doom-warnings 1)))) -(defmacro success! (&rest args) `(msg! (green ,@args))) -(defmacro section! (&rest args) `(msg! (bold (blue ,@args)))) - -(defmacro explain! (&rest args) - `(msg! (indent (+ indent 2) (autofill ,@args)))) - - -;;; Polyfills -;; early versions of emacs won't have this -(unless (fboundp 'string-match-p) - (defun string-match-p (regexp string &optional start) - (save-match-data - (string-match regexp string &optional start)))) - -;; subr-x don't exist in older versions of Emacs -(unless (fboundp 'string-trim-right) - (defsubst string-trim-right (string &optional regexp) - (if (string-match (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'") string) - (replace-match "" t t string) - string))) - - -;; -;;; Basic diagnostics - -(msg! (bold "Doom Doctor")) -(msg! "Emacs v%s" emacs-version) -(msg! "Doom v%s (%s)" - (or (let ((core-file (expand-file-name "core/core.el" user-emacs-directory))) - (and (file-exists-p core-file) - (ignore-errors - (with-temp-buffer - (insert-file-contents-literally core-file) - (goto-char (point-min)) - (when (search-forward "doom-version" nil t) - (forward-char) - (sexp-at-point)))))) - "???") - (if (and (executable-find "git") - (file-directory-p (expand-file-name ".git" user-emacs-directory))) - (sh "git log -1 --format=\"%D %h %ci\"") - "n/a")) -(msg! "shell: %s%s" - (getenv "SHELL") - (if (equal (getenv "SHELL") (sh "echo $SHELL")) - "" - (red " (mismatch)"))) -(when (boundp 'system-configuration-features) - (msg! "Compiled with:\n%s" (indent 2 system-configuration-features))) -(msg! "uname -msrv:\n%s\n" (indent 2 (sh "uname -msrv"))) - - -;; -;;; Check if Emacs is set up correctly - -(section! "Checking Emacs") -(let ((indent 2)) - (section! "Checking your Emacs version is 25.3 or newer...") - (when (version< emacs-version "25.3") - (error! "Important: Emacs %s detected [%s]" emacs-version (executable-find "emacs")) - (explain! - "DOOM only supports >= 25.3. Perhaps your PATH wasn't set up properly." - (when (eq system-type 'darwin) - (concat "\nMacOS users should use homebrew (https://brew.sh) to install Emacs\n" - " brew install emacs --with-modules --with-imagemagick --with-cocoa")))) - - (section! "Checking for Emacs config conflicts...") - (when (file-exists-p "~/.emacs") - (warn! "Detected an ~/.emacs file, which may prevent Doom from loading") - (explain! "If Emacs finds an ~/.emacs file, it will ignore ~/.emacs.d, where Doom is " - "typically installed. If you're seeing a vanilla Emacs splash screen, this " - "may explain why. If you use Chemacs, you may ignore this warning.")) - - (section! "Checking for private config conflicts...") - (let ((xdg-dir (concat (or (getenv "XDG_CONFIG_HOME") - "~/.config") - "/doom/")) - (doom-dir (or (getenv "DOOMDIR") - "~/.doom.d/"))) - (when (and (not (file-equal-p xdg-dir doom-dir)) - (file-directory-p xdg-dir) - (file-directory-p doom-dir)) - (warn! "Detected two private configs, in %s and %s" - (abbreviate-file-name xdg-dir) - doom-dir) - (explain! "The second directory will be ignored, as it has lower precedence."))) - - (section! "Checking for stale elc files...") - (elc-check-dir user-emacs-directory)) - - -;; -;;; Check if system environment is set up correctly - -(section! "Checking your system...") -(let ((indent 2)) - ;; on windows? - (when (memq system-type '(windows-nt ms-dos cygwin)) - (warn! "Warning: Windows detected") - (explain! "DOOM was designed for MacOS and Linux. Expect a bumpy ride!"))) - - -;; -;;; Check if Doom Emacs is set up correctly - -(condition-case-unless-debug ex - (let ((after-init-time (current-time)) - (doom-format-backend 'ansi) - noninteractive) - (section! "Checking DOOM Emacs...") - (load (concat user-emacs-directory "core/core.el") nil t) - (unless (file-directory-p doom-private-dir) - (error "No DOOMDIR was found, did you run `doom install` yet?")) - - (let ((indent 2)) - ;; Make sure Doom is initialized and loaded - (doom-initialize 'force) - (doom-initialize-core) - (success! "Initialized Doom Emacs %s" doom-version) - - (doom-initialize-modules) - (if (hash-table-p doom-modules) - (success! "Initialized %d modules" (hash-table-count doom-modules)) - (warn! "Failed to load any modules. Do you have an private init.el?")) - - (doom-initialize-packages) - (success! "Initialized %d packages" (length doom-packages)) - - (section! "Checking Doom core for irregularities...") - (let ((indent (+ indent 2))) - (load (expand-file-name "doctor.el" doom-core-dir) nil 'nomessage)) - - (section! "Checking for stale elc files in your DOOMDIR...") - (when (file-directory-p doom-private-dir) - (let ((indent (+ indent 2))) - (elc-check-dir doom-private-dir))) - - (when doom-modules - (section! "Checking your enabled modules...") - (let ((indent (+ indent 2))) - (advice-add #'require :around #'doom-shut-up-a) - (maphash - (lambda (key plist) - (let ((prefix (format! (bold "(%s %s) " (car key) (cdr key))))) - (condition-case-unless-debug ex - (let ((doctor-file (doom-module-path (car key) (cdr key) "doctor.el")) - (packages-file (doom-module-path (car key) (cdr key) "packages.el"))) - (cl-loop for name in (let (doom-packages - doom-disabled-packages) - (load packages-file 'noerror 'nomessage) - (mapcar #'car doom-packages)) - unless (or (doom-package-get name :disable) - (eval (doom-package-get name :ignore)) - (doom-package-built-in-p name) - (doom-package-installed-p name)) - do (error! "%s is not installed" name)) - (load doctor-file 'noerror 'nomessage)) - (file-missing (error! "%s" (error-message-string ex))) - (error (error! "Syntax error: %s" ex))))) - doom-modules))))) - (error - (warn! "Attempt to load DOOM failed\n %s\n" - (or (cdr-safe ex) (car ex))) - (setq doom-modules nil))) - - -;; -;;; Final report - -(message "") -(dolist (msg (list (list doom-errors "error" 'red) - (list doom-warnings "warning" 'yellow))) - (when (> (car msg) 0) - (msg! (color (nth 2 msg) - (if (= (car msg) 1) - "There is %d %s!" - "There are %d %ss!") - (car msg) (nth 1 msg))))) - -(when (and (zerop doom-errors) - (zerop doom-warnings)) - (success! "Everything seems fine, happy Emacs'ing!")) diff --git a/core/autoload/cli.el b/core/autoload/cli.el index f547a289b..0c455f741 100644 --- a/core/autoload/cli.el +++ b/core/autoload/cli.el @@ -124,89 +124,3 @@ Warning: freezes indefinitely on any stdin prompt." (sit-for 0.1)) (process-exit-status process)) (string-trim (buffer-string))))) - -(defun doom--cli-normalize (args specs) - (let* ((args (cl-remove-if-not #'stringp args)) - (optspec (cl-remove-if-not #'listp specs)) - (argspec (cl-remove-if #'listp specs)) - (options (mapcar #'list (mapcar #'car-safe optspec))) - extra - arguments) - (dolist (spec optspec) - (setf (nth 1 spec) (doom-enlist (nth 1 spec)))) - (while args - (let ((arg (pop args))) - (cl-check-type arg string) - (if (not (string-prefix-p "-" arg)) - (push arg arguments) - (if-let (specs (cl-remove-if-not - (if (string-prefix-p "--" arg) - (doom-partial #'member arg) - (lambda (flags) - (cl-loop for switch in (split-string (string-remove-prefix "-" arg) "" t) - if (member (concat "-" switch) flags) - return t))) - optspec - :key #'cadr)) - (pcase-dolist (`(,sym ,flags ,type) specs) - (setf (alist-get sym options) - (list - (let ((value (if type (pop args)))) - (pcase type - (`&string value) - (`&int `(truncate (read ,value))) - (`&float `(float (read ,value))) - (`&path `(expand-file-name ,value)) - (`&directory - `(let ((path (expand-file-name ,value))) - (unless (file-directory-p path) - (error "Directory does not exist: %s" path)) - path)) - (`&file - `(let ((path (expand-file-name ,value))) - (unless (file-exists-p path) - (error "File does not exist: %s" path)) - path)) - (`&sexp `(read ,value)) - ((or `nil `t) arg) - (_ (error "Not a valid type: %S" type))))))) - (push arg extra))))) - (list optspec (nreverse options) - argspec (nreverse arguments)))) - -;;;###autoload -(defun doom-cli-getopts (args specs) - "TODO" - (cl-destructuring-bind (optspec options argspec arguments) - (doom--cli-normalize args specs) - (let ((i 0) - optional-p - noerror-p) - (cl-dolist (spec argspec) - (cond ((eq spec '&rest) - (push (list (cadr (member '&rest specs)) - `(quote - ,(reverse - (butlast (reverse arguments) i)))) - options) - (cl-return)) - ((eq spec '&all) - (push (list (cadr (member '&all specs)) - `(quote ,args)) - options)) - ((eq spec '&noerror) (setq noerror-p t)) - ((eq spec '&optional) (setq optional-p t)) - ((and (>= i (length arguments)) (not optional-p)) - (signal 'wrong-number-of-arguments - (list argspec (length arguments)))) - ((push (list spec (nth i arguments)) options) - (cl-incf i))))) - (nreverse options))) - -;;;###autoload -(defmacro let-cliopts! (args spec &rest body) - "Run BODY with command line ARGS parsed according to SPEC." - (declare (indent 2)) - `(eval (append (list 'let (doom-cli-getopts ,args ',spec)) - (quote ,body)) - t)) diff --git a/core/cli/autoloads.el b/core/cli/autoloads.el index cdd1000e6..1e5906cf2 100644 --- a/core/cli/autoloads.el +++ b/core/cli/autoloads.el @@ -1,14 +1,11 @@ ;;; core/cli/autoloads.el -*- lexical-binding: t; -*- -(require 'autoload) - - (defvar doom-autoload-excluded-packages '("gh") "Packages that have silly or destructive autoload files that try to load everyone in the universe and their dog, causing errors that make babies cry. No one wants that.") -;; external variables +;; externs (defvar autoload-timestamps) (defvar generated-autoload-load-name) (defvar generated-autoload-file) @@ -27,15 +24,14 @@ 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)) + (doom-cli-reload-autoloads nil 'force)) ;; ;;; Helpers -(defun doom-delete-autoloads-file (file) +(defun doom--cli-delete-autoloads-file (file) "Delete FILE (an autoloads file) and accompanying *.elc file, if any." (cl-check-type file string) (when (file-exists-p file) @@ -47,29 +43,29 @@ It also caches `load-path', `Info-directory-list', `doom-disabled-packages', (ignore-errors (delete-file (byte-compile-dest-file file))) t)) -(defun doom--warn-refresh-session-h () +(defun doom--cli-warn-refresh-session-h () (message "Restart or reload Doom Emacs for changes to take effect:\n") (message " M-x doom/restart-and-restore") (message " M-x doom/restart") (message " M-x doom/reload")) -(defun doom--byte-compile-file (file) +(defun doom--cli-byte-compile-file (file) (let ((byte-compile-warnings (if doom-debug-mode byte-compile-warnings)) (byte-compile-dynamic t) (byte-compile-dynamic-docstrings t)) (condition-case-unless-debug e (when (byte-compile-file file) - (prog1 (load file 'noerror 'nomessage) + (prog1 (load file 'noerror 'nomessage 'nosuffix) (when noninteractive - (add-hook 'doom-cli-post-success-execute-hook #'doom--warn-refresh-session-h)))) + (add-hook 'doom-cli-post-success-execute-hook #'doom--cli-warn-refresh-session-h)))) ((debug error) (let ((backup-file (concat file ".bk"))) (print! (warn "Copied backup to %s") (relpath backup-file)) (copy-file file backup-file 'overwrite)) - (doom-delete-autoloads-file file) + (doom--cli-delete-autoloads-file file) (signal 'doom-autoload-error (list file e)))))) -(defun doom-reload-autoloads (&optional file force-p) +(defun doom-cli-reload-autoloads (&optional file force-p) "Reloads FILE (an autoload file), if it needs reloading. FILE should be one of `doom-autoload-file' or `doom-package-autoload-file'. If @@ -80,23 +76,23 @@ even if it doesn't need reloading!" (signal 'wrong-type-argument (list 'stringp file))) (if (stringp file) (cond ((file-equal-p file doom-autoload-file) - (doom-reload-core-autoloads force-p)) + (doom-cli-reload-core-autoloads force-p)) ((file-equal-p file doom-package-autoload-file) - (doom-reload-package-autoloads force-p)) + (doom-cli-reload-package-autoloads force-p)) ((error "Invalid autoloads file: %s" file))) - (doom-reload-core-autoloads force-p) - (doom-reload-package-autoloads force-p))) + (doom-cli-reload-core-autoloads force-p) + (doom-cli-reload-package-autoloads force-p))) ;; ;;; Doom autoloads -(defun doom--generate-header (func) +(defun doom--cli-generate-header (func) (goto-char (point-min)) (insert ";; -*- lexical-binding:t; -*-\n" ";; This file is autogenerated by `" (symbol-name func) "', DO NOT EDIT !!\n\n")) -(defun doom--generate-autoloads (targets) +(defun doom--cli-generate-autoloads (targets) (let ((n 0)) (dolist (file targets) (insert @@ -115,7 +111,7 @@ even if it doesn't need reloading!" "Scanned %d file(s)") n))) -(defun doom--expand-autoload-paths (&optional allow-internal-paths) +(defun doom--cli-expand-autoload-paths (&optional allow-internal-paths) (let ((load-path ;; NOTE With `doom-private-dir' in `load-path', Doom autoloads files ;; will be unable to declare autoloads for the built-in autoload.el @@ -140,7 +136,7 @@ even if it doesn't need reloading!" path) t t nil 1))))) -(defun doom--generate-autodefs-1 (path &optional member-p) +(defun doom--cli-generate-autodefs-1 (path &optional member-p) (let (forms) (while (re-search-forward "^;;;###autodef *\\([^\n]+\\)?\n" nil t) (let* ((sexp (sexp-at-point)) @@ -202,7 +198,7 @@ even if it doesn't need reloading!" (member-p (push sexp forms))))) forms)) -(defun doom--generate-autodefs (targets enabled-targets) +(defun doom--cli-generate-autodefs (targets enabled-targets) (goto-char (point-max)) (search-backward ";;;***" nil t) (save-excursion (insert "\n")) @@ -210,17 +206,17 @@ even if it doesn't need reloading!" (insert (with-temp-buffer (insert-file-contents path) - (if-let (forms (doom--generate-autodefs-1 path (member path enabled-targets))) + (if-let (forms (doom--cli-generate-autodefs-1 path (member path enabled-targets))) (concat (mapconcat #'prin1-to-string (nreverse forms) "\n") "\n") ""))))) -(defun doom--cleanup-autoloads () +(defun doom--cli-cleanup-autoloads () (goto-char (point-min)) (when (re-search-forward "^;;\\(;[^\n]*\\| no-byte-compile: t\\)\n" nil t) (replace-match "" t t))) -(defun doom-reload-core-autoloads (&optional force-p) +(defun doom-cli-reload-core-autoloads (&optional force-p) "Refreshes `doom-autoload-file', if necessary (or if FORCE-P is non-nil). It scans and reads autoload cookies (;;;###autoload) in core/autoload/*.el, @@ -228,6 +224,7 @@ modules/*/*/autoload.el and modules/*/*/autoload/*.el, and generates `doom-autoload-file'. Run this whenever your `doom!' block, or a module autoload file, is modified." + (require 'autoload) (let* ((default-directory doom-emacs-dir) (doom-modules (doom-modules)) @@ -269,37 +266,38 @@ Run this whenever your `doom!' block, or a module autoload file, is modified." (ignore (print! (success "Skipping core autoloads, they are up-to-date")) (doom-load-autoloads-file doom-autoload-file)) - (print! (start "Regenerating core autoloads file")) - - (if (doom-delete-autoloads-file doom-autoload-file) + (if (doom--cli-delete-autoloads-file doom-autoload-file) (print! (success "Deleted old %s") (filename doom-autoload-file)) (make-directory (file-name-directory doom-autoload-file) t)) - (with-temp-file doom-autoload-file - (doom--generate-header 'doom-reload-core-autoloads) - (save-excursion - (doom--generate-autoloads active-targets) - (print! (success "Generated new autoloads.el"))) - ;; Replace autoload paths (only for module autoloads) with absolute - ;; paths for faster resolution during load and simpler `load-path' - (save-excursion - (doom--expand-autoload-paths 'allow-internal-paths) - (print! (success "Expanded module autoload paths"))) - ;; Generates stub definitions for functions/macros defined in disabled - ;; modules, so that you will never get a void-function when you use - ;; them. - (save-excursion - (doom--generate-autodefs targets (reverse active-targets)) - (print! (success "Generated autodefs"))) - ;; Remove byte-compile-inhibiting file variables so we can byte-compile - ;; the file, and autoload comments. - (doom--cleanup-autoloads) - (print! (success "Clean up autoloads"))) + (print! (start "Regenerating core autoloads file")) + (print-group! + (with-temp-file doom-autoload-file + (doom--cli-generate-header 'doom-cli-reload-core-autoloads) + (save-excursion + (doom--cli-generate-autoloads active-targets) + (print! (success "Generated new autoloads.el"))) + ;; Replace autoload paths (only for module autoloads) with absolute + ;; paths for faster resolution during load and simpler `load-path' + (save-excursion + (doom--cli-expand-autoload-paths 'allow-internal-paths) + (print! (success "Expanded module autoload paths"))) + ;; Generates stub definitions for functions/macros defined in disabled + ;; modules, so that you will never get a void-function when you use + ;; them. + (save-excursion + (doom--cli-generate-autodefs targets (reverse active-targets)) + (print! (success "Generated autodefs"))) + ;; Remove byte-compile-inhibiting file variables so we can byte-compile + ;; the file, and autoload comments. + (doom--cli-cleanup-autoloads) + (print! (success "Cleaned up autoloads")))) ;; Byte compile it to give the file a chance to reveal errors (and buy us a ;; few marginal performance boosts) (print! "> Byte-compiling %s..." (relpath doom-autoload-file)) - (when (doom--byte-compile-file doom-autoload-file) - (print! (success "Finished compiling %s") (relpath doom-autoload-file)))) + (when (doom--cli-byte-compile-file doom-autoload-file) + (print-group! + (print! (success "Compiled %s") (relpath doom-autoload-file))))) t))) @@ -346,7 +344,7 @@ served no purpose but to waste cycles." (goto-char (match-beginning 1)) (kill-sexp))) -(defun doom-reload-package-autoloads (&optional force-p) +(defun doom-cli-reload-package-autoloads (&optional force-p) "Compiles `doom-package-autoload-file' from the autoloads files of all installed packages. It also caches `load-path', `Info-directory-list', `doom-disabled-packages', `package-activated-list' and `auto-mode-alist'. @@ -355,6 +353,7 @@ Will do nothing if none of your installed packages have been modified. If FORCE-P (universal argument) is non-nil, regenerate it anyway. This should be run whenever your `doom!' block or update your packages." + (require 'autoload) (print! (start "Checking package autoloads file")) (print-group! (if (and (not force-p) @@ -381,37 +380,39 @@ This should be run whenever your `doom!' block or update your packages." (version-control 'never) (case-fold-search nil) ; reduce magic (autoload-timestamps nil)) - (print! (start "Regenerating package autoloads file")) - (if (doom-delete-autoloads-file doom-package-autoload-file) + (if (doom--cli-delete-autoloads-file doom-package-autoload-file) (print! (success "Deleted old %s") (filename doom-package-autoload-file)) (make-directory (file-name-directory doom-autoload-file) t)) - (with-temp-file doom-package-autoload-file - (doom--generate-header 'doom-reload-package-autoloads) + (print! (start "Regenerating package autoloads file")) + (print-group! + (with-temp-file doom-package-autoload-file + (doom--cli-generate-header 'doom-cli-reload-package-autoloads) - (save-excursion - ;; Cache important and expensive-to-initialize state here. - (doom--generate-var-cache) - (print! (success "Cached package state")) - ;; Concatenate the autoloads of all installed packages. - (doom--generate-package-autoloads) - (print! (success "Package autoloads included"))) + (save-excursion + ;; Cache important and expensive-to-initialize state here. + (doom--generate-var-cache) + (print! (success "Cached package state")) + ;; Concatenate the autoloads of all installed packages. + (doom--generate-package-autoloads) + (print! (success "Package autoloads included"))) - ;; Replace autoload paths (only for module autoloads) with absolute - ;; paths for faster resolution during load and simpler `load-path' - (save-excursion - (doom--expand-autoload-paths) - (print! (success "Expanded module autoload paths"))) + ;; Replace autoload paths (only for module autoloads) with absolute + ;; paths for faster resolution during load and simpler `load-path' + (save-excursion + (doom--cli-expand-autoload-paths) + (print! (success "Expanded module autoload paths"))) - ;; Remove `load-path' and `auto-mode-alist' modifications (most of them, - ;; at least); they are cached later, so all those membership checks are - ;; unnecessary overhead. - (doom--cleanup-package-autoloads) - (print! (success "Removed load-path/auto-mode-alist entries"))) + ;; Remove `load-path' and `auto-mode-alist' modifications (most of them, + ;; at least); they are cached later, so all those membership checks are + ;; unnecessary overhead. + (doom--cleanup-package-autoloads) + (print! (success "Removed load-path/auto-mode-alist entries")))) ;; Byte compile it to give the file a chance to reveal errors (and buy us a ;; few marginal performance boosts) (print! (start "Byte-compiling %s...") (relpath doom-package-autoload-file)) - (when (doom--byte-compile-file doom-package-autoload-file) - (print! (success "Finished compiling %s") (relpath doom-package-autoload-file))))) + (when (doom--cli-byte-compile-file doom-package-autoload-file) + (print-group! + (print! (success "Compiled %s") (relpath doom-package-autoload-file)))))) t)) diff --git a/core/cli/byte-compile.el b/core/cli/byte-compile.el index 94c6e69c5..0ca58076e 100644 --- a/core/cli/byte-compile.el +++ b/core/cli/byte-compile.el @@ -1,6 +1,8 @@ ;;; core/cli/byte-compile.el -*- lexical-binding: t; -*- -(defcli! (compile c) (&rest targets) +(defcli! (compile c) + ((recompile-p ["-r" "--recompile"]) + &rest targets) "Byte-compiles your config or selected modules. compile [TARGETS...] @@ -10,14 +12,11 @@ Accepts :core and :private as special arguments, which target Doom's core files and your private config files, respectively. To recompile your packages, use 'doom rebuild' instead." - (doom-byte-compile targets)) - -(defcli! (recompile rc) (&rest targets) - "Re-byte-compiles outdated *.elc files." - (doom-byte-compile targets 'recompile)) + (doom-cli-byte-compile targets recompile-p)) (defcli! clean () "Delete all *.elc files." + :bare t (doom-clean-byte-compiled-files)) @@ -31,7 +30,7 @@ and your private config files, respectively. To recompile your packages, use (not (equal (file-name-extension path) "el")) (member filename (list "packages.el" "doctor.el"))))) -(cl-defun doom-byte-compile (&optional modules recompile-p) +(cl-defun doom-cli-byte-compile (&optional modules recompile-p) "Byte compiles your emacs configuration. init.el is always byte-compiled by this. @@ -149,7 +148,7 @@ If RECOMPILE-P is non-nil, only recompile out-of-date files." (unless recompile-p (doom-clean-byte-compiled-files)) - (dolist (target (delete-dups targets)) + (dolist (target (delete-dups (delq nil targets))) (cl-incf (if (not (or (not recompile-p) (let ((elc-file (byte-compile-dest-file target))) diff --git a/core/cli/debug.el b/core/cli/debug.el index 278140fdc..d36f73dc6 100644 --- a/core/cli/debug.el +++ b/core/cli/debug.el @@ -1,21 +1,11 @@ ;;; core/cli/debug.el -*- lexical-binding: t; -*- -(load! "autoload/debug" doom-core-dir) - - ;; ;;; Commands -(defcli! info (&optional format) - "Output system info in markdown for bug reports. - -Will print in the following formats: - - --json - --md / --markdown - --lisp - -If no arguments are given, --raw is assumed." +(defcli! info + ((format ["--json" "--md" "--lisp"] "What format to dump info into")) + "Output system info in markdown for bug reports." (pcase format ("--json" (require 'json) @@ -23,7 +13,7 @@ If no arguments are given, --raw is assumed." (insert (json-encode (doom-info))) (json-pretty-print-buffer) (print! (buffer-string)))) - ((or "--md" "--markdown") + ("--md" (doom/info)) ((or `nil "--lisp") (doom/info 'raw)) @@ -33,6 +23,7 @@ If no arguments are given, --raw is assumed." nil) (defcli! (version v) () - "Reports the version of Doom and Emacs." + "Show version information for Doom & Emacs." + :bare t (doom/version) nil) diff --git a/core/cli/doctor.el b/core/cli/doctor.el new file mode 100644 index 000000000..28b1b009d --- /dev/null +++ b/core/cli/doctor.el @@ -0,0 +1,209 @@ +;;; core/cli/doctor.el -*- lexical-binding: t; -*- + +(defvar doom-warnings ()) +(defvar doom-errors ()) + +;;; Helpers +(defun elc-check-dir (dir) + (dolist (file (directory-files-recursively dir "\\.elc$")) + (when (file-newer-than-file-p (concat (file-name-sans-extension file) ".el") + file) + (warn! "%s is out-of-date" (abbreviate-file-name file))))) + +(defmacro assert! (condition message &rest args) + `(unless ,condition + (error! ,message ,@args))) + + +;;; Logging +(defmacro error! (&rest args) + `(progn (unless inhibit-message (print! (error ,@args))) + (push (format! (error ,@args)) doom-errors))) +(defmacro warn! (&rest args) + `(progn (unless inhibit-message (print! (warn ,@args))) + (push (format! (warn ,@args)) doom-warnings))) +(defmacro success! (&rest args) + `(print! (green ,@args))) +(defmacro section! (&rest args) + `(print! (bold (blue ,@args)))) + +(defmacro explain! (&rest args) + `(print-group! (print! (autofill ,@args)))) + + +;; +;;; CLI commands + +(defcli! (doctor doc) () + "Diagnoses common issues on your system. + +The Doom doctor is essentially one big, self-contained elisp shell script that +uses a series of simple heuristics to diagnose common issues on your system. +Issues that could intefere with Doom Emacs. + +Doom modules may optionally have a doctor.el file to run their own heuristics +in." + :bare t + (print! "The doctor will see you now...\n") + + ;; REVIEW Refactor me + (print! (start "Checking your Emacs version...")) + (when EMACS27+ + (warn! "Emacs %s detected. Emacs HEAD is unstable and may cause errors." + emacs-version)) + + (print! (start "Checking for Emacs config conflicts...")) + (when (file-exists-p "~/.emacs") + (warn! "Detected an ~/.emacs file, which may prevent Doom from loading") + (explain! "If Emacs finds an ~/.emacs file, it will ignore ~/.emacs.d, where Doom is " + "typically installed. If you're seeing a vanilla Emacs splash screen, this " + "may explain why. If you use Chemacs, you may ignore this warning.")) + + (print! (start "Checking for private config conflicts...")) + (let ((xdg-dir (concat (or (getenv "XDG_CONFIG_HOME") + "~/.config") + "/doom/")) + (doom-dir (or (getenv "DOOMDIR") + "~/.doom.d/"))) + (when (and (not (file-equal-p xdg-dir doom-dir)) + (file-directory-p xdg-dir) + (file-directory-p doom-dir)) + (print! (warn "Detected two private configs, in %s and %s") + (abbreviate-file-name xdg-dir) + doom-dir) + (explain! "The second directory will be ignored, as it has lower precedence."))) + + (print! (start "Checking for stale elc files...")) + (elc-check-dir user-emacs-directory) + + (print! (start "Checking Doom Emacs...")) + (condition-case-unless-debug ex + (print-group! + ;; Make sure Doom is initialized and loaded + (let ((doom-interactive-mode t)) + (doom-initialize 'force)) + (doom-initialize-core) + (print! (success "Initialized Doom Emacs %s") doom-version) + + (doom-initialize-modules) + (print! + (if (hash-table-p doom-modules) + (success "Detected %d modules" (hash-table-count doom-modules)) + (warn "Failed to load any modules. Do you have an private init.el?"))) + + (print! (success "Detected %d packages") (length doom-packages)) + + (print! (start "Checking Doom core for irregularities...")) + (print-group! + ;; Check for oversized problem files in cache that may cause unusual/tremendous + ;; delays or freezing. This shouldn't happen often. + (dolist (file (list "savehist" + "projectile.cache")) + (let* ((path (expand-file-name file doom-cache-dir)) + (size (/ (doom-file-size path) 1024))) + (when (and (numberp size) (> size 1000)) + (warn! "%s is too large (%.02fmb). This may cause freezes or odd startup delays" + (relpath path) + (/ size 1024)) + (explain! "Consider deleting it from your system (manually)")))) + + (unless (ignore-errors (executable-find doom-projectile-fd-binary)) + (warn! "Couldn't find the `fd' binary; project file searches will be slightly slower") + (unless (executable-find "rg") + (warn! "Couldn't find the `rg' binary either; project file searches will be even slower"))) + + (let ((default-directory "~")) + (require 'projectile) + (when (cl-find-if #'projectile-file-exists-p projectile-project-root-files-bottom-up) + (warn! "Your $HOME is recognized as a project root") + (explain! "Doom will disable bottom-up root search, which may reduce the accuracy of project\n" + "detection."))) + + ;; There should only be one + (when (and (file-equal-p doom-private-dir "~/.config/doom") + (file-directory-p "~/.doom.d")) + (print! (warn "Both %S and '~/.doom.d' exist on your system") + (path doom-private-dir)) + (explain! "Doom will only load one of these (~/.config/doom takes precedence). Possessing\n" + "both is rarely intentional; you should one or the other.")) + + ;; Check for fonts + (if (not (fboundp 'find-font)) + (progn + (warn! "Warning: unable to detect font") + (explain! "The `find-font' function is missing. This could indicate the incorrect " + "version of Emacs is being used!")) + ;; all-the-icons fonts + (when (and (pcase system-type + (`gnu/linux (concat (or (getenv "XDG_DATA_HOME") + "~/.local/share") + "/fonts/")) + (`darwin "~/Library/Fonts/")) + (require 'all-the-icons nil t)) + (dolist (font all-the-icons-font-families) + (if (with-temp-buffer + (insert (cdr (doom-call-process "fc-list"))) + (re-search-backward "Fira" nil t)) + (success! "Found font %s" font) + (print! (warn "Warning: couldn't find %s font in %s") + font font-dest) + (explain! "You can install it by running `M-x all-the-icons-install-fonts' within Emacs.\n\n" + "This could also mean you've installed them in non-standard locations, in which " + "case feel free to ignore this warning.")))))) + + (print! (start "Checking for stale elc files in your DOOMDIR...")) + (when (file-directory-p doom-private-dir) + (print-group! + (elc-check-dir doom-private-dir))) + + (when doom-modules + (print! (start "Checking your enabled modules...")) + (advice-add #'require :around #'doom-shut-up-a) + (maphash (lambda (key plist) + (let (doom-local-errors + doom-local-warnings) + (let (doom-errors + doom-warnings) + (condition-case-unless-debug ex + (let ((doctor-file (doom-module-path (car key) (cdr key) "doctor.el")) + (packages-file (doom-module-path (car key) (cdr key) "packages.el"))) + (cl-loop for name in (let (doom-packages + doom-disabled-packages) + (load packages-file 'noerror 'nomessage) + (mapcar #'car doom-packages)) + unless (or (doom-package-get name :disable) + (eval (doom-package-get name :ignore)) + (doom-package-built-in-p name) + (doom-package-installed-p name)) + do (print! (error "%s is not installed") name)) + (let ((inhibit-message t)) + (load doctor-file 'noerror 'nomessage))) + (file-missing (error! "%s" (error-message-string ex))) + (error (error! "Syntax error: %s" ex))) + (when (or doom-errors doom-warnings) + (print-group! + (print! (start (bold "%s %s")) (car key) (cdr key)) + (print! "%s" (string-join (append doom-errors doom-warnings) "\n"))) + (setq doom-local-errors doom-errors + doom-local-warnings doom-warnings))) + (appendq! doom-errors doom-local-errors) + (appendq! doom-warnings doom-local-warnings))) + doom-modules))) + (error + (warn! "Attempt to load DOOM failed\n %s\n" + (or (cdr-safe ex) (car ex))) + (setq doom-modules nil))) + + ;; Final report + (message "") + (dolist (msg (list (list doom-errors "error" 'red) + (list doom-warnings "warning" 'yellow))) + (when (car msg) + (print! (color (nth 2 msg) + (if (cdr msg) + "There are %d %ss!" + "There is %d %s!") + (length (car msg)) (nth 1 msg))))) + (unless (or doom-errors doom-warnings) + (success! "Everything seems fine, happy Emacs'ing!")) + t) diff --git a/core/cli/env.el b/core/cli/env.el index 83cc678c9..df882e764 100644 --- a/core/cli/env.el +++ b/core/cli/env.el @@ -1,13 +1,15 @@ ;;; core/cli/env.el -*- lexical-binding: t; -*- -(defcli! env (&rest args) +(defcli! env + ((clear-p ["-c" "--clear"] "Clear and delete your envvar file") + (outputfile ["-o" PATH] + "Generate the envvar file at PATH. Note that envvar files that aren't in +`doom-env-file' won't be loaded automatically at startup. You will need to +load them manually from your private config with the `doom-load-envvars-file' +function.") + &rest args) "Creates or regenerates your envvars file. - doom env [-c|--clear] - -This is meant to be a faster and more comprehensive alternative to -exec-path-from-shell. See the FAQ in the documentation for an explanation why. - The envvars file is created by scraping your (interactive) shell environment into newline-delimited KEY=VALUE pairs. Typically by running '$SHELL -ic env' (or '$SHELL -c set' on windows). Doom loads this file at startup (if it exists) @@ -21,14 +23,23 @@ app launchers on Linux). 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." - (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)) +Why this over exec-path-from-shell? + + 1. `exec-path-from-shell' spawns (at least) one process at startup to scrape + your shell environment. This can be arbitrarily slow depending on the + user's shell configuration. A single program (like pyenv or nvm) or config + framework (like oh-my-zsh) could undo all of Doom's startup optimizations + in one fell swoop. + + 2. `exec-path-from-shell' only scrapes some state from your shell. You have to + be proactive in order to get it to capture all the envvars relevant to your + development environment. + + I'd rather it inherit your shell environment /correctly/ (and /completely/) + or not at all. It frontloads the debugging process rather than hiding it + until it you least want to deal with it." + (let ((env-file (expand-file-name (or outputfile doom-env-file)))) + (cond (clear-p (unless (file-exists-p env-file) (user-error! "%S does not exist to be cleared" (path env-file))) @@ -36,12 +47,11 @@ Use the -c or --clear switch to delete your envvar file." (print! (success "Successfully deleted %S") (path env-file))) - ((or (null args) - (member "-o" args)) - (doom-reload-env-file 'force env-file)) + (args + (user-error "I don't understand 'doom env %s'" + (string-join args " "))) - ((user-error "I don't understand 'doom env %s'" - (string-join args " ")))))) + ((doom-cli-reload-env-file 'force env-file))))) ;; @@ -66,22 +76,7 @@ Use the -c or --clear switch to delete your envvar file." Each string is a regexp, matched against variable names to omit from `doom-env-file'.") -(defvar doom-env-executable - (if IS-WINDOWS - "set" - (executable-find "env")) - "The program to use to scrape your shell environment with. -It is rare that you'll need to change this.") - -(defvar doom-env-switches - (if IS-WINDOWS - "-c" - "-ic") ; Execute in an interactive shell - "The `shell-command-switch'es to use on `doom-env-executable'. -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.") - -(defun doom-reload-env-file (&optional force-p env-file) +(defun doom-cli-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 @@ -99,49 +94,37 @@ default, on Linux, this is '$SHELL -ic /usr/bin/env'. Variables in "Generating") (path env-file)) (let ((process-environment doom--initial-process-environment)) - (let ((shell-command-switch doom-env-switches) - (error-buffer (get-buffer-create "*env errors*"))) - (print! (info "Scraping shell environment with '%s %s %s'") - (filename shell-file-name) - shell-command-switch - (filename doom-env-executable)) - (save-excursion - (shell-command doom-env-executable (current-buffer) error-buffer)) - (print-group! - (let ((errors (with-current-buffer error-buffer (buffer-string)))) - (unless (string-empty-p errors) - (print! (info "Warnings:\n\n%s") (indent 4 errors)))) - ;; Remove undesireable variables - (insert - (concat - "# -*- mode: dotenv -*-\n" - (format "# Generated with: %s %s %s\n" - shell-file-name - doom-env-switches - doom-env-executable) - "# ---------------------------------------------------------------------------\n" - "# This file was auto-generated by `doom env'. It contains a list of environment\n" - "# variables scraped from your default shell (excluding variables blacklisted\n" - "# 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 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) - (save-excursion - (let* ((valend (or (save-match-data - (when (re-search-forward "^\\([^= ]+\\)=" nil t) - (line-beginning-position))) - (point-max))) - (var (match-string 1))) - (when (cl-loop for regexp in doom-env-ignored-vars - if (string-match-p regexp var) - return t) - (print! (info "Ignoring %s") var) - (delete-region (match-beginning 0) (1- valend))))))) - (print! (success "Successfully generated %S") - (path env-file)) - t)))))) + (print! (info "Scraping shell environment")) + (print-group! + (when doom-interactive-mode + (user-error "'doom env' must be run on the command line, not an interactive session")) + (goto-char (point-min)) + (insert + (concat + "# -*- mode: dotenv -*-\n" + (format "# Generated from a %s shell environent\n" shell-file-name) + "# ---------------------------------------------------------------------------\n" + "# This file was auto-generated by `doom env'. It contains a list of environment\n" + "# variables scraped from your default shell (excluding variables blacklisted\n" + "# in doom-env-ignored-vars).\n" + "#\n" + (if (file-equal-p env-file doom-env-file) + (concat "# It is NOT safe to edit this file. Changes will be overwritten next time you\n" + "# run 'doom refresh'. To create a safe-to-edit envvar file use:\n#\n" + "# doom env -o ~/.doom.d/myenv\n#\n" + "# And load it with (doom-load-envvars-file \"~/.doom.d/myenv\").\n") + (concat "# This file is safe to edit by hand, but needs to be loaded manually with:\n#\n" + "# (doom-load-envvars-file \"path/to/this/file\")\n#\n" + "# Use 'doom env -o path/to/this/file' to regenerate it.")) + "# ---------------------------------------------------------------------------\n\n")) + ;; We assume that this noninteractive session was spawned from the + ;; user's interactive shell, therefore we just dump + ;; `process-environment' to a file. + (dolist (env process-environment) + (if (cl-find-if (doom-rpartial #'string-match-p env) + doom-env-ignored-vars) + (print! (info "Ignoring %s") env) + (insert env "\n"))) + (print! (success "Successfully generated %S") + (path env-file)) + t)))))) diff --git a/core/cli/help.el b/core/cli/help.el new file mode 100644 index 000000000..13e82ea77 --- /dev/null +++ b/core/cli/help.el @@ -0,0 +1,101 @@ +;;; core/cli/help.el -*- lexical-binding: t; -*- + +(defun doom--cli-print-signature (cli) + (print! (bold "Usage: doom %s%s%s") + (if (doom-cli-internal-p cli) + "" + (concat (doom-cli-name cli) " ")) + (if-let* ((optlist (doom-cli-optlist cli)) + (flags (cl-loop for opt in optlist + append (doom-cli-option-flags opt))) + (fn (doom-partial #'string-prefix-p "--"))) + (concat (when-let (short-flags (cl-remove-if fn flags)) + ;; TODO Show arguments of short flags + (format "[-%s]" + (string-join (mapcar (doom-rpartial #'substring 1 nil) short-flags) + ""))) + ;; TODO Show long flags + ;; (when-let (long-flags (cl-remove-if-not fn flags)) + ;; (concat " " (string-join long-flags " "))) + " ") + "") + (if-let (arglist (doom-cli-arglist cli)) + (string-join (append (cl-loop for arg in arglist + until (memq arg cl--lambda-list-keywords) + collect (upcase (symbol-name arg))) + (cl-loop for arg in (cdr (memq '&optional arglist)) + until (memq arg cl--lambda-list-keywords) + collect (format "[%s]" (upcase (symbol-name arg))))) + " ") + ""))) + +(defun doom--cli-print-desc (cli &optional short) + (print! "%s" + (if short + (car (split-string (doom-cli-desc cli) "\n")) + (doom-cli-desc cli)))) + +(defun doom--cli-print-short-desc (cli) + (doom--cli-print-desc cli 'short)) + +(defun doom--cli-print-options (cli) + (when-let (optlist (doom-cli-optlist cli)) + (print! (bold "Options:")) + (print-group! + (cl-loop for opt in optlist + for flags = (doom-cli-option-flags opt) + for desc = (doom-cli-option-desc opt) + for args = (doom-cli-option-args opt) + for flagstr = (string-join (doom-cli-option-flags opt) ", ") + do + ;; TODO Adjust columns dynamically + (print! "%-18s" + (concat flagstr + (when-let (arg (car args)) + (concat " " (upcase (symbol-name arg)))))) + (print-group! + (print! (autofill "%s") desc)))))) + + +(defun doom--cli-print (cli) + (doom--cli-print-signature cli) + (terpri) + (doom--cli-print-desc cli) + (terpri) + (doom--cli-print-options cli)) + + +;; +;;; Commands + +(defcli! (help h) (&optional command) + "Describe a command or list them all." + :bare t + (if command + (doom--cli-print (doom-cli-get (intern command))) + (doom--cli-print (doom-cli-get :main)) + (terpri) + (print! (bold "Commands:")) + (print-group! + (dolist (group (seq-group-by (lambda (cli) + (plist-get (doom-cli-plist cli) :group)) + (cl-loop for name being the hash-keys of doom--cli-commands + for cli = (gethash name doom--cli-commands) + if (and (doom-cli-p cli) + (not (doom-cli-internal-p cli)) + (not (plist-get (doom-cli-plist cli) :hidden))) + collect cli))) + (if (null (car group)) + (dolist (cli (cdr group)) + (print! "%-16s %s" + (doom-cli-name cli) + (car (split-string (doom-cli-desc cli) "\n")))) + (print! "%-26s %s" + (bold (concat (car group) ":")) + (gethash (car group) doom--cli-groups)) + (print-group! + (dolist (cli (cdr group)) + (print! "%-16s %s" + (doom-cli-name cli) + (car (split-string (doom-cli-desc cli) "\n")))))) + (terpri))))) diff --git a/core/cli/install.el b/core/cli/install.el index b50b1522f..32d411ece 100644 --- a/core/cli/install.el +++ b/core/cli/install.el @@ -1,13 +1,11 @@ ;;; core/cli/install.el -*- lexical-binding: t; -*- -(defcli! quickstart (&rest args) ; DEPRECATED - "This is a deprecated alias for 'doom install'. - -See 'doom help install' instead." - :hidden t - (apply #'doom-cli-install args)) - -(defcli! (install i) (&rest args) +(defcli! (install i) + ((noconfig-p ["--no-config"] "Don't create DOOMDIR or dummy files therein") + (noenv-p ["--no-env"] "Don't generate an envvars file (see 'doom help env')") + (noinstall-p ["--no-install"] "Don't auto-install packages") + (nofonts-p ["--no-fonts"] "Don't install (or prompt to install) all-the-icons fonts") + &rest args) "Installs and sets up Doom Emacs for the first time. This command does the following: @@ -25,23 +23,17 @@ The location of DOOMDIR can be changed with the -p option, or by setting the DOOMDIR environment variable. e.g. doom -p ~/.config/doom install - DOOMDIR=~/.config/doom doom install - -The following switches are recognized: - - --no-config Don't create DOOMDIR or dummy files therein - --no-install Don't auto-install packages - --no-env Don't generate an envvars file (see `doom help env`) - --no-fonts Don't install (or prompt to install) all-the-icons fonts - -y / --yes Auto-accept any confirmation prompts" + DOOMDIR=~/.config/doom doom install" + :bare t (print! (green "Installing Doom Emacs!\n")) (let ((default-directory (doom-path "~"))) ;; Create `doom-private-dir' - (if (member "--no-config" args) + (if noconfig-p (print! (warn "Not copying private config template, as requested")) - (print! "> Creating %s" (relpath doom-private-dir)) + (print! (start "Creating %s") (relpath doom-private-dir)) (make-directory doom-private-dir 'parents) - (print! (success "Created %s") (relpath doom-private-dir)) + (print-group! + (print! (success "Created %s") (relpath doom-private-dir))) ;; Create init.el, config.el & packages.el (mapc (lambda (file) @@ -71,26 +63,29 @@ The following switches are recognized: ;; In case no init.el was present the first time `doom-initialize-modules' was ;; called in core.el (e.g. on first install) - (doom-initialize-packages 'force-p) + (doom-initialize 'force) + (doom-initialize-modules) - ;; Ask if Emacs.app should be patched - (if (member "--no-env" args) - (print! (warn "- Not generating envvars file, as requested")) - (when (or doom-auto-accept - (y-or-n-p "Generate an env file? (see `doom help env` for details)")) - (doom-reload-env-file 'force-p))) + ;; Ask if user would like an envvar file generated + (if noenv-p + (print! (warn "Not generating envvars file, as requested")) + (if (file-exists-p doom-env-file) + (print! (info "Envvar file already exists, skipping")) + (when (or doom-auto-accept + (y-or-n-p "Generate an env file? (see `doom help env` for details)")) + (doom-cli-reload-env-file 'force-p)))) ;; Install Doom packages - (if (member "--no-install" args) - (print! (warn "- Not installing plugins, as requested")) + (if noinstall-p + (print! (warn "Not installing plugins, as requested")) (print! "Installing plugins") - (doom-packages-install doom-auto-accept)) + (doom-cli-packages-install doom-auto-accept)) (print! "Regenerating autoloads files") (doom-reload-autoloads nil 'force-p) - (if (member "--no-fonts" args) - (print! (warn "- Not installing fonts, as requested")) + (if nofonts-p + (print! (warn "Not installing fonts, as requested")) (when (or doom-auto-accept (y-or-n-p "Download and install all-the-icon's fonts?")) (require 'all-the-icons) @@ -98,6 +93,9 @@ The following switches are recognized: (IS-LINUX 'x)))) (all-the-icons-install-fonts 'yes)))) + (when (file-exists-p "~/.emacs") + (print! (warn "A ~/.emacs file was detected. This conflicts with Doom and should be deleted!"))) + (print! (success "\nFinished! Doom is ready to go!\n")) (with-temp-buffer (doom-template-insert "QUICKSTART_INTRO") diff --git a/core/cli/packages.el b/core/cli/packages.el index 2b2faf15d..caaebfec2 100644 --- a/core/cli/packages.el +++ b/core/cli/packages.el @@ -1,73 +1,55 @@ ;; -*- no-byte-compile: t; -*- ;;; core/cli/packages.el -(defmacro doom--ensure-autoloads-while (&rest body) - `(progn - (straight-check-all) - (doom-reload-core-autoloads) - (when (progn ,@body) - (doom-reload-package-autoloads 'force-p)) - t)) - - -;; -;;; Dispatchers - -(defcli! (update u) (&rest args) +(defcli! (update u) () "Updates packages. 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." + (straight-check-all) + (doom-cli-reload-core-autoloads) + (when (doom-cli-packages-update) + (doom-cli-reload-package-autoloads 'force-p)) + t) -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 - (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))))) - -(defcli! (rebuild build b) (&rest args) - "Rebuilds all installed packages. +(defcli! (build b) + ((rebuild-p ["-r"] "Only rebuild packages that need rebuilding")) + "Byte-compiles & symlinks 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. This is especially necessary if you upgrade +Emacs (as byte-code is generally not forward-compatible)." + (when (doom-cli-packages-build (not rebuild-p)) + (doom-cli-reload-package-autoloads 'force-p)) + t) -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) + ((nobuilds-p ["-b" "--no-builds"] "Don't purge unneeded (built) packages") + (noelpa-p ["-p" "--no-elpa"] "Don't purge ELPA packages") + (norepos-p ["-r" "--no-repos"] "Don't purge unused straight repos") + (regraft-p ["-g" "--regraft"] "Regraft git repos (ie. compact them)")) + "Deletes orphaned packages & repos, and compacts them. -(defcli! (purge p) (&rest args) - "Deletes any unused ELPA packages, straight builds, and (optionally) repos. +Purges all installed ELPA packages (as they are considered temporary). Purges +all orphaned package repos and builds. If -g/--regraft is supplied, the git +repos among them will be regrafted and compacted to ensure they are as small as +possible. -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. +It is a good idea to occasionally run this doom purge -g to ensure your package +list remains lean." + (straight-check-all) + (when (doom-cli-packages-purge + (not noelpa-p) + (not norepos-p) + (not nobuilds-p) + regraft-p) + (doom-cli-reload-package-autoloads 'force-p)) + t) -Switches: - --no-builds Don't purge unneeded (built) packages - -e / --elpa Don't purge ELPA packages - -r / --repos Purge unused repos - --all Purge builds, elpa packages and repos" - (doom--ensure-autoloads-while - (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 "--all" args)) - doom-auto-accept))) - -;; (defcli! rollback () ; TODO rollback +;; (defcli! rollback () ; TODO doom rollback ;; "" ;; (user-error "Not implemented yet, sorry!")) @@ -75,15 +57,12 @@ Switches: ;; ;;; Library -(defun doom-packages-install (&optional auto-accept-p) +(defun doom-cli-packages-install () "Installs missing packages. This function will install any primary package (i.e. a package with a `package!' -declaration) or dependency thereof that hasn't already been. - -Unless AUTO-ACCEPT-P is non-nil, this function will prompt for confirmation with -a list of packages that will be installed." - (print! "> Installing & building packages...") +declaration) or dependency thereof that hasn't already been." + (print! (start "Installing & building packages...")) (print-group! (let ((n 0)) (dolist (package (hash-table-keys straight--recipe-cache)) @@ -91,7 +70,7 @@ a list of packages that will be installed." (local-repo) (let ((existed-p (file-directory-p (straight--repos-dir package)))) (condition-case-unless-debug e - (and (straight-use-package (intern package) nil nil " ") + (and (straight-use-package (intern package) nil nil (make-string (1- (or doom-format-indent 1)) 32)) (not existed-p) (file-directory-p (straight--repos-dir package)) (cl-incf n)) @@ -104,17 +83,18 @@ a list of packages that will be installed." t)))) -(defun doom-packages-rebuild (&optional auto-accept-p all) +(defun doom-cli-packages-build (&optional force-p) "(Re)build all packages." - (print! (start "(Re)building %spackages...") (if all "all " "")) + (print! (start "(Re)building %spackages...") (if force-p "all " "")) (print-group! (let ((n 0)) - (if all + (if force-p (let ((straight--packages-to-rebuild :all) (straight--packages-not-to-rebuild (make-hash-table :test #'equal))) (dolist (package (hash-table-keys straight--recipe-cache)) (straight-use-package - (intern package) nil (lambda (_) (cl-incf n) nil) " "))) + (intern package) nil (lambda (_) (cl-incf n) nil) + (make-string (1- (or doom-format-indent 1)) 32)))) (dolist (recipe (hash-table-values straight--recipe-cache)) (straight--with-plist recipe (package local-repo no-build) (unless (or no-build (null local-repo)) @@ -139,7 +119,9 @@ a list of packages that will be installed." (lambda (&rest _) (cl-incf n))) (let ((straight--packages-to-rebuild :all) (straight--packages-not-to-rebuild (make-hash-table :test #'equal))) - (straight-use-package (intern package) nil nil " ")) + (straight-use-package + (intern package) nil nil + (make-string (or doom-format-indent 0) 32))) (straight--byte-compile-package recipe) (dolist (dep (straight--get-dependencies package)) (when-let (recipe (gethash dep straight--recipe-cache)) @@ -151,268 +133,107 @@ a list of packages that will be installed." t)))) -(defun doom--packages-remove-outdated-f (packages) - (async-start - `(lambda () - (setq load-path ',load-path - doom-modules ',doom-modules - user-emacs-directory ',user-emacs-directory) - (condition-case e - (let (packages errors) - (load ,(concat doom-core-dir "core.el")) - (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) - (condition-case e - (let ((default-directory (straight--repos-dir local-repo))) - ;; HACK We normalize packages to avoid certain scenarios - ;; where `straight-fetch-package' will create an - ;; interactive popup prompting for action (which will - ;; cause this async process to block indefinitely). We - ;; 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" branch) - (straight--get-call "git" "clean" "-ffd") - (unless nonrecursive - (shell-command-to-string "git submodule update --init --recursive")) - (when upstream-repo - (let ((desired-url (straight-vc-git--encode-url upstream-repo upstream-host)) - (actual-url (condition-case nil - (straight--get-call "git" "remote" "get-url" upstream-remote) - (error nil)))) - (unless (straight-vc-git--urls-compatible-p actual-url desired-url) - (straight--get-call "git" "remote" "remove" upstream-remote) - (straight--get-call "git" "remote" "add" upstream-remote desired-url) - (straight--get-call "git" "fetch" upstream-remote)))) - (straight-fetch-package package) - ;; REVIEW Is there no better way to get this information? - (let ((n (length - (split-string - (straight--get-call "git" "rev-list" "--left-right" "HEAD..@{u}") - "\n" t))) - (pretime - (string-to-number - (shell-command-to-string "git log -1 --format=%at HEAD"))) - (time - (string-to-number - ;; HACK `straight--get-call' has a higher failure - ;; rate when querying FETCH_HEAD; not sure why. - ;; Doing this manually, with - ;; `shell-command-to-string' works fine. - (shell-command-to-string "git log -1 --format=%at FETCH_HEAD")))) - (with-current-buffer (straight--process-get-buffer) - (with-silent-modifications - (print! (debug (autofill "%s") (indent 2 (buffer-string)))) - (erase-buffer))) - (when (> n 0) - (push (list n pretime time recipe) - packages)))) - (error - (push (list package e (string-trim (or (straight--process-get-output) ""))) - errors)))))) - (if errors - (cons 'error errors) - (cons 'ok (nreverse packages)))) - (error - (cons 'error e)))))) - - -(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 -a list of packages that will be updated." - (print! (start "Scanning for outdated packages (this may take a while)...")) - (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) - (or threads 8))) - for future = (doom--packages-remove-outdated-f group) - if (processp future) - collect (cons future group) - else - do (print! (warn "Failed to create thread for:\n\n%s\n\nReason: %s" - group future))) - (error! "Failed to create any threads"))) - (total (length futures)) - (timeout (or timeout 45))) - (condition-case-unless-debug e - (let (specs) - (while futures - (print! ". %.0f%%" (* (/ (- total (length futures)) - (float total)) - 100)) - (let ((time 0)) - (catch 'timeout - (while (not (async-ready (caar futures))) - (when (> time timeout) - (print! (warn "A thread has timed out. The following packages were skipped: %s" - (mapconcat (lambda (p) (plist-get p :package)) - (cdar futures) - ", "))) - (throw 'timeout (pop futures))) - (sleep-for 1) - (when (cl-evenp time) - (print! ".")) - (cl-incf time)) - (cl-destructuring-bind (status . result) - (or (async-get (car (pop futures))) - (cons nil nil)) - (cond ((null status) - (error "Thread returned an invalid result: %S" errors)) - ((eq status 'error) - (error "There were errors:\n\n%s" - (cond ((and (listp result) - (symbolp (car result))) - (prin1-to-string result)) - ((stringp result) - result) - ((mapconcat (lambda (e) - (format! " - %s: %s" (yellow (car e)) (cdr e))) - result - "\n"))))) - ((eq status 'ok) - (print! (debug "Appended %S to package list") (or result "nothing")) - (appendq! specs result)) - ((error "Thread returned a non-standard status: %s\n\n%s" - status result))))))) - (print! ". 100%%") - (terpri) - (if-let (specs (delq nil specs)) - (if (not - (or auto-accept-p - (y-or-n-p - (format! - "%s\n\nThere %s %d package%s available to update. Update them?" - (mapconcat - (lambda (spec) - (cl-destructuring-bind (n pretime time recipe) spec - (straight--with-plist recipe (package) - (format! "+ %-33s %s commit(s) behind %s -> %s" - (yellow package) (yellow n) - (format-time-string "%Y%m%d" pretime) - (format-time-string "%Y%m%d" time))))) - specs - "\n") - (if (cdr specs) "are" "is") - (length specs) - (if (cdr specs) "s" ""))))) - (ignore (print! (info "Aborted update"))) - (terpri) - (straight--make-package-modifications-available) - (let ((straight--packages-to-rebuild (make-hash-table :test #'equal)) - (straight--packages-not-to-rebuild (make-hash-table :test #'equal))) - (dolist (spec specs) - (cl-destructuring-bind (n pretime time recipe) spec - (straight--with-plist recipe (local-repo package) - (let ((default-directory (straight--repos-dir local-repo))) - (print! (start "Updating %S") package) - (straight-merge-package package) - ;; HACK `straight-rebuild-package' doesn't pick up that - ;; this package has changed, so we do it manually. Is - ;; there a better way? - (ignore-errors - (delete-directory (straight--build-dir package) 'recursive)) - (puthash package t straight--packages-to-rebuild) - (cl-incf n)) - (with-current-buffer (straight--process-get-buffer) - (with-silent-modifications - (print! (debug (autofill "%s") (indent 2 (buffer-string)))) - (erase-buffer)))))) - (doom--finalize-straight) - (doom-packages-rebuild auto-accept-p)) - t) - (print! (success "No packages to update")) - nil)) - (error - (message "Output:\n%s" (straight--process-get-output)) - (signal (car e) (error-message-string e))))))) +(defun doom-cli-packages-update () + "Updates packages." + (print! (start "Updating packages (this may take a while)...")) + (let ((straight--packages-to-rebuild (make-hash-table :test #'equal)) + (total (hash-table-count straight--repo-cache)) + (i 1) + errors) + (print-group! + (dolist (recipe (hash-table-values straight--repo-cache)) + (straight--with-plist recipe (package type local-repo) + (condition-case-unless-debug e + (let* ((default-directory (straight--repos-dir local-repo)) + (commit (straight-vc-get-commit type local-repo))) + (if (not (straight-vc-fetch-from-remote recipe)) + (print! (warn "(%d/%d) Failed to fetch %s" i total package)) + (let ((output (straight--process-get-output))) + (straight-merge-package package) + (let ((newcommit (straight-vc-get-commit type local-repo))) + (if (string= commit newcommit) + (print! (info "(%d/%d) %s is up-to-date") i total package) + (ignore-errors + (delete-directory (straight--build-dir package) 'recursive)) + (puthash package t straight--packages-to-rebuild) + (print! (success "(%d/%d) %s updated (%s -> %s)") i total package + (substring commit 0 7) + (substring newcommit 0 7)) + (unless (string-empty-p output) + (print-group! + (print! (info "%s") output) + (when (eq type 'git) + (straight--call "git" "log" "--oneline" newcommit (concat "^" commit)) + (print-group! + (print! "%s" (straight--process-get-output)))))))))) + (cl-incf i)) + (user-error + (signal 'user-error (error-message-string e))) + (error + (print! (warn "(%d/%d) Encountered error with %s" i total package)) + (print-group! + (print! (error "%s" e)) + (print-group! (print! (info "%s" (straight--process-get-output))))) + (push package errors))))) + (when errors + (print! (error "There were %d errors, the offending packages are: %s") + (length errors) (string-join errors ", "))) + (if (hash-table-empty-p straight--packages-to-rebuild) + (ignore + (print! (success "All %d packages are up-to-date") + (hash-table-count straight--repo-cache))) + (let ((count (hash-table-count straight--packages-to-rebuild)) + (packages (hash-table-keys straight--packages-to-rebuild))) + (sort packages #'string-lessp) + (doom--finalize-straight) + (doom-cli-packages-build) + (print! (success "Updated %d package(s)") count)) + t)))) ;;; PURGE (for the emperor) -(defun doom--prompt-p (list-fn list preamble postamble) - (or (y-or-n-p (format "%s%s\n\n%s" - (if preamble (concat preamble "\n\n") "") - (mapconcat list-fn list "\n") - (or postamble ""))) - (user-error! "Aborted"))) - -(defun doom--prompt-columns-p (row-fn list preamble postamble) - (doom--prompt-p (lambda (row) - (mapconcat row-fn row "")) - (seq-partition (cl-sort (copy-sequence list) #'string-lessp) - 3) - preamble - postamble)) - -(defun doom--packages-purge-build (build) +(defun doom--cli-packages-purge-build (build) (let ((build-dir (straight--build-dir build))) - (print! (start "Purging build/%s..." build)) (delete-directory build-dir 'recursive) (if (file-directory-p build-dir) (ignore (print! (error "Failed to purg build/%s" build))) (print! (success "Purged build/%s" build)) t))) -(defun doom--packages-purge-builds (builds &optional auto-accept-p) +(defun doom--cli-packages-purge-builds (builds) (if (not builds) (progn (print! (info "No builds to purge")) 0) - (or auto-accept-p - (doom--prompt-columns-p - (lambda (p) (format " + %-20.20s" p)) builds nil - (format! "Found %d orphaned package builds. Purge them?" - (length builds)))) (length - (delq nil (mapcar #'doom--packages-purge-build builds))))) + (delq nil (mapcar #'doom--cli-packages-purge-build builds))))) -(defun doom--packages-regraft-repo (repo) +(defun doom--cli-packages-regraft-repo (repo) (let ((default-directory (straight--repos-dir repo))) (if (not (file-directory-p ".git")) (ignore (print! (warn "repos/%s is not a git repo, skipping" repo))) - (print! (debug "Regrafting repos/%s..." repo)) - (straight--call "git" "reset" "--hard") - (straight--call "git" "clean" "--ffd") - (straight--call "git" "replace" "--graft" "HEAD") - (straight--call "git" "gc") - (print! (debug "%s" (straight--process-get-output))) - (print! (success "Regrafted repos/%s" repo)) + (let ((before-size (doom-directory-size default-directory))) + (straight--call "git" "reset" "--hard") + (straight--call "git" "clean" "-ffd") + (if (not (car (straight--call "git" "replace" "--graft" "HEAD"))) + (print! (info "repos/%s is already compact" repo)) + (straight--call "git" "gc") + (print! (success "Regrafted repos/%s (from %0.1fKB to %0.1fKB)") + repo before-size (doom-directory-size default-directory)) + (print-group! (print! "%s" (straight--process-get-output))))) t))) -(defun doom--packages-regraft-repos (repos &optional auto-accept-p) +(defun doom--cli-packages-regraft-repos (repos) (if (not repos) (progn (print! (info "No repos to regraft")) 0) - (or auto-accept-p - (y-or-n-p (format! "Preparing to regraft all %d repos. Continue?" - (length repos))) - (user-error! "Aborted!")) - (if (executable-find "du") - (cl-destructuring-bind (status . size) - (doom-sh "du" "-sh" (straight--repos-dir)) - (prog1 (delq nil (mapcar #'doom--packages-regraft-repo repos)) - (cl-destructuring-bind (status . newsize) - (doom-sh "du" "-sh" (straight--repos-dir)) - (print! (success "Finshed regrafted. Size before: %s and after: %s" - (car (split-string size "\t")) - (car (split-string newsize "\t"))))))) - (delq nil (mapcar #'doom--packages-regraft-repo repos))))) + (let ((before-size (doom-directory-size (straight--repos-dir)))) + (prog1 (print-group! (delq nil (mapcar #'doom--cli-packages-regraft-repo repos))) + (let ((after-size (doom-directory-size (straight--repos-dir)))) + (print! (success "Finished regrafting. Size before: %0.1fKB and after: %0.1fKB (-%0.1fKB)") + before-size after-size + (- after-size before-size))))))) -(defun doom--packages-purge-repo (repo) - (print! (debug "Purging repos/%s..." repo)) +(defun doom--cli-packages-purge-repo (repo) (let ((repo-dir (straight--repos-dir repo))) (delete-directory repo-dir 'recursive) (ignore-errors @@ -422,19 +243,14 @@ a list of packages that will be updated." (print! (success "Purged repos/%s" repo)) t))) -(defun doom--packages-purge-repos (repos &optional auto-accept-p) +(defun doom--cli-packages-purge-repos (repos) (if (not repos) (progn (print! (info "No repos to purge")) 0) - (or auto-accept-p - (doom--prompt-columns-p - (lambda (p) (format " + %-20.20s" p)) repos nil - (format! "Found %d orphaned repos. Purge them?" - (length repos)))) (length - (delq nil (mapcar #'doom--packages-purge-repo repos))))) + (delq nil (mapcar #'doom--cli-packages-purge-repo repos))))) -(defun doom--packages-purge-elpa (&optional auto-accept-p) +(defun doom--cli-packages-purge-elpa () (unless (bound-and-true-p package--initialized) (package-initialize)) (let ((packages (cl-loop for (package desc) in package-alist @@ -444,16 +260,11 @@ a list of packages that will be updated." (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 packages) nil - (format! "Found %d orphaned ELPA packages. Purge them?" - (length package-alist))) (mapc (doom-rpartial #'delete-directory 'recursive) (mapcar #'cdr packages)) (length packages)))) -(defun doom-packages-purge (&optional elpa-p builds-p repos-p auto-accept-p) +(defun doom-cli-packages-purge (&optional elpa-p builds-p repos-p regraft-repos-p) "Auto-removes orphaned packages and repos. An orphaned package is a package that isn't a primary package (i.e. doesn't have @@ -461,10 +272,7 @@ a `package!' declaration) or isn't depended on by another primary package. If BUILDS-P, include straight package builds. If REPOS-P, include straight repos. -If ELPA-P, include packages installed with package.el (M-x package-install). - -Unless AUTO-ACCEPT-P is non-nil, this function will prompt for confirmation with -a list of packages that will be removed." +If ELPA-P, include packages installed with package.el (M-x package-install)." (print! (start "Searching for orphaned packages to purge (for the emperor)...")) (cl-destructuring-bind (&optional builds-to-purge repos-to-purge repos-to-regraft) (let ((rdirs (straight--directory-files (straight--repos-dir) nil nil 'sort)) @@ -479,18 +287,20 @@ a list of packages that will be removed." (print-group! (if (not builds-p) (print! (info "Skipping builds")) - (and (/= 0 (doom--packages-purge-builds builds-to-purge auto-accept-p)) + (and (/= 0 (doom--cli-packages-purge-builds builds-to-purge)) (setq success t) (straight-prune-build-cache))) (if (not elpa-p) (print! (info "Skipping elpa packages")) - (and (/= 0 (doom--packages-purge-elpa auto-accept-p)) + (and (/= 0 (doom--cli-packages-purge-elpa)) (setq success t))) (if (not repos-p) (print! (info "Skipping repos")) - (and (/= 0 (doom--packages-purge-repos repos-to-purge auto-accept-p)) - (setq success t)) - (and (doom--packages-regraft-repos repos-to-regraft auto-accept-p) + (and (/= 0 (doom--cli-packages-purge-repos repos-to-purge)) + (setq success t))) + (if (not regraft-repos-p) + (print! (info "Skipping regrafting")) + (and (doom--cli-packages-regraft-repos repos-to-regraft) (setq success t))) (when success (doom--finalize-straight) diff --git a/core/cli/test.el b/core/cli/test.el index e052365c6..9572a9d88 100644 --- a/core/cli/test.el +++ b/core/cli/test.el @@ -7,9 +7,13 @@ runemacs-binary-path emacs-binary-path))) + (defcli! test (&rest targets) "Run Doom unit tests." - (let (files error) + :bare t + (doom-initialize 'force) + (require 'ansi-color) + (let (files error read-files) (unless targets (setq targets (cons doom-core-dir @@ -17,7 +21,7 @@ (lambda (path) (file-in-directory-p path doom-emacs-dir)) ;; Omit `doom-private-dir', which is always first (let (doom-modules) - (load! "test/init" doom-core-dir) + (load (expand-file-name "test/init" doom-core-dir) nil t) (cdr (doom-module-load-path))))))) (while targets (let ((target (pop targets))) @@ -31,45 +35,70 @@ (push target files))))) (with-temp-buffer (print! (start "Bootstrapping test environment, if necessary...")) - (if (zerop - (call-process - (doom--emacs-binary) - nil t nil "--batch" - "--eval" (prin1-to-string - `(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) - (doom-reload-core-autoloads 'force) - (when (doom-packages-install 'auto-accept) - (doom-reload-package-autoloads 'force)))))) - (message "%s" (buffer-string)) - (message "%s" (buffer-string)) - (error "Failed to bootstrap unit tests"))) - (dolist (file files) - (if (doom-file-cookie-p file "if" t) - (with-temp-buffer - (unless - (zerop - (apply #'call-process - (doom--emacs-binary) - nil t nil "--batch" - (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")))) - (setq error t)) - (message "%s" (buffer-string))) - (print! (info "Ignoring %s" (relpath file))))) - (if error - (user-error "A test failed") + (cl-destructuring-bind (status . output) + (doom-exec-process + (doom--emacs-binary) + "--batch" + "--eval" + (prin1-to-string + `(progn + (setq doom-emacs-dir ,doom-emacs-dir + doom-local-dir ,(concat doom-local-dir "test/") + doom-private-dir ,(concat doom-core-dir "test/") + doom-auto-accept t) + (require 'core ,(locate-library "core")) + (require 'core-cli) + (doom-initialize 'force) + (doom-initialize-modules) + (doom-cli-reload-core-autoloads 'force) + (when (doom-cli-packages-install) + (doom-cli-reload-package-autoloads 'force))))) + (unless (zerop status) + (error "Failed to bootstrap unit tests")))) + (with-temp-buffer + (dolist (file files) + (if (doom-file-cookie-p file "if" t) + (cl-destructuring-bind (_status . output) + (apply #'doom-exec-process + (doom--emacs-binary) + "--batch" + "-l" (concat doom-core-dir "core.el") + "-l" (concat doom-core-dir "test/helpers.el") + (append (when (file-in-directory-p file doom-modules-dir) + (list "-f" "doom-initialize-core")) + (list "-l" file + "-f" "buttercup-run"))) + (insert (replace-regexp-in-string ansi-color-control-seq-regexp "" output)) + (push file read-files)) + (print! (info "Ignoring %s" (relpath file))))) + (let ((total 0) + (total-failed 0) + (i 0)) + (print! "\n----------------------------------------\nTests finished") + (print-group! + (goto-char (point-min)) + (while (re-search-forward "^Ran \\([0-9]+\\) specs, \\([0-9]+\\) failed," nil t) + (let ((ran (string-to-number (match-string 1))) + (failed (string-to-number (match-string 2)))) + (when (> failed 0) + (terpri) + (print! (warn "(%s) Failed %d/%d tests") + (path (nth i read-files)) + failed ran) + (save-excursion + (print-group! + (print! + "%s" (string-trim + (buffer-substring + (match-beginning 0) + (dotimes (_ failed (point)) + (search-backward "========================================")))))))) + (cl-incf total ran) + (cl-incf total-failed failed) + (cl-incf i)))) + (terpri) + (if (= total-failed 0) + (print! (success "Ran %d tests successfully." total total-failed)) + (print! (error "Ran %d tests, %d failed") total total-failed) + (kill-emacs 1))) t))) diff --git a/core/cli/upgrade.el b/core/cli/upgrade.el index 893012f41..9244c293b 100644 --- a/core/cli/upgrade.el +++ b/core/cli/upgrade.el @@ -1,6 +1,8 @@ ;;; core/cli/upgrade.el -*- lexical-binding: t; -*- -(defcli! (upgrade up) (&rest args) +(defcli! (upgrade up) + ((force-p ["-f" "--force"]) + &rest args) "Updates Doom and packages. This requires that ~/.emacs.d is a git repo, and is the equivalent of the @@ -10,22 +12,10 @@ following shell commands: git pull --rebase bin/doom clean bin/doom refresh - 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 - (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))) + bin/doom update" + (and (doom-cli-upgrade doom-auto-accept force-p) + (doom-cli-packages-update) + (doom-cli-reload-package-autoloads 'force-p))) ;; @@ -44,7 +34,7 @@ Switches: (error "Failed to check working tree in %s" dir)))) -(defun doom-upgrade (&optional auto-accept-p force-p) +(defun doom-cli-upgrade (&optional auto-accept-p force-p) "Upgrade Doom to the latest version non-destructively." (require 'vc-git) (let ((default-directory doom-emacs-dir) @@ -110,9 +100,8 @@ Switches: (equal (vc-git--rev-parse "HEAD") new-rev)) (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") + (doom-cli-execute "refresh" (append (if auto-accept-p '("-y")) '("-f"))) + (doom-cli-execute "update" (if auto-accept-p '("-y"))) t) (print! (success "Done! Restart Emacs for changes to take effect.")))))) diff --git a/core/core-cli.el b/core/core-cli.el index d3c4bb4e3..1d5738ca0 100644 --- a/core/core-cli.el +++ b/core/core-cli.el @@ -1,156 +1,219 @@ ;;; -*- lexical-binding: t; no-byte-compile: t; -*- -(require 'seq) +(require 'map) +;; 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"))) + + +;; +;;; Variables (defvar doom-auto-accept (getenv "YES") "If non-nil, Doom will auto-accept any confirmation prompts during batch -commands like `doom-packages-install', `doom-packages-update' and +commands like `doom-cli-packages-install', `doom-cli-packages-update' and `doom-packages-autoremove'.") -(defvar doom-cli-pre-execute-hook nil - "TODO") -(defvar doom-cli-post-success-execute-hook nil - "TODO") - +(defvar doom--cli-p nil) (defvar doom--cli-commands (make-hash-table :test 'equal)) (defvar doom--cli-groups (make-hash-table :test 'equal)) (defvar doom--cli-group nil) +;; TODO Constructors for optlist, arglist and fn +(cl-defstruct doom-cli + (name) + (desc "TODO") + (aliases ()) + (optlist ()) + (arglist ()) + (plist ()) + (fn (lambda (_) (print! "But nobody came!")))) -;; -;;; Dispatcher API +(cl-defstruct doom-cli-option + (symbol) + (flags ()) + (args ()) + (desc "TODO")) -(defun doom-sh (command &rest args) - "Execute COMMAND with ARGS in the shell and return (STATUS . OUTPUT). +(defun doom--cli-get-option (cli flag) + (cl-find-if (doom-partial #'member flag) + (doom-cli-optlist cli) + :key #'doom-cli-option-flags)) -STATUS is a boolean" - (let ((output (get-buffer-create "*doom-sh-output*"))) - (unwind-protect - (cons (or (apply #'call-process command nil output nil args) - -1) - (with-current-buffer output - (string-trim (buffer-string)))) - (kill-buffer output)))) +(defun doom--cli-process (cli args) + (let* ((args (copy-sequence args)) + (arglist (copy-sequence (doom-cli-arglist cli))) + (expected (or (cl-position-if (doom-rpartial #'memq cl--lambda-list-keywords) + arglist) + (length arglist))) + (got 0) + restvar + rest + alist) + (catch 'done + (while args + (let ((arg (pop args))) + (cond ((eq (car arglist) '&rest) + (setq restvar (cadr arglist) + rest (cons arg args)) + (throw 'done t)) -(defun doom--dispatch-command (command) - (when (symbolp command) - (setq command (symbol-name command))) - (cl-check-type command string) - (intern-soft - (format "doom-cli-%s" - (if (gethash command doom--cli-commands) - command - (cl-loop for key - being the hash-keys in doom--cli-commands - for aliases = (plist-get (gethash key doom--cli-commands) :aliases) - if (member command aliases) - return key))))) + ((string-match "^\\(--\\([a-zA-Z0-9][a-zA-Z0-9-_]*\\)\\)\\(?:=\\(.+\\)\\)?$" arg) + (let* ((fullflag (match-string 1 arg)) + (opt (doom--cli-get-option cli fullflag))) + (unless opt + (user-error "Unrecognized switch %S" (concat "--" (match-string 2 arg)))) + (map-put + alist (doom-cli-option-symbol opt) + (or (if (doom-cli-option-args opt) + (or (match-string 3 arg) + (pop args) + (user-error "%S expected an argument, but got none" + fullflag)) + (if (match-string 3 arg) + (user-error "%S was not expecting an argument, but got %S" + fullflag (match-string 3 arg)) + fullflag)))))) -(defun doom--dispatch-format (desc &optional short) - (with-temp-buffer - (let ((fill-column 72)) - (save-excursion - (insert desc) - (while (re-search-backward "\n\n[^ \n]" nil t) - (fill-paragraph)))) - (if (not short) - (buffer-string) - (buffer-substring (line-beginning-position) - (line-end-position))))) + ((string-match "^\\(-\\([a-zA-Z0-9]+\\)\\)$" arg) + (let ((fullflag (match-string 1 arg)) + (flag (match-string 2 arg))) + (dolist (switch (split-string flag "" t)) + (if-let (opt (doom--cli-get-option cli (concat "-" switch))) + (map-put + alist (doom-cli-option-symbol opt) + (if (doom-cli-option-args opt) + (or (pop args) + (user-error "%S expected an argument, but got none" + fullflag)) + fullflag)) + (user-error "Unrecognized switch %S" (concat "-" switch)))))) -(defun doom--dispatch-help-1 (command) - (cl-destructuring-bind (&key aliases hidden _group) - (gethash command doom--cli-commands) - (unless hidden - (print! "%-11s\t%s\t%s" - command (if aliases (string-join aliases ",") "") - (doom--dispatch-format - (documentation (doom--dispatch-command command)) - t))))) + (arglist + (cl-incf got) + (let ((spec (pop arglist))) + (when (eq spec '&optional) + (setq spec (pop arglist))) + (map-put alist spec arg)) + (when (null arglist) + (throw 'done t))) -(defun doom--dispatch-help (&optional fn &rest args) - "Display help documentation for a dispatcher command. If fn and DESC are -omitted, show all available commands, their aliases and brief descriptions." - (if fn - (princ (documentation fn)) - (print! (bold "%-11s\t%s\t%s" "Command:" "Alias" "Description")) - (print-group! - (dolist (group (seq-group-by (lambda (key) (plist-get (gethash key doom--cli-commands) :group)) - (hash-table-keys doom--cli-commands))) - (if (null (car group)) - (mapc #'doom--dispatch-help-1 (cdr group)) - (print! "%-30s\t%s" (bold (car group)) (gethash (car group) doom--cli-groups)) - (print-group! - (mapc #'doom--dispatch-help-1 (cdr group)))) - (terpri))))) + (t + (push arg args) + (throw 'done t)))))) + (when (< got expected) + (error "Expected %d arguments, got %d" expected got)) + (when rest + (map-put alist restvar rest)) + alist)) -(defun doom-dispatch (cmd args &optional show-help) - "Parses ARGS and invokes a dispatcher. +(defun doom-cli-get (command) + "Return a CLI object associated by COMMAND name (string)." + (cond ((null command) nil) + ((doom-cli-p command) command) + ((doom-cli-get + (gethash (cond ((symbolp command) command) + ((stringp command) (intern command)) + (command)) + doom--cli-commands))))) -If SHOW-HELP is non-nil, show the documentation for said dispatcher." - (when (equal cmd "help") - (setq show-help t) - (when args - (setq cmd (car args) - args (cdr args)))) - (let ((fn (doom--dispatch-command cmd))) - (unless (fboundp fn) - (user-error "%S is not any command *I* know!" cmd)) - (if show-help - (doom--dispatch-help fn args) - (let ((start-time (current-time))) - (run-hooks 'doom-cli-pre-execute-hook) - (unwind-protect - (when-let (ret (apply fn args)) - (print! - "\n%s" - (success "Finished! (%.4fs)" - (float-time - (time-subtract (current-time) - start-time)))) - (run-hooks 'doom-cli-post-execute-hook) - ret) - (run-hooks 'doom-cli-post-error-execute-hook)))))) +(defun doom-cli-internal-p (cli) + "Return non-nil if CLI is an internal (non-public) command." + (string-prefix-p ":" (doom-cli-name cli))) + +(defun doom-cli-execute (command &optional args) + "Execute COMMAND (string) with ARGS (list of strings). + +Executes a cli defined with `defcli!' with the name or alias specified by +COMMAND, and passes ARGS to it." + (if-let (cli (doom-cli-get command)) + (funcall (doom-cli-fn cli) + (doom--cli-process cli args)) + (user-error "Couldn't find any %S command" command))) + +(defmacro defcli! (name speclist &optional docstring &rest body) + "Defines a CLI command. + +COMMAND is a symbol or a list of symbols representing the aliases for this +command. DOCSTRING is a string description; its first line should be short +(under 60 characters), as it will be used as a summary for 'doom help'. + +SPECLIST is a specification for options and arguments, which can be a list +specification for an option/switch in the following format: + + (VAR [FLAGS... ARGS...] DESCRIPTION) + +Otherwise, SPECLIST accepts the same argument specifiers as `defun'. + +BODY will be run when this dispatcher is called." + (declare (indent 2) (doc-string 3)) + (unless (stringp docstring) + (push docstring body) + (setq docstring "TODO")) + (let ((names (doom-enlist name)) + (optlist (cl-remove-if-not #'listp speclist)) + (arglist (cl-remove-if #'listp speclist)) + (plist (cl-loop for (key val) on body by #'cddr + if (keywordp key) + nconc (list key val) into plist + else return plist))) + `(let ((name ',(car names)) + (aliases ',(cdr names)) + (plist ',plist)) + (when doom--cli-group + (setq plist (plist-put plist :group doom--cli-group))) + (puthash + name + (make-doom-cli :name (symbol-name name) + :desc ,docstring + :aliases (mapcar #'symbol-name aliases) + :arglist ',arglist + :optlist + (cl-loop for (symbol options desc) in ',optlist + for ((_ . options) (_ . params)) + = (seq-group-by #'stringp options) + collect + (make-doom-cli-option :symbol symbol + :flags options + :args params + :desc desc)) + :plist plist + :fn + (lambda (--alist--) + (let ,(cl-loop for opt in speclist + for optsym = (if (listp opt) (car opt) opt) + unless (memq optsym cl--lambda-list-keywords) + collect (list optsym `(cdr (assq ',optsym --alist--)))) + ,@(unless (plist-get plist :bare) + '((unless doom-init-p + (doom-initialize 'force) + (doom-initialize-modules)))) + ,@body))) + doom--cli-commands) + (when aliases + (mapc (doom-rpartial #'puthash name doom--cli-commands) + aliases))))) (defmacro defcligroup! (name docstring &rest body) - "TODO" + "Declare all enclosed cli commands are part of the NAME group." (declare (indent defun) (doc-string 2)) `(let ((doom--cli-group ,name)) (puthash doom--cli-group ,docstring doom--cli-groups) ,@body)) -(defmacro defcli! (names arglist docstring &rest body) - "Define a dispatcher command. COMMAND is a symbol or a list of symbols -representing the aliases for this command. DESC is a string description. The -first line should be short (under 60 letters), as it will be displayed for -bin/doom help. - -BODY will be run when this dispatcher is called." - (declare (indent defun) (doc-string 3)) - (let* ((names (mapcar #'symbol-name (doom-enlist names))) - (fn (intern (format "doom-cli-%s" (car names)))) - (plist (cl-loop while (keywordp (car body)) - collect (pop body) - collect (pop body)))) - (macroexp-progn - (reverse - `((let ((plist ',plist)) - (setq plist (plist-put plist :aliases ',(cdr names))) - (unless (or (plist-member plist :group) - (null doom--cli-group)) - (plist-put plist :group doom--cli-group)) - (puthash ,(car names) plist doom--cli-commands)) - (defun ,fn ,arglist - ,docstring - ,@body)))))) - ;; -;;; Dispatch commands +;;; CLI Commands -;; Load all of our subcommands -(defcli! (refresh re) (&rest args) +(load! "cli/help") +(load! "cli/install") + +(defcli! (refresh re) + ((force-p ["-f" "--force"] "Regenerate autoloads files, whether or not they're stale") + &rest args) "Ensure Doom is properly set up. This is the equivalent of running autoremove, install, autoloads, then @@ -165,36 +228,25 @@ It will ensure that unneeded packages are removed, all needed packages are installed, autoloads files are up-to-date and no byte-compiled files have gone stale." (print! (green "Initiating a refresh of Doom Emacs...\n")) - (let ((force-p (or (member "-f" args) - (member "--force" args))) - success) + (let (success) (when (file-exists-p doom-env-file) - (doom-reload-env-file 'force)) - (doom-reload-core-autoloads force-p) + (doom-cli-reload-env-file 'force)) + (doom-cli-reload-core-autoloads force-p) (unwind-protect (progn - (and (doom-packages-install doom-auto-accept) + (and (doom-cli-packages-install) (setq success t)) - (and (doom-packages-rebuild doom-auto-accept) + (and (doom-cli-packages-build) (setq success t)) - (and (doom-packages-purge nil 'builds-p nil doom-auto-accept) + (and (doom-cli-packages-purge nil 'builds-p nil) (setq success t))) - (doom-reload-package-autoloads (or success force-p)) - (doom-byte-compile nil 'recompile)) + (doom-cli-reload-package-autoloads (or success force-p)) + (doom-cli-byte-compile nil 'recompile)) t)) - -;; Load all of our subcommands -(load! "cli/install") - (defcligroup! "Diagnostics" "For troubleshooting and diagnostics" - (defcli! (doctor doc) () - "Checks for issues with your environment & Doom config. - -Use the doctor to diagnose common problems or list missing dependencies in -enabled modules.") - + (load! "cli/doctor") (load! "cli/debug") (load! "cli/test")) @@ -205,8 +257,8 @@ enabled modules.") (load! "cli/packages") (load! "cli/autoloads")) -(defcligroup! "Byte compilation" - "For byte-compiling Doom and your config" +(defcligroup! "Compilation" + "For compiling Doom and your config" (load! "cli/byte-compile")) (defcligroup! "Utilities" @@ -214,7 +266,7 @@ enabled modules.") (defcli! run () "Run Doom Emacs from bin/doom's parent directory. -All arguments are passed on to Emacs (except for -p and -e). +All arguments are passed on to Emacs. doom run doom run -nw init.el diff --git a/core/core.el b/core/core.el index 81762e1ed..6cd60b1dc 100644 --- a/core/core.el +++ b/core/core.el @@ -434,26 +434,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) + (let (environment) (with-temp-buffer - (insert-file-contents file) + (save-excursion + (insert "\n") + (insert-file-contents file)) (while (re-search-forward "\n *\\([^#][^= \n]+\\)=" nil t) - (save-excursion - (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 + (push (buffer-substring + (match-beginning 1) + (1- (or (save-excursion + (when (re-search-forward "^\\([^= ]+\\)=" nil t) + (line-beginning-position))) + (point-max)))) + environment))) + (when environment (setq-default + process-environment environment exec-path (append (parse-colon-path (getenv "PATH")) (list exec-directory)) shell-file-name (or (getenv "SHELL") shell-file-name)) - (nreverse vars))))) + t)))) (defun doom-initialize (&optional force-p) "Bootstrap Doom, if it hasn't already (or if FORCE-P is non-nil). @@ -523,12 +524,6 @@ to least)." (require 'core-packages) (doom-initialize-packages))) - ;; 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 diff --git a/core/doctor.el b/core/doctor.el deleted file mode 100644 index 1a5f5fc0e..000000000 --- a/core/doctor.el +++ /dev/null @@ -1,61 +0,0 @@ -;;; core/doctor.el -*- lexical-binding: t; -*- - -(defun file-size (file &optional dir) - (setq file (expand-file-name file dir)) - (when (file-exists-p file) - (/ (nth 7 (file-attributes file)) - 1024.0))) - -;; Check for oversized problem files in cache that may cause unusual/tremendous -;; delays or freezing. This shouldn't happen often. -(dolist (file (list "savehist" - "projectile.cache")) - (let* ((path (expand-file-name file doom-cache-dir)) - (size (file-size path))) - (when (and (numberp size) (> size 2000)) - (warn! "%s is too large (%.02fmb). This may cause freezes or odd startup delays" - (file-relative-name path doom-core-dir) - (/ size 1024)) - (explain! "Consider deleting it from your system (manually)")))) - -(unless (ignore-errors (executable-find doom-projectile-fd-binary)) - (warn! "Couldn't find the `fd' binary; project file searches will be slightly slower") - (unless (executable-find "rg") - (warn! "Couldn't find the `rg' binary either; project file searches will be even slower"))) - -(let ((default-directory "~")) - (require 'projectile) - (when (cl-find-if #'projectile-file-exists-p projectile-project-root-files-bottom-up) - (warn! "Your $HOME is recognized as a project root") - (explain! "Doom will disable bottom-up root search, which may reduce the accuracy of project\n" - "detection."))) - -;; There should only be one -(when (and (file-equal-p doom-private-dir "~/.config/doom") - (file-directory-p "~/.doom.d")) - (warn! "Both %S and '~/.doom.d' exist on your system" - (abbreviate-file-name doom-private-dir)) - (explain! "Doom will only load one of these (~/.config/doom takes precedence). Possessing\n" - "both is rarely intentional; you should one or the other.")) - -;; Check for fonts -(if (not (fboundp 'find-font)) - (progn - (warn! "Warning: unable to detect font") - (explain! "The `find-font' function is missing. This could indicate the incorrect " - "version of Emacs is being used!")) - ;; all-the-icons fonts - (let ((font-dest (pcase system-type - (`gnu/linux (concat (or (getenv "XDG_DATA_HOME") - "~/.local/share") - "/fonts/")) - (`darwin "~/Library/Fonts/")))) - (when (and font-dest (require 'all-the-icons nil t)) - (dolist (font all-the-icons-font-families) - (if (sh "fc-list | grep %s" font) - (success! "Found font %s" font) - (warn! "Warning: couldn't find %s font in %s" - font font-dest) - (explain! "You can install it by running `M-x all-the-icons-install-fonts' within Emacs.\n\n" - "This could also mean you've installed them in non-standard locations, in which " - "case feel free to ignore this warning.")))))) From 44d5e097c949c9bf201471d6729f4dd4d1ca3cfd Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 7 Nov 2019 18:20:38 -0500 Subject: [PATCH 016/129] shell-command-to-string -> doom-call-process #1887 Minor optimization to remove a layer of indirection when starting processes. --- core/autoload/debug.el | 11 ++-- core/autoload/help.el | 16 +++--- modules/completion/ivy/autoload/ivy.el | 54 ++++++++++---------- modules/email/notmuch/autoload.el | 4 +- modules/lang/org/autoload/contrib-ipython.el | 6 +-- 5 files changed, 46 insertions(+), 45 deletions(-) diff --git a/core/autoload/debug.el b/core/autoload/debug.el index f56eef252..92ef42ffe 100644 --- a/core/autoload/debug.el +++ b/core/autoload/debug.el @@ -32,9 +32,8 @@ ready to be pasted in a bug report on github." (doom-modules (doom-modules))) (cl-letf (((symbol-function 'sh) - (lambda (format) - (string-trim - (shell-command-to-string format))))) + (lambda (&rest args) + (cdr (apply #'doom-call-process args))))) `((emacs (version . ,emacs-version) (features ,@system-configuration-features) @@ -47,14 +46,14 @@ ready to be pasted in a bug report on github." 'server-running)))) (doom (version . ,doom-version) - (build . ,(sh "git log -1 --format=\"%D %h %ci\""))) + (build . ,(sh "git" "log" "-1" "--format=%D %h %ci"))) (system (type . ,system-type) (config . ,system-configuration) (shell . ,shell-file-name) (uname . ,(if IS-WINDOWS "n/a" - (sh "uname -msrv"))) + (sh "uname" "-msrv"))) (path . ,(mapcar #'abbreviate-file-name exec-path))) (config (envfile @@ -117,7 +116,7 @@ branch and commit." "n/a") (or (vc-git-working-revision doom-core-dir) "n/a") - (or (string-trim (shell-command-to-string "git log -1 --format=%ci")) + (or (cdr (doom-call-process "git" "log" "-1" "--format=%ci")) "n/a")))) ;;;###autoload diff --git a/core/autoload/help.el b/core/autoload/help.el index 085976af6..362ec25bc 100644 --- a/core/autoload/help.el +++ b/core/autoload/help.el @@ -395,13 +395,15 @@ current file is in, or d) the module associated with the current major mode (see (message "Couldn't find the config block")))))))) (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)) + ;; TODO Use ripgrep instead (split-string - (shell-command-to-string - (format "git grep --no-break --no-heading --line-number '%s %s\\($\\| \\)' ':(exclude)*.org'" - "\\(^;;;###package\\|(after!\\|(use-package!\\)" - package)) + (cdr (doom-call-process + "git" "grep" "--no-break" "--no-heading" "--line-number" + (format "%s %s\\($\\| \\)" + "\\(^;;;###package\\|(after!\\|(use-package!\\)" + package) + ":(exclude)*.org")) "\n" t))) ;;;###autoload @@ -463,8 +465,8 @@ If prefix arg is present, refresh the cache." (`straight (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\""))) + (cdr + (doom-call-process "git" "log" "-1" "--format=%D %h %ci"))) (indent 13 (string-trim (pp-to-string diff --git a/modules/completion/ivy/autoload/ivy.el b/modules/completion/ivy/autoload/ivy.el index c264f8337..4dbd940d4 100644 --- a/modules/completion/ivy/autoload/ivy.el +++ b/modules/completion/ivy/autoload/ivy.el @@ -179,38 +179,38 @@ If ARG (universal argument), open selection in other-window." .type .file .line))))) (defun +ivy--tasks (target) - (let* (case-fold-search - (task-tags (mapcar #'car +ivy-task-tags)) - (cmd - (format "%s -H -S --no-heading -- %s %s" - (or (when-let (bin (executable-find "rg")) - (concat bin " --line-number")) - (when-let (bin (executable-find "ag")) - (concat bin " --numbers")) - (error "ripgrep & the_silver_searcher are unavailable")) - (shell-quote-argument - (concat "\\s(" - (string-join task-tags "|") - ")([\\s:]|\\([^)]+\\):?)")) - target))) - (save-match-data - (cl-loop with out = (shell-command-to-string cmd) - for x in (and out (split-string out "\n" t)) - when (condition-case-unless-debug ex + (let (case-fold-search) + (cl-loop with task-tags = (mapcar #'car +ivy-task-tags) + with out = + (cdr + (apply #'doom-call-process + (append + (or (when-let (bin (executable-find "rg")) + (list bin "--line-number")) + (when-let (bin (executable-find "ag")) + (list bin "--numbers")) + (user-error "ripgrep & the_silver_searcher are unavailable")) + (list "-H" "-S" "--no-heading" "--" + (concat "\\s(" + (string-join task-tags "|") + ")([\\s:]|\\([^)]+\\):?)") + target)))) + for x in (and out (split-string out "\n" t)) + when (condition-case-unless-debug ex (string-match (concat "^\\([^:]+\\):\\([0-9]+\\):.+\\(" (string-join task-tags "\\|") "\\):?\\s-*\\(.+\\)") x) - (error - (print! (red "Error matching task in file: (%s) %s") - (error-message-string ex) - (car (split-string x ":"))) - nil)) - collect `((type . ,(match-string 3 x)) - (desc . ,(match-string 4 x)) - (file . ,(match-string 1 x)) - (line . ,(match-string 2 x))))))) + (error + (print! (red "Error matching task in file: (%s) %s") + (error-message-string ex) + (car (split-string x ":"))) + nil)) + collect `((type . ,(match-string 3 x)) + (desc . ,(match-string 4 x)) + (file . ,(match-string 1 x)) + (line . ,(match-string 2 x)))))) (defun +ivy--tasks-open-action (x) "Jump to the file and line of the current task." diff --git a/modules/email/notmuch/autoload.el b/modules/email/notmuch/autoload.el index 211e45957..49fdd745f 100644 --- a/modules/email/notmuch/autoload.el +++ b/modules/email/notmuch/autoload.el @@ -100,7 +100,7 @@ (interactive) (let* ((msg-path (car (plist-get (notmuch-tree-get-message-properties) :filename))) (temp (make-temp-file "notmuch-message-" nil ".eml"))) - (shell-command-to-string (format "cp '%s' '%s'" msg-path temp)) + (doom-call-process "cp" msg-path temp) (start-process-shell-command "email" nil (format "xdg-open '%s'" temp)))) ;;;###autoload @@ -108,7 +108,7 @@ (interactive) (let* ((msg-path (car (plist-get (notmuch-show-get-message-properties) :filename))) (temp (make-temp-file "notmuch-message-" nil ".eml"))) - (shell-command-to-string (format "cp '%s' '%s'" msg-path temp)) + (doom-call-process "cp" msg-path temp) (start-process-shell-command "email" nil (format "xdg-open '%s'" temp)))) diff --git a/modules/lang/org/autoload/contrib-ipython.el b/modules/lang/org/autoload/contrib-ipython.el index 4e8e82ef3..e729a0711 100644 --- a/modules/lang/org/autoload/contrib-ipython.el +++ b/modules/lang/org/autoload/contrib-ipython.el @@ -21,12 +21,12 @@ Make sure your src block has a :session param.") (defun +org--ob-ipython-generate-local-path-from-remote (session host params) "Given a remote SESSION with PARAMS and corresponding HOST, copy remote config to local, start a jupyter console to generate a new one." (let* ((runtime-dir - (substring (shell-command-to-string (concat "ssh " host " jupyter --runtime-dir")) 0 -1)) + (cdr + (doom-call-process "ssh " host "jupyter" "--runtime-dir"))) (runtime-file (concat runtime-dir "/" "kernel-" session ".json")) (tramp-path (concat "/ssh:" host ":" runtime-file)) (tramp-copy (concat (or +ob-ipython-local-runtime-dir - (substring (shell-command-to-string "jupyter --runtime-dir") - 0 -1)) + (cdr (doom-call-process "jupyter" "--runtime-dir"))) "/remote-" host "-kernel-" session ".json")) (local-path (concat From c37bdf71d1bc3c39e658a5d928c672af562f9b3e Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 7 Nov 2019 18:26:32 -0500 Subject: [PATCH 017/129] Demote "no more buttons" error to warning If the shortmenu or buttons were disabled, this error would break the dashboard (and Doom). Mentioned in #2024 --- modules/ui/doom-dashboard/config.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/ui/doom-dashboard/config.el b/modules/ui/doom-dashboard/config.el index 5aa448a07..87f12df10 100644 --- a/modules/ui/doom-dashboard/config.el +++ b/modules/ui/doom-dashboard/config.el @@ -200,8 +200,9 @@ PLIST can have the following properties: (if (button-at (point)) (forward-button 0) (backward-button 1))) - (progn (goto-char (point-min)) - (forward-button 1)))) + (ignore-errors + (goto-char (point-min)) + (forward-button 1)))) (defun +doom-dashboard-reload-maybe-h () "Reload the dashboard or its state. From fbf9010c80ac4a11f1ced1da22bc8a42019abf82 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 7 Nov 2019 18:43:46 -0500 Subject: [PATCH 018/129] Log benchmark whether or not dashboard is enabled --- modules/ui/doom-dashboard/config.el | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/ui/doom-dashboard/config.el b/modules/ui/doom-dashboard/config.el index 87f12df10..7df29520c 100644 --- a/modules/ui/doom-dashboard/config.el +++ b/modules/ui/doom-dashboard/config.el @@ -128,8 +128,6 @@ PLIST can have the following properties: (add-hook 'persp-before-switch-functions #'+doom-dashboard--persp-record-project-h))) (add-hook 'doom-init-ui-hook #'+doom-dashboard-init-h) -(unless doom-debug-mode - (remove-hook 'window-setup-hook #'doom-display-benchmark-h)) ;; From 9ef6ccb7cde73ec9cfc6e9d35282b967c6688578 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 7 Nov 2019 18:51:12 -0500 Subject: [PATCH 019/129] Refactor doom-run-all-startup-hooks-h --- core/autoload/debug.el | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/autoload/debug.el b/core/autoload/debug.el index 92ef42ffe..2bec4307f 100644 --- a/core/autoload/debug.el +++ b/core/autoload/debug.el @@ -8,10 +8,10 @@ emacs -Q -l init.el -f doom-run-all-startup-hooks-h" (run-hook-wrapped 'after-init-hook #'doom-try-run-hook) (setq after-init-time (current-time)) - (dolist (hook (list 'delayed-warnings-hook - 'emacs-startup-hook 'term-setup-hook - 'window-setup-hook)) - (run-hook-wrapped hook #'doom-try-run-hook))) + (mapc (doom-rpartial #'run-hook-wrapped #'doom-try-run-hook) + (list 'delayed-warnings-hook + 'emacs-startup-hook 'tty-setup-hook + 'window-setup-hook))) ;; From d78d584fdff339148a037b91d1b1a0d3c5282b4d Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 7 Nov 2019 20:55:57 -0500 Subject: [PATCH 020/129] Demote autoload errors to warnings --- core/core.el | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/core/core.el b/core/core.el index 6cd60b1dc..57b3e816d 100644 --- a/core/core.el +++ b/core/core.el @@ -425,9 +425,8 @@ in interactive sessions, nil otherwise (but logs a warning)." (let (command-switch-alist) (load (substring file 0 -3) 'noerror 'nomessage)) ((debug error) - (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)))))) + (message "Autoload file error: %s -> %s" (file-name-nondirectory file) e) + nil))) (defun doom-load-envvars-file (file &optional noerror) "Read and set envvars from FILE." @@ -504,16 +503,12 @@ to least)." (let (;; `doom-autoload-file' tells Emacs where to load all its functions ;; from. This includes everything in core/autoload/*.el and autoload ;; files in enabled modules. - (core-autoloads-p - (with-demoted-errors "Core autoload error: %s" - (doom-load-autoloads-file doom-autoload-file))) + (core-autoloads-p (doom-load-autoloads-file doom-autoload-file)) ;; Loads `doom-package-autoload-file', which loads a concatenated ;; package autoloads file which caches `load-path', `auto-mode-alist', ;; `Info-directory-list', and `doom-disabled-packages'. A big ;; reduction in startup time. - (pkg-autoloads-p - (with-demoted-errors "Package autoload error: %s" - (doom-load-autoloads-file doom-package-autoload-file)))) + (pkg-autoloads-p (doom-load-autoloads-file doom-package-autoload-file))) (if (and core-autoloads-p pkg-autoloads-p (not force-p)) ;; In case we want to use package.el or straight via M-x From d683effd234fc53dfd92603df392ff32357e98f6 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 7 Nov 2019 21:35:04 -0500 Subject: [PATCH 021/129] Recognize single-character envvars in doom-load-envvars-file And preserve insertion order for process-environment's new value. --- core/core.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/core.el b/core/core.el index 57b3e816d..cb12f8d08 100644 --- a/core/core.el +++ b/core/core.el @@ -438,7 +438,7 @@ in interactive sessions, nil otherwise (but logs a warning)." (save-excursion (insert "\n") (insert-file-contents file)) - (while (re-search-forward "\n *\\([^#][^= \n]+\\)=" nil t) + (while (re-search-forward "\n *\\([^#][^= \n]*\\)=" nil t) (push (buffer-substring (match-beginning 1) (1- (or (save-excursion @@ -448,12 +448,12 @@ in interactive sessions, nil otherwise (but logs a warning)." environment))) (when environment (setq-default - process-environment environment + process-environment (nreverse environment) exec-path (append (parse-colon-path (getenv "PATH")) (list exec-directory)) shell-file-name (or (getenv "SHELL") shell-file-name)) - t)))) + process-environment)))) (defun doom-initialize (&optional force-p) "Bootstrap Doom, if it hasn't already (or if FORCE-P is non-nil). From d099fac2b9fa1e55b317345eccf3bac6ed600dfa Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 7 Nov 2019 21:36:18 -0500 Subject: [PATCH 022/129] Fix core & core-lib tests --- core/cli/test.el | 2 +- core/test/test-core-lib.el | 6 ++-- core/test/test-core.el | 61 +++++++++++++++++++++++--------------- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/core/cli/test.el b/core/cli/test.el index 9572a9d88..8696dc1e4 100644 --- a/core/cli/test.el +++ b/core/cli/test.el @@ -18,7 +18,7 @@ (setq targets (cons doom-core-dir (cl-remove-if-not - (lambda (path) (file-in-directory-p path doom-emacs-dir)) + (doom-rpartial #'file-in-directory-p doom-emacs-dir) ;; Omit `doom-private-dir', which is always first (let (doom-modules) (load (expand-file-name "test/init" doom-core-dir) nil t) diff --git a/core/test/test-core-lib.el b/core/test/test-core-lib.el index 82eaa0fc1..9007465f7 100644 --- a/core/test/test-core-lib.el +++ b/core/test/test-core-lib.el @@ -234,11 +234,13 @@ (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)) + (expect 'load :to-have-been-called-with + (expand-file-name "path" (eval-when-compile (dir!))) nil 'nomessage)) (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))) + (expect 'load :to-have-been-called-with + (expand-file-name "path" doom-etc-dir) nil 'nomessage))) (describe "quiet!" (it "suppresses output from message" diff --git a/core/test/test-core.el b/core/test/test-core.el index 22892b4fd..00a45acb4 100644 --- a/core/test/test-core.el +++ b/core/test/test-core.el @@ -48,21 +48,13 @@ (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))) + (it "loads autoloads files" + (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") @@ -81,20 +73,39 @@ (expect 'require :to-have-been-called-with 'core-editor)))) (describe "doom-load-autoloads-file" + :var (doom-autoload-file doom-alt-autoload-file result) (before-each - (spy-on 'load :and-return-value t)) + (setq doom-autoload-file (make-temp-file "doom-autoload" nil ".el")) + (with-temp-file doom-autoload-file + (insert "(eval-when-compile (defvar x 1))") + (insert "(defvar x 2)")) + (byte-compile-file doom-autoload-file)) + (after-each + (delete-file doom-autoload-file) + (delete-file (byte-compile-dest-file doom-autoload-file))) - (it "loads the autoloads file" + (it "loads the byte-compiled autoloads file if available" (doom-load-autoloads-file doom-autoload-file) - (expect 'load :to-have-been-called-with (file-name-sans-extension doom-autoload-file) - 'noerror 'nomessage))) + (expect (caar load-history) :to-equal + (byte-compile-dest-file doom-autoload-file)) + + (delete-file (byte-compile-dest-file doom-autoload-file)) + (doom-load-autoloads-file doom-autoload-file) + (expect (caar load-history) :to-equal doom-autoload-file)) + + (it "returns non-nil if successful" + (expect (doom-load-autoloads-file doom-autoload-file))) + + (it "returns nil on failure or error, non-fatally" + (expect (doom-load-autoloads-file "/does/not/exist") :to-be nil))) (describe "doom-load-envvars-file" - :var (envvarfile process-environment) + :var (doom-env-file process-environment) (before-each - (setq process-environment (copy-sequence process-environment)) + (setq process-environment nil + doom-env-file (make-temp-file "doom-env")) (with-temp-file doom-env-file - (insert "\n\n\nA=1\nB=2\nC=3\n"))) + (insert "A=1\nB=2\nC=3\n"))) (after-each (delete-file doom-env-file)) @@ -106,12 +117,14 @@ (expect (doom-load-envvars-file "/tmp/envvardoesnotexist" 'noerror) :not :to-throw)) - (it "loads a well-formed envvar file" - (expect (getenv "A") :not :to-be-truthy) + (it "returns the new value for `process-environment'" (expect (doom-load-envvars-file doom-env-file) - :to-equal '(("A" . "1") ("B" . "2") ("C" . "3"))) - (expect (getenv "A") :to-equal "1")) + :to-equal '("A=1" "B=2" "C=3"))) - (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)))) + (it "alters environment variables" + (dolist (key '("A" "B" "C")) + (expect (getenv key) :not :to-be-truthy)) + (expect (doom-load-envvars-file doom-env-file)) + (expect (getenv "A") :to-equal "1") + (expect (getenv "B") :to-equal "2") + (expect (getenv "C") :to-equal "3")))) From 3a74c81bf2bb96f7197e704f2adb1d7cc196e34f Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 7 Nov 2019 21:46:33 -0500 Subject: [PATCH 023/129] Add 26.2 to list of versions to test --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 65dbb2818..cc11691f2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,6 +17,7 @@ jobs: matrix: emacs_version: - 26.1 + - 26.2 - 26.3 - snapshot include: From bf8ee34c19fc392656e0bf53bcff752a65ae65c5 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 8 Nov 2019 00:02:50 -0500 Subject: [PATCH 024/129] tools/lsp: fix +lsp-prompt-if-no-project-a #1928 Don't prompt for blacklisted folders, and don't refuse to recognize $HOME (let the user decide whether to blacklist it or not). --- modules/tools/lsp/config.el | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/modules/tools/lsp/config.el b/modules/tools/lsp/config.el index c31591ff9..f4bdc3a79 100644 --- a/modules/tools/lsp/config.el +++ b/modules/tools/lsp/config.el @@ -53,12 +53,14 @@ auto-killed (which is usually an expensive process)." lsp--cur-workspace)))) (defadvice! +lsp-prompt-if-no-project-a (root) - "Prompt for the project root only if no project was found. -Also refuses to recognize $HOME as a valid project root." + "Prompt for the project root only if no project was found." :filter-return #'lsp--calculate-root - (cond ((and root (not (file-equal-p root "~"))) - root) - (lsp-auto-guess-root + (cond ((not lsp-auto-guess-root) nil) + ((null root) nil) + ((not (cl-find-if (lambda (dir) + (and (lsp--files-same-host dir root) + (file-in-directory-p dir root))) + (lsp-session-folders-blacklist (lsp-session)))) (lsp--find-root-interactively (lsp-session))))) (defadvice! +lsp-init-a (&optional arg) From 8e394ba3f07a719e9c19f7fd0f8e1cc8fb6b5d94 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 8 Nov 2019 04:10:16 -0500 Subject: [PATCH 025/129] tools/lookup: lazy load dash-docs --- modules/tools/lookup/autoload/docsets.el | 7 ++++--- modules/tools/lookup/config.el | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/tools/lookup/autoload/docsets.el b/modules/tools/lookup/autoload/docsets.el index a3e20021f..0e20f061b 100644 --- a/modules/tools/lookup/autoload/docsets.el +++ b/modules/tools/lookup/autoload/docsets.el @@ -65,9 +65,10 @@ Docsets must be installed with one of the following commands: + `dash-docs-async-install-docset-from-file' Docsets can be searched directly via `+lookup/in-docsets'." - (when-let (docsets (cl-remove-if-not #'dash-docs-docset-path (dash-docs-buffer-local-docsets))) - (+lookup/in-docsets nil identifier docsets) - 'deferred)) + (when (require 'dash-docs nil t) + (when-let (docsets (cl-remove-if-not #'dash-docs-docset-path (dash-docs-buffer-local-docsets))) + (+lookup/in-docsets nil identifier docsets) + 'deferred))) ;; diff --git a/modules/tools/lookup/config.el b/modules/tools/lookup/config.el index d519f2b23..6dc5adada 100644 --- a/modules/tools/lookup/config.el +++ b/modules/tools/lookup/config.el @@ -132,6 +132,7 @@ this list.") (use-package! dash-docs :when (featurep! +docsets) + :defer t :init (add-hook '+lookup-documentation-functions #'+lookup-dash-docsets-backend-fn) :config From ee2c1e384c6e8f8beb3404f6d687ffb67d324863 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 8 Nov 2019 16:12:25 -0500 Subject: [PATCH 026/129] Fix void-variable doom-module-dirs error from 'doom clean' --- core/cli/byte-compile.el | 1 + 1 file changed, 1 insertion(+) diff --git a/core/cli/byte-compile.el b/core/cli/byte-compile.el index 0ca58076e..916a11ba9 100644 --- a/core/cli/byte-compile.el +++ b/core/cli/byte-compile.el @@ -182,6 +182,7 @@ If RECOMPILE-P is non-nil, only recompile out-of-date files." (defun doom-clean-byte-compiled-files () "Delete all the compiled elc files in your Emacs configuration and private module. This does not include your byte-compiled, third party packages.'" + (require 'core-modules) (print! (start "Cleaning .elc files")) (print-group! (cl-loop with default-directory = doom-emacs-dir From 35152fda6749f9c8a5201559462f33d458869482 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 8 Nov 2019 16:20:34 -0500 Subject: [PATCH 027/129] Fix 'doom env -c' Throwing "I don't understand 'doom env -c'" errors --- core/cli/env.el | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/cli/env.el b/core/cli/env.el index df882e764..4368f948d 100644 --- a/core/cli/env.el +++ b/core/cli/env.el @@ -6,8 +6,7 @@ "Generate the envvar file at PATH. Note that envvar files that aren't in `doom-env-file' won't be loaded automatically at startup. You will need to load them manually from your private config with the `doom-load-envvars-file' -function.") - &rest args) +function.")) "Creates or regenerates your envvars file. The envvars file is created by scraping your (interactive) shell environment From d20d664f84c1cdaa969a22a6b7c5e75732017f3d Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 8 Nov 2019 16:39:48 -0500 Subject: [PATCH 028/129] Update 'doom install' to reflect recent changes #2033 --- core/cli/install.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/cli/install.el b/core/cli/install.el index 32d411ece..f4bf12126 100644 --- a/core/cli/install.el +++ b/core/cli/install.el @@ -79,10 +79,10 @@ DOOMDIR environment variable. e.g. (if noinstall-p (print! (warn "Not installing plugins, as requested")) (print! "Installing plugins") - (doom-cli-packages-install doom-auto-accept)) + (doom-cli-packages-install)) (print! "Regenerating autoloads files") - (doom-reload-autoloads nil 'force-p) + (doom-cli-reload-autoloads nil 'force-p) (if nofonts-p (print! (warn "Not installing fonts, as requested")) From fd470f4052717b8c3767580257b2899e361549fc Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 8 Nov 2019 16:46:01 -0500 Subject: [PATCH 029/129] Don't test on snapshot It's too volatile, and as of yet I don't know how to get github actions to ignore failures on this version. --- .github/workflows/test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cc11691f2..e189bc259 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,7 +19,6 @@ jobs: - 26.1 - 26.2 - 26.3 - - snapshot include: - emacs_version: 26.3 lint_ignore: 1 From 4ce153519c4ed2d213fbb142a40d309185c66709 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 8 Nov 2019 16:56:58 -0500 Subject: [PATCH 030/129] Refactor out map.el dependency Since map-put appears to be deprecated on Emacs 27 --- core/core-cli.el | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/core/core-cli.el b/core/core-cli.el index 1d5738ca0..69d53c066 100644 --- a/core/core-cli.el +++ b/core/core-cli.el @@ -1,7 +1,5 @@ ;;; -*- lexical-binding: t; no-byte-compile: t; -*- -(require 'map) - ;; 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). @@ -66,30 +64,28 @@ commands like `doom-cli-packages-install', `doom-cli-packages-update' and (opt (doom--cli-get-option cli fullflag))) (unless opt (user-error "Unrecognized switch %S" (concat "--" (match-string 2 arg)))) - (map-put - alist (doom-cli-option-symbol opt) - (or (if (doom-cli-option-args opt) - (or (match-string 3 arg) - (pop args) - (user-error "%S expected an argument, but got none" - fullflag)) - (if (match-string 3 arg) - (user-error "%S was not expecting an argument, but got %S" - fullflag (match-string 3 arg)) - fullflag)))))) + (setf (alist-get (doom-cli-option-symbol opt) alist) + (or (if (doom-cli-option-args opt) + (or (match-string 3 arg) + (pop args) + (user-error "%S expected an argument, but got none" + fullflag)) + (if (match-string 3 arg) + (user-error "%S was not expecting an argument, but got %S" + fullflag (match-string 3 arg)) + fullflag)))))) ((string-match "^\\(-\\([a-zA-Z0-9]+\\)\\)$" arg) (let ((fullflag (match-string 1 arg)) (flag (match-string 2 arg))) (dolist (switch (split-string flag "" t)) (if-let (opt (doom--cli-get-option cli (concat "-" switch))) - (map-put - alist (doom-cli-option-symbol opt) - (if (doom-cli-option-args opt) - (or (pop args) - (user-error "%S expected an argument, but got none" - fullflag)) - fullflag)) + (setf (alist-get (doom-cli-option-symbol opt) alist) + (if (doom-cli-option-args opt) + (or (pop args) + (user-error "%S expected an argument, but got none" + fullflag)) + fullflag)) (user-error "Unrecognized switch %S" (concat "-" switch)))))) (arglist @@ -97,7 +93,7 @@ commands like `doom-cli-packages-install', `doom-cli-packages-update' and (let ((spec (pop arglist))) (when (eq spec '&optional) (setq spec (pop arglist))) - (map-put alist spec arg)) + (setf (alist-get spec alist) arg)) (when (null arglist) (throw 'done t))) @@ -107,7 +103,7 @@ commands like `doom-cli-packages-install', `doom-cli-packages-update' and (when (< got expected) (error "Expected %d arguments, got %d" expected got)) (when rest - (map-put alist restvar rest)) + (setf (alist-get restvar alist) rest)) alist)) (defun doom-cli-get (command) From 5c459e75f87c7b158a0c24e07cbe90a323a87331 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 8 Nov 2019 16:57:25 -0500 Subject: [PATCH 031/129] Fix 'doom refresh' not seeing -f/--force --- core/core-cli.el | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/core-cli.el b/core/core-cli.el index 69d53c066..7acf5a1b1 100644 --- a/core/core-cli.el +++ b/core/core-cli.el @@ -208,8 +208,7 @@ BODY will be run when this dispatcher is called." (load! "cli/install") (defcli! (refresh re) - ((force-p ["-f" "--force"] "Regenerate autoloads files, whether or not they're stale") - &rest args) + ((force-p ["-f" "--force"] "Regenerate autoloads files, whether or not they're stale")) "Ensure Doom is properly set up. This is the equivalent of running autoremove, install, autoloads, then From 3896b994b534704dc09035a8266020c7d29b5ecd Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 8 Nov 2019 17:30:21 -0500 Subject: [PATCH 032/129] Remove double-negative filesize from 'doom purge' --- core/cli/packages.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/cli/packages.el b/core/cli/packages.el index caaebfec2..b25ce2194 100644 --- a/core/cli/packages.el +++ b/core/cli/packages.el @@ -229,7 +229,7 @@ declaration) or dependency thereof that hasn't already been." (let ((before-size (doom-directory-size (straight--repos-dir)))) (prog1 (print-group! (delq nil (mapcar #'doom--cli-packages-regraft-repo repos))) (let ((after-size (doom-directory-size (straight--repos-dir)))) - (print! (success "Finished regrafting. Size before: %0.1fKB and after: %0.1fKB (-%0.1fKB)") + (print! (success "Finished regrafting. Size before: %0.1fKB and after: %0.1fKB (%0.1fKB)") before-size after-size (- after-size before-size))))))) From 135e7ffc89b41772b6f75650f40419483dd5f273 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 8 Nov 2019 17:48:16 -0500 Subject: [PATCH 033/129] Load seq in core-cli --- core/core-cli.el | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/core-cli.el b/core/core-cli.el index 7acf5a1b1..6a36e2e04 100644 --- a/core/core-cli.el +++ b/core/core-cli.el @@ -1,5 +1,7 @@ ;;; -*- lexical-binding: t; no-byte-compile: t; -*- +(require 'seq) + ;; 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). From cc1bbe0b7ea7426f964871f8f8387d91f4c69353 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 9 Nov 2019 02:23:58 -0500 Subject: [PATCH 034/129] core-cli: add doom-cli constructor --- core/core-cli.el | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/core/core-cli.el b/core/core-cli.el index 6a36e2e04..7ae183275 100644 --- a/core/core-cli.el +++ b/core/core-cli.el @@ -22,14 +22,28 @@ commands like `doom-cli-packages-install', `doom-cli-packages-update' and (defvar doom--cli-groups (make-hash-table :test 'equal)) (defvar doom--cli-group nil) -;; TODO Constructors for optlist, arglist and fn -(cl-defstruct doom-cli - (name) +(cl-defstruct + (doom-cli + (:constructor nil) + (:constructor + make-doom-cli + (name &key desc aliases optlist arglist plist fn + &aux + (optlist + (cl-loop for (symbol options desc) in optlist + for ((_ . options) (_ . params)) + = (seq-group-by #'stringp options) + collect + (make-doom-cli-option :symbol symbol + :flags options + :args params + :desc desc)))))) + (name nil :read-only t) (desc "TODO") - (aliases ()) - (optlist ()) - (arglist ()) - (plist ()) + aliases + optlist + arglist + plist (fn (lambda (_) (print! "But nobody came!")))) (cl-defstruct doom-cli-option @@ -165,19 +179,11 @@ BODY will be run when this dispatcher is called." (setq plist (plist-put plist :group doom--cli-group))) (puthash name - (make-doom-cli :name (symbol-name name) + (make-doom-cli (symbol-name name) :desc ,docstring :aliases (mapcar #'symbol-name aliases) :arglist ',arglist - :optlist - (cl-loop for (symbol options desc) in ',optlist - for ((_ . options) (_ . params)) - = (seq-group-by #'stringp options) - collect - (make-doom-cli-option :symbol symbol - :flags options - :args params - :desc desc)) + :optlist ',optlist :plist plist :fn (lambda (--alist--) From a55b5a4514b8fa04e0bda8d426358a4143cb01e3 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 9 Nov 2019 11:06:06 -0500 Subject: [PATCH 035/129] Fix void-function doom-sh error in 'doom upgrade' #2034 --- core/cli/upgrade.el | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/core/cli/upgrade.el b/core/cli/upgrade.el index 9244c293b..dad07e387 100644 --- a/core/cli/upgrade.el +++ b/core/cli/upgrade.el @@ -28,7 +28,7 @@ following shell commands: (defun doom--working-tree-dirty-p (dir) (cl-destructuring-bind (success . stdout) - (doom-sh "git" "status" "--porcelain" "-uno") + (doom-call-process "git" "status" "--porcelain" "-uno") (if (= 0 success) (string-match-p "[^ \t\n]" (buffer-string)) (error "Failed to check working tree in %s" dir)))) @@ -55,15 +55,15 @@ following shell commands: (format "Refusing to upgrade because %S has been modified." (path doom-emacs-dir)) "Either stash/undo your changes or run 'doom upgrade -f' to discard local changes.") (print! (info "You have local modifications in Doom's source. Discarding them...")) - (doom-sh "git" "reset" "--hard" (format "origin/%s" branch)) - (doom-sh "git" "clean" "-ffd"))) + (doom-call-process "git" "reset" "--hard" (format "origin/%s" branch)) + (doom-call-process "git" "clean" "-ffd"))) - (doom-sh "git" "remote" "remove" doom-repo-remote) + (doom-call-process "git" "remote" "remove" doom-repo-remote) (unwind-protect (progn - (or (zerop (car (doom-sh "git" "remote" "add" doom-repo-remote doom-repo-url))) + (or (zerop (car (doom-call-process "git" "remote" "add" doom-repo-remote doom-repo-url))) (error "Failed to add %s to remotes" doom-repo-remote)) - (or (zerop (car (doom-sh "git" "fetch" "--tags" doom-repo-remote branch))) + (or (zerop (car (doom-call-process "git" "fetch" "--tags" doom-repo-remote branch))) (error "Failed to fetch from upstream")) (let ((this-rev (vc-git--rev-parse "HEAD")) @@ -79,9 +79,9 @@ following shell commands: ((print! (info "A new version of Doom Emacs is available!\n\n Old revision: %s (%s)\n New revision: %s (%s)\n" (substring this-rev 0 10) - (cdr (doom-sh "git" "log" "-1" "--format=%cr" "HEAD")) + (cdr (doom-call-process "git" "log" "-1" "--format=%cr" "HEAD")) (substring new-rev 0 10) - (cdr (doom-sh "git" "log" "-1" "--format=%cr" target-remote)))) + (cdr (doom-call-process "git" "log" "-1" "--format=%cr" target-remote)))) (when (and (not auto-accept-p) (y-or-n-p "View the comparison diff in your browser?")) @@ -96,7 +96,7 @@ following shell commands: (print! (start "Upgrading Doom Emacs...")) (print-group! (doom-clean-byte-compiled-files) - (unless (and (zerop (car (doom-sh "git" "reset" "--hard" target-remote))) + (unless (and (zerop (car (doom-call-process "git" "reset" "--hard" target-remote))) (equal (vc-git--rev-parse "HEAD") new-rev)) (error "Failed to check out %s" (substring new-rev 0 10))) (print! (success "Finished upgrading Doom Emacs"))) @@ -106,4 +106,4 @@ following shell commands: (print! (success "Done! Restart Emacs for changes to take effect.")))))) (ignore-errors - (doom-sh "git" "remote" "remove" doom-repo-remote)))))) + (doom-call-process "git" "remote" "remove" doom-repo-remote)))))) From 5b5c7cbaff9b533cf09ee31a41edee7d0980b4b3 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 9 Nov 2019 11:51:28 -0500 Subject: [PATCH 036/129] docs/getting_started: remove markdown-isms --- docs/getting_started.org | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/docs/getting_started.org b/docs/getting_started.org index cb9940b6a..ff7c80d78 100644 --- a/docs/getting_started.org +++ b/docs/getting_started.org @@ -59,8 +59,8 @@ - [[#variables-functions-faces-etc][Variables, functions, faces, etc.]] - [[#for-doom-modules-packages-autodefs-etc][For Doom Modules, packages, autodefs, etc.]] - [[#how-to-extract-a-backtrace-from-an-error][How to extract a backtrace from an error]] - - [[#enabling-debug-on-error][Enabling `debug-on-error`]] - - [[#a-backtrace-from-bindoom][A backtrace from `bin/doom`]] + - [[#enabling-debug-on-error][Enabling ~debug-on-error~]] + - [[#a-backtrace-from-bindoom][A backtrace from ~bin/doom~]] - [[#evaluating-elisp-on-the-fly][Evaluating Elisp on-the-fly]] - [[#how-to-determine-the-origin-of-a-bug][How to determine the origin of a bug]] - [[#testing-in-dooms-sandbox][Testing in Doom's sandbox]] @@ -1080,24 +1080,23 @@ You can also evaluate code with ~eval-expression~ (=M-;= or =SPC ;=). ** How to extract a backtrace from an error If you encounter an error while using Doom Emacs, you're probably about to head -off and file a bug report (or request help on [[[https://discord.gg/bcZ6P3y][our Discord server]]. Before you do, -please generate a backtrace to include with it. +off and file a bug report (or request help on [[https://discord.gg/bcZ6P3y][our Discord server]]). Before you +do, please generate a backtrace to include with it. To do so you must enable ~debug-on-error~ then recreate the error. -*** Enabling `debug-on-error` -There are three ways to enable `debug-on-error`: +*** Enabling ~debug-on-error~ +There are three ways to enable ~debug-on-error~: -1. Start Emacs with `emacs --debug-init`. Use this for errors that occur at +1. Start Emacs with ~emacs --debug-init~. Use this for errors that occur at startup. -2. Evil users can press SPC h d d and non-evil users can press - =C-h d d=. -3. If the above don't work, there's always: `M-x toggle-debug-on-error` +2. Evil users can press =SPC h d d= and non-evil users can press =C-h d d=. +3. If the above don't work, there's always: ~M-x toggle-debug-on-error~ -Now that `debug-on-error` is on, recreate the error. A window should pop up with +Now that ~debug-on-error~ is on, recreate the error. A window should pop up with a backtrace. -*** A backtrace from `bin/doom` +*** A backtrace from ~bin/doom~ If the error you've encountered is emitted from ~bin/doom~, you can re-run the same command with the ~-d~ or ~--debug~ switches to force it to emit a backtrace when an error occurs. The ~DEBUG~ environment variable will work to. From 3911a733b7deccd15a611c6dee073c2300ad17d3 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 9 Nov 2019 12:02:53 -0500 Subject: [PATCH 037/129] Run tests in debug mode --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e189bc259..65c1ca307 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,7 +33,7 @@ jobs: - name: Doom version run: "bin/doom version" - name: Run tests - run: "bin/doom test" + run: "bin/doom -d test" # FIXME # name: Compile # run: "bin/doom -y compile" From b3b0af8a35e7d6b8db88226e67fa0dd4b26a0188 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 9 Nov 2019 17:00:33 -0500 Subject: [PATCH 038/129] Complain if autoload libs fail to load --- core/core-cli.el | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/core-cli.el b/core/core-cli.el index 7ae183275..5cde55b4b 100644 --- a/core/core-cli.el +++ b/core/core-cli.el @@ -2,10 +2,10 @@ (require 'seq) -;; 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) +;; 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 nil (not doom-debug-mode) 'nosuffix) (file-expand-wildcards (concat doom-core-dir "autoload/*.el"))) From 31f1873aaa656b4eac943c7b161307d8ffafd7ff Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 9 Nov 2019 17:03:40 -0500 Subject: [PATCH 039/129] Fix tests --- core/cli/test.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/cli/test.el b/core/cli/test.el index 8696dc1e4..4def753a3 100644 --- a/core/cli/test.el +++ b/core/cli/test.el @@ -33,6 +33,8 @@ (appendq! files (nreverse (doom-glob target "test/test-*.el")))) ((file-exists-p target) (push target files))))) + (setenv "DOOMLOCALDIR" (concat doom-local-dir "test/")) + (setenv "DOOMDIR" (concat doom-core-dir "test/")) (with-temp-buffer (print! (start "Bootstrapping test environment, if necessary...")) (cl-destructuring-bind (status . output) @@ -42,9 +44,7 @@ "--eval" (prin1-to-string `(progn - (setq doom-emacs-dir ,doom-emacs-dir - doom-local-dir ,(concat doom-local-dir "test/") - doom-private-dir ,(concat doom-core-dir "test/") + (setq user-emacs-directory ,doom-emacs-dir doom-auto-accept t) (require 'core ,(locate-library "core")) (require 'core-cli) From a996dfdb6de1c59955ef612bb9dfdacbb875ebda Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 9 Nov 2019 17:19:38 -0500 Subject: [PATCH 040/129] Don't run tests in debug mode Way too verbose. Buttercup does enough of a job putting out debug info. --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 65c1ca307..e189bc259 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,7 +33,7 @@ jobs: - name: Doom version run: "bin/doom version" - name: Run tests - run: "bin/doom -d test" + run: "bin/doom test" # FIXME # name: Compile # run: "bin/doom -y compile" From 967e32c0845d001ba87ad867a7be5090e454d93b Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 9 Nov 2019 17:28:39 -0500 Subject: [PATCH 041/129] Ignore doom-debug-mode in quiet! tests --- core/test/test-core-lib.el | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/test/test-core-lib.el b/core/test/test-core-lib.el index 9007465f7..132ed295a 100644 --- a/core/test/test-core-lib.el +++ b/core/test/test-core-lib.el @@ -243,6 +243,10 @@ (expand-file-name "path" doom-etc-dir) nil 'nomessage))) (describe "quiet!" + :var (doom-debug-mode) + (before-each + (setq doom-debug-mode nil)) + (it "suppresses output from message" (expect (message "hello world") :to-output "hello world\n") (expect (message "hello world") :to-output) From 2158b7bdeb6ed41b5a089416355cc0bccb122c1d Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 9 Nov 2019 20:25:55 -0500 Subject: [PATCH 042/129] Fix dir! & file! tests --- core/test/test-core-lib.el | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/test/test-core-lib.el b/core/test/test-core-lib.el index 132ed295a..5391070d1 100644 --- a/core/test/test-core-lib.el +++ b/core/test/test-core-lib.el @@ -69,13 +69,15 @@ (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)))) + :to-equal + (eval-and-compile load-file-name)))) (describe "dir!" (it "returns the executing directory" (expect (eval-and-compile (dir!)) - :to-equal (expand-file-name "test" doom-core-dir)))) + :to-equal + (eval-and-compile + (directory-file-name (file-name-directory load-file-name)))))) (describe "pushnew!" (it "pushes values onto a list symbol, in order" From 5c3f7d648d5aed7508732e9228f719e75117783b Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 9 Nov 2019 20:28:31 -0500 Subject: [PATCH 043/129] cli/doctor: fix void-variable font-dest error ...when a font is missing. --- core/cli/doctor.el | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/cli/doctor.el b/core/cli/doctor.el index 28b1b009d..c04409426 100644 --- a/core/cli/doctor.el +++ b/core/cli/doctor.el @@ -145,8 +145,7 @@ in." (insert (cdr (doom-call-process "fc-list"))) (re-search-backward "Fira" nil t)) (success! "Found font %s" font) - (print! (warn "Warning: couldn't find %s font in %s") - font font-dest) + (print! (warn "Warning: couldn't find %S font") font) (explain! "You can install it by running `M-x all-the-icons-install-fonts' within Emacs.\n\n" "This could also mean you've installed them in non-standard locations, in which " "case feel free to ignore this warning.")))))) From 6c31968a462d1fb75ec4aeaba38641a1b1f2d7bb Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 9 Nov 2019 20:32:48 -0500 Subject: [PATCH 044/129] cli/doctor: fix font checks --- core/cli/doctor.el | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/core/cli/doctor.el b/core/cli/doctor.el index c04409426..2288388a2 100644 --- a/core/cli/doctor.el +++ b/core/cli/doctor.el @@ -140,15 +140,15 @@ in." "/fonts/")) (`darwin "~/Library/Fonts/")) (require 'all-the-icons nil t)) - (dolist (font all-the-icons-font-families) - (if (with-temp-buffer - (insert (cdr (doom-call-process "fc-list"))) - (re-search-backward "Fira" nil t)) - (success! "Found font %s" font) - (print! (warn "Warning: couldn't find %S font") font) - (explain! "You can install it by running `M-x all-the-icons-install-fonts' within Emacs.\n\n" - "This could also mean you've installed them in non-standard locations, in which " - "case feel free to ignore this warning.")))))) + (with-temp-buffer + (insert (cdr (doom-call-process "fc-list"))) + (dolist (font all-the-icons-font-names) + (if (save-excursion (re-search-backward font nil t)) + (success! "Found font %s" font) + (print! (warn "Warning: couldn't find %S font") font) + (explain! "You can install it by running `M-x all-the-icons-install-fonts' within Emacs.\n\n" + "This could also mean you've installed them in non-standard locations, in which " + "case feel free to ignore this warning."))))))) (print! (start "Checking for stale elc files in your DOOMDIR...")) (when (file-directory-p doom-private-dir) From 7034b22e0dea3a0d0e44ca6fbac8e147e361a1a0 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 10 Nov 2019 14:14:23 +0900 Subject: [PATCH 045/129] remove extra level of parens Signed-off-by: Rudi Grinberg --- modules/lang/rst/config.el | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/lang/rst/config.el b/modules/lang/rst/config.el index 77cec504d..34ea7a0b5 100644 --- a/modules/lang/rst/config.el +++ b/modules/lang/rst/config.el @@ -12,7 +12,7 @@ "a" #'rst-adjust "r" #'rst-adjust-region) (:prefix ("t" . "table of contents") - ("t" #'rst-toc - "i" #'rst-toc-insert - "u" #'rst-toc-update - "f" #'rst-toc-follow-link)))) + "t" #'rst-toc + "i" #'rst-toc-insert + "u" #'rst-toc-update + "f" #'rst-toc-follow-link))) From d3d51e32a25c22f875c085a0182b5e13cba8e62f Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 10 Nov 2019 01:23:27 -0500 Subject: [PATCH 046/129] lang/org: remove unusable localleader keybinds #2042 These commands only make sense in org-agenda-mode, specifically. --- modules/lang/org/config.el | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/lang/org/config.el b/modules/lang/org/config.el index d89c3de41..6bd4cbb8e 100644 --- a/modules/lang/org/config.el +++ b/modules/lang/org/config.el @@ -676,8 +676,6 @@ between the two." (:when (featurep! :completion ivy) "g" #'counsel-org-goto "G" #'counsel-org-goto-all) - "a" #'org-agenda-goto - "A" #'org-agenda-clock-goto "c" #'org-clock-goto "C" (λ! (org-clock-goto 'select)) "i" #'org-id-goto From 17b874dedd5cb5657478e725ab183bcff1acc1a6 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 10 Nov 2019 01:32:58 -0500 Subject: [PATCH 047/129] Refactor doom-file-size Change it throw an error if the file doesn't exist. --- core/autoload/files.el | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/autoload/files.el b/core/autoload/files.el index 7365641f6..3499f14ad 100644 --- a/core/autoload/files.el +++ b/core/autoload/files.el @@ -169,8 +169,10 @@ single file or nested compound statement of `and' and `or' statements." ;;;###autoload (defun doom-file-size (file &optional dir) - "Returns the size of FILE (in DIR) in kilobytes." - (when-let (file (file-exists-p! file dir)) + "Returns the size of FILE (in DIR) in bytes." + (let ((file (expand-file-name file dir))) + (unless (file-exists-p file) + (error "Couldn't find file %S" file)) (unless (file-readable-p file) (error "File %S is unreadable; can't acquire its filesize" file)) From 962459e8ba4c8f3fe486a08f8da7518385a309e2 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 10 Nov 2019 01:35:21 -0500 Subject: [PATCH 048/129] cli/doctor: fix cache filesize checks Closes #2041 --- core/cli/doctor.el | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/core/cli/doctor.el b/core/cli/doctor.el index 2288388a2..bf6ed3a7e 100644 --- a/core/cli/doctor.el +++ b/core/cli/doctor.el @@ -97,11 +97,9 @@ in." (print-group! ;; Check for oversized problem files in cache that may cause unusual/tremendous ;; delays or freezing. This shouldn't happen often. - (dolist (file (list "savehist" - "projectile.cache")) - (let* ((path (expand-file-name file doom-cache-dir)) - (size (/ (doom-file-size path) 1024))) - (when (and (numberp size) (> size 1000)) + (dolist (file (list "savehist" "projectile.cache")) + (when-let (size (ignore-errors (doom-file-size path))) + (when (> size 1048576) ; larger than 1mb (warn! "%s is too large (%.02fmb). This may cause freezes or odd startup delays" (relpath path) (/ size 1024)) From e252ee61e724ee275ed6ec2ece105625f5447ad4 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 10 Nov 2019 01:39:30 -0500 Subject: [PATCH 049/129] cli/doctor: fix HOME project root detection --- core/cli/doctor.el | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/core/cli/doctor.el b/core/cli/doctor.el index bf6ed3a7e..dcc07ccd3 100644 --- a/core/cli/doctor.el +++ b/core/cli/doctor.el @@ -110,12 +110,11 @@ in." (unless (executable-find "rg") (warn! "Couldn't find the `rg' binary either; project file searches will be even slower"))) - (let ((default-directory "~")) - (require 'projectile) - (when (cl-find-if #'projectile-file-exists-p projectile-project-root-files-bottom-up) - (warn! "Your $HOME is recognized as a project root") - (explain! "Doom will disable bottom-up root search, which may reduce the accuracy of project\n" - "detection."))) + (require 'projectile) + (when (projectile-project-root "~") + (warn! "Your $HOME is recognized as a project root") + (explain! "Doom will disable bottom-up root search, which may reduce the accuracy of project\n" + "detection.")) ;; There should only be one (when (and (file-equal-p doom-private-dir "~/.config/doom") From dd1dd6901fc1a98e3e0cebbaa7d48df1237ec25c Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 10 Nov 2019 04:29:53 -0500 Subject: [PATCH 050/129] doom-directory-size: error if path doesn't exist --- core/autoload/files.el | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/autoload/files.el b/core/autoload/files.el index 3499f14ad..a61434cda 100644 --- a/core/autoload/files.el +++ b/core/autoload/files.el @@ -181,6 +181,8 @@ single file or nested compound statement of `and' and `or' statements." ;;;###autoload (defun doom-directory-size (dir) "Returns the size of FILE (in DIR) in kilobytes." + (unless (file-directory-p dir) + (error "Directory %S does not exist" dir)) (if (executable-find "du") (/ (string-to-number (cdr (doom-call-process "du" "-sb" dir))) 1024.0) From 6625ef7177f4cde64e701bfcd07e0dc9c9b8e1a7 Mon Sep 17 00:00:00 2001 From: johsi-k Date: Sun, 10 Nov 2019 17:33:06 +0800 Subject: [PATCH 051/129] [lang/javascript] Add prefix names to JavaScript bindings (#1991) * add prefix names to javascript bindings * move prefixes into respective package declarations --- modules/lang/javascript/config.el | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/modules/lang/javascript/config.el b/modules/lang/javascript/config.el index 55e8daff1..45168fddf 100644 --- a/modules/lang/javascript/config.el +++ b/modules/lang/javascript/config.el @@ -188,7 +188,7 @@ to tide." :map tide-mode-map "R" #'tide-restart-server "f" #'tide-format - "rs" #'tide-rename-symbol + "rrs" #'tide-rename-symbol "roi" #'tide-organize-imports)) @@ -205,7 +205,25 @@ to tide." :config (when (featurep! :editor evil +everywhere) (let ((js2-refactor-mode-map (evil-get-auxiliary-keymap js2-refactor-mode-map 'normal t t))) - (js2r-add-keybindings-with-prefix (format "%s r" doom-localleader-key))))) + (js2r-add-keybindings-with-prefix (format "%s r" doom-localleader-key)))) + (map! :map js2-mode-map + :localleader + (:prefix ("r" . "refactor") + (:prefix ("a" . "add/arguments")) + (:prefix ("b" . "barf")) + (:prefix ("c" . "contract")) + (:prefix ("d" . "debug")) + (:prefix ("e" . "expand/extract")) + (:prefix ("i" . "inject/inline/introduce")) + (:prefix ("l" . "localize/log")) + (:prefix ("o" . "organize")) + (:prefix ("r" . "rename")) + (:prefix ("s" . "slurp/split/string")) + (:prefix ("t" . "toggle")) + (:prefix ("u" . "unwrap")) + (:prefix ("v" . "var")) + (:prefix ("w" . "wrap")) + (:prefix ("3" . "ternary"))))) (use-package! eslintd-fix @@ -234,6 +252,9 @@ to tide." (:after skewer-html :map skewer-html-mode-map "e" #'skewer-html-eval-tag)) +(map! :map js2-mode-map + :localleader + (:prefix ("s" . "skewer"))) ;;;###package npm-mode @@ -242,7 +263,10 @@ to tide." :config (map! :localleader :map npm-mode-keymap - "n" npm-mode-command-keymap)) + "n" npm-mode-command-keymap) + (map! :map js2-mode-map + :localleader + (:prefix ("n" . "npm")))) ;; From 829e1762b1df228b953c591a3fa1091862b9caaf Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 10 Nov 2019 04:50:47 -0500 Subject: [PATCH 052/129] cli/doctor: fix vestigial variable references --- core/cli/doctor.el | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/cli/doctor.el b/core/cli/doctor.el index dcc07ccd3..e568ff3c9 100644 --- a/core/cli/doctor.el +++ b/core/cli/doctor.el @@ -98,11 +98,10 @@ in." ;; Check for oversized problem files in cache that may cause unusual/tremendous ;; delays or freezing. This shouldn't happen often. (dolist (file (list "savehist" "projectile.cache")) - (when-let (size (ignore-errors (doom-file-size path))) + (when-let (size (ignore-errors (doom-file-size file doom-cache-dir))) (when (> size 1048576) ; larger than 1mb (warn! "%s is too large (%.02fmb). This may cause freezes or odd startup delays" - (relpath path) - (/ size 1024)) + file (/ size 1024)) (explain! "Consider deleting it from your system (manually)")))) (unless (ignore-errors (executable-find doom-projectile-fd-binary)) From 58e674d8fb85515e7980c87fc708dabb2b276128 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 10 Nov 2019 05:05:42 -0500 Subject: [PATCH 053/129] tools/lsp: fix LSP prompting for project too often --- modules/tools/lsp/config.el | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/modules/tools/lsp/config.el b/modules/tools/lsp/config.el index f4bdc3a79..8c323994f 100644 --- a/modules/tools/lsp/config.el +++ b/modules/tools/lsp/config.el @@ -52,16 +52,17 @@ auto-killed (which is usually an expensive process)." (funcall orig-fn)))) lsp--cur-workspace)))) - (defadvice! +lsp-prompt-if-no-project-a (root) + (defadvice! +lsp-prompt-if-no-project-a (session file-name) "Prompt for the project root only if no project was found." - :filter-return #'lsp--calculate-root - (cond ((not lsp-auto-guess-root) nil) - ((null root) nil) - ((not (cl-find-if (lambda (dir) - (and (lsp--files-same-host dir root) - (file-in-directory-p dir root))) - (lsp-session-folders-blacklist (lsp-session)))) - (lsp--find-root-interactively (lsp-session))))) + :after-until #'lsp--calculate-root + (cond ((not lsp-auto-guess-root) + nil) + ((cl-find-if (lambda (dir) + (and (lsp--files-same-host dir file-name) + (file-in-directory-p file-name dir))) + (lsp-session-folders-blacklist session)) + nil) + ((lsp--find-root-interactively session)))) (defadvice! +lsp-init-a (&optional arg) "Enable `lsp-mode' in the current buffer. From 396b433ae0781819475d47cb428595f662a3056a Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 10 Nov 2019 19:10:49 +0900 Subject: [PATCH 054/129] Add clock bindings to org agenda Signed-off-by: Rudi Grinberg --- modules/lang/org/config.el | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/lang/org/config.el b/modules/lang/org/config.el index bd1bf6d1d..32b5e4564 100644 --- a/modules/lang/org/config.el +++ b/modules/lang/org/config.el @@ -698,6 +698,13 @@ between the two." [remap org-agenda-Quit] #'org-agenda-exit :localleader "d" #'org-agenda-deadline + (:prefix ("c" . "clock") + "c" #'org-agenda-clock-in + "C" #'org-agenda-clock-out + "g" #'org-agenda-clock-goto + "l" #'org-agenda-clock-cancel + "r" #'org-agenda-clockreport-mode + "s" #'org-agenda-show-clocking-issues) "q" #'org-agenda-set-tags "r" #'org-agenda-refile "s" #'org-agenda-schedule From 69c4964e3bdcfc7f3b3601ee0d191f61740138ad Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 10 Nov 2019 13:44:23 -0500 Subject: [PATCH 055/129] Move org-agenda-clock-cancel to cx To match lang/org's cx keybind --- modules/lang/org/config.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/lang/org/config.el b/modules/lang/org/config.el index 32b5e4564..03c27fcc7 100644 --- a/modules/lang/org/config.el +++ b/modules/lang/org/config.el @@ -702,9 +702,9 @@ between the two." "c" #'org-agenda-clock-in "C" #'org-agenda-clock-out "g" #'org-agenda-clock-goto - "l" #'org-agenda-clock-cancel "r" #'org-agenda-clockreport-mode - "s" #'org-agenda-show-clocking-issues) + "s" #'org-agenda-show-clocking-issues + "x" #'org-agenda-clock-cancel) "q" #'org-agenda-set-tags "r" #'org-agenda-refile "s" #'org-agenda-schedule From 89893719dc73b270d1c4b39ca8e5098a0337d216 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 10 Nov 2019 13:42:14 -0500 Subject: [PATCH 056/129] lang/org: bind cr -> org-clock-report --- modules/lang/org/config.el | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/lang/org/config.el b/modules/lang/org/config.el index 03c27fcc7..d59fa794d 100644 --- a/modules/lang/org/config.el +++ b/modules/lang/org/config.el @@ -669,6 +669,7 @@ between the two." "l" #'org-clock-in-last "g" #'org-clock-goto "G" (λ! (org-clock-goto 'select)) + "r" #'org-clock-report "x" #'org-clock-cancel "=" #'org-clock-timestamps-up "-" #'org-clock-timestamps-down) From 4ceb09c219c22f72b3e9c55c1b5980a63b819289 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 10 Nov 2019 16:44:53 -0500 Subject: [PATCH 057/129] cli/upgrade: don't double-update packages And don't initialize too much of Doom before updating it. --- core/cli/upgrade.el | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/cli/upgrade.el b/core/cli/upgrade.el index dad07e387..7116d7395 100644 --- a/core/cli/upgrade.el +++ b/core/cli/upgrade.el @@ -1,8 +1,7 @@ ;;; core/cli/upgrade.el -*- lexical-binding: t; -*- (defcli! (upgrade up) - ((force-p ["-f" "--force"]) - &rest args) + ((force-p ["-f" "--force"])) "Updates Doom and packages. This requires that ~/.emacs.d is a git repo, and is the equivalent of the @@ -13,6 +12,7 @@ following shell commands: bin/doom clean bin/doom refresh bin/doom update" + :bare t (and (doom-cli-upgrade doom-auto-accept force-p) (doom-cli-packages-update) (doom-cli-reload-package-autoloads 'force-p))) @@ -101,7 +101,6 @@ following shell commands: (error "Failed to check out %s" (substring new-rev 0 10))) (print! (success "Finished upgrading Doom Emacs"))) (doom-cli-execute "refresh" (append (if auto-accept-p '("-y")) '("-f"))) - (doom-cli-execute "update" (if auto-accept-p '("-y"))) t) (print! (success "Done! Restart Emacs for changes to take effect.")))))) From af63b0eb7a3cf33f5b8cc85fe0237b019e3b6291 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 10 Nov 2019 16:45:33 -0500 Subject: [PATCH 058/129] lang/swift: activate lsp on swift-mode-local-vars-hook --- modules/lang/swift/config.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/lang/swift/config.el b/modules/lang/swift/config.el index 74fd60da3..68470f3c7 100644 --- a/modules/lang/swift/config.el +++ b/modules/lang/swift/config.el @@ -22,7 +22,7 @@ (use-package! lsp-sourcekit :when (featurep! +lsp) :after swift-mode - :init (add-hook 'swift-mode-hook #'lsp!) + :init (add-hook 'swift-mode-local-vars-hook #'lsp!) :config (unless (getenv "SOURCEKIT_TOOLCHAIN_PATH") (setenv "SOURCEKIT_TOOLCHAIN_PATH" "/Library/Developer/Toolchains/swift-latest.xctoolchain")) From 8d112fdca8fe1eb43be01afab0d6ba3f04dacc96 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 10 Nov 2019 20:15:25 -0500 Subject: [PATCH 059/129] Prevent void-variable errors on 'doom upgrade' If Doom is up-to-date, certain Doom package state doesn't get initialized for the 'doom update' that occurs directly after, causing these errors. --- core/cli/upgrade.el | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/cli/upgrade.el b/core/cli/upgrade.el index 7116d7395..334fae5d3 100644 --- a/core/cli/upgrade.el +++ b/core/cli/upgrade.el @@ -13,9 +13,11 @@ following shell commands: bin/doom refresh bin/doom update" :bare t - (and (doom-cli-upgrade doom-auto-accept force-p) - (doom-cli-packages-update) - (doom-cli-reload-package-autoloads 'force-p))) + (when (doom-cli-upgrade doom-auto-accept force-p) + (doom-initialize) + (doom-initialize-packages) + (when (doom-cli-packages-update) + (doom-cli-reload-package-autoloads 'force-p)))) ;; From d2d079877c2086a5e226e3692aa7c579a7545b78 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 10 Nov 2019 20:50:01 -0500 Subject: [PATCH 060/129] lang/org: reformat packages.el --- modules/lang/org/packages.el | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/modules/lang/org/packages.el b/modules/lang/org/packages.el index f4f4cd52a..15ef59d61 100644 --- a/modules/lang/org/packages.el +++ b/modules/lang/org/packages.el @@ -14,12 +14,29 @@ (package! org-yt :recipe (:host github :repo "TobiasZawada/org-yt")) (package! ox-clip) (package! toc-org) + (when (featurep! :editor evil +everywhere) (package! evil-org :recipe (:host github :repo "hlissner/evil-org-mode"))) (when (featurep! :tools pdf) (package! org-pdfview)) (when (featurep! :tools magit) (package! orgit)) +(when (featurep! +dragndrop) + (package! org-download)) +(when (featurep! +gnuplot) + (package! gnuplot) + (package! gnuplot-mode)) +(when (featurep! +ipython) + (package! ob-ipython)) +(when (featurep! +pomodoro) + (package! org-pomodoro)) +(when (featurep! +present) + (package! centered-window + :recipe (:host github :repo "anler/centered-window-mode")) + (package! org-tree-slide) + (package! org-re-reveal)) +(when (featurep! +journal) + (package! org-journal)) ;;; Babel (package! ob-async) @@ -36,25 +53,9 @@ (when (featurep! :lang rust) (package! ob-rust)) -;;; Modules -(when (featurep! +dragndrop) - (package! org-download)) -(when (featurep! +gnuplot) - (package! gnuplot) - (package! gnuplot-mode)) -(when (featurep! +ipython) - (package! ob-ipython)) +;;; Export (when (featurep! +pandoc) (package! ox-pandoc)) -(when (featurep! +pomodoro) - (package! org-pomodoro)) -(when (featurep! +present) - (package! centered-window - :recipe (:host github :repo "anler/centered-window-mode")) - (package! org-tree-slide) - (package! org-re-reveal)) -(when (featurep! +journal) - (package! org-journal)) (when (featurep! +hugo) (package! ox-hugo :recipe (:host github :repo "kaushalmodi/ox-hugo" :nonrecursive t))) From c297d091bd72c4c3b90ba5f21dbb05ccf3aabdd0 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 10 Nov 2019 23:43:05 -0500 Subject: [PATCH 061/129] Fix void-function doom-initialize-packages on 'doom upgrade' --- core/cli/upgrade.el | 1 + 1 file changed, 1 insertion(+) diff --git a/core/cli/upgrade.el b/core/cli/upgrade.el index 334fae5d3..a11f3438c 100644 --- a/core/cli/upgrade.el +++ b/core/cli/upgrade.el @@ -14,6 +14,7 @@ following shell commands: bin/doom update" :bare t (when (doom-cli-upgrade doom-auto-accept force-p) + (require 'core-packages) (doom-initialize) (doom-initialize-packages) (when (doom-cli-packages-update) From 904ace43b65c934d0398e4735f599c277b216c46 Mon Sep 17 00:00:00 2001 From: Antoine Martin Date: Mon, 11 Nov 2019 19:38:48 +0100 Subject: [PATCH 062/129] Add rst module to init.example.el --- init.example.el | 1 + 1 file changed, 1 insertion(+) diff --git a/init.example.el b/init.example.el index cebc1f191..a50371ad0 100644 --- a/init.example.el +++ b/init.example.el @@ -143,6 +143,7 @@ ;;qt ; the 'cutest' gui framework ever ;;racket ; a DSL for DSLs ;;rest ; Emacs as a REST client + ;;rst ; ReST in peace ;;ruby ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"} ;;rust ; Fe2O3.unwrap().unwrap().unwrap().unwrap() ;;scala ; java, but good From e0d9ef80e097965a17ec87708d288a6631acd979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benno=20F=C3=BCnfst=C3=BCck?= Date: Mon, 11 Nov 2019 22:02:45 +0100 Subject: [PATCH 063/129] Fix coding style --- modules/ui/hydra/config.el | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/modules/ui/hydra/config.el b/modules/ui/hydra/config.el index ce36937cc..40a870fbe 100644 --- a/modules/ui/hydra/config.el +++ b/modules/ui/hydra/config.el @@ -9,8 +9,7 @@ ;;;###package hydra (setq lv-use-separator t) -(after! hydra - (defadvice! +hydra/inhibit-window-switch-hooks-a (orig-fn) - :around #'lv-window - (let ((doom-inhibit-switch-window-hooks t)) - (funcall orig-fn)))) +(defadvice! +hydra--inhibit-window-switch-hooks-a (orig-fn) + :around #'lv-window + (let ((doom-inhibit-switch-window-hooks t)) + (funcall orig-fn))) From e19c73843dcff3b034ba7cd0f4251ef3ddc83d06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benno=20F=C3=BCnfst=C3=BCck?= Date: Mon, 11 Nov 2019 22:03:48 +0100 Subject: [PATCH 064/129] Display empty string instead of magic EMPTY BUFFER --- modules/completion/ivy/autoload/ivy.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/completion/ivy/autoload/ivy.el b/modules/completion/ivy/autoload/ivy.el index 27a358f5a..50d9d41d3 100644 --- a/modules/completion/ivy/autoload/ivy.el +++ b/modules/completion/ivy/autoload/ivy.el @@ -513,7 +513,7 @@ If ALL-FILES-P, search compressed and hidden files as well." (cons (format "%s:%d: %s" (buffer-name) (line-number-at-pos) - (string-trim-right (or (thing-at-point 'line) ""))) + (string-trim-right (or (thing-at-point 'line) ""))) (point-marker))))))) (cddr (better-jumper-jump-list-struct-ring (better-jumper-get-jumps (better-jumper--get-current-context)))))))) From 781238f986d5ad65ab9adeca1a13ef54e4c2582b Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 11 Nov 2019 00:19:55 -0500 Subject: [PATCH 065/129] lang/org: alphabetize localleader keys --- modules/lang/org/config.el | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/modules/lang/org/config.el b/modules/lang/org/config.el index d59fa794d..6f6a72a1a 100644 --- a/modules/lang/org/config.el +++ b/modules/lang/org/config.el @@ -649,18 +649,19 @@ between the two." "s" #'org-schedule "t" #'org-todo "T" #'org-todo-list - (:prefix ("r" . "refile") - "." #'+org/refile-to-current-file - "c" #'+org/refile-to-running-clock - "l" #'+org/refile-to-last-location - "o" #'+org/refile-to-other-window - "O" #'+org/refile-to-other-buffers - "r" #'org-refile) ; to all `org-refile-targets' (:prefix ("a" . "attachments") "a" #'+org-attach/file "u" #'+org-attach/uri "f" #'+org-attach/find-file "s" #'+org-attach/sync) + (:prefix ("b" . "tables") + "-" #'org-table-insert-hline + "a" #'org-table-align + "c" #'org-table-create-or-convert-from-region + "e" #'org-table-edit-field + "h" #'org-table-field-info + (:when (featurep! +gnuplot) + "p" #'org-plot/gnuplot)) (:prefix ("c" . "clock") "c" #'org-clock-in "C" #'org-clock-out @@ -683,14 +684,13 @@ between the two." "i" #'org-id-goto "r" #'org-refile-goto-last-stored "x" #'org-capture-goto-last-stored) - (:prefix ("b" . "tables") - "-" #'org-table-insert-hline - "a" #'org-table-align - "c" #'org-table-create-or-convert-from-region - "e" #'org-table-edit-field - "h" #'org-table-field-info - (:when (featurep! +gnuplot) - "p" #'org-plot/gnuplot))) + (:prefix ("r" . "refile") + "." #'+org/refile-to-current-file + "c" #'+org/refile-to-running-clock + "l" #'+org/refile-to-last-location + "o" #'+org/refile-to-other-window + "O" #'+org/refile-to-other-buffers + "r" #'org-refile)) ; to all `org-refile-targets' (map! :after org-agenda :map org-agenda-mode-map From f70f788df38216f9ae3c62ccf1328558dfd23301 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 11 Nov 2019 14:48:37 -0500 Subject: [PATCH 066/129] lang/org: don't auto-demote headings on C-RET This can be harder to predict. Instead, use TAB and S-TAB after-the-fact to adjust heading level. --- modules/lang/org/autoload/org.el | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/modules/lang/org/autoload/org.el b/modules/lang/org/autoload/org.el index 22c2a1e20..52b23c76c 100644 --- a/modules/lang/org/autoload/org.el +++ b/modules/lang/org/autoload/org.el @@ -90,24 +90,16 @@ org-insert-heading-respect-content) (goto-char (line-end-position)) (org-end-of-subtree) - (insert (concat "\n" - (when (= level 1) - (if at-eol - (ignore (cl-incf level)) - "\n")) - (make-string level ?*) - " ")))) + (insert "\n" (make-string level ?*) " "))) (`above (org-back-to-heading) (insert (make-string level ?*) " ") - (save-excursion - (insert "\n") - (if (= level 1) (insert "\n"))))) + (save-excursion (insert "\n")))) (when-let (todo-keyword (org-element-property :todo-keyword context)) (org-todo (or (car (+org-get-todo-keywords-for todo-keyword)) 'todo))))) - (t (user-error "Not a valid list, heading or table"))) + ((user-error "Not a valid list, heading or table"))) (when (org-invisible-p) (org-show-hidden-entry)) From 7879a93081ab5d82e4fed8bbecfc62dfff755879 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 11 Nov 2019 14:49:34 -0500 Subject: [PATCH 067/129] lang/org: preserve TODO keyword on C-RET Rather than reverting to first TODO keyword. --- modules/lang/org/autoload/org.el | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/lang/org/autoload/org.el b/modules/lang/org/autoload/org.el index 52b23c76c..98d919ea9 100644 --- a/modules/lang/org/autoload/org.el +++ b/modules/lang/org/autoload/org.el @@ -95,9 +95,12 @@ (org-back-to-heading) (insert (make-string level ?*) " ") (save-excursion (insert "\n")))) - (when-let (todo-keyword (org-element-property :todo-keyword context)) - (org-todo (or (car (+org-get-todo-keywords-for todo-keyword)) - 'todo))))) + (when-let* ((todo-keyword (org-element-property :todo-keyword context)) + (todo-type (org-element-property :todo-type context))) + (org-todo (cond ((eq todo-type 'done) + (car (+org-get-todo-keywords-for todo-keyword))) + (todo-keyword) + ('todo)))))) ((user-error "Not a valid list, heading or table"))) From 82c0fb6fc7074c7fe77b3a597e4c7cb179b364f1 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 11 Nov 2019 22:49:10 -0500 Subject: [PATCH 068/129] cli/doctor: ensure modules are fully loaded --- core/cli/doctor.el | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/core/cli/doctor.el b/core/cli/doctor.el index e568ff3c9..d50cfb564 100644 --- a/core/cli/doctor.el +++ b/core/cli/doctor.el @@ -79,13 +79,12 @@ in." (print! (start "Checking Doom Emacs...")) (condition-case-unless-debug ex (print-group! - ;; Make sure Doom is initialized and loaded - (let ((doom-interactive-mode t)) - (doom-initialize 'force)) - (doom-initialize-core) - (print! (success "Initialized Doom Emacs %s") doom-version) + (let ((doom-interactive-mode 'doctor)) + (doom-initialize 'force) + (doom-initialize-core) + (doom-initialize-modules)) - (doom-initialize-modules) + (print! (success "Initialized Doom Emacs %s") doom-version) (print! (if (hash-table-p doom-modules) (success "Detected %d modules" (hash-table-count doom-modules)) From 64222c69c88c230424d630ddb452c6786d3c0d27 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 11 Nov 2019 23:47:27 -0500 Subject: [PATCH 069/129] Fix wrong-number-of-arguments on newline-and-indent And ensure all custom comment-line-break-function functions its argument requirements. --- modules/config/default/autoload/default.el | 2 +- modules/lang/ocaml/autoload.el | 2 +- modules/lang/scala/autoload.el | 2 +- modules/lang/web/autoload/css.el | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/config/default/autoload/default.el b/modules/config/default/autoload/default.el index a6a91a0c1..a85f299e2 100644 --- a/modules/config/default/autoload/default.el +++ b/modules/config/default/autoload/default.el @@ -120,7 +120,7 @@ languages)." (interactive) (if (and (sp-point-in-comment) comment-line-break-function) - (funcall comment-line-break-function) + (funcall comment-line-break-function nil) (delete-horizontal-space t) (newline nil t) (indent-according-to-mode))) diff --git a/modules/lang/ocaml/autoload.el b/modules/lang/ocaml/autoload.el index af6139bac..9ab554c7e 100644 --- a/modules/lang/ocaml/autoload.el +++ b/modules/lang/ocaml/autoload.el @@ -1,7 +1,7 @@ ;;; lang/ocaml/autoload.el -*- lexical-binding: t; -*- ;;;###autoload -(defun +ocaml/comment-indent-new-line () +(defun +ocaml/comment-indent-new-line (&optional _) "Break line at point and indent, continuing comment if within one." (interactive) (comment-indent-new-line) diff --git a/modules/lang/scala/autoload.el b/modules/lang/scala/autoload.el index d9eff6195..4733c1561 100644 --- a/modules/lang/scala/autoload.el +++ b/modules/lang/scala/autoload.el @@ -1,7 +1,7 @@ ;;; lang/scala/autoload.el -*- lexical-binding: t; -*- ;;;###autoload -(defun +scala-comment-indent-new-line (&rest _) +(defun +scala-comment-indent-new-line (&optional _) "Continue the commnt on the current line. Meant to be used for `scala-mode's `comment-line-break-function'." diff --git a/modules/lang/web/autoload/css.el b/modules/lang/web/autoload/css.el index 2389af5b3..e1844b297 100644 --- a/modules/lang/web/autoload/css.el +++ b/modules/lang/web/autoload/css.el @@ -44,7 +44,7 @@ (+css--toggle-inline-or-block beg end)))) ;;;###autoload -(defun +css/comment-indent-new-line () +(defun +css/comment-indent-new-line (&optional _) "Continues the comment in an indented new line. Meant for `comment-line-break-function' in `css-mode' and `scss-mode'." From 27277c17e567c36e04bfe38a7d4cdb625e3a5a1d Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Tue, 12 Nov 2019 15:22:44 -0500 Subject: [PATCH 070/129] docs/getting_started: remove reddit link in windows instructions The reddit post contains outdated information that shouldn't be used. Mentioned in #2030 --- docs/getting_started.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting_started.org b/docs/getting_started.org index ff7c80d78..54de52c43 100644 --- a/docs/getting_started.org +++ b/docs/getting_started.org @@ -187,8 +187,8 @@ cause you issues later on. Do not use them: + XEmacs *** On Windows -*Support for Windows is immature,* so your mileage will vary. [[https://www.reddit.com/r/emacs/comments/6bw35d/doom_an_emacsd_to_espouse_and_surpass_vim_in_any/dhtw32t/][Some have reported -success]] with installing Doom via WSL, chocolatey on git-bash or cygwin. +*Support for Windows is immature,* so your mileage will vary. Some have reported +success with installing Doom via WSL, chocolatey on git-bash or cygwin. #+BEGIN_QUOTE If you manage to get Doom on Windows and found this wasn't enough, or could be From 62e6e7d81f8aa4ce6e9d3dbbc4726ef2d76a0bc3 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Tue, 12 Nov 2019 16:15:42 -0500 Subject: [PATCH 071/129] lang/org: fix tests to reflect f70f788df --- modules/lang/org/test/test-org.el | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/modules/lang/org/test/test-org.el b/modules/lang/org/test/test-org.el index cbe36f62d..ff065b5e4 100644 --- a/modules/lang/org/test/test-org.el +++ b/modules/lang/org/test/test-org.el @@ -18,31 +18,19 @@ (kill-buffer (get-buffer "org"))) (describe "headlines" - (it "appends first-level headlines with an extra newline" + (it "opens new headline below" (insert!! "* {0}Header") (+org/insert-item-below 1) (expect (eobp)) (expect (buffer-substring-no-properties (point-min) (point-max)) - :to-equal "* Header\n\n* ")) - (it "prepends first-level headlines with an extra newline" - (insert!! "* {0}Header") - (+org/insert-item-above 1) - (expect (eolp)) - (expect (buffer-substring-no-properties (point-min) (point-max)) - :to-equal "* \n\n* Header")) + :to-equal "* Header\n* ")) - (it "appends second-level headlines with an no extra newline" - (insert!! "** {0}Header") - (+org/insert-item-below 1) - (expect (eobp)) - (expect (buffer-substring-no-properties (point-min) (point-max)) - :to-equal "** Header\n** ")) - (it "prepends second-level headlines with an no extra newline" - (insert!! "** {0}Header") + (it "opens new headline above" + (insert!! "* {0}Header") (+org/insert-item-above 1) (expect (eolp)) (expect (buffer-substring-no-properties (point-min) (point-max)) - :to-equal "** \n** Header")) + :to-equal "* \n* Header")) (it "appends headlines, skipping subtrees" (insert!! "** {0}First\n" From 5498b17de2f887e279f20ed9ec4ed9570c48927c Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Tue, 12 Nov 2019 16:24:51 -0500 Subject: [PATCH 072/129] Bind 'gr' to revert-buffer in dired-mode --- modules/editor/evil/config.el | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/editor/evil/config.el b/modules/editor/evil/config.el index 7b3f22096..f9fe28220 100644 --- a/modules/editor/evil/config.el +++ b/modules/editor/evil/config.el @@ -479,7 +479,10 @@ To change these keys see `+evil-repeat-keys'." (:when (featurep! :tools eval) :nv "gr" #'+eval:region :n "gR" #'+eval/buffer - :v "gR" #'+eval:replace-region) + :v "gR" #'+eval:replace-region + (:after dired + :map dired-mode-map + :n "gr" #'revert-buffer)) :nv "z=" #'flyspell-correct-word-generic ;; custom evil keybinds From d0a7cac3ad27b53ba1e2b92770192b5201d3d16d Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Tue, 12 Nov 2019 20:22:38 -0500 Subject: [PATCH 073/129] Fix +eval:region sending whole buffer to REPL #1941 --- modules/tools/eval/autoload/evil.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/tools/eval/autoload/evil.el b/modules/tools/eval/autoload/evil.el index 2583e8043..801f69ee3 100644 --- a/modules/tools/eval/autoload/evil.el +++ b/modules/tools/eval/autoload/evil.el @@ -8,7 +8,7 @@ (interactive "") (if (and (fboundp '+eval--ensure-in-repl-buffer) (+eval--ensure-in-repl-buffer)) - (+eval/send-region-to-repl (point-min) (point-max)) + (+eval/send-region-to-repl beg end) (+eval/region beg end))) ;;;###autoload (autoload '+eval:replace-region "tools/eval/autoload/evil" nil t) From 2dd27260bb040b48b8fcb4b3cd63305a3e069f33 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Tue, 12 Nov 2019 20:35:14 -0500 Subject: [PATCH 074/129] lang/python: move pipenv keybinds to pipenv config Why was it under pyvenv? --- modules/lang/python/config.el | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/modules/lang/python/config.el b/modules/lang/python/config.el index 3b773a7a1..be7276f3f 100644 --- a/modules/lang/python/config.el +++ b/modules/lang/python/config.el @@ -193,7 +193,18 @@ called.") (_ (pipenv-project-p))) (format "PIPENV_MAX_DEPTH=9999 %s run %%c %%o %%s %%a" bin) "%c %o %s %a"))) - (:description . "Run Python script")))) + (:description . "Run Python script"))) + (map! :map python-mode-map + :localleader + :prefix "e" + :desc "activate" "a" #'pipenv-activate + :desc "deactivate" "d" #'pipenv-deactivate + :desc "install" "i" #'pipenv-install + :desc "lock" "l" #'pipenv-lock + :desc "open module" "o" #'pipenv-open + :desc "run" "r" #'pipenv-run + :desc "shell" "s" #'pipenv-shell + :desc "uninstall" "u" #'pipenv-uninstall)) (use-package! pyvenv @@ -206,18 +217,7 @@ called.") (add-hook 'python-mode-local-vars-hook #'pyvenv-track-virtualenv) (add-to-list 'global-mode-string '(pyvenv-virtual-env-name (" venv:" pyvenv-virtual-env-name " ")) - 'append) - (map! :map python-mode-map - :localleader - :prefix "e" - :desc "activate" "a" #'pipenv-activate - :desc "deactivate" "d" #'pipenv-deactivate - :desc "install" "i" #'pipenv-install - :desc "lock" "l" #'pipenv-lock - :desc "open module" "o" #'pipenv-open - :desc "run" "r" #'pipenv-run - :desc "shell" "s" #'pipenv-shell - :desc "uninstall" "u" #'pipenv-uninstall)) + 'append)) From 2a01a9dcdfef2ed8e0d904292ce9c0c9e1ba636c Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 14 Nov 2019 01:45:40 -0500 Subject: [PATCH 075/129] tools/ein: fix +ein/hydra autoload #2054 --- modules/tools/ein/autoload/hydra.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/tools/ein/autoload/hydra.el b/modules/tools/ein/autoload/hydra.el index c06b65f2e..3bbba5fcd 100644 --- a/modules/tools/ein/autoload/hydra.el +++ b/modules/tools/ein/autoload/hydra.el @@ -1,7 +1,7 @@ ;;; tools/ein/autoload/hydra.el -*- lexical-binding: t; -*- ;;;###if (featurep! :ui hydra) -;;;###autoload (autoload '+ein/hydra/body "tools/ein/autoload" nil t) +;;;###autoload (autoload '+ein/hydra/body "tools/ein/autoload/hydra" nil t) (defhydra +ein/hydra (:hint t :color red) " Operations on Cells^^^^^^ Other From 6599388f006b1cd7e050a2415511e2462ebda24f Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 14 Nov 2019 02:37:24 -0500 Subject: [PATCH 076/129] Fix infinite loop on invalid answer to straight prompts --- core/core-packages.el | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/core/core-packages.el b/core/core-packages.el index 04c941adc..e7a62fd1f 100644 --- a/core/core-packages.el +++ b/core/core-packages.el @@ -161,15 +161,20 @@ missing) and shouldn't be deleted.") (push func options) (print! "%2s) %s" (length options) desc))))) (terpri) - (let ((answer - (read-number (format! "How to proceed? (%s) " - (mapconcat #'number-to-string - (number-sequence 1 (length options)) - ", ")))) - fn) - (setq options (nreverse options)) - (while (not (setq fn (nth (1- answer) options))) - (print! "%s is not a valid answer, try again." answer)) + (let ((options (nreverse options)) + answer fn) + (while + (not + (setq + fn (ignore-errors + (nth (1- (setq answer + (read-number + (format! "How to proceed? (%s) " + (mapconcat #'number-to-string + (number-sequence 1 (length options)) + ", "))))) + options)))) + (print! (warn "%s is not a valid answer, try again.") answer)) (funcall fn)))))) From 12fcd3857dadc93ea2ae35d31cd22d62ab645f12 Mon Sep 17 00:00:00 2001 From: Ralf Beckmann Date: Thu, 14 Nov 2019 20:40:40 +0100 Subject: [PATCH 077/129] Avoid superfluous buffers when sudo-editing When invoking 'doom/sudo-this-file', do not keep the old buffer around, since it is most likely no longer needed. --- core/autoload/files.el | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/core/autoload/files.el b/core/autoload/files.el index 9a9b21bfc..d3e183d58 100644 --- a/core/autoload/files.el +++ b/core/autoload/files.el @@ -313,26 +313,26 @@ file if it exists, without confirmation." (`aborted (message "Aborted")) (_ t))) +(defun doom--sudo-file (file) + (let ((host (or (file-remote-p file 'host) "localhost"))) + (concat "/" (when (file-remote-p file) + (concat (file-remote-p file 'method) ":" + (if-let (user (file-remote-p file 'user)) + (concat user "@" host) + host) + "|")) + "sudo:root@" host + ":" (or (file-remote-p file 'localname) + file)))) + ;;;###autoload (defun doom/sudo-find-file (file) "Open FILE as root." (interactive "FOpen file as root: ") - (let* ((host (or (file-remote-p file 'host) "localhost")) - (f (concat "/" (when (file-remote-p file) - (concat (file-remote-p file 'method) ":" - (if-let (user (file-remote-p file 'user)) - (concat user "@" host) - host) - "|")) - "sudo:root@" host - ":" (or (file-remote-p file 'localname) - file)))) - (if (and buffer-file-name (equal file (file-truename buffer-file-name))) - (find-alternate-file f) - (find-file f)))) + (find-file (doom--sudo-file file))) ;;;###autoload (defun doom/sudo-this-file () "Open the current file as root." (interactive) - (doom/sudo-find-file (file-truename buffer-file-name))) + (find-alternate-file (doom--sudo-file buffer-file-name))) From 8f793a387b4b957458766f56bbef19792aeff5e4 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 14 Nov 2019 15:43:44 -0500 Subject: [PATCH 078/129] docs/api: expand map! example --- docs/api.org | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/docs/api.org b/docs/api.org index 1d436128b..578418981 100644 --- a/docs/api.org +++ b/docs/api.org @@ -252,6 +252,76 @@ It is integrated into Helpful, in Doom. :desc "Eval expression" ";" #'eval-expression) #+END_SRC +These are side-by-side comparisons, showing how to bind keys with and without +~map!~: + +#+BEGIN_SRC elisp :eval no +;; bind a global key +(global-set-key (kbd "C-x y") #'do-something) +(map! "C-x y" #'do-something) + +;; bind a key on a keymap +(define-key emacs-lisp-mode (kbd "C-c p") #'do-something) +(map! :map emacs-lisp-mode "C-c p" #'do-something) + +;; unbind a key defined elsewhere +(define-key lua-mode-map (kbd "SPC m b") nil) +(map! :map lua-mode-map "SPC m b" nil) + +;; bind multiple keys +(global-set-key "C-x x" #'do-something) +(global-set-key "C-x y" #'do-something-else) +(global-set-key "C-x z" #'do-another-thing) +(map! "C-x x" #'do-something + "C-x y" #'do-something-else + "C-x z" #'do-another-thing) + +;; bind global keys in normal mode +(evil-define-key* 'normal 'global + (kbd "C-x x") #'do-something + (kbd "C-x y") #'do-something-else + (kbd "C-x z") #'do-another-thing) +(map! :n "C-x x" #'do-something + :n "C-x y" #'do-something-else + :n "C-x z" #'do-another-thing) + +;; or on a deferred keymap +(evil-define-key 'normal emacs-lisp-mode-map + (kbd "C-x x") #'do-something + (kbd "C-x y") #'do-something-else + (kbd "C-x z") #'do-another-thing) +(map! :map emacs-lisp-mode-map + :n "C-x x" #'do-something + :n "C-x y" #'do-something-else + :n "C-x z" #'do-another-thing) + +;; or multiple maps +(dolist (map (list emacs-lisp-mode go-mode-map ivy-minibuffer-map)) + (evil-define-key '(normal insert) map + "a" #'a + "b" #'b + "c" #'c)) +(map! :map (emacs-lisp-mode go-mode-map ivy-minibuffer-map) + :ni "a" #'a + :ni "b" #'b + :ni "c" #'c) + +;; or in multiple states (order of states doesn't matter) +(evil-define-key* '(normal visual) emacs-lisp-mode-map (kbd "C-x x") #'do-something) +(evil-define-key* 'insert emacs-lisp-mode-map (kbd "C-x x") #'do-something-else) +(evil-define-key* '(visual normal insert emacs) emacs-lisp-mode-map (kbd "C-x z") #'do-another-thing) +(map! :map emacs-lisp-mode + :nv "C-x x" #'do-something ; normal+visual + :i "C-x y" #'do-something-else ; insert + :vnie "C-x z" #'do-another-thing) ; visual+normal+insert+emacs + +;; You can nest map! calls: +(evil-define-key* '(normal visual) emacs-lisp-mode-map (kbd "C-x x") #'do-something) +(evil-define-key* 'normal go-lisp-mode-map (kbd "C-x x") #'do-something-else) +(map! (:map emacs-lisp-mode :nv "C-x x" #'do-something) + (:map go-lisp-mode :n "C-x x" #'do-something-else)) +#+END_SRC + *** package! #+BEGIN_SRC elisp :eval no ;; To install a package that can be found on ELPA or any of the sources From 031a68a36dfba9d31db7fa0f9c81b25c97aadd32 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 14 Nov 2019 15:47:29 -0500 Subject: [PATCH 079/129] docs/faq: revise & remove redundancies --- docs/faq.org | 149 ++++++++++++--------------------------------------- 1 file changed, 34 insertions(+), 115 deletions(-) diff --git a/docs/faq.org b/docs/faq.org index 608078e69..af9f9f3d9 100644 --- a/docs/faq.org +++ b/docs/faq.org @@ -1,7 +1,7 @@ #+TITLE: Frequently Asked Questions #+STARTUP: nofold -* Table of Contents :TOC: +* Table of Contents :TOC: - [[#general][General]] - [[#why-is-it-called-doom][Why is it called Doom?]] - [[#does-doom-work-on-windows][Does Doom work on Windows?]] @@ -392,7 +392,7 @@ What's more, I don't like using more tools than I need. We should not need a second program just to make the first run comfortably. ** How do I use Doom alongside other Emacs configs? -I recommend [[https://github.com/plexus/chemacs][Chemacs]]. You can think of it as a bootloader for Emacs. You'll [[file:getting_started.org::Alongside%20other%20Emacs%20configs%20(with%20Chemacs)][find +I recommend [[https://github.com/plexus/chemacs][Chemacs]]. You can think of it as a bootloader for Emacs. You'll [[file:getting_started.org::*Alongside other Emacs configs (with Chemacs)][find instructions on how to use it with Doom in the user manual]]. If you only want to try it out without affecting your current config, it is safe @@ -439,45 +439,7 @@ summons to fight for custody of your kids. Also, Doom's fast yo. ** What is the meaning behind Doom's naming conventions? -Doom has a number of naming conventions that it uses in addition to the standard -lisp conventions. Third party packages may use their own conventions as well, -but this guide focuses only on what Doom Emacs uses: - -*** Lisp Naming Conventions -The lisp conventions are simple. Symbols follow ~NAMESPACE-SYMBOLNAME~ for -public variables/functions (e.g. ~bookmark-default-file~ or -~electric-indent-mode~) and ~NAMESPACE--SYMBOLNAME~ for private ones (e.g. -~byte-compile--lexical-environment~ and ~yas--tables~). - -~NAMESPACE~ is usually the name of the containing file or package. E.g. the -~company~ plugin prefixes all its variables/functions with ~company-~. - -*** Doom Naming Conventions -+ ~doom/NAME~ or ~+MODULE/NAME~ :: Denotes a public command designed to be used - interactively, via =M-x= or a keybinding. e.g. ~doom/info~, ~+popup/other~, - ~+ivy/rg~. -+ ~doom:NAME~ :: A public evil operator, motion or command. e.g. ~+evil:align~, - ~+ivy:rg~. -+ ~doom-[-]NAME-h~ or ~+MODULE-[-]NAME-h~ :: A non-interactive function meant to - be used (exclusively) as a hook. e.g. ~+cc-fontify-constants-h~, - ~+flycheck-buffer-h~. -+ ~doom-[-]NAME-a~ or ~+MODULE-[-]NAME-a~ :: Functions designed to be used as - advice for other functions. e.g. ~doom-set-jump-a~, - ~doom--fix-broken-smie-modes-a~, ~+org--babel-lazy-load-library-a~ -+ ~doom-[-]NAME-fn~ or ~+MODULE-[-]NAME-fn~ :: Indicates an [[https://en.wikipedia.org/wiki/Strategy_pattern][strategy]] function. A - good rule of thumb for what makes a strategy function is: is it - interchangeable? Can it be replaced with another function with a matching - signature? e.g. ~+lookup-dumb-jump-backend-fn~, ~+magit-display-buffer-fn~, - ~+workspaces-set-project-action-fn~ -+ ~abc!~ :: A public Doom "autodef" function or macro. An autodef should always - be defined, even if its containing module is disabled (i.e. they will not - throw a void-function error). The purpose of this is to avoid peppering module - configs with conditionals or `after!` blocks before using their APIs. They - should noop if their module is disabled, and should be zero-cost in the case - their module is disabled. - - Autodefs usually serve to configure Doom or a module. e.g. ~after!~, - ~set-company-backends!~, ~set-evil-initial-state!~ +You'll find [[file:contributing.org::*Conventions][an overview of Doom's code conventions]] in the [[file:contributing.org][contributing guide]]. ** How can I contribute to/support Doom? Take a look at the [[file:contributing.org][Contributing guide]]. @@ -503,7 +465,11 @@ Canonically, your private config is kept in =~/.doom.d/= or =~/.config/doom/=. Doom will prioritize =~/.config/doom=, if it exists. This directory is referred to as your ~$DOOMDIR~. -TL;DR. Put all your private configuration in =$DOOMDIR/config.el=. +Your private config is typically comprised of an =init.el=, =config.el= and +=packages.el= file. Put all your config in =config.el=, install packages by +adding ~package!~ declarations to =packagse.el=, and enable/disable modules in +you ~doom!~ block, which should have been created in your =init.el= when you +first ran ~doom install~. Check out the [[file:getting_started.org::Customize][Customize section]] in the [[file:getting_started.org][Getting Started]] guide for details. @@ -539,8 +505,8 @@ You'll find more information in the "[[file:getting_started.org::*Installing%20p Started]] guide. ** How do I install a package from github/another source? -The ~package!~ macro can be passed a MELPA style ~:recipe~, allowing you to -install packages from just about anywhere: +The ~package!~ macro can be passed a MELPA style recipe, allowing you to install +packages from just about anywhere: #+BEGIN_SRC elisp (package! evil :recipe (:host github :repo "hlissner/my-evil-fork")) @@ -562,14 +528,15 @@ You'll find more information in the "[[file:getting_started.org::*Installing%20p section of the [[file:getting_started.org][Getting Started]] guide. ** How do I change where an existing package is installed from? -~package!~ declarations in your private config have precedence over modules -(even your own). Simply add a new one for that package with the new recipe. +~package!~ declarations in your private =packages.el= file have precedence over +modules (even your own). Simply add a new one for that package with the new +recipe. You'll find more information in the "[[file:getting_started.org::*Changing%20a%20built-in%20recipe%20for%20a%20package][Changing a built-in recipe for a package]]" section of the [[file:getting_started.org][Getting Started]] guide. ** How do I disable a package completely? -The ~package!~ macro has a ~:disable~ property: +With the ~package!~ macro's ~:disable~ property: #+BEGIN_SRC elisp ;;; in DOOMDIR/packages.el @@ -630,8 +597,8 @@ At the moment, the only difference between the two is that ~doom-theme~ is loaded when Emacs has finished initializing at startup and ~load-theme~ loads the theme immediately. Which you choose depends on your needs, but I recommend setting ~doom-theme~ because, if I later discover a better way to load themes, I -can easily change how Doom uses ~doom-theme~, but I can't control how you use -the ~load-theme~ function. +can easily change how Doom uses ~doom-theme~, but I can't (easily) control how +you use the ~load-theme~ function. *** Installing a third party theme To install a theme from a third party plugin, say, [[https://github.com/bbatsov/solarized-emacs][solarized]], you need only @@ -670,60 +637,12 @@ e.g. #+END_SRC ** How do I bind my own keys (or change existing ones)? -The ~map!~ macro is recommended; it is a convenience macro that acts as a -wrapper around ~define-key~, ~global-set-key~, ~local-set-key~ and -~evil-define-key~. +The ~map!~ macro is recommended; it is a convenience macro that wraps around +Emacs' (and evil's) keybinding API, i.e. ~define-key~, ~global-set-key~, +~local-set-key~ and ~evil-define-key~. -#+BEGIN_SRC emacs-lisp -;; bind a global key -(global-set-key (kbd "C-x y") #'do-something) -(map! "C-x y" #'do-something) - -;; bind a key on a keymap -(define-key emacs-lisp-mode (kbd "C-c p") #'do-something) -(map! :map emacs-lisp-mode "C-c p" #'do-something) - -;; unbind a key defined elsewhere -(define-key lua-mode-map (kbd "SPC m b") nil) -(map! :map lua-mode-map "SPC m b" nil) - -;; bind multiple keys -(map! "C-x x" #'do-something - "C-x y" #'do-something-else - "C-x z" #'do-another-thing) -#+END_SRC - -Evil users can also define keys in particular evil states: - -#+BEGIN_SRC emacs-lisp -;; bind global keys in normal mode -(map! :n "C-x x" #'do-something - :n "C-x y" #'do-something-else - :n "C-x z" #'do-another-thing) - -;; or on a keymap -(map! :map emacs-lisp-mode - :n "C-x x" #'do-something - :n "C-x y" #'do-something-else - :n "C-x z" #'do-another-thing) - -;; or multiple maps -(map! :map (emacs-lisp-mode go-mode-map ivy-minibuffer-map) ...) - -;; or in multiple states (order of states doesn't matter) -(map! :map emacs-lisp-mode - :nv "C-x x" #'do-something ; normal+visual - :i "C-x y" #'do-something-else ; insert - :vnie "C-x z" #'do-another-thing) ; visual+normal+insert+emacs - -;; You can nest map! calls: -(map! (:map emacs-lisp-mode :nv "C-x x" #'do-something) - (:map go-lisp-mode :n "C-x x" #'do-something-else)) -#+END_SRC - -~map!~ supports other properties, like ~:after~, ~:when~, ~:prefix~ and ~:desc~. -Look at ~map!~'s documentation for more information (=SPC h f map!= for evil -users, =C-h f map!= otherwise). +You'll find comprehensive examples of ~map!~'s usage in its documentation (via +=SPC h f map!= or =C-h f map!= -- also found [[file:api.org][in docs/api]]). You'll find a more comprehensive example of ~map!~'s usage in [[file:../modules/config/default/+evil-bindings.el][config/default/+evil-bindings.el]]. @@ -845,10 +764,10 @@ tools for experienced Emacs users to skirt around it (most of the time): Doom provides ~M-x doom/reload~ for your convenience, which will run ~doom refresh~, restart the Doom initialization process, and re-evaluate your personal config, but this won't clear pre-existing state. That may or may not - be a problem, this hasn't be thoroughly tested, and Doom cannot anticipate + be a problem, this hasn't be thoroughly tested and Doom cannot anticipate complications arising from your private config. - If you intend to use ~doom/reload~, try to design your config to be + If you intend to use ~doom/reload~, you must design your config to be idempotent. - Many ~bin/doom~ commands are available as elisp commands with the ~doom//*~ prefix. e.g. ~doom//refresh~, ~doom//update~, etc. Feel free to use them, but @@ -868,28 +787,28 @@ deprecated. It forwards to ~bin/doom~ anyway. a shell script incapable of sentience and thus incapable of retaining, much less divulging, your secrets to others). -You can run ~bin/doom help~ to see what it's capable of, but here are the -highlights: +You can run ~bin/doom help~ to see what it's capable of, but here are some +commands that you may find particularly useful: + ~doom doctor~ :: Diagnose common issues in your environment and list missing external dependencies for your enabled modules. -+ ~doom install~ :: Install any missing packages. -+ ~doom update~ :: Update all packages that Doom's (enabled) modules use. + ~doom refresh~ :: Ensures that all missing packages are installed, orphaned packages are removed, and metadata properly generated. ++ ~doom install~ :: Install any missing packages. ++ ~doom update~ :: Update all packages that Doom's (enabled) modules use. + ~doom env~ :: Regenerates your envvar file, which contains a snapshot of your shell environment for Doom Emacs to load on startup. You need to run this for changes to your shell environment to take effect. -+ ~doom purge~ :: Purge orphaned packages (i.e. ones that aren't needed anymore) - and regraft your repos. ++ ~doom purge -g~ :: Purge orphaned packages (i.e. ones that aren't needed + anymore) and regraft your repos. + ~doom upgrade~ :: Upgrade Doom to the latest version (then update your packages). This is equivalent to: - #+BEGIN_SRC bash - git pull - doom refresh - doom update - #+END_SRC + #+BEGIN_SRC bash + git pull + doom refresh + doom update + #+END_SRC ** When to run ~doom refresh~ As a rule of thumb you should run ~doom refresh~ whenever you: From 6536eded02f7367c409792bf1bd78f7d5a33bf42 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 14 Nov 2019 15:47:42 -0500 Subject: [PATCH 080/129] docs/index: add github links warning --- docs/index.org | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/index.org b/docs/index.org index 9b34c9800..eadfd4f4c 100644 --- a/docs/index.org +++ b/docs/index.org @@ -7,9 +7,10 @@ for your own Emacs configuration or a resource for enthusiasts to learn more about our favorite OS. #+begin_quote -Doom's documentation can be viewed from within Emacs by pressing = d h= -(== is =SPC h= for evil users and =C-h= for vanilla users), or searched -with = d /=. +Github fails to render org links to sub-sections, so it is recommended that you +view the documentation from within Doom Emacs by pressing = d h= (== +is =SPC h= for evil users and =C-h= for vanilla users) or searching it with += d /=. #+end_quote * Table of Contents :TOC: From c2db4a87081aa0c9e7449515df6190392b4f39c9 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 15 Nov 2019 00:17:10 -0500 Subject: [PATCH 081/129] tools/eval: add REPL support for +eval/buffer --- modules/tools/eval/autoload/eval.el | 21 +++++++++++++++------ modules/tools/eval/autoload/evil.el | 5 +---- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/modules/tools/eval/autoload/eval.el b/modules/tools/eval/autoload/eval.el index 3d82bff7d..41be372c4 100644 --- a/modules/tools/eval/autoload/eval.el +++ b/modules/tools/eval/autoload/eval.el @@ -56,18 +56,27 @@ (defun +eval/buffer () "Evaluate the whole buffer." (interactive) - (cond ((assq major-mode +eval-runners) - (+eval/region (point-min) (point-max))) - ((quickrun)))) + (if (or (assq major-mode +eval-runners) + (and (fboundp '+eval--ensure-in-repl-buffer) + (ignore-errors + (get-buffer-window (or (+eval--ensure-in-repl-buffer) + t))))) + (+eval/region (point-min) (point-max)) + (quickrun))) ;;;###autoload (defun +eval/region (beg end) "Evaluate a region between BEG and END and display the output." (interactive "r") (let ((load-file-name buffer-file-name)) - (if-let (runner (cdr (assq major-mode +eval-runners))) - (funcall runner beg end) - (quickrun-region beg end)))) + (if (and (fboundp '+eval--ensure-in-repl-buffer) + (ignore-errors + (get-buffer-window (or (+eval--ensure-in-repl-buffer) + t)))) + (+eval/send-region-to-repl beg end) + (if-let (runner (cdr (assq major-mode +eval-runners))) + (funcall runner beg end) + (quickrun-region beg end))))) ;;;###autoload (defun +eval/line-or-region () diff --git a/modules/tools/eval/autoload/evil.el b/modules/tools/eval/autoload/evil.el index 801f69ee3..218b12ce6 100644 --- a/modules/tools/eval/autoload/evil.el +++ b/modules/tools/eval/autoload/evil.el @@ -6,10 +6,7 @@ "Evaluate selection or sends it to the open REPL, if available." :move-point nil (interactive "") - (if (and (fboundp '+eval--ensure-in-repl-buffer) - (+eval--ensure-in-repl-buffer)) - (+eval/send-region-to-repl beg end) - (+eval/region beg end))) + (+eval/region beg end)) ;;;###autoload (autoload '+eval:replace-region "tools/eval/autoload/evil" nil t) (evil-define-operator +eval:replace-region (beg end) From 287cc94cbafcc7da313b6a8aa00875491a85829c Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 15 Nov 2019 00:56:58 -0500 Subject: [PATCH 082/129] Fix doom-load-autoloads-file tests on macos Since /var is symlinked to /private/var on macos, the tests -- which do a simple string comparison between two paths -- won't correctly determine the two paths are the same file. --- core/test/helpers.el | 2 ++ core/test/test-core.el | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/test/helpers.el b/core/test/helpers.el index a4d9986eb..618087fb4 100644 --- a/core/test/helpers.el +++ b/core/test/helpers.el @@ -13,6 +13,8 @@ ;; ;;; Buttercup extensions +(buttercup-define-matcher-for-binary-function :to-equal-file file-equal-p) + (buttercup-define-matcher :to-expand-into (form expected) (cl-destructuring-bind (form expected) (mapcar #'funcall (list form expected)) diff --git a/core/test/test-core.el b/core/test/test-core.el index 00a45acb4..a236ed5e9 100644 --- a/core/test/test-core.el +++ b/core/test/test-core.el @@ -86,12 +86,12 @@ (it "loads the byte-compiled autoloads file if available" (doom-load-autoloads-file doom-autoload-file) - (expect (caar load-history) :to-equal + (expect (caar load-history) :to-equal-file (byte-compile-dest-file doom-autoload-file)) (delete-file (byte-compile-dest-file doom-autoload-file)) (doom-load-autoloads-file doom-autoload-file) - (expect (caar load-history) :to-equal doom-autoload-file)) + (expect (caar load-history) :to-equal-file doom-autoload-file)) (it "returns non-nil if successful" (expect (doom-load-autoloads-file doom-autoload-file))) From 3353727452f855ad963d02b6baa5cdb8506baa25 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Fri, 15 Nov 2019 16:04:01 +0900 Subject: [PATCH 083/129] Add binding for setting effort The org-clock-modify-effort-estimate is only useful after we've clocked in a task. Signed-off-by: Rudi Grinberg --- modules/lang/org/config.el | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/lang/org/config.el b/modules/lang/org/config.el index 6f6a72a1a..ceabd3a41 100644 --- a/modules/lang/org/config.el +++ b/modules/lang/org/config.el @@ -667,6 +667,7 @@ between the two." "C" #'org-clock-out "d" #'org-clock-mark-default-task "e" #'org-clock-modify-effort-estimate + "E" #'org-set-effort "l" #'org-clock-in-last "g" #'org-clock-goto "G" (λ! (org-clock-goto 'select)) From 2b3674032533a22ef535614839adc8429d28d1a2 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 15 Nov 2019 02:14:06 -0500 Subject: [PATCH 084/129] lang/web: fix duplicate closing delimiters --- modules/lang/web/+html.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/lang/web/+html.el b/modules/lang/web/+html.el index 6869b89c0..424cad0c3 100644 --- a/modules/lang/web/+html.el +++ b/modules/lang/web/+html.el @@ -41,7 +41,9 @@ (setcdr alist (cl-loop for pair in (cdr alist) unless (string-match-p "^[a-z-]" (cdr pair)) - collect (cons (car pair) (string-trim-right (cdr pair)))))) + collect (cons (car pair) + (string-trim-right (cdr pair) + "\\(?:>\\|]\\|}\\)+\\'"))))) (delq! nil web-mode-engines-auto-pairs)) (map! :map web-mode-map From 9108f4780ec8061fe767515649806943bb5fda8a Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 15 Nov 2019 02:14:42 -0500 Subject: [PATCH 085/129] Clean up & refactor tests --- core/test/test-autoload-buffers.el | 111 ++++++++++++++++++++--------- core/test/test-autoload-files.el | 26 +++++-- core/test/test-core-keybinds.el | 1 + core/test/test-core-modules.el | 22 +++++- core/test/test-core-projects.el | 6 +- core/test/test-core.el | 4 +- 6 files changed, 120 insertions(+), 50 deletions(-) diff --git a/core/test/test-autoload-buffers.el b/core/test/test-autoload-buffers.el index 5c44ce232..f452783c0 100644 --- a/core/test/test-autoload-buffers.el +++ b/core/test/test-autoload-buffers.el @@ -19,11 +19,23 @@ (kill-buffer c) (kill-buffer d)) - (describe "buffer-list" - (it "should only see four buffers" - (expect (doom-buffer-list) :to-contain-items (list a b c d)))) + (describe "buffer lists" + (describe "doom-buffer-list" + (it "should only see four buffers" + (expect (doom-buffer-list) :to-contain-items (list a b c d))))) - (describe "project-buffer-list" + ;; TODO predicate tests + (xdescribe "predicate functions" + (describe "doom-dired-buffer-p") + (describe "doom-special-buffer-p") + (describe "doom-temp-buffer-p") + (describe "doom-visible-buffer-p") + (describe "doom-buried-buffer-p") + (describe "doom-non-file-visiting-buffer-p") + (describe "doom-dired-buffer-p") + (describe "doom-buffer-frame-predicate")) + + (describe "doom-project-buffer-list" :var (projectile-projects-cache-time projectile-projects-cache) (before-all (require 'projectile)) (after-all (unload-feature 'projectile t)) @@ -47,7 +59,7 @@ (expect (doom-project-buffer-list) :to-have-same-items-as (buffer-list))))) - (describe "fallback-buffer" + (describe "doom-fallback-buffer" (it "returns a live buffer" (expect (buffer-live-p (doom-fallback-buffer)))) @@ -56,12 +68,22 @@ (describe "real buffers" (before-each - (doom-set-buffer-real a t) (with-current-buffer b (setq buffer-file-name "x")) (with-current-buffer c (rename-buffer "*C*"))) - (describe "real-buffer-p" + (describe "doom-mark-buffer-as-real-h" + (with-current-buffer a + (doom-mark-buffer-as-real-h) + (expect (buffer-local-value 'doom-real-buffer-p a)))) + + (describe "doom-set-buffer-real" + (it "sets `doom-real-buffer-p' buffer-locally" + (doom-set-buffer-real a t) + (expect (buffer-local-value 'doom-real-buffer-p a)))) + + (describe "doom-real-buffer-p" (it "returns t for buffers manually marked real" + (doom-set-buffer-real a t) (expect (doom-real-buffer-p a))) (it "returns t for file-visiting buffers" (expect (doom-real-buffer-p b))) @@ -69,7 +91,16 @@ (expect (doom-real-buffer-p c) :to-be nil) (expect (doom-real-buffer-p d) :to-be nil))) - (describe "real-buffer-list" + (describe "doom-unreal-buffer-p" + (it "returns t for unreal buffers" + (expect (doom-unreal-buffer-p c)) + (expect (doom-unreal-buffer-p d))) + (it "returns nil for real buffers" + (doom-set-buffer-real a t) + (expect (not (doom-unreal-buffer-p a))) + (expect (not (doom-unreal-buffer-p b))))) + + (describe "doom-real-buffer-list" (it "returns only real buffers" (expect (doom-real-buffer-list) :to-contain-items (list a b))))) @@ -82,36 +113,48 @@ (split-window) (switch-to-buffer b)) - (it "can match buffers by regexp" - (expect (doom-matching-buffers "^[ac]$") :to-have-same-items-as (list a c))) + (describe "doom-matching-buffers" + (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))) + (describe "doom-buffers-in-mode" + (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-contain-items (list c d))) + (describe "doom-buried-buffers" + (it "can find all buried buffers" + (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))) + (describe "doom-visible-buffers" + (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 - (mapcar #'get-buffer-window (list a b))))) + (describe "doom-visible-windows" + (it "can find all visible windows" + (expect (doom-visible-windows) + :to-have-same-items-as + (mapcar #'get-buffer-window (list a b)))))) - (describe "kill-buffer-and-windows" - (before-each - (split-window) (switch-to-buffer b) - (split-window) (switch-to-buffer a)) + (describe "killing buffers/windows" + (describe "doom-kill-buffer-and-windows" + (before-each + (split-window) (switch-to-buffer b) + (split-window) (switch-to-buffer a)) - (it "kills the selected buffers and all its windows" - (doom-kill-buffer-and-windows a) - (expect (buffer-live-p a) :to-be nil) - (expect (length (doom-visible-windows)) :to-be 1))) + (it "kills the selected buffers and all its windows" + (doom-kill-buffer-and-windows a) + (expect (buffer-live-p a) :to-be nil) + (expect (length (doom-visible-windows)) :to-be 1))) - ;; TODO - (xdescribe "kill-all-buffers") - (xdescribe "kill-other-buffers") - (xdescribe "kill-matching-buffers") - (xdescribe "cleanup-session"))) + ;; TODO + (xdescribe "doom-fixup-windows") + (xdescribe "doom-kill-buffer-fixup-windows") + (xdescribe "doom-kill-buffers-fixup-windows")) + + (xdescribe "commands" + (describe "doom/kill-all-buffers") + (describe "doom/kill-other-buffers") + (describe "doom/kill-matching-buffers") + (describe "doom/kill-buried-buffers") + (describe "doom/kill-project-buffers")))) diff --git a/core/test/test-autoload-files.el b/core/test/test-autoload-files.el index 87a63edde..7429eb3c1 100644 --- a/core/test/test-autoload-files.el +++ b/core/test/test-autoload-files.el @@ -5,11 +5,6 @@ (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'" @@ -96,7 +91,16 @@ (getfilename)) "LICENSE") doom-emacs-dir) - :to-equal (expand-file-name "LICENSE" doom-emacs-dir)))))) + :to-equal (expand-file-name "LICENSE" doom-emacs-dir))))) + + ;; TODO + (xdescribe "doom-glob") + (xdescribe "doom-path") + (xdescribe "doom-dir") + (xdescribe "doom-files-in") + (xdescribe "doom-file-size") + (xdescribe "doom-directory-size") + (xdescribe "doom-file-cookie-p")) (describe "interactive file operations" :var (src dest projectile-projects-cache-time projectile-projects-cache) @@ -149,4 +153,12 @@ (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)))) + + (xdescribe "sudo {this,find} file" + (before-each + (spy-on 'find-file :and-return-value nil) + (spy-on 'find-alternate-file :and-return-value nil)) + + (describe "doom/sudo-find-file") + (describe "doom/sudo-this-file"))) diff --git a/core/test/test-core-keybinds.el b/core/test/test-core-keybinds.el index 5482205b2..52fe7238d 100644 --- a/core/test/test-core-keybinds.el +++ b/core/test/test-core-keybinds.el @@ -4,6 +4,7 @@ (describe "core/keybinds" (require 'core-keybinds) + ;; FIXME test against their side effects rather than their implementation (describe "map!" :var (doom--map-evil-p states-alist) (before-each diff --git a/core/test/test-core-modules.el b/core/test/test-core-modules.el index 9263f305a..f8c8966ce 100644 --- a/core/test/test-core-modules.el +++ b/core/test/test-core-modules.el @@ -1,7 +1,23 @@ ;; -*- no-byte-compile: t; -*- ;;; core/test/test-core-modules.el -;;;###if nil -;; (require 'core-modules) +(xdescribe "core-modules" + (require 'core-modules) -(xdescribe "core-modules") + (describe "doom!") + (describe "doom-modules") + + (describe "doom-module-p") + (describe "doom-module-get") + (describe "doom-module-put") + (describe "doom-module-set") + (describe "doom-module-path") + (describe "doom-module-locate-path") + (describe "doom-module-from-path") + (describe "doom-module-load-path") + + (describe "require!") + (describe "featurep!") + (describe "after!") + (describe "use-package!") + (describe "use-package-hook!")) diff --git a/core/test/test-core-projects.el b/core/test/test-core-projects.el index 8febc5cdd..c64304f47 100644 --- a/core/test/test-core-projects.el +++ b/core/test/test-core-projects.el @@ -21,14 +21,14 @@ (describe "project-root" (it "should resolve to the project's root" - (expect (doom-project-root doom-core-dir) :to-equal doom-emacs-dir)) + (expect (doom-project-root doom-core-dir) :to-equal-file doom-emacs-dir)) (it "should return nil if not in a project" (expect (doom-project-root (expand-file-name "~")) :to-be nil))) (describe "project-expand" (it "expands to a path relative to the project root" - (expect (doom-project-expand "init.el" doom-core-dir) - :to-equal (expand-file-name "init.el" (doom-project-root doom-core-dir))))) + (expect (doom-project-expand "init.el" doom-core-dir) :to-equal-file + (expand-file-name "init.el" (doom-project-root doom-core-dir))))) (describe "project-file-exists-p!" (let ((default-directory doom-core-dir)) diff --git a/core/test/test-core.el b/core/test/test-core.el index a236ed5e9..0207390b4 100644 --- a/core/test/test-core.el +++ b/core/test/test-core.el @@ -76,9 +76,7 @@ :var (doom-autoload-file doom-alt-autoload-file result) (before-each (setq doom-autoload-file (make-temp-file "doom-autoload" nil ".el")) - (with-temp-file doom-autoload-file - (insert "(eval-when-compile (defvar x 1))") - (insert "(defvar x 2)")) + (with-temp-file doom-autoload-file) (byte-compile-file doom-autoload-file)) (after-each (delete-file doom-autoload-file) From ad2b9053303f1974ebdd4be557f4c798f5c63dc4 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 15 Nov 2019 13:22:38 -0500 Subject: [PATCH 086/129] editor/evil: fix gr/gR in notmuch & elfeed --- modules/editor/evil/config.el | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/modules/editor/evil/config.el b/modules/editor/evil/config.el index f9fe28220..0873bea44 100644 --- a/modules/editor/evil/config.el +++ b/modules/editor/evil/config.el @@ -480,9 +480,19 @@ To change these keys see `+evil-repeat-keys'." :nv "gr" #'+eval:region :n "gR" #'+eval/buffer :v "gR" #'+eval:replace-region + ;; Restore these keybinds, since the blacklisted/overwritten gr/gR will + ;; undo them: (:after dired :map dired-mode-map - :n "gr" #'revert-buffer)) + :n "gr" #'revert-buffer) + (:after notmuch + :map notmuch-common-keymap + :n "gr" #'notmuch-refresh-this-buffer + :n "gR" #'notmuch-poll-and-refresh-this-buffer) + (:after elfeed + :map elfeed-search-update--force + :n "gr" #'elfeed-search-update--force + :n "gR" #'elfeed-search-fetch)) :nv "z=" #'flyspell-correct-word-generic ;; custom evil keybinds From 46bea60ad3b1137a9597a7badaad8e9d574bdbdd Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 15 Nov 2019 14:26:09 -0500 Subject: [PATCH 087/129] Add :Read ex command & 'SPC i p' keybind This can be used to extract paths from evil-ex style paths. e.g. the following inserts the stdout into the current buffer (assuming we're in ~/some/project/filename.c): :R!echo %:P ~/some/project :R!echo %:t filename.c :R!echo %:e c :R!echo %:r filename :R!echo ~/another/project/%:t:r.h ~/another/project/filename.h :R % contents of current file http://vimdoc.sourceforge.net/htmldoc/cmdline.html#filename-modifiers has a full list of vim filename modifiers. Doom doesn't support all of them, but it does support most of them. --- modules/config/default/+evil-bindings.el | 5 +++-- modules/editor/evil/+commands.el | 1 + modules/editor/evil/autoload/ex.el | 6 ++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index e63d2ce0c..069b4427d 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -468,10 +468,11 @@ ;;; i --- insert (:prefix-map ("i" . "insert") - :desc "From clipboard" "y" #'+default/yank-pop + :desc "Evil ex path" "p" (λ! (evil-ex "R!echo ")) :desc "From evil register" "r" #'evil-ex-registers :desc "Snippet" "s" #'yas-insert-snippet - :desc "Unicode" "u" #'unicode-chars-list-chars) + :desc "Unicode" "u" #'unicode-chars-list-chars + :desc "From clipboard" "y" #'+default/yank-pop) ;;; n --- notes (:prefix-map ("n" . "notes") diff --git a/modules/editor/evil/+commands.el b/modules/editor/evil/+commands.el index 8859ebac9..c1a61fc52 100644 --- a/modules/editor/evil/+commands.el +++ b/modules/editor/evil/+commands.el @@ -4,6 +4,7 @@ ;;; Custom commands ;; Editing (evil-ex-define-cmd "@" #'+evil:macro-on-all-lines) ; TODO Test me +(evil-ex-define-cmd "R[ead]" #'+evil:read) (evil-ex-define-cmd "al[ign]" #'+evil:align) (evil-ex-define-cmd "ral[ign]" #'+evil:align-right) (evil-ex-define-cmd "enhtml" #'+web:encode-html-entities) diff --git a/modules/editor/evil/autoload/ex.el b/modules/editor/evil/autoload/ex.el index 159af43a2..6ad458106 100644 --- a/modules/editor/evil/autoload/ex.el +++ b/modules/editor/evil/autoload/ex.el @@ -182,3 +182,9 @@ non-nil, a search is preformed against Doom's manual (wiht `doom/help-search')." (evil-ex-completed-binding (match-string 1 query)))) ((message "Searching for %S, this may take a while..." query) (apropos query t)))))) + +;;;###autoload (autoload '+evil:read "editor/evil/autoload/ex" nil t) +(evil-define-command +evil:read (count file) + "Alternative version of `evil-read' that replaces filename modifiers in FILE." + (interactive "P") + (evil-read count (evil-ex-replace-special-filenames file))) From 21eeb5c1a5679aeb47ef213ea14b6ed7e4e4ce87 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 15 Nov 2019 15:36:07 -0500 Subject: [PATCH 088/129] Bind 'SPC i {f,F}' to insert current file name/path --- modules/config/default/+evil-bindings.el | 2 ++ modules/config/default/autoload/default.el | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index 069b4427d..662d7694a 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -468,6 +468,8 @@ ;;; i --- insert (:prefix-map ("i" . "insert") + :desc "Current file name" "f" #'+default/insert-file-path + :desc "Current file path" "F" (λ!! #'+default/insert-file-path t) :desc "Evil ex path" "p" (λ! (evil-ex "R!echo ")) :desc "From evil register" "r" #'evil-ex-registers :desc "Snippet" "s" #'yas-insert-snippet diff --git a/modules/config/default/autoload/default.el b/modules/config/default/autoload/default.el index a85f299e2..a558f2ef7 100644 --- a/modules/config/default/autoload/default.el +++ b/modules/config/default/autoload/default.el @@ -333,3 +333,14 @@ ARG is set, prompt for a known project to search from." (while (server-running-p) (sit-for 1)) (server-start)) + +;;;###autoload +(defun +default/insert-file-path (arg) + "Insert the file name (absolute path if prefix ARG). +If `buffer-file-name' isn't set, uses `default-directory'." + (interactive "P") + (let ((path (or buffer-file-name default-directory))) + (insert + (if arg + (abbreviate-file-name path) + (file-name-nondirectory path))))) From 3d26befd471b7c91779a9da1394c7e9bdfe5a196 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 15 Nov 2019 16:10:42 -0500 Subject: [PATCH 089/129] Move 'SPC /' to 'SPC s' / is harder to reach than s, more so on certain keyboard layouts, so 'SPC /' has been moved to 'SPC s'. Similar has been done to other / and . leader keybinds. Whats more, 'SPC s' for snippets is seldomly used and available through other means, so it was removed. Summary: - 'SPC /' moved to 'SPC s' - 'SPC f .' and 'SPC f /' moved to 'SPC f f' and 'SPC f F', respectively - 'SPC p /' removed (already on 'SPC p f') - 'SPC p ?' moved to 'SPC p F' (doom/find-file-in-other-projects) - 'SPC n /' moved to 'SPC n s' (+default/org-notes-search) - 'SPC n .' removed (already on 'SPC n N') - Remove 'SPC s' prefix for snippets. Was seldomly used and most of its commands are available on other keys or through `M-x`, which is enough. --- modules/completion/ivy/README.org | 40 +++++++------- modules/config/default/+evil-bindings.el | 63 ++++++++-------------- modules/config/default/autoload/default.el | 8 +++ 3 files changed, 49 insertions(+), 62 deletions(-) diff --git a/modules/completion/ivy/README.org b/modules/completion/ivy/README.org index 84c1afc9d..4f2afbe7e 100644 --- a/modules/completion/ivy/README.org +++ b/modules/completion/ivy/README.org @@ -108,8 +108,8 @@ https://assets.doomemacs.org/completion/ivy/projectile.png | Keybind | Description | |----------------------+-------------------------------------| -| =SPC f /=, =SPC SPC= | Jump to file in project | -| =SPC f .=, =SPC .= | Jump to file from current directory | +| =SPC p f=, =SPC SPC= | Jump to file in project | +| =SPC f f=, =SPC .= | Jump to file from current directory | ** Project search & replace This module provides interactive text search and replace using the first search @@ -117,9 +117,9 @@ program available on your system (rg, ag, git-grep or grep). | Keybind | Description | |-----------+---------------------------------| -| =SPC / b= | Search the current buffer | -| =SPC / p= | Search project | -| =SPC / d= | Search this directory | +| =SPC s b= | Search the current buffer | +| =SPC s p= | Search project | +| =SPC s d= | Search this directory | | =SPC p t= | List all TODO/FIXMEs in project | https://assets.doomemacs.org/completion/ivy/search.png @@ -176,7 +176,7 @@ https://assets.doomemacs.org/completion/ivy/search-replace.png The =swiper= package provides an interactive buffer search powered by ivy. It can be invoked with: -+ =SPC / b= ++ =SPC s b= + ~:sw[iper] [QUERY]~ https://assets.doomemacs.org/completion/ivy/swiper.png @@ -200,24 +200,24 @@ https://assets.doomemacs.org/completion/ivy/todo.png | =SPC '= | Resume last ivy session | *** Jump to files, buffers or projects) -| Keybind | Description | -|---------------------------------+---------------------------------------| -| =SPC RET= | Find bookmark | -| =SPC f .=, =SPC .= | Browse from current directory | -| =SPC f /=, =SPC p /=, =SPC SPC= | Find file in project | -| =SPC f r= | Find recently opened file | -| =SPC p p= | Open another project | -| =SPC b b=, =SPC ,= | Switch to buffer in current workspace | -| =SPC b B=, =SPC <= | Switch to buffer | +| Keybind | Description | +|----------------------+---------------------------------------| +| =SPC RET= | Find bookmark | +| =SPC f f=, =SPC .= | Browse from current directory | +| =SPC p f=, =SPC SPC= | Find file in project | +| =SPC f r= | Find recently opened file | +| =SPC p p= | Open another project | +| =SPC b b=, =SPC ,= | Switch to buffer in current workspace | +| =SPC b B=, =SPC <= | Switch to buffer | *** Search | Keybind | Description | |-----------+------------------------------------------| -| =SPC / i= | Search for symbol in current buffer | -| =SPC / I= | Search for symbol in all similar buffers | -| =SPC / b= | Search the current buffer | -| =SPC / p= | Search project | -| =SPC / d= | Search this directory | +| =SPC s i= | Search for symbol in current buffer | +| =SPC s I= | Search for symbol in all similar buffers | +| =SPC s b= | Search the current buffer | +| =SPC s p= | Search project | +| =SPC s d= | Search this directory | | =SPC p t= | List all TODO/FIXMEs in project | * Configuration diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index 662d7694a..58f9ce519 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -294,24 +294,6 @@ :desc "Find file in project" "SPC" #'projectile-find-file :desc "Jump to bookmark" "RET" #'bookmark-jump - ;;; / --- search - (:prefix-map ("/" . "search") - :desc "Search buffer" "/" #'swiper - :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 "Jump list" "j" #'evil-show-jumps - :desc "Jump to mark" "m" #'evil-show-marks - :desc "Look up online" "o" #'+lookup/online - :desc "Look up online (w/ prompt)" "O" #'+lookup/online-select - :desc "Look up in local docsets" "k" #'+lookup/in-docsets - :desc "Look up in all docsets" "K" #'+lookup/in-all-docsets - :desc "Search project" "p" #'+default/search-project - :desc "Search other project" "P" #'+default/search-other-project) - ;;; TAB --- workspace (:when (featurep! :ui workspaces) (:prefix-map ("TAB" . "workspace") @@ -388,18 +370,14 @@ ;;; f --- file (:prefix-map ("f" . "file") - :desc "Find file" "." #'find-file - :desc "Find file from here" "/" - (if (featurep! :completion ivy) - #'counsel-file-jump - (λ! (doom-project-find-file default-directory))) :desc "Open project editorconfig" "c" #'editorconfig-find-current-editorconfig :desc "Copy this file" "C" #'doom/copy-this-file :desc "Find directory" "d" #'dired :desc "Delete this file" "D" #'doom/delete-this-file :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 "Find file" "f" #'find-file + :desc "Find file from here" "F" #'+default/find-file-under-here :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 @@ -478,8 +456,6 @@ ;;; n --- notes (:prefix-map ("n" . "notes") - :desc "Browse notes" "." #'+default/browse-notes - :desc "Search notes" "/" #'+default/org-notes-search :desc "Search notes for symbol" "*" #'+default/search-notes-for-symbol-at-point :desc "Org agenda" "a" #'org-agenda :desc "Org capture" "c" #'org-capture @@ -490,6 +466,7 @@ :desc "Find file in notes" "n" #'+default/find-in-notes :desc "Browse notes" "N" #'+default/browse-notes :desc "Todo list" "t" #'org-todo-list + :desc "Search notes" "s" #'+default/org-notes-search :desc "View search" "v" #'org-search-view :desc "Org export to clipboard" "y" #'+org/export-to-clipboard :desc "Org export to clipboard as RTF" "Y" #'+org/export-to-clipboard-as-rich-text @@ -545,8 +522,6 @@ (:prefix-map ("p" . "project") :desc "Browse project" "." #'+default/browse-project :desc "Browse other project" ">" #'doom/browse-in-other-project - :desc "Find file in project" "/" #'projectile-find-file - :desc "Find file in other project" "?" #'doom/find-file-in-other-project :desc "Run cmd in project root" "!" #'projectile-run-shell-command-in-root :desc "Add new project" "a" #'projectile-add-known-project :desc "Switch to project buffer" "b" #'projectile-switch-to-buffer @@ -555,7 +530,7 @@ :desc "Remove known project" "d" #'projectile-remove-known-project :desc "Edit project .dir-locals" "e" #'projectile-edit-dir-locals :desc "Find file in project" "f" #'projectile-find-file - :desc "Browse project" "F" #'+default/browse-project + :desc "Find file in other project" "F" #'doom/find-file-in-other-project :desc "Configure project" "g" #'projectile-configure-project :desc "Invalidate project cache" "i" #'projectile-invalidate-cache :desc "Kill project buffers" "k" #'projectile-kill-buffers @@ -594,19 +569,23 @@ :desc "Browse remote files" "." #'ssh-deploy-browse-remote-handler :desc "Detect remote changes" ">" #'ssh-deploy-remote-changes-handler)) - ;;; s --- snippets - (:when (featurep! :editor snippets) - (:prefix-map ("s" . "snippets") - :desc "View snippet for mode" "/" #'+snippets/find-for-current-mode - :desc "View snippet (global)" "?" #'+snippets/find - :desc "Edit snippet" "c" #'+snippets/edit - :desc "View private snippet" "f" #'+snippets/find-private - :desc "Insert snippet" "i" #'yas-insert-snippet - :desc "New snippet" "n" #'+snippets/new - :desc "New snippet alias" "N" #'+snippets/new-alias - :desc "Reload snippets" "r" #'yas-reload-all - :desc "Create temporary snippet" "s" #'aya-create - :desc "Expand temporary snippet" "e" #'aya-expand)) + ;;; s --- search + (:prefix-map ("s" . "search") + :desc "Search buffer" "s" #'swiper + :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 "Jump list" "j" #'evil-show-jumps + :desc "Jump to mark" "m" #'evil-show-marks + :desc "Look up online" "o" #'+lookup/online + :desc "Look up online (w/ prompt)" "O" #'+lookup/online-select + :desc "Look up in local docsets" "k" #'+lookup/in-docsets + :desc "Look up in all docsets" "K" #'+lookup/in-all-docsets + :desc "Search project" "p" #'+default/search-project + :desc "Search other project" "P" #'+default/search-other-project) ;;; t --- toggle (:prefix-map ("t" . "toggle") diff --git a/modules/config/default/autoload/default.el b/modules/config/default/autoload/default.el index a558f2ef7..08cf7b8cf 100644 --- a/modules/config/default/autoload/default.el +++ b/modules/config/default/autoload/default.el @@ -334,6 +334,14 @@ ARG is set, prompt for a known project to search from." (sit-for 1)) (server-start)) +;;;###autoload +(defun +default/find-file-under-here () + "Perform a recursive file search from the current directory." + (interactive) + (if (featurep! :completion ivy) + (call-interactively #'counsel-file-jump) + (λ! (doom-project-find-file default-directory)))) + ;;;###autoload (defun +default/insert-file-path (arg) "Insert the file name (absolute path if prefix ARG). From b9e5059e3f74d3165d488342f8a9f1a4a8a36ffa Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 15 Nov 2019 16:25:56 -0500 Subject: [PATCH 090/129] Ensure only one window after doom/kill-all-buffers --- core/autoload/buffers.el | 1 + 1 file changed, 1 insertion(+) diff --git a/core/autoload/buffers.el b/core/autoload/buffers.el index f393a570d..4f355417a 100644 --- a/core/autoload/buffers.el +++ b/core/autoload/buffers.el @@ -289,6 +289,7 @@ belong to the current project." (when (memq (current-buffer) buffer-list) (switch-to-buffer (doom-fallback-buffer))) (mapc #'doom-kill-buffer-and-windows buffer-list) + (delete-other-windows) (when interactive (message "Killed %s buffers" (- (length buffer-list) From 7192a686a26d9c042bd26c9a808451a553fddaa2 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 15 Nov 2019 16:28:32 -0500 Subject: [PATCH 091/129] Use swiper-isearch instead of swiper Much faster to start up --- modules/config/default/+evil-bindings.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index 58f9ce519..ebc0c964b 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -571,7 +571,6 @@ ;;; s --- search (:prefix-map ("s" . "search") - :desc "Search buffer" "s" #'swiper :desc "Search buffer" "b" #'swiper :desc "Search current directory" "d" #'+default/search-cwd :desc "Search other directory" "D" #'+default/search-other-cwd @@ -585,7 +584,8 @@ :desc "Look up in local docsets" "k" #'+lookup/in-docsets :desc "Look up in all docsets" "K" #'+lookup/in-all-docsets :desc "Search project" "p" #'+default/search-project - :desc "Search other project" "P" #'+default/search-other-project) + :desc "Search other project" "P" #'+default/search-other-project + :desc "Search buffer" "s" #'swiper-isearch) ;;; t --- toggle (:prefix-map ("t" . "toggle") From 03e9dc1daff2e307640347a12147b814f6a18e34 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 15 Nov 2019 19:15:23 -0500 Subject: [PATCH 092/129] Follow up on 64222c69c To fix cases where comment-line-break-function's first argument isn't optional. --- modules/editor/evil/autoload/advice.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/editor/evil/autoload/advice.el b/modules/editor/evil/autoload/advice.el index 2a86105b9..4e02b9adf 100644 --- a/modules/editor/evil/autoload/advice.el +++ b/modules/editor/evil/autoload/advice.el @@ -99,7 +99,7 @@ more information on modifiers." ;; FIXME oh god why (save-excursion (if comment-line-break-function - (funcall comment-line-break-function) + (funcall comment-line-break-function nil) (comment-indent-new-line)) (when (and (derived-mode-p 'c-mode 'c++-mode 'objc-mode 'java-mode 'js2-mode) (eq (char-after) ?/)) From bd4755123f2f1f710a05090dedc040140b9f1e90 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 15 Nov 2019 22:12:45 -0500 Subject: [PATCH 093/129] Replace */tasks commands w/ magit-todos-list If we want ivy/helm interfaces to it, we should use magit-todos as a backend. --- modules/completion/helm/autoload/helm.el | 6 -- modules/completion/ivy/autoload/ivy.el | 82 ---------------------- modules/completion/ivy/config.el | 20 ------ modules/config/default/+emacs-bindings.el | 2 +- modules/config/default/+evil-bindings.el | 2 +- modules/config/default/autoload/default.el | 9 --- 6 files changed, 2 insertions(+), 119 deletions(-) diff --git a/modules/completion/helm/autoload/helm.el b/modules/completion/helm/autoload/helm.el index c132b29a2..3859281be 100644 --- a/modules/completion/helm/autoload/helm.el +++ b/modules/completion/helm/autoload/helm.el @@ -1,11 +1,5 @@ ;;; completion/helm/autoload/helm.el -*- lexical-binding: t; -*- -;;;###autoload -(defun +helm/tasks (&optional _arg) - (interactive "P") - ;; TODO Implement `+helm/tasks' - (error "Not implemented yet")) - ;;;###autoload (defun +helm/projectile-find-file () "Call `helm-find-files' if called from HOME, otherwise diff --git a/modules/completion/ivy/autoload/ivy.el b/modules/completion/ivy/autoload/ivy.el index 4332aafaa..a698d31b0 100644 --- a/modules/completion/ivy/autoload/ivy.el +++ b/modules/completion/ivy/autoload/ivy.el @@ -157,88 +157,6 @@ If ARG (universal argument), open selection in other-window." (interactive) (+ivy--switch-buffer nil t)) -(defun +ivy--tasks-candidates (tasks) - "Generate a list of task tags (specified by `+ivy-task-tags') for -`+ivy/tasks'." - (let* ((max-type-width - (cl-loop for task in +ivy-task-tags maximize (length (car task)))) - (max-desc-width - (cl-loop for task in tasks maximize (length (cl-cdadr task)))) - (max-width (max (+ max-desc-width 3) - 25))) - (cl-loop - with fmt = (format "%%-%ds %%-%ds%%s:%%s" max-type-width max-width) - for alist in tasks - collect - (let-alist alist - (list (format fmt - (propertize .type 'face (cdr (assoc .type +ivy-task-tags))) - (substring .desc 0 (min max-desc-width (length .desc))) - (propertize (abbreviate-file-name .file) 'face 'font-lock-keyword-face) - (propertize .line 'face 'font-lock-constant-face)) - .type .file .line))))) - -(defun +ivy--tasks (target) - (let (case-fold-search) - (cl-loop with task-tags = (mapcar #'car +ivy-task-tags) - with out = - (cdr - (apply #'doom-call-process - (append - (or (when-let (bin (executable-find "rg")) - (list bin "--line-number")) - (when-let (bin (executable-find "ag")) - (list bin "--numbers")) - (user-error "ripgrep & the_silver_searcher are unavailable")) - (list "-H" "-S" "--no-heading" "--" - (concat "\\s(" - (string-join task-tags "|") - ")([\\s:]|\\([^)]+\\):?)") - target)))) - for x in (and out (split-string out "\n" t)) - when (condition-case-unless-debug ex - (string-match - (concat "^\\([^:]+\\):\\([0-9]+\\):.+\\(" - (string-join task-tags "\\|") - "\\):?\\s-*\\(.+\\)") - x) - (error - (print! (red "Error matching task in file: (%s) %s") - (error-message-string ex) - (car (split-string x ":"))) - nil)) - collect `((type . ,(match-string 3 x)) - (desc . ,(match-string 4 x)) - (file . ,(match-string 1 x)) - (line . ,(match-string 2 x)))))) - -(defun +ivy--tasks-open-action (x) - "Jump to the file and line of the current task." - (cl-destructuring-bind (_label type file line) x - (with-ivy-window - (find-file (expand-file-name file (doom-project-root))) - (goto-char (point-min)) - (forward-line (1- (string-to-number line))) - (when (search-forward type (line-end-position) t) - (backward-char (length type))) - (recenter)))) - -;;;###autoload -(defun +ivy/tasks (&optional arg) - "Search through all TODO/FIXME tags in the current project. If ARG, only -search current file. See `+ivy-task-tags' to customize what this searches for." - (interactive "P") - (ivy-read (format "Tasks (%s): " - (if arg - (concat "in: " (file-relative-name buffer-file-name)) - "project")) - (let ((tasks (+ivy--tasks (if arg buffer-file-name (doom-project-root))))) - (unless tasks - (user-error "No tasks in your project! Good job!")) - (+ivy--tasks-candidates tasks)) - :action #'+ivy--tasks-open-action - :caller '+ivy/tasks)) - ;;;###autoload (defun +ivy/woccur () "Invoke a wgrep buffer on the current ivy results, if supported." diff --git a/modules/completion/ivy/config.el b/modules/completion/ivy/config.el index f12ddf55d..669e16eb4 100644 --- a/modules/completion/ivy/config.el +++ b/modules/completion/ivy/config.el @@ -7,26 +7,6 @@ When nil, don't preview anything. When non-nil, preview non-virtual buffers. When 'everything, also preview virtual buffers") -(defvar +ivy-task-tags - '(("TODO" . warning) - ("FIXME" . error) - ("HACK" . font-lock-constant-face) - ("REVIEW" . font-lock-keyword-face) - ("NOTE" . success) - ("DEPRECATED" . font-lock-doc-face)) - "An alist of tags for `+ivy/tasks' to include in its search, whose CDR is the -face to render it with.") - -(defvar +ivy-project-search-engines '(rg ag) - "What search tools for `+ivy/project-search' (and `+ivy-file-search' when no -ENGINE is specified) to try, and in what order. - -To disable a particular tool, remove it from this list. To prioritize a tool -over others, move it to the front of the list. Later duplicates in this list are -silently ignored. - -If you want to already use git-grep or grep, set this to nil.") - (defvar +ivy-buffer-unreal-face 'font-lock-comment-face "The face for unreal buffers in `ivy-switch-to-buffer'.") diff --git a/modules/config/default/+emacs-bindings.el b/modules/config/default/+emacs-bindings.el index 4b6bf75af..e63e544ce 100644 --- a/modules/config/default/+emacs-bindings.el +++ b/modules/config/default/+emacs-bindings.el @@ -82,7 +82,7 @@ (:prefix ("p" . "project") :desc "Find file in other project" "F" #'doom/find-file-in-other-project :desc "Search project" "s" #'+default/search-project - :desc "List project tasks" "t" #'+default/project-tasks + :desc "List project tasks" "t" #'magit-todos-list :desc "Open project scratch buffer" "x" #'doom/open-project-scratch-buffer :desc "Switch to project scratch buffer" "X" #'doom/switch-to-project-scratch-buffer ;; later expanded by projectile diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index ebc0c964b..4450d4003 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -541,7 +541,7 @@ :desc "Save project files" "s" #'projectile-save-project-buffers :desc "Pop up scratch buffer" "x" #'doom/open-project-scratch-buffer :desc "Switch to scratch buffer" "X" #'doom/switch-to-project-scratch-buffer - :desc "List project tasks" "t" #'+default/project-tasks + :desc "List project tasks" "t" #'magit-todos-list :desc "Test project" "T" #'projectile-test-project) ;;; q --- quit/session diff --git a/modules/config/default/autoload/default.el b/modules/config/default/autoload/default.el index 08cf7b8cf..ad49e2f6d 100644 --- a/modules/config/default/autoload/default.el +++ b/modules/config/default/autoload/default.el @@ -73,15 +73,6 @@ If ARG (universal argument), runs `compile' from the current directory." (with-current-buffer buffer (funcall (default-value 'major-mode)))))) -;;;###autoload -(defun +default/project-tasks () - "Invokes `+ivy/tasks' or `+helm/tasks', depending on which is available." - (interactive) - (cond ((featurep! :tools magit) - (call-interactively #'magit-todos-list)) - ((featurep! :completion ivy) (+ivy/tasks)) - ((featurep! :completion helm) (+helm/tasks)))) - ;;;###autoload (defun +default/newline-above () "Insert an indented new line before the current one." From 449ddb986c0a5c9b5ee3d9eb4882eaee1768bc96 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 15 Nov 2019 22:16:09 -0500 Subject: [PATCH 094/129] Minor refactors & reformatting across the board --- modules/completion/helm/autoload/helm.el | 2 +- modules/completion/ivy/autoload/ivy.el | 2 +- modules/editor/evil/autoload/advice.el | 7 ++++--- modules/term/eshell/config.el | 2 +- modules/tools/pass/config.el | 1 - 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/completion/helm/autoload/helm.el b/modules/completion/helm/autoload/helm.el index 3859281be..f5464067e 100644 --- a/modules/completion/helm/autoload/helm.el +++ b/modules/completion/helm/autoload/helm.el @@ -35,7 +35,7 @@ workspace." ;; -;; Project search +;;; Project search (defun +helm-ag-search-args (all-files-p recursive-p) (list (concat "ag " (if IS-WINDOWS "--vimgrep" "--nocolor --nogroup")) diff --git a/modules/completion/ivy/autoload/ivy.el b/modules/completion/ivy/autoload/ivy.el index a698d31b0..88928647c 100644 --- a/modules/completion/ivy/autoload/ivy.el +++ b/modules/completion/ivy/autoload/ivy.el @@ -211,7 +211,7 @@ If ARG (universal argument), open selection in other-window." ;; -;; File searching +;;; File searching ;;;###autoload (defun +ivy/projectile-find-file () diff --git a/modules/editor/evil/autoload/advice.el b/modules/editor/evil/autoload/advice.el index 4e02b9adf..651393858 100644 --- a/modules/editor/evil/autoload/advice.el +++ b/modules/editor/evil/autoload/advice.el @@ -80,9 +80,10 @@ more information on modifiers." (when (and (not (string= path "")) (equal (substring path -1) "/")) (setq path (substring path 0 -1)))) (setq file-name - (replace-regexp-in-string (format "\\(?:^\\|[^\\\\]\\)\\(%s\\)" - (regexp-quote (string-trim-left (car match)))) - path file-name t t 1)))) + (replace-regexp-in-string + (format "\\(?:^\\|[^\\\\]\\)\\(%s\\)" + (regexp-quote (string-trim-left (car match)))) + path file-name t t 1)))) (replace-regexp-in-string regexp "\\1" file-name t))) (defun +evil--insert-newline (&optional above _noextranewline) diff --git a/modules/term/eshell/config.el b/modules/term/eshell/config.el index f07a3d43a..39af256d8 100644 --- a/modules/term/eshell/config.el +++ b/modules/term/eshell/config.el @@ -132,7 +132,7 @@ You should use `set-eshell-alias!' to change this.") :n "C" #'+eshell/evil-change-line :n "d" #'+eshell/evil-delete :n "D" #'+eshell/evil-delete-line - :ig "C-d" #'+eshell/quit-or-delete-char + :ig "C-d" #'+eshell/quit-or-delete-char "TAB" #'+eshell/pcomplete [tab] #'+eshell/pcomplete "C-s" #'+eshell/search-history diff --git a/modules/tools/pass/config.el b/modules/tools/pass/config.el index 4017d6f56..d6d78baf8 100644 --- a/modules/tools/pass/config.el +++ b/modules/tools/pass/config.el @@ -23,7 +23,6 @@ (buffer-substring-no-properties (point-min) (point-max)))) -;; `pass' (after! pass (set-evil-initial-state! 'pass-mode 'emacs) (set-popup-rule! "^\\*Password-Store" :side 'left :size 0.25 :quit nil) From b7044b5f32e128ed329a7b1613a87918cf097cde Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 15 Nov 2019 23:56:08 -0500 Subject: [PATCH 095/129] Fix #2064: partially revert bd4755123 A change unintentionally snuck into bd4755123. --- modules/completion/ivy/config.el | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/modules/completion/ivy/config.el b/modules/completion/ivy/config.el index 669e16eb4..d6ab7e367 100644 --- a/modules/completion/ivy/config.el +++ b/modules/completion/ivy/config.el @@ -7,6 +7,16 @@ When nil, don't preview anything. When non-nil, preview non-virtual buffers. When 'everything, also preview virtual buffers") +(defvar +ivy-project-search-engines '(rg ag) + "What search tools for `+ivy/project-search' (and `+ivy-file-search' when no +ENGINE is specified) to try, and in what order. + +To disable a particular tool, remove it from this list. To prioritize a tool +over others, move it to the front of the list. Later duplicates in this list are +silently ignored. + +If you want to already use git-grep or grep, set this to nil.") + (defvar +ivy-buffer-unreal-face 'font-lock-comment-face "The face for unreal buffers in `ivy-switch-to-buffer'.") From 5738e39fea05e4f9cfe5f7783c6be1b9184fceab Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 17 Nov 2019 00:33:52 +0900 Subject: [PATCH 096/129] Disable proof general's splash screen --- modules/lang/coq/config.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/lang/coq/config.el b/modules/lang/coq/config.el index 086d3648b..ef7ef196f 100644 --- a/modules/lang/coq/config.el +++ b/modules/lang/coq/config.el @@ -9,7 +9,8 @@ ;; tries to load `proof-site'. We prevent this by defining these two variables ;; early, in our own autoloads file. (setq pg-init--script-full-path (locate-library "proof-general") - pg-init--pg-root (file-name-directory pg-init--script-full-path)) + pg-init--pg-root (file-name-directory pg-init--script-full-path) + proof-splash-enable nil) ;;;###package coq From 78bb2e2ae54d9e1b711212af1bda34e4eb0624bb Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 17 Nov 2019 00:34:15 +0900 Subject: [PATCH 097/129] diable the hello feature of company-coq --- modules/lang/coq/config.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/lang/coq/config.el b/modules/lang/coq/config.el index ef7ef196f..2383e8be7 100644 --- a/modules/lang/coq/config.el +++ b/modules/lang/coq/config.el @@ -75,10 +75,11 @@ :documentation #'company-coq-doc) (if (not (featurep! :completion company)) - (setq company-coq-disabled-features '(company company-defaults)) + (setq company-coq-disabled-features '(hello company company-defaults)) ;; `company-coq''s company defaults impose idle-completion on folks, so ;; we'll set up company ourselves. (add-to-list 'company-coq-disabled-features 'company-defaults) + (add-to-list 'company-coq-disabled-features 'hello) ;; See https://github.com/cpitclaudel/company-coq/issues/42 (map! :map coq-mode-map [remap company-complete-common] #'company-indent-or-complete-common)) From c4fad17c2914362fc0de576bcd4589a521dbe0d7 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 17 Nov 2019 01:21:11 +0900 Subject: [PATCH 098/129] Remove company-coq's hello page --- modules/lang/coq/config.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/lang/coq/config.el b/modules/lang/coq/config.el index 2383e8be7..757c376a6 100644 --- a/modules/lang/coq/config.el +++ b/modules/lang/coq/config.el @@ -74,12 +74,12 @@ :references #'company-coq-grep-symbol :documentation #'company-coq-doc) + (setq company-coq-disabled-features '(hello company-defaults)) + (if (not (featurep! :completion company)) - (setq company-coq-disabled-features '(hello company company-defaults)) + (add-to-list 'company-coq-disabled-features 'company) ;; `company-coq''s company defaults impose idle-completion on folks, so ;; we'll set up company ourselves. - (add-to-list 'company-coq-disabled-features 'company-defaults) - (add-to-list 'company-coq-disabled-features 'hello) ;; See https://github.com/cpitclaudel/company-coq/issues/42 (map! :map coq-mode-map [remap company-complete-common] #'company-indent-or-complete-common)) From a4e9d85db4e1dccce3cf161487f1a47626a5b02c Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 17 Nov 2019 01:22:12 +0900 Subject: [PATCH 099/129] invert (if (not ..)) statement --- modules/lang/coq/config.el | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/lang/coq/config.el b/modules/lang/coq/config.el index 757c376a6..86cd6ee0b 100644 --- a/modules/lang/coq/config.el +++ b/modules/lang/coq/config.el @@ -76,13 +76,13 @@ (setq company-coq-disabled-features '(hello company-defaults)) - (if (not (featurep! :completion company)) - (add-to-list 'company-coq-disabled-features 'company) + (if (featurep! :completion company) + (map! :map coq-mode-map [remap company-complete-common] + #'company-indent-or-complete-common) ;; `company-coq''s company defaults impose idle-completion on folks, so ;; we'll set up company ourselves. ;; See https://github.com/cpitclaudel/company-coq/issues/42 - (map! :map coq-mode-map [remap company-complete-common] - #'company-indent-or-complete-common)) + (add-to-list 'company-coq-disabled-features 'company)) (map! :map coq-mode-map :localleader From 25e5c667779f3718193dbb23a5b937888f5fc627 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 16 Nov 2019 13:23:01 -0500 Subject: [PATCH 100/129] Fix 'irc-buffers is not a defined segment' error It was merged into irc segment upstream: seagle0128/doom-modeline/dcc57fd4 --- modules/ui/modeline/config.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ui/modeline/config.el b/modules/ui/modeline/config.el index d26458f56..ef23ab0c3 100644 --- a/modules/ui/modeline/config.el +++ b/modules/ui/modeline/config.el @@ -62,7 +62,7 @@ (doom-modeline-def-modeline 'special '(bar window-number matches buffer-info-simple buffer-position selection-info) - '(objed-state misc-info persp-name debug input-method irc-buffers buffer-encoding lsp major-mode process checker)) + '(objed-state misc-info persp-name debug input-method irc buffer-encoding lsp major-mode process checker)) (doom-modeline-def-modeline 'project '(bar window-number buffer-default-directory) From 32089d9acb468b387d62c3e9054b5d332adfb215 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 16 Nov 2019 20:13:31 -0500 Subject: [PATCH 101/129] docs/faq: fix module index link --- docs/faq.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/faq.org b/docs/faq.org index af9f9f3d9..56b4b6990 100644 --- a/docs/faq.org +++ b/docs/faq.org @@ -489,7 +489,7 @@ semicolons: Remember to run ~bin/doom refresh~ afterwards, on the command line, to sync your module list with Doom. -You can find a comprehensive list of modules in the [[file:../modules/README.org][Module Index]]. +You can find a comprehensive list of modules in the [[file:index.org::*Module list][Module Index]]. ** How do I install a package from ELPA? Add a ~package!~ declaration to =~/.doom.d/packages.el= for each package you From c363791da0031f36ab3713184ce5c158b03468a4 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 16 Nov 2019 20:41:46 -0500 Subject: [PATCH 102/129] Made -f the default for 'doom refresh' #2065 -f is necessary when there are changes to your system that Doom needs to pick up when running 'doom refresh'. It won't do anything if your doom dotfiles haven't visibly changed, which won't be the case if you are installing, say, mu4e or vterm, through your system package manager. What was initially a time-saving mechanic has become a trap for beginners, so I've made -f its default behavior and its previous behavior opt-in with the -n / --if-necessary switches. --- core/core-cli.el | 6 +++--- docs/contributing.org | 4 ++-- docs/faq.org | 12 +++++++----- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/core/core-cli.el b/core/core-cli.el index 5cde55b4b..e1ca98b87 100644 --- a/core/core-cli.el +++ b/core/core-cli.el @@ -216,7 +216,7 @@ BODY will be run when this dispatcher is called." (load! "cli/install") (defcli! (refresh re) - ((force-p ["-f" "--force"] "Regenerate autoloads files, whether or not they're stale")) + ((if-necessary-p ["-n" "--if-necessary"] "Only regenerate autoloads files if necessary")) "Ensure Doom is properly set up. This is the equivalent of running autoremove, install, autoloads, then @@ -234,7 +234,7 @@ stale." (let (success) (when (file-exists-p doom-env-file) (doom-cli-reload-env-file 'force)) - (doom-cli-reload-core-autoloads force-p) + (doom-cli-reload-core-autoloads (not if-necessary-p)) (unwind-protect (progn (and (doom-cli-packages-install) @@ -243,7 +243,7 @@ stale." (setq success t)) (and (doom-cli-packages-purge nil 'builds-p nil) (setq success t))) - (doom-cli-reload-package-autoloads (or success force-p)) + (doom-cli-reload-package-autoloads (or success (not if-necessary-p))) (doom-cli-byte-compile nil 'recompile)) t)) diff --git a/docs/contributing.org b/docs/contributing.org index e8850ecf7..46feb468f 100644 --- a/docs/contributing.org +++ b/docs/contributing.org @@ -59,8 +59,8 @@ things you should try first: + Make sure your configuration (or Doom Emacs) is *not* byte-compiled. Run ~doom clean~ to ensure it isn't. *Byte-compilation interferes with debugging!* -+ Run ~bin/doom refresh -f~ to ensure all plugins are installed and autoload - files generated. ++ Run ~bin/doom refresh~ to ensure all plugins are installed and autoload files + generated. + Run ~bin/doom doctor~ to diagnose common issues with your system. + Check [[file:faq.org::*Common%20Issues][Common Issues]] in the FAQ to see if yours is a known issue. + If you happen to know what module(s) are relevant to your issue, check their diff --git a/docs/faq.org b/docs/faq.org index 56b4b6990..695ee890c 100644 --- a/docs/faq.org +++ b/docs/faq.org @@ -813,10 +813,12 @@ commands that you may find particularly useful: ** When to run ~doom refresh~ As a rule of thumb you should run ~doom refresh~ whenever you: -+ Update Doom (with ~git pull~), ++ Update Doom with ~git pull~ instead of ~doom upgrade~, + Change your ~doom!~ block in =$DOOMDIR/init.el=, -+ Change the autoload files in any module (or =$DOOMDIR=), ++ Change autoload files in any module (or =$DOOMDIR=), + Or change the packages.el file in any module (or =$DOOMDIR=). ++ Install an Emacs package or dependency outside of Emacs (i.e. through your OS + package manager). If anything is misbehaving, it's a good idea to run ~doom refresh~ first. ~doom refresh~ is responsible for regenerating your autoloads file (which tells Doom @@ -985,12 +987,12 @@ manually (e.g. by double-clicking each file in explorer). ** ~void-variable~ and ~void-function~ errors on startup The most common culprit for these types of errors are: -1. An out-of-date autoloads file. To regenerate it, run ~doom refresh -f~. +1. An out-of-date autoloads file. To regenerate it, run ~doom refresh~. To avoid this issue, remember to run ~doom refresh~ whenever you modify your ~doom!~ block in =~/.doom.d/init.el=, or add ~package!~ declarations to - =~/.doom.d/packages.el=. If you modify =~/.emacs.d/.local= by hand, for - whatever reason, run ~doom refresh -f~ to bypass caches and modify-checks. + =~/.doom.d/packages.el=. Or if you modify =~/.emacs.d/.local= by hand, for + whatever reason. See ~doom help refresh~ for details on what this command does and when you should use it. From 4dc3f0956a122034546d887029a3c4040aea1568 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 16 Nov 2019 20:55:53 -0500 Subject: [PATCH 103/129] lang/csharp: move omnisharp-cache-directory to doom-etc-dir It deceptively uses this directory to store the omnisharp server, rather than just its cache files. Servers belong in doom-etc-dir. --- modules/lang/csharp/config.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/lang/csharp/config.el b/modules/lang/csharp/config.el index 66a31acc5..c8bf81259 100644 --- a/modules/lang/csharp/config.el +++ b/modules/lang/csharp/config.el @@ -21,7 +21,7 @@ :commands omnisharp-install-server :preface (setq omnisharp-auto-complete-want-documentation nil - omnisharp-cache-directory (concat doom-cache-dir "omnisharp")) + omnisharp-cache-directory (concat doom-etc-dir "omnisharp")) :config (defun +csharp-cleanup-omnisharp-server-h () "Clean up the omnisharp server once you kill the last csharp-mode buffer." From f54d7a15cd18db18fafe9d6c4e496ebc1b99d7e1 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 16 Nov 2019 20:57:04 -0500 Subject: [PATCH 104/129] tools/eval: send to repl (via gr) by line #2056 --- modules/tools/eval/autoload/repl.el | 32 +++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/modules/tools/eval/autoload/repl.el b/modules/tools/eval/autoload/repl.el index 09d1bdc22..a5e48b570 100644 --- a/modules/tools/eval/autoload/repl.el +++ b/modules/tools/eval/autoload/repl.el @@ -115,11 +115,27 @@ immediately after." (buffer (+eval--ensure-in-repl-buffer))) (unless buffer (error "No REPL open")) - (with-selected-window (get-buffer-window buffer) - (when (bound-and-true-p evil-local-mode) - (call-interactively #'evil-append-line)) - (insert (string-trim selection)) - (unless inhibit-auto-execute-p - ;; `comint-send-input' isn't enough because some REPLs may not use - ;; comint, so just emulate the keypress. - (execute-kbd-macro (kbd "RET")))))) + (let ((origin-window (selected-window)) + (selection + (with-temp-buffer + (insert selection) + (goto-char (point-min)) + (when (> (skip-chars-forward "\n") 0) + (delete-region (point-min) (point))) + (indent-rigidly (point) (point-max) + (- (skip-chars-forward " \t"))) + (string-trim-right (buffer-string))))) + (with-selected-window (get-buffer-window buffer) + (with-current-buffer buffer + (dolist (line (split-string selection "\n")) + (insert line) + (if inhibit-auto-execute-p + (insert "\n") + ;; `comint-send-input' isn't enough because some REPLs may not use + ;; comint, so just emulate the keypress. + (execute-kbd-macro (kbd "RET"))) + (sit-for 0.001) + (redisplay 'force))) + (when (and (eq origin-window (selected-window)) + (bound-and-true-p evil-local-mode)) + (call-interactively #'evil-append-line)))))) From d474223a99144ba668b0c101b6afa7dd9c9b6638 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 16 Nov 2019 21:03:37 -0500 Subject: [PATCH 105/129] cli/upgrade: don't use removed -f switch --- core/cli/upgrade.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/cli/upgrade.el b/core/cli/upgrade.el index a11f3438c..7b9912ecf 100644 --- a/core/cli/upgrade.el +++ b/core/cli/upgrade.el @@ -18,7 +18,7 @@ following shell commands: (doom-initialize) (doom-initialize-packages) (when (doom-cli-packages-update) - (doom-cli-reload-package-autoloads 'force-p)))) + (doom-cli-reload-package-autoloads 'force)))) ;; @@ -103,7 +103,7 @@ following shell commands: (equal (vc-git--rev-parse "HEAD") new-rev)) (error "Failed to check out %s" (substring new-rev 0 10))) (print! (success "Finished upgrading Doom Emacs"))) - (doom-cli-execute "refresh" (append (if auto-accept-p '("-y")) '("-f"))) + (doom-cli-execute "refresh" (if auto-accept-p '("-y"))) t) (print! (success "Done! Restart Emacs for changes to take effect.")))))) From 8aff94944993985399d858791176eae55fe121f6 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 16 Nov 2019 21:33:17 -0500 Subject: [PATCH 106/129] config/default: remove unneeded feature gating --- modules/config/default/+evil-bindings.el | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index 4450d4003..3dee4231e 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -363,10 +363,9 @@ :desc "Send to repl" "s" #'+eval/send-region-to-repl :desc "Delete trailing whitespace" "w" #'delete-trailing-whitespace :desc "Delete trailing newlines" "W" #'doom/delete-trailing-newlines + :desc "List errors" "x" #'flymake-show-diagnostics-buffer (:when (featurep! :tools flycheck) - :desc "List errors" "x" #'flycheck-list-errors) - (:unless (featurep! :tools flycheck) - :desc "List errors" "x" #'flymake-show-diagnostics-buffer)) + :desc "List errors" "x" #'flycheck-list-errors)) ;;; f --- file (:prefix-map ("f" . "file") @@ -590,10 +589,9 @@ ;;; t --- toggle (:prefix-map ("t" . "toggle") :desc "Big mode" "b" #'doom-big-font-mode + :desc "Flymake" "f" #'flymake-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 (:when (featurep! :ui indent-guides) From c30d0ab1b76511a751c062b87d7fa50a51800caa Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 17 Nov 2019 01:15:51 -0500 Subject: [PATCH 107/129] tools/eval: ensure final newline after repl input #2056 Fix an issue where the final line of send-to-repl input (via gr) isn't consistently processed. --- modules/tools/eval/autoload/repl.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/tools/eval/autoload/repl.el b/modules/tools/eval/autoload/repl.el index a5e48b570..7db09a522 100644 --- a/modules/tools/eval/autoload/repl.el +++ b/modules/tools/eval/autoload/repl.el @@ -124,7 +124,8 @@ immediately after." (delete-region (point-min) (point))) (indent-rigidly (point) (point-max) (- (skip-chars-forward " \t"))) - (string-trim-right (buffer-string))))) + (concat (string-trim-right (buffer-string)) + "\n")))) (with-selected-window (get-buffer-window buffer) (with-current-buffer buffer (dolist (line (split-string selection "\n")) From 7a7b89ded1346f66624b36b94581b6bd57894a57 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 17 Nov 2019 01:17:34 -0500 Subject: [PATCH 108/129] Init packages from init.el in noninteractive sessions This allows users to load init.el for their batch scripts, rather than some monstrosity involving loading core/core.el and doom-initialize. --- core/core.el | 2 ++ init.el | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/core/core.el b/core/core.el index cb12f8d08..176a93855 100644 --- a/core/core.el +++ b/core/core.el @@ -28,6 +28,8 @@ ;; Load the bare necessities (require 'core-lib) +(autoload 'doom-initialize-packages "core-packages") + ;; ;;; Global variables diff --git a/init.el b/init.el index a4c8c0a88..4ddc67d78 100644 --- a/init.el +++ b/init.el @@ -48,7 +48,8 @@ ;; And let 'er rip! (doom-initialize) -(unless noninteractive +(if noninteractive + (doom-initialize-packages) (doom-initialize-core) (doom-initialize-modules) (add-hook 'window-setup-hook #'doom-display-benchmark-h) From a66872fe259ee6a99b6f4fae63ac4854102dc2b7 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 17 Nov 2019 01:19:59 -0500 Subject: [PATCH 109/129] Focus on ripgrep; remove ag, git-grep & grep support We're focusing on ripgrep so we can iterate on search functionality in Doom quicker. There is nothing the other search backends can do that ripgrep can't. It is now a hard dependency for Doom. --- core/autoload/help.el | 27 ++-- modules/completion/helm/autoload/helm.el | 166 ++++------------------ modules/completion/ivy/autoload/ivy.el | 169 ++++++----------------- modules/tools/lookup/autoload/lookup.el | 8 +- 4 files changed, 78 insertions(+), 292 deletions(-) diff --git a/core/autoload/help.el b/core/autoload/help.el index 362ec25bc..731c4737e 100644 --- a/core/autoload/help.el +++ b/core/autoload/help.el @@ -610,18 +610,12 @@ Uses the symbol at point or the current selection, if available." (list (read-string (format "Search load-path (default: %s): " query) nil 'git-grep query)))) - ;; REVIEW Replace with deadgrep or ivy/helm interface when we drop ag/git-grep - ;; support later + ;; REVIEW Replace with deadgrep (grep-find (mapconcat #'shell-quote-argument - (cond ((executable-find "rg") - `("rg" "-L" "--search-zip" "--no-heading" "--color=never" - ,query ,@(cl-remove-if-not #'file-directory-p load-path))) - ((executable-find "ag") - `("ag" "--search-zip" "--nogroup" "--nocolor" - ,query ,@(cl-remove-if-not #'file-directory-p load-path))) - ((user-error "This command requires ripgrep or the_silver_searcher to be installed on your system"))) + (append (list "rg" "-L" "--search-zip" "--no-heading" "--color=never" query) + (cl-remove-if-not #'file-directory-p load-path)) " "))) ;; TODO factor our the duplicate code between this and the above @@ -639,18 +633,13 @@ Uses the symbol at point or the current selection, if available." (list (read-string (format "Search load-path (default: %s): " query) nil 'git-grep query)))) + (unless (executable-find "rg") + (user-error "Can't find ripgrep on your system")) (require 'elisp-refs) - ;; REVIEW Replace with deadgrep or ivy/helm interface when we drop ag/git-grep - ;; support later + ;; REVIEW Replace with deadgrep (grep-find (mapconcat #'shell-quote-argument - (let ((search (elisp-refs--loaded-paths))) - (cond ((executable-find "rg") - `("rg" "-L" "--search-zip" "--no-heading" "--color=never" - ,query ,@(cl-remove-if-not #'file-directory-p search))) - ((executable-find "ag") - `("ag" "--search-zip" "--nogroup" "--nocolor" - ,query ,@(cl-remove-if-not #'file-directory-p search))) - ((user-error "This command requires ripgrep or the_silver_searcher to be installed on your system")))) + (append (list "rg" "-L" "--search-zip" "--no-heading" "--color=never" query) + (cl-remove-if-not #'file-directory-p (elisp-refs--loaded-paths))) " "))) diff --git a/modules/completion/helm/autoload/helm.el b/modules/completion/helm/autoload/helm.el index f5464067e..116fc079d 100644 --- a/modules/completion/helm/autoload/helm.el +++ b/modules/completion/helm/autoload/helm.el @@ -37,68 +37,9 @@ workspace." ;; ;;; Project search -(defun +helm-ag-search-args (all-files-p recursive-p) - (list (concat "ag " (if IS-WINDOWS "--vimgrep" "--nocolor --nogroup")) - "-S" - (if all-files-p "-z -a") - (unless recursive-p "--depth 1"))) - -(defun +helm-rg-search-args (all-files-p recursive-p) - (list "rg --no-heading --line-number --color never" - "-S" - (when all-files-p "-z -uu") - (unless recursive-p "--maxdepth 1"))) - -;; -(defun +helm--grep-source () - (require 'helm-projectile) - (helm-build-async-source (capitalize (helm-grep-command t)) - :header-name (lambda (_name) "Helm Projectile Grep (C-c ? Help)") - :candidates-process #'helm-grep-collect-candidates - :filter-one-by-one #'helm-grep-filter-one-by-one - :candidate-number-limit 9999 - :nohighlight t - :keymap helm-grep-map - :history 'helm-grep-history - :action (apply #'helm-make-actions helm-projectile-grep-or-ack-actions) - :persistent-action 'helm-grep-persistent-action - :persistent-help "Jump to line (`C-u' Record in mark ring)" - :requires-pattern 2)) - -(defun +helm--grep-search (directory query prompt &optional all-files-p recursive-p) - (let* ((default-directory directory) - (helm-ff-default-directory directory) - (helm-grep-in-recurse recursive-p) - (helm-grep-ignored-files - (unless all-files-p - (cl-union (projectile-ignored-files-rel) grep-find-ignored-files))) - (helm-grep-ignored-directories - (unless all-files-p - (cl-union (mapcar 'directory-file-name (projectile-ignored-directories-rel)) - grep-find-ignored-directories))) - (helm-grep-default-command - (if (and nil (eq (projectile-project-vcs) 'git)) - (format "git --no-pager grep --no-color -n%%c -e %%p %s -- %%f" - (if recursive-p "" "--max-depth 1 ")) - (format "grep -si -a%s %%e -n%%cH -e %%p %%f %s" - (if recursive-p " -R" "") - (if recursive-p "." "./*")))) - (helm-grep-default-recurse-command helm-grep-default-command)) - (setq helm-source-grep (+helm--grep-source)) - (helm :sources 'helm-source-grep - :input query - :prompt prompt - :buffer "*helm grep*" - :default-directory directory - :keymap helm-grep-map - :history 'helm-grep-history - :truncate-lines helm-grep-truncate-lines))) - ;;;###autoload -(cl-defun +helm-file-search (engine &key query in all-files (recursive t)) - "Conduct a file search using ENGINE, which can be any of: rg, ag, pt, and -grep. If omitted, ENGINE will default to the first one it detects, in that -order. +(cl-defun +helm-file-search (&key query in all-files (recursive t)) + "Conduct a file search using ripgrep. :query STRING Determines the initial input to search for. @@ -108,6 +49,8 @@ order. :recursive BOOL Whether or not to search files recursively from the base directory." (declare (indent defun)) + (unless (executable-find "rg") + (user-error "Couldn't find ripgrep in your PATH")) (require 'helm-ag) (helm-ag--init-state) (let* ((project-root (or (doom-project-root) default-directory)) @@ -115,13 +58,6 @@ order. (default-directory directory) (helm-ag--default-directory directory) (helm-ag--default-target (list directory)) - (engine (or engine - (cl-find-if #'executable-find +helm-project-search-engines - :key #'symbol-name) - (and (or (executable-find "grep") - (executable-find "git")) - 'grep) - (user-error "No search engine specified (is ag, rg, or git installed?)"))) (query (or query (when (use-region-p) (let ((beg (or (bound-and-true-p evil-visual-beginning) (region-beginning))) @@ -129,23 +65,20 @@ order. (when (> (abs (- end beg)) 1) (rxt-quote-pcre (buffer-substring-no-properties beg end))))) "")) - (prompt (format "[%s %s] " - (symbol-name engine) + (prompt (format "[rg %s] " (cond ((file-equal-p directory project-root) (projectile-project-name)) ((file-equal-p directory default-directory) "./") ((file-relative-name directory project-root))))) (command - (pcase engine - (`ag (+helm-ag-search-args all-files recursive)) - (`rg (+helm-rg-search-args all-files recursive)) - ('grep (+helm--grep-search directory query prompt all-files recursive) - (cl-return t)))) + (list "rg --no-heading --line-number --color never" + "-S" + (when all-files-p "-z -uu") + (unless recursive-p "--maxdepth 1"))) (helm-ag-base-command (string-join command " "))) ;; TODO Define our own sources instead - (helm-attrset 'name (format "[%s %s] Searching %s" - engine + (helm-attrset 'name (format "[rg %s] Searching %s" (string-join (delq nil (cdr command)) " ") (abbreviate-file-name directory)) helm-source-do-ag) @@ -153,82 +86,39 @@ order. (cl-letf (((symbol-function 'helm-do-ag--helm) (lambda () (helm :sources '(helm-source-do-ag) :prompt prompt - :buffer "*helm-ag*" + :buffer "*helm-rg*" :keymap helm-do-ag-map :input query :history 'helm-ag--helm-history)))) (helm-do-ag directory)))) -(defun +helm--get-command (format) - (cl-loop for tool in (cl-remove-duplicates +helm-project-search-engines :from-end t) - if (executable-find (symbol-name tool)) - return (intern (format format tool)))) - ;;;###autoload (defun +helm/project-search (&optional arg initial-query directory) - "Performs a project search from the project root. + "Performs a project search from the project root with ripgrep. -Uses the first available search backend from `+helm-project-search-engines'. If ARG (universal argument), include all files, even hidden or compressed ones, in the search." (interactive "P") - (funcall (or (+helm--get-command "+helm/%s") - #'+helm/grep) - arg - initial-query - directory)) + (+helm-file-search + :query initial-query + :in directory + :all-files (and (not (null arg)) + (listp arg)))) ;;;###autoload (defun +helm/project-search-from-cwd (&optional arg initial-query) "Performs a project search recursively from the current directory. -Uses the first available search backend from `+helm-project-search-engines'. If -ARG (universal argument), include all files, even hidden or compressed ones." +If ARG (universal argument), include all files, even hidden or compressed ones." (interactive "P") - (funcall (or (+helm--get-command "+helm/%s-from-cwd") - #'+helm/grep-from-cwd) - arg - initial-query)) + (+helm-file-search + :query initial-query + :in default-directory + :all-files (and (not (null arg)) + (listp arg)))) - -;;;###autoload (autoload '+helm/rg "completion/helm/autoload/helm" nil t) -;;;###autoload (autoload '+helm/rg-from-cwd "completion/helm/autoload/helm" nil t) -;;;###autoload (autoload '+helm/ag "completion/helm/autoload/helm" nil t) -;;;###autoload (autoload '+helm/ag-from-cwd "completion/helm/autoload/helm" nil t) -;;;###autoload (autoload '+helm/grep "completion/helm/autoload/helm" nil t) -;;;###autoload (autoload '+helm/grep-from-cwd "completion/helm/autoload/helm" nil t) - -(dolist (engine `(,@(cl-remove-duplicates +helm-project-search-engines :from-end t) grep)) - (defalias (intern (format "+helm/%s" engine)) - (lambda (arg &optional query directory) - (interactive "P") - (+helm-file-search engine - :query query - :in directory - :all-files (and (not (null arg)) - (listp arg)))) - (format "Perform a project file search using %s. - -QUERY is a regexp. If omitted, the current selection is used. If no selection is -active, the last known search is used. - -ARG is the universal argument. If a number is passed through it, e.g. C-u 3, then - -If ALL-FILES-P, search compressed and hidden files as well." - engine)) - - (defalias (intern (format "+helm/%s-from-cwd" engine)) - (lambda (arg &optional query) - (interactive "P") - (+helm-file-search engine - :query query - :in default-directory - :all-files (and (not (null arg)) - (listp arg)))) - (format "Perform a project file search from the current directory using %s. - -QUERY is a regexp. If omitted, the current selection is used. If no selection is -active, the last known search is used. - -If ALL-FILES-P, search compressed and hidden files as well." - engine))) +;;;###autoload +(defun +helm/jump-list () + "TODO" + (interactive) + (error "not implemented yet")) diff --git a/modules/completion/ivy/autoload/ivy.el b/modules/completion/ivy/autoload/ivy.el index 88928647c..c596e4168 100644 --- a/modules/completion/ivy/autoload/ivy.el +++ b/modules/completion/ivy/autoload/ivy.el @@ -236,25 +236,9 @@ The point of this is to avoid Emacs locking up indexing massive file trees." (#'counsel-file-jump)))) -(defvar +ivy-file-search-shell - (or (executable-find "dash") - (executable-find "sh") - shell-file-name) - "The SHELL to invoke ag/rg/pt/git-grep/grep searchs from. - -This only affects `+ivy/*' search commands (e.g. `+ivy/rg' and -`+ivy/project-search'). - -By default, this the most basic, uncustomized shell, to prevent interference -caused by slow shell configs at the cost of isolating these programs from -envvars that may have been set in the user's shell config to change their -behavior. If this bothers you, change this to `shell-file-name'.") - ;;;###autoload -(cl-defun +ivy-file-search (engine &key query in all-files (recursive t)) - "Conduct a file search using ENGINE, which can be any of: rg, ag, pt, and -grep. If omitted, ENGINE will default to the first one it detects, in that -order. +(cl-defun +ivy-file-search (&key query in all-files (recursive t)) + "Conduct a file search using ripgrep. :query STRING Determines the initial input to search for. @@ -264,131 +248,56 @@ order. :recursive BOOL Whether or not to search files recursively from the base directory." (declare (indent defun)) - (let* ((project-root (or (doom-project-root) default-directory)) + (unless (executable-find "rg") + (user-error "Couldn't find ripgrep in your PATH")) + (require 'counsel) + (let* ((ivy-more-chars-alist '((t . 1))) + (project-root (or (doom-project-root) default-directory)) (directory (or in project-root)) (default-directory directory) - (engine (or engine - (cl-loop for tool in +ivy-project-search-engines - if (executable-find (symbol-name tool)) - return tool) - (and (or (executable-find "grep") - (executable-find "git")) - 'grep) - (error "No search engine specified (is ag, rg, pt or git installed?)"))) - (query - (or (if query query) - (when (use-region-p) - (let ((beg (or (bound-and-true-p evil-visual-beginning) (region-beginning))) - (end (or (bound-and-true-p evil-visual-end) (region-end)))) - (when (> (abs (- end beg)) 1) - (let ((query (buffer-substring-no-properties beg end))) - ;; Escape characters that are special to ivy searches - (replace-regexp-in-string "[! |]" (lambda (substr) - (cond ((and (string= substr " ") - (not (featurep! +fuzzy))) - " ") - ((and (string= substr "|") - (eq engine 'rg)) - "\\\\\\\\|") - ((concat "\\\\" substr)))) - (rxt-quote-pcre query)))))))) - (prompt - (format "%s%%s %s" - (symbol-name engine) - (cond ((equal directory default-directory) - "./") - ((equal directory project-root) - (projectile-project-name)) - ((file-relative-name directory project-root)))))) - (require 'counsel) - (let ((ivy-more-chars-alist - (if query '((t . 1)) ivy-more-chars-alist)) - (shell-file-name +ivy-file-search-shell)) - (pcase engine - (`grep - (let ((counsel-projectile-grep-initial-input query)) - (cl-letf (((symbol-function #'counsel-locate-git-root) - (lambda () directory))) - (if all-files - (cl-letf (((symbol-function #'projectile-ignored-directories-rel) - (symbol-function #'ignore)) - ((symbol-function #'projectile-ignored-files-rel) - (symbol-function #'ignore))) - (counsel-projectile-grep)) - (counsel-projectile-grep))))) - (`ag - (let ((args (concat (if all-files " -a") - (unless recursive " --depth 1")))) - (counsel-ag query directory args (format prompt args)))) - (`rg - (let ((args (concat (if all-files " -uu") - (unless recursive " --maxdepth 1")))) - (counsel-rg query directory args (format prompt args)))) - (_ (error "No search engine specified")))))) - -(defun +ivy--get-command (format) - (cl-loop for tool in (cl-remove-duplicates +ivy-project-search-engines :from-end t) - if (executable-find (symbol-name tool)) - return (intern (format format tool)))) + (args (concat (if all-files " -uu") + (unless recursive " --maxdepth 1")))) + (counsel-rg + (or (if query query) + (when (use-region-p) + (let ((beg (or (bound-and-true-p evil-visual-beginning) (region-beginning))) + (end (or (bound-and-true-p evil-visual-end) (region-end)))) + (when (> (abs (- end beg)) 1) + (let ((query (buffer-substring-no-properties beg end))) + ;; Escape characters that are special to ivy searches + (replace-regexp-in-string "[! |]" (lambda (substr) + (cond ((and (string= substr " ") + (not (featurep! +fuzzy))) + " ") + ((string= substr "|") + "\\\\\\\\|") + ((concat "\\\\" substr)))) + (rxt-quote-pcre query))))))) + directory args + (format "rg%s %s" + args + (cond ((equal directory default-directory) + "./") + ((equal directory project-root) + (projectile-project-name)) + ((file-relative-name directory project-root))))))) ;;;###autoload (defun +ivy/project-search (&optional arg initial-query directory) - "Performs a project search from the project root. + "Performs a live project search from the project root using ripgrep. -Uses the first available search backend from `+ivy-project-search-engines'. If -ARG (universal argument), include all files, even hidden or compressed ones, in -the search." +If ARG (universal argument), include all files, even hidden or compressed ones, +in the search." (interactive "P") - (funcall (or (+ivy--get-command "+ivy/%s") - #'+ivy/grep) - arg - initial-query - directory)) + (+ivy-file-search :query initial-query :in directory :all-files arg)) ;;;###autoload (defun +ivy/project-search-from-cwd (&optional arg initial-query) "Performs a project search recursively from the current directory. -Uses the first available search backend from `+ivy-project-search-engines'. If -ARG (universal argument), include all files, even hidden or compressed ones." +If ARG (universal argument), include all files, even hidden or compressed ones." (interactive "P") - (funcall (or (+ivy--get-command "+ivy/%s-from-cwd") - #'+ivy/grep-from-cwd) - arg - initial-query)) - - -;;;###autoload (autoload '+ivy/rg "completion/ivy/autoload/ivy" nil t) -;;;###autoload (autoload '+ivy/rg-from-cwd "completion/ivy/autoload/ivy" nil t) -;;;###autoload (autoload '+ivy/ag "completion/ivy/autoload/ivy" nil t) -;;;###autoload (autoload '+ivy/ag-from-cwd "completion/ivy/autoload/ivy" nil t) -;;;###autoload (autoload '+ivy/grep "completion/ivy/autoload/ivy" nil t) -;;;###autoload (autoload '+ivy/grep-from-cwd "completion/ivy/autoload/ivy" nil t) - -(dolist (engine `(,@(cl-remove-duplicates +ivy-project-search-engines :from-end t) grep)) - (defalias (intern (format "+ivy/%s" engine)) - (lambda (all-files-p &optional query directory) - (interactive "P") - (+ivy-file-search engine :query query :in directory :all-files all-files-p)) - (format "Perform a project file search using %s. - -QUERY is a regexp. If omitted, the current selection is used. If no selection is -active, the last known search is used. - -If ALL-FILES-P, search compressed and hidden files as well." - engine)) - - (defalias (intern (format "+ivy/%s-from-cwd" engine)) - (lambda (all-files-p &optional query) - (interactive "P") - (+ivy-file-search engine :query query :in default-directory :all-files all-files-p)) - (format "Perform a project file search from the current directory using %s. - -QUERY is a regexp. If omitted, the current selection is used. If no selection is -active, the last known search is used. - -If ALL-FILES-P, search compressed and hidden files as well." - engine))) + (+ivy/project-search arg initial-query default-directory)) ;; diff --git a/modules/tools/lookup/autoload/lookup.el b/modules/tools/lookup/autoload/lookup.el index 2fd233599..46726eca0 100644 --- a/modules/tools/lookup/autoload/lookup.el +++ b/modules/tools/lookup/autoload/lookup.el @@ -208,17 +208,15 @@ This backend prefers \"just working\" over accuracy." "Conducts a simple project text search for IDENTIFIER. Uses and requires `+ivy-file-search' or `+helm-file-search'. Will return nil if -neither is available. These search backends will use ag, rg, or pt (in an order -dictated by `+ivy-project-search-engines' or `+helm-project-search-engines', -falling back to git-grep)." +neither is available. These require ripgrep to be installed." (unless identifier (let ((query (rxt-quote-pcre identifier))) (ignore-errors (cond ((featurep! :completion ivy) - (+ivy-file-search nil :query query) + (+ivy-file-search :query query) t) ((featurep! :completion helm) - (+helm-file-search nil :query query) + (+helm-file-search :query query) t)))))) (defun +lookup-evil-goto-definition-backend-fn (_identifier) From 39f01450cbf87887617e93138ac074e69855c7b0 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 17 Nov 2019 01:23:45 -0500 Subject: [PATCH 110/129] lang/python: load flycheck-cython conditionally --- modules/lang/python/config.el | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/lang/python/config.el b/modules/lang/python/config.el index be7276f3f..db90dbfcf 100644 --- a/modules/lang/python/config.el +++ b/modules/lang/python/config.el @@ -297,5 +297,6 @@ called.") (use-package! flycheck-cython + :when (featurep! +cython) :when (featurep! :tools flycheck) :after cython-mode) From ffb4aa91dade498991749222abc5e05c62985fa5 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 17 Nov 2019 16:45:50 -0500 Subject: [PATCH 111/129] lang/python: minor refactor & reformatting --- modules/lang/python/config.el | 58 ++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/modules/lang/python/config.el b/modules/lang/python/config.el index db90dbfcf..66450c698 100644 --- a/modules/lang/python/config.el +++ b/modules/lang/python/config.el @@ -20,6 +20,9 @@ called.") :init (setq python-environment-directory doom-cache-dir python-indent-guess-indent-offset-verbose nil) + + (when (featurep! +lsp) + (add-hook 'python-mode-local-vars-hook #'lsp!)) :config (set-repl-handler! 'python-mode #'+python/open-repl :persist t) (set-docsets! 'python-mode "Python 3" "NumPy" "SciPy") @@ -45,9 +48,6 @@ called.") ;; Stop the spam! (setq python-indent-guess-indent-offset-verbose nil) - (when (featurep! +lsp) - (add-hook 'python-mode-local-vars-hook #'lsp!)) - ;; Default to Python 3. Prefer the versioned Python binaries since some ;; systems stupidly make the unversioned one point at Python 2. (when (and (executable-find "python3") @@ -88,10 +88,17 @@ called.") (use-package! anaconda-mode - :after python + :defer t :init (setq anaconda-mode-installation-directory (concat doom-etc-dir "anaconda/") anaconda-mode-eldoc-as-single-line t) + + (add-hook! 'python-mode-local-vars-hook + (defun +python-init-anaconda-mode-maybe-h () + "Enable `anaconda-mode' if `lsp-mode' isn't." + (unless (or (bound-and-true-p lsp-mode) + (bound-and-true-p lsp--buffer-deferred)) + (anaconda-mode +1)))) :config (add-hook 'anaconda-mode-hook #'anaconda-eldoc-mode) (set-company-backend! 'anaconda-mode '(company-anaconda)) @@ -101,13 +108,6 @@ called.") :documentation #'anaconda-mode-show-doc) (set-popup-rule! "^\\*anaconda-mode" :select nil) - (add-hook! 'python-mode-local-vars-hook :append - (defun +python-init-anaconda-mode-maybe-h () - "Enable `anaconda-mode' if `lsp-mode' isn't." - (unless (or (bound-and-true-p lsp-mode) - (bound-and-true-p lsp--buffer-deferred)) - (anaconda-mode +1)))) - (defun +python-auto-kill-anaconda-processes-h () "Kill anaconda processes if this buffer is the last python buffer." (when (and (eq major-mode 'python-mode) @@ -115,7 +115,8 @@ called.") (doom-buffers-in-mode 'python-mode (buffer-list))))) (anaconda-mode-stop))) (add-hook! 'python-mode-hook - (add-hook 'kill-buffer-hook #'+python-auto-kill-anaconda-processes-h nil t)) + (add-hook 'kill-buffer-hook #'+python-auto-kill-anaconda-processes-h + nil 'local)) (when (featurep 'evil) (add-hook 'anaconda-mode-hook #'evil-normalize-keymaps)) @@ -130,9 +131,10 @@ called.") (use-package! pyimport - :after python - :config - (map! :map python-mode-map + :defer t + :init + (map! :after python + :map python-mode-map :localleader (:prefix ("i" . "imports") :desc "Insert missing imports" "i" #'pyimport-insert-missing @@ -243,19 +245,19 @@ called.") ;; If none of these work for you, `conda-anaconda-home' must be set ;; explicitly. Afterwards, run M-x `conda-env-activate' to switch between ;; environments - (unless (cl-loop for dir in (list conda-anaconda-home - "~/.anaconda" - "~/.miniconda" - "~/.miniconda3" - "~/miniconda3" - "/usr/bin/anaconda3" - "/usr/local/anaconda3" - "/usr/local/miniconda3" - "/usr/local/Caskroom/miniconda/base") - if (file-directory-p dir) - return (setq conda-anaconda-home dir - conda-env-home-directory dir)) - (message "Cannot find Anaconda installation")) + (or (cl-loop for dir in (list conda-anaconda-home + "~/.anaconda" + "~/.miniconda" + "~/.miniconda3" + "~/miniconda3" + "/usr/bin/anaconda3" + "/usr/local/anaconda3" + "/usr/local/miniconda3" + "/usr/local/Caskroom/miniconda/base") + if (file-directory-p dir) + return (setq conda-anaconda-home dir + conda-env-home-directory dir)) + (message "Cannot find Anaconda installation")) ;; integration with term/eshell (conda-env-initialize-interactive-shells) From 3195b84fd26fa16d71cf4a87afd76e84d4e2f134 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 17 Nov 2019 16:43:23 -0500 Subject: [PATCH 112/129] Evaluate package! properties & error on :fetcher - No longer translates :fetcher to :host. Update your package! declaration people! - Now evaluates the values for properties (except for :recipe IF it is a list whose CAR passes keywordp -- for backwards compatibility). - Throws error if an invalid property is used for a package!'s :recipe --- core/autoload/packages.el | 2 +- core/core-packages.el | 44 ++++++++++++++++++--------------------- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/core/autoload/packages.el b/core/autoload/packages.el index b5c0b0c1c..7406dddc1 100644 --- a/core/autoload/packages.el +++ b/core/autoload/packages.el @@ -81,7 +81,7 @@ Excludes packages that have a non-nil :built-in property." (when-let (plist (doom-package-get package)) - (not (plist-get plist :ignore) t))) + (not (plist-get plist :ignore)))) ;;;###autoload (defun doom-package-private-p (package) diff --git a/core/core-packages.el b/core/core-packages.el index e7a62fd1f..fc381b3bd 100644 --- a/core/core-packages.el +++ b/core/core-packages.el @@ -254,7 +254,7 @@ necessary package metadata is initialized and available for them." ;;; Module package macros (cl-defmacro package! - (name &rest plist &key built-in _recipe disable ignore _freeze) + (name &rest plist &key built-in recipe ignore _disable _freeze) "Declares a package and how to install it (if applicable). This macro is declarative and does not load nor install packages. It is used to @@ -282,6 +282,12 @@ Accepts the following properties: Returns t if package is successfully registered, and nil if it was disabled elsewhere." (declare (indent defun)) + (when (and recipe (keywordp (car-safe recipe))) + (plist-put! plist :recipe `(quote ,recipe))) + (when built-in + (when (and (not ignore) (eq built-in 'prefer)) + (setq built-in `(locate-library ,(symbol-name name) nil doom--initial-load-path))) + (plist-put! plist :ignore built-in)) `(let* ((name ',name) (plist (cdr (assq name doom-packages)))) (let ((module-list (plist-get plist :modules)) @@ -292,33 +298,23 @@ elsewhere." (list module) nil)))) - ;; Handle :built-in - (let ((built-in ,built-in)) - (unless ,ignore - (when built-in - (doom-log "Ignoring built-in package %S" name) - (when (eq built-in 'prefer) - (setq built-in (locate-library (symbol-name name) nil doom--initial-load-path)))) - (plist-put! plist :ignore built-in))) - - ;; DEPRECATED Translate :fetcher to :host - (with-plist! plist (recipe) - (with-plist! recipe (fetcher) - (when fetcher - (message "%s\n%s" - (format "WARNING: The :fetcher property was used for the %S package." - name) - "This property is deprecated. Replace it with :host.") - (plist-put! recipe :host fetcher) - (plist-delete! recipe :fetcher)) - (plist-put! plist :recipe recipe))) - - (doplist! ((prop val) ',plist plist) + (doplist! ((prop val) (list ,@plist) plist) (unless (null val) (plist-put! plist prop val))) + ;; Some basic key validation; error if you're not using a valid key + (condition-case e + (cl-destructuring-bind + (&key _local-repo _files _flavor _no-build + _type _repo _host _branch _remote _nonrecursive _fork _depth) + (plist-get plist :recipe)) + (error + (signal 'doom-package-error + (cons ,(symbol-name name) + (error-message-string e))))) + (setf (alist-get name doom-packages) plist) - (if (not ,disable) t + (if (not (plist-get plist :disable)) t (doom-log "Disabling package %S" name) (cl-pushnew name doom-disabled-packages) nil))) From 5df104a851dfc9630f33883ed256fc552075d51c Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 17 Nov 2019 16:46:28 -0500 Subject: [PATCH 113/129] Remove redundant comments in init.example.el Now that they're in the module index in docs/index.org --- init.example.el | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/init.example.el b/init.example.el index a50371ad0..7965ffdab 100644 --- a/init.example.el +++ b/init.example.el @@ -155,28 +155,17 @@ ;;web ; the tubes :email - ;;(mu4e +gmail) ; WIP - ;;notmuch ; WIP - ;;(wanderlust +gmail) ; WIP + ;;(mu4e +gmail) + ;;notmuch + ;;(wanderlust +gmail) - ;; Applications are complex and opinionated modules that transform Emacs - ;; toward a specific purpose. They may have additional dependencies and - ;; should be loaded late. :app ;;calendar ;;irc ; how neckbeards socialize ;;(rss +org) ; emacs as an RSS reader ;;twitter ; twitter client https://twitter.com/vnought - ;;(write ; emacs for writers (fiction, notes, papers, etc.) - ;; +wordnut ; wordnet (wn) search - ;; +langtool) ; a proofreader (grammar/style check) for Emacs + ;;write ; emacs for writers (fiction, notes, papers, etc.) :config - ;; For literate config users. This will tangle+compile a config.org - ;; literate config in your `doom-private-dir' whenever it changes. ;;literate - - ;; The default module sets reasonable defaults for Emacs. It also - ;; provides a Spacemacs-inspired keybinding scheme and a smartparens - ;; config. Use it as a reference for your own modules. (default +bindings +smartparens)) From fa1a19a1f0f390c8961d44578285c7756dd4e8c5 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 17 Nov 2019 16:47:56 -0500 Subject: [PATCH 114/129] core: minor refactor & reformatting --- core/autoload/plist.el | 2 +- core/core.el | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/autoload/plist.el b/core/autoload/plist.el index b99351dd6..aeb9c7f9a 100644 --- a/core/autoload/plist.el +++ b/core/autoload/plist.el @@ -9,7 +9,7 @@ Evaluate BODY with either ARGLIST bound to (cons PROP VAL) or, if ARGLIST is a list, the pair is destructured into (CAR . CDR)." - (declare (indent defun)) + (declare (indent 1)) (let ((plist-var (make-symbol "plist"))) `(let ((,plist-var (copy-sequence ,plist))) (while ,plist-var diff --git a/core/core.el b/core/core.el index 176a93855..7034c51f5 100644 --- a/core/core.el +++ b/core/core.el @@ -7,7 +7,7 @@ (defconst doom-version "2.0.9" "Current version of Doom Emacs.") -(defconst EMACS27+ (> emacs-major-version 26)) +(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))) From 8ea3733e739b1a78001caf7e0d9a3fe23ba1487f Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 17 Nov 2019 17:55:06 -0500 Subject: [PATCH 115/129] Fix :built-in property for package! --- core/core-packages.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/core-packages.el b/core/core-packages.el index fc381b3bd..fd5bb0a1a 100644 --- a/core/core-packages.el +++ b/core/core-packages.el @@ -285,8 +285,9 @@ elsewhere." (when (and recipe (keywordp (car-safe recipe))) (plist-put! plist :recipe `(quote ,recipe))) (when built-in - (when (and (not ignore) (eq built-in 'prefer)) + (when (and (not ignore) (equal built-in '(quote prefer))) (setq built-in `(locate-library ,(symbol-name name) nil doom--initial-load-path))) + (plist-delete! plist :built-in) (plist-put! plist :ignore built-in)) `(let* ((name ',name) (plist (cdr (assq name doom-packages)))) From d2092ae44efa5f7d1468eb3e46e4bd981b25122b Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 17 Nov 2019 17:56:25 -0500 Subject: [PATCH 116/129] completion/ivy: load counsel earlier Fixes an issue where counsel was being loaded later than ivy-prescient, which requires that it be loaded earlier. --- modules/completion/ivy/config.el | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/completion/ivy/config.el b/modules/completion/ivy/config.el index d6ab7e367..4cb329f78 100644 --- a/modules/completion/ivy/config.el +++ b/modules/completion/ivy/config.el @@ -59,6 +59,11 @@ results buffer.") [remap persp-switch-to-buffer] #'+ivy/switch-workspace-buffer [remap evil-show-jumps] #'+ivy/jump-list) :config + ;; Counsel changes a lot of ivy's state at startup; to control for that, we + ;; need to load it as early as possible. Some packages (like `ivy-prescient') + ;; require this. + (require 'counsel nil t) + (setq ivy-height 17 ivy-wrap t ivy-fixed-height-minibuffer t @@ -172,7 +177,7 @@ evil-ex-specific constructs, so we disable it solely in evil-ex." (use-package! counsel - :commands counsel-describe-face + :defer t :init (define-key! [remap apropos] #'counsel-apropos From ed3408d839c09ddc64babba2572dc67aeb636c5f Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 17 Nov 2019 18:45:30 -0500 Subject: [PATCH 117/129] Move tramp-histfile-override to doom-cache-dir --- core/core.el | 1 + 1 file changed, 1 insertion(+) diff --git a/core/core.el b/core/core.el index 7034c51f5..9a6f017db 100644 --- a/core/core.el +++ b/core/core.el @@ -210,6 +210,7 @@ users).") tramp-auto-save-directory (concat doom-cache-dir "tramp-auto-save/") tramp-backup-directory-alist backup-directory-alist tramp-persistency-file-name (concat doom-cache-dir "tramp-persistency.el") + tramp-histfile-override (concat doom-cache-dir "tramp-histfile.el") 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/")) From abe9239088fa254ee441210217bf3189c8572742 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 17 Nov 2019 21:09:06 -0500 Subject: [PATCH 118/129] Simplify doom/report-bug --- core/autoload/debug.el | 59 +----------------------------------------- 1 file changed, 1 insertion(+), 58 deletions(-) diff --git a/core/autoload/debug.el b/core/autoload/debug.el index 2bec4307f..14ae8fc00 100644 --- a/core/autoload/debug.el +++ b/core/autoload/debug.el @@ -301,34 +301,6 @@ to reproduce bugs and determine if Doom is to blame." ;; ;;; Reporting bugs -(defun doom--report-bug () - "TODO" - (interactive) - (let ((url "https://github.com/hlissner/doom-emacs/issues/new?body=")) - ;; TODO Refactor me - (save-restriction - (widen) - (goto-char (point-min)) - (re-search-forward "^-------------------------------------------------------------------\n" nil t) - (skip-chars-forward " \n\t") - (condition-case e - (progn - (save-excursion - (when (and (re-search-backward "\\+ [ ] " nil t) - (not (y-or-n-p "You haven't checked all the boxes. Continue anyway?"))) - (error "Aborted submit"))) - (narrow-to-region (point) (point-max)) - (let ((text (buffer-string))) - ;; `url-encode-url' doesn't encode ampersands - (setq text (replace-regexp-in-string "&" "%26" text)) - (setq url (url-encode-url (concat url text))) - ;; HACK: encode some characters according to HTML URL Encoding Reference - ;; http://www.w3schools.com/tags/ref_urlencode.asp - (setq url (replace-regexp-in-string "#" "%23" url)) - (setq url (replace-regexp-in-string ";" "%3B" url)) - (browse-url url))) - (error (signal (car e) (car e))))))) - ;;;###autoload (defun doom/report-bug () "Open a markdown buffer destinated to populate the New Issue page on Doom @@ -337,36 +309,7 @@ Emacs' issue tracker. If called when a backtrace buffer is present, it and the output of `doom-info' will be automatically appended to the result." (interactive) - ;; TODO Refactor me - (let ((backtrace - (when (get-buffer "*Backtrace*") - (with-current-buffer "*Backtrace*" - (string-trim - (buffer-substring-no-properties - (point-min) - (min (point-max) 1000)))))) - (buf (get-buffer-create "*doom:sandbox*"))) - (with-current-buffer buf - (erase-buffer) - (condition-case _ (gfm-mode) - (error (text-mode))) - (doom-template-insert "SUBMIT_BUG_REPORT") - (goto-char (point-max)) - (let ((pos (point))) - (save-excursion - (insert - "\n" (doom-info) "\n" - (if (and backtrace (not (string-empty-p backtrace))) - (format "\n
\nBacktrace\n\n```\n%s\n```\n
\n" - backtrace) - ""))) - (local-set-key (kbd "C-c C-c") #'doom--report-bug) - (local-set-key (kbd "C-c C-k") #'kill-current-buffer) - (setq header-line-format "C-c C-c to submit / C-c C-k to close") - ;; - (narrow-to-region (point-min) pos) - (goto-char (point-min))) - (pop-to-buffer buf)))) + (browse-url "https://github.com/hlissner/doom-emacs/issues/new/choose")) ;; From 088541a32d999e532ea0338ebaf9be69de65238e Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 17 Nov 2019 23:41:00 -0500 Subject: [PATCH 119/129] Bind 'SPC s S' to swiper-isearch-thing-at-point --- modules/config/default/+evil-bindings.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index 3dee4231e..855eb6393 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -584,7 +584,8 @@ :desc "Look up in all docsets" "K" #'+lookup/in-all-docsets :desc "Search project" "p" #'+default/search-project :desc "Search other project" "P" #'+default/search-other-project - :desc "Search buffer" "s" #'swiper-isearch) + :desc "Search buffer" "s" #'swiper-isearch + :desc "Search buffer for thing at point" "S" #'swiper-isearch-thing-at-point) ;;; t --- toggle (:prefix-map ("t" . "toggle") From dca4ff7887fff3f23a07d81fe2020f6c6fe1132c Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 17 Nov 2019 23:43:28 -0500 Subject: [PATCH 120/129] completion/helm: remove redundant package cookies --- modules/completion/helm/config.el | 6 ------ 1 file changed, 6 deletions(-) diff --git a/modules/completion/helm/config.el b/modules/completion/helm/config.el index 1753c416f..e4034d0c3 100644 --- a/modules/completion/helm/config.el +++ b/modules/completion/helm/config.el @@ -135,7 +135,6 @@ be negative.") :config (helm-flx-mode +1)) -;;;###package helm-ag (after! helm-ag (map! :map helm-ag-edit-map :n "RET" #'compile-goto-error) (define-key helm-ag-edit-map [remap quit-window] #'helm-ag--edit-abort) @@ -150,14 +149,12 @@ be negative.") (setq helm-bookmark-show-location t) -;;;###package helm-files (after! helm-files (setq helm-boring-file-regexp-list (append (list "\\.projects$" "\\.DS_Store$") helm-boring-file-regexp-list))) -;;;###package helm-locate (defvar helm-generic-files-map (make-sparse-keymap)) (after! helm-locate (when (and IS-MAC @@ -167,7 +164,6 @@ be negative.") (set-keymap-parent helm-generic-files-map helm-map)) -;;;###package helm-org (use-package! helm-org :when (featurep! :lang org) :defer t @@ -178,7 +174,6 @@ be negative.") '(org-set-tags . helm-org-completing-read-tags)))) -;;;###package helm-projectile (use-package! helm-projectile :commands (helm-projectile-find-file helm-projectile-recentf @@ -191,7 +186,6 @@ be negative.") (set-keymap-parent helm-projectile-find-file-map helm-map)) -;;;###package swiper-helm (after! swiper-helm (setq swiper-helm-display-function (lambda (buf &optional _resume) (pop-to-buffer buf))) From c44185168de90e23ca3f1b53a01f9e7106901ad3 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 17 Nov 2019 23:57:45 -0500 Subject: [PATCH 121/129] completion/helm: remove +helm-project-search-engines No longer used as of a66872fe2 --- modules/completion/helm/config.el | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/modules/completion/helm/config.el b/modules/completion/helm/config.el index e4034d0c3..071c33335 100644 --- a/modules/completion/helm/config.el +++ b/modules/completion/helm/config.el @@ -1,15 +1,5 @@ ;;; completion/helm/config.el -*- lexical-binding: t; -*- -(defvar +helm-project-search-engines '(rg ag) - "What search tools for `+helm/project-search' (and `+helm-file-search' when no -ENGINE is specified) to try, and in what order. - -To disable a particular tool, remove it from this list. To prioritize a tool -over others, move it to the front of the list. Later duplicates in this list are -silently ignored. - -This falls back to git-grep (then grep) if none of these available.") - ;; Posframe (requires +childframe) (defvar +helm-posframe-handler #'+helm-poshandler-frame-center-near-bottom-fn "The function that determines the location of the childframe. It should return From fd979d8e529ebb9729bc14f8d95ad2737a64dd13 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 18 Nov 2019 14:17:48 -0500 Subject: [PATCH 122/129] completion/helm: fix void variable refs #2071 --- modules/completion/helm/autoload/helm.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/completion/helm/autoload/helm.el b/modules/completion/helm/autoload/helm.el index 116fc079d..70105d239 100644 --- a/modules/completion/helm/autoload/helm.el +++ b/modules/completion/helm/autoload/helm.el @@ -74,9 +74,9 @@ workspace." (command (list "rg --no-heading --line-number --color never" "-S" - (when all-files-p "-z -uu") - (unless recursive-p "--maxdepth 1"))) - (helm-ag-base-command (string-join command " "))) + (when all-files "-z -uu") + (unless recursive "--maxdepth 1"))) + (helm-ag-base-command (string-join (delq nil command) " "))) ;; TODO Define our own sources instead (helm-attrset 'name (format "[rg %s] Searching %s" (string-join (delq nil (cdr command)) " ") From c7ddcefba99b55bc90cab3430079f89a95085097 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 18 Nov 2019 14:18:18 -0500 Subject: [PATCH 123/129] core: use-package!->after! where former is unnecessary --- core/core-ui.el | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/core/core-ui.el b/core/core-ui.el index 620feb24b..4ac1f96ff 100644 --- a/core/core-ui.el +++ b/core/core-ui.el @@ -366,9 +366,7 @@ treat Emacs as a non-application window." (setq ansi-color-for-comint-mode t) -(use-package! compile - :defer t - :config +(after! compile (setq compilation-always-kill t ; kill compilation process before starting another compilation-ask-about-save nil ; save all buffers on `compile' compilation-scroll-output 'first-error) @@ -376,9 +374,7 @@ treat Emacs as a non-application window." (add-hook 'compilation-filter-hook #'doom-apply-ansi-color-to-compilation-buffer-h)) -(use-package! ediff - :defer t - :config +(after! ediff (setq ediff-diff-options "-w" ; turn off whitespace checking ediff-split-window-function #'split-window-horizontally ediff-window-setup-function #'ediff-setup-windows-plain) From 0be962bb7732ef16bac8c36fd177b96315dec978 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 18 Nov 2019 14:19:10 -0500 Subject: [PATCH 124/129] tools/eshell: remove ag alias, add dired alias --- modules/term/eshell/config.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/term/eshell/config.el b/modules/term/eshell/config.el index 39af256d8..5b05e0810 100644 --- a/modules/term/eshell/config.el +++ b/modules/term/eshell/config.el @@ -22,9 +22,9 @@ buffer.") (defvar +eshell-aliases '(("q" "exit") ; built-in ("f" "find-file $1") + ("d" "dired $1") ("bd" "eshell-up $1") ("rg" "rg --color=always $*") - ("ag" "ag --color=always $*") ("l" "ls -lh") ("ll" "ls -lah") ("clear" "clear-scrollback")) ; more sensible than default From 263c82def11ec7cd90f950b086b2c4e32e1fce1e Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 18 Nov 2019 15:05:20 -0500 Subject: [PATCH 125/129] Remove references to old ivy/helm search commands And consolidate ex commands into :pg[rep][!] and :pg[rep]d[!]. --- core/core-projects.el | 6 +- modules/completion/helm/autoload/evil.el | 41 ++---------- modules/completion/ivy/README.org | 82 +++++++----------------- modules/completion/ivy/autoload/evil.el | 57 +++------------- modules/editor/evil/+commands.el | 26 +++----- 5 files changed, 50 insertions(+), 162 deletions(-) diff --git a/core/core-projects.el b/core/core-projects.el index f37babe59..e2920934b 100644 --- a/core/core-projects.el +++ b/core/core-projects.el @@ -72,9 +72,9 @@ Emacs.") ;; 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") - (put 'projectile-grep 'disabled "Use +{ivy,helm}/project-search or +{ivy,helm}/grep instead") + (put 'projectile-ag 'disabled "Use +{ivy,helm}/project-search instead") + (put 'projectile-ripgrep 'disabled "Use +{ivy,helm}/project-search instead") + (put 'projectile-grep 'disabled "Use +{ivy,helm}/project-search 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) diff --git a/modules/completion/helm/autoload/evil.el b/modules/completion/helm/autoload/evil.el index da37452fc..fbcf0a9db 100644 --- a/modules/completion/helm/autoload/evil.el +++ b/modules/completion/helm/autoload/evil.el @@ -1,46 +1,17 @@ ;;; completion/helm/autoload/evil.el -*- lexical-binding: t; -*- ;;;###if (featurep! :editor evil) -;; -;; Project searching - -;;;###autoload (autoload '+helm:grep "completion/helm/autoload/evil" nil t) -(evil-define-command +helm:grep (all-files-p query) +;;;###autoload (autoload '+helm:project-search "completion/helm/autoload/evil" nil t) +(evil-define-command +helm:project-search (all-files-p query) "Ex interface for `+helm/grep'" (interactive "
") - (+helm/grep all-files-p query)) + (+helm/project-search all-files-p query)) -;;;###autoload (autoload '+helm:ag "completion/helm/autoload/evil" nil t) -(evil-define-command +helm:ag (all-files-p query) - "Ex interface for `+helm/ag'" - (interactive "") - (+helm/ag all-files-p query)) - -;;;###autoload (autoload '+helm:rg "completion/helm/autoload/evil" nil t) -(evil-define-command +helm:rg (all-files-p query) - "Ex interface for `+helm/rg'" - (interactive "") - (+helm/rg all-files-p query)) - - -;;;###autoload (autoload '+helm:grep-from-cwd "completion/helm/autoload/evil" nil t) -(evil-define-command +helm:grep-from-cwd (query &optional recurse-p) +;;;###autoload (autoload '+helm:project-search-from-cwd "completion/helm/autoload/evil" nil t) +(evil-define-command +helm:project-search-from-cwd (query &optional recurse-p) "Ex interface for `+helm/grep-from-cwd'." (interactive "") - (+helm/grep-from-cwd (not recurse-p) query)) - -;;;###autoload (autoload '+helm:ag-from-cwd "completion/helm/autoload/evil" nil t) -(evil-define-command +helm:ag-from-cwd (query &optional recurse-p) - "Ex interface for `+helm/ag-from-cwd'." - (interactive "") - (+helm/ag-from-cwd (not recurse-p) query)) - -;;;###autoload (autoload '+helm:rg-from-cwd "completion/helm/autoload/evil" nil t) -(evil-define-command +helm:rg-from-cwd (query &optional recurse-p) - "Ex interface for `+helm/rg-from-cwd'." - (interactive "") - (+helm/rg-from-cwd (not recurse-p) query)) - + (+helm/project-search-from-cwd (not recurse-p) query)) ;;;###autoload (defun +helm--set-prompt-display (pos) diff --git a/modules/completion/ivy/README.org b/modules/completion/ivy/README.org index 4f2afbe7e..0bc51166f 100644 --- a/modules/completion/ivy/README.org +++ b/modules/completion/ivy/README.org @@ -17,7 +17,6 @@ - [[#jump-to-file-project-navigation][Jump-to-file project navigation]] - [[#project-search--replace][Project search & replace]] - [[#in-buffer-searching][In-buffer searching]] - - [[#task-lookup][Task lookup]] - [[#ivy-integration-for-various-completing-commands][Ivy integration for various completing commands]] - [[#general][General]] - [[#jump-to-files-buffers-or-projects][Jump to files, buffers or projects)]] @@ -29,8 +28,7 @@ * Description This module provides Ivy integration for a variety of Emacs commands, as well as -a unified interface for project search and replace, powered by ag, rg, -git-grep & grep (whichever is available). +a unified interface for project search and replace, powered by ripgrep. #+begin_quote I prefer ivy over ido for its flexibility. I prefer ivy over helm because it's @@ -41,7 +39,6 @@ lighter, simpler and faster in many cases. + =+fuzzy= Enables fuzzy completion for Ivy searches. + =+prescient= Enables prescient filtering and sorting for Ivy searches. + =+childframe= Causes Ivy to display in a floating child frame, above Emacs. - *This requires GUI Emacs 26.1+* + =+icons= Enables file icons for switch-{buffer,project}/find-file counsel commands. @@ -67,32 +64,24 @@ lighter, simpler and faster in many cases. command) * Prerequisites -This module optionally depends on one of: +This module depends on: + [[https://github.com/BurntSushi/ripgrep][ripgrep]] (rg) -+ [[https://github.com/ggreer/the_silver_searcher][the_silver_searcher]] (ag) - -Ripgrep is recommended, but the order of its results aren't deterministic and it -doesn't support full PCRE (at the time of writing). The_silver_searcher is a -good alternative if either of these bother you. - -If none of these are installed, file search commands will use git-grep (falling -back to grep, otherwise). ** Install *** MacOS #+BEGIN_SRC sh -brew install ripgrep the_silver_searcher +brew install ripgrep #+END_SRC *** Arch Linux #+BEGIN_SRC sh :dir /sudo:: -sudo pacman --needed --noconfirm -S ripgrep the_silver_searcher +sudo pacman --needed --noconfirm -S ripgrep #+END_SRC *** openSUSE #+BEGIN_SRC sh :dir /sudo:: -sudo zypper install ripgrep the_silver_searcher +sudo zypper install ripgrep #+END_SRC * Features @@ -112,8 +101,7 @@ https://assets.doomemacs.org/completion/ivy/projectile.png | =SPC f f=, =SPC .= | Jump to file from current directory | ** Project search & replace -This module provides interactive text search and replace using the first search -program available on your system (rg, ag, git-grep or grep). +This module provides interactive text search and replace using ripgrep. | Keybind | Description | |-----------+---------------------------------| @@ -124,41 +112,23 @@ program available on your system (rg, ag, git-grep or grep). https://assets.doomemacs.org/completion/ivy/search.png -The ~+ivy-project-search-engines~ variable is consulted to determine which -underlying program to check for (and in what order). It's default value is ~'(rg -ag pt)~. If none of these are available, it will resort to =git-grep= (falling -back to =grep= after that). - -To use a specific program, the following engine-specific commands are available -(but not bound to any key by default) for searching from the project root or the -current directory (recursively), respectively: - -+ ~+ivy/ag~ / ~+ivy/ag-from-cwd~ -+ ~+ivy/rg~ / ~+ivy/rg-from-cwd~ -+ ~+ivy/grep~ / ~+ivy/grep-from-cwd~ - The universal argument (=SPC u= for evil users; =C-u= otherwise) changes the behavior of these commands, instructing the underlying search engine to include ignored files. This module also provides Ex Commands for evil users: -| Ex command | Description | -|-----------------------+------------------------------------------------| -| ~:ag[!] [QUERY]~ | Search project w/ ag[fn:1] | -| ~:rg[!] [QUERY]~ | Search project w/ rg[fn:1] | -| ~:grep[!] [QUERY]~ | Search project w/ git-grep/grep[fn:1] | -| ~:agcwd[!] [QUERY]~ | Search this directory w/ the_silver_searcher | -| ~:rgcwd[!] [QUERY]~ | Search this directory w/ ripgrep | -| ~:grepcwd[!] [QUERY]~ | Search this directory w/ git-grep/grep | +| Ex command | Description | +|------------------------+------------------------------------------------------------------| +| ~:pg[rep][!] [QUERY]~ | Search project (if ~!~, include hidden files) | +| ~:pg[rep]d[!] [QUERY]~ | Search from current directory (if ~!~, don't search recursively) | The optional BANG functions is equivalent to the universal argument for the previous commands. ----- -While in a search (e.g. invoked from ~+ivy:ag~ or ~:rg~), these extra -keybindings are available to you: +While in a search these extra keybindings are available to you: | Keybind | Description | |-----------+-----------------------------------------------| @@ -176,22 +146,14 @@ https://assets.doomemacs.org/completion/ivy/search-replace.png The =swiper= package provides an interactive buffer search powered by ivy. It can be invoked with: -+ =SPC s b= ++ =SPC s s= ++ =SPC s S= (uses thing at point as initial input) + ~:sw[iper] [QUERY]~ https://assets.doomemacs.org/completion/ivy/swiper.png A wgrep buffer can be opened from swiper with =C-c C-e=. -** Task lookup -Some projects have TODO's and FIXME's littered across them. The ~+ivy/tasks~ -command allows you to search and jump to them. It can be invoked with: - -+ =SPC p t= (C-u = restrict search to current file) -+ ~:todo[!]~ (BANG = restrict search to current file) - -https://assets.doomemacs.org/completion/ivy/todo.png - ** Ivy integration for various completing commands *** General | Keybind | Description | @@ -211,14 +173,16 @@ https://assets.doomemacs.org/completion/ivy/todo.png | =SPC b B=, =SPC <= | Switch to buffer | *** Search -| Keybind | Description | -|-----------+------------------------------------------| -| =SPC s i= | Search for symbol in current buffer | -| =SPC s I= | Search for symbol in all similar buffers | -| =SPC s b= | Search the current buffer | -| =SPC s p= | Search project | -| =SPC s d= | Search this directory | -| =SPC p t= | List all TODO/FIXMEs in project | +| Keybind | Description | +|-----------+-------------------------------------------| +| =SPC p t= | List all TODO/FIXMEs in project | +| =SPC s b= | Search the current buffer | +| =SPC s d= | Search this directory | +| =SPC s D= | Search another directory | +| =SPC s i= | Search for symbol in current buffer | +| =SPC s p= | Search project | +| =SPC s P= | Search another project | +| =SPC s s= | Search the current buffer (incrementally) | * Configuration ** TODO Enable fuzzy/non-fuzzy search for specific commands diff --git a/modules/completion/ivy/autoload/evil.el b/modules/completion/ivy/autoload/evil.el index 43faf2a6b..8a8125536 100644 --- a/modules/completion/ivy/autoload/evil.el +++ b/modules/completion/ivy/autoload/evil.el @@ -1,55 +1,14 @@ ;; completion/ivy/autoload/evil.el -*- lexical-binding: t; -*- ;;;###if (featurep! :editor evil) -;;;###autoload (autoload '+ivy:swiper "completion/ivy/autoload/evil" nil t) -(evil-define-command +ivy:swiper (&optional search) - "Invoke `swiper' with SEARCH, otherwise with the symbol at point." - (interactive "") - (swiper search)) - -;;;###autoload (autoload '+ivy:todo "completion/ivy/autoload/evil" nil t) -(evil-define-command +ivy:todo (&optional bang) - "An ex wrapper around `+ivy/tasks'." - (interactive "") - (+ivy/tasks bang)) - - -;; -;; Project searching - -;;;###autoload (autoload '+ivy:grep "completion/ivy/autoload/evil" nil t) -(evil-define-command +ivy:grep (all-files-p query) - "Ex interface for `+ivy/grep'" - (interactive "") - (+ivy/grep all-files-p query)) - -;;;###autoload (autoload '+ivy:ag "completion/ivy/autoload/evil" nil t) -(evil-define-command +ivy:ag (all-files-p query) - "Ex interface for `+ivy/ag'" - (interactive "") - (+ivy/ag all-files-p query)) - -;;;###autoload (autoload '+ivy:rg "completion/ivy/autoload/evil" nil t) -(evil-define-command +ivy:rg (all-files-p query) - "Ex interface for `+ivy/rg'" - (interactive "") - (+ivy/rg all-files-p query)) - - -;;;###autoload (autoload '+ivy:grep-from-cwd "completion/ivy/autoload/evil" nil t) -(evil-define-command +ivy:grep-from-cwd (query &optional recurse-p) - "Ex interface for `+ivy/grep-from-cwd'." +;;;###autoload (autoload '+ivy:project-search "completion/ivy/autoload/evil" nil t) +(evil-define-command +ivy:project-search (query &optional all-files-p) + "Ex interface for `+ivy/project-search'." (interactive "") - (+ivy/grep-from-cwd (not recurse-p) query)) + (+ivy/project-search all-files-p query)) -;;;###autoload (autoload '+ivy:ag-from-cwd "completion/ivy/autoload/evil" nil t) -(evil-define-command +ivy:ag-from-cwd (query &optional recurse-p) - "Ex interface for `+ivy/ag-from-cwd'." +;;;###autoload (autoload '+ivy:project-search-from-cwd "completion/ivy/autoload/evil" nil t) +(evil-define-command +ivy:project-search-from-cwd (query &optional recurse-p) + "Ex interface for `+ivy/project-search-from-cwd'." (interactive "") - (+ivy/ag-from-cwd (not recurse-p) query)) - -;;;###autoload (autoload '+ivy:rg-from-cwd "completion/ivy/autoload/evil" nil t) -(evil-define-command +ivy:rg-from-cwd (query &optional recurse-p) - "Ex interface for `+ivy/rg-from-cwd'." - (interactive "") - (+ivy/rg-from-cwd (not recurse-p) query)) + (+ivy/project-search-from-cwd (not recurse-p) query)) diff --git a/modules/editor/evil/+commands.el b/modules/editor/evil/+commands.el index c1a61fc52..56f36286b 100644 --- a/modules/editor/evil/+commands.el +++ b/modules/editor/evil/+commands.el @@ -57,25 +57,19 @@ (evil-ex-define-cmd "cd" #'+evil:cd) (evil-ex-define-cmd "pwd" #'+evil:pwd) +(evil-define-command +evil:swiper (&optional search) + "Invoke `swiper' with SEARCH, otherwise with the symbol at point." + (interactive "") + (swiper-isearch search)) +(evil-ex-define-cmd "sw[iper]" #'+evil:swiper) + (cond ((featurep! :completion ivy) - (evil-ex-define-cmd "ag" #'+ivy:ag) - (evil-ex-define-cmd "agc[wd]" #'+ivy:ag-from-cwd) - (evil-ex-define-cmd "rg" #'+ivy:rg) - (evil-ex-define-cmd "rgc[wd]" #'+ivy:rg-from-cwd) - (evil-ex-define-cmd "grep" #'+ivy:grep) - (evil-ex-define-cmd "grepc[wd]" #'+ivy:grep-from-cwd) - (evil-ex-define-cmd "sw[iper]" #'+ivy:swiper) - (evil-ex-define-cmd "todo" #'+ivy:todo)) + (evil-ex-define-cmd "pg[rep]" #'+ivy:project-search) + (evil-ex-define-cmd "pg[grep]d" #'+ivy:project-search-from-cwd)) ((featurep! :completion helm) - (evil-ex-define-cmd "ag" #'+helm:ag) - (evil-ex-define-cmd "agc[wd]" #'+helm:ag-from-cwd) - (evil-ex-define-cmd "rg" #'+helm:rg) - (evil-ex-define-cmd "rgc[wd]" #'+helm:rg-from-cwd) - (evil-ex-define-cmd "grep" #'+helm:grep) - (evil-ex-define-cmd "grepc[wd]" #'+helm:grep-from-cwd) - ;; (evil-ex-define-cmd "todo" #'+helm:todo) TODO implement `+helm:todo' - )) + (evil-ex-define-cmd "pg[rep]" #'+helm:project-search) + (evil-ex-define-cmd "pg[grep]d" #'+helm:project-search-from-cwd))) ;;; Project tools (evil-ex-define-cmd "compile" #'+evil:compile) From caed1f2d1ac7fcbf479f196129918328167a0a6d Mon Sep 17 00:00:00 2001 From: Andrew Whatson Date: Tue, 19 Nov 2019 09:58:44 +1000 Subject: [PATCH 126/129] Use CMake docset for cmake-mode --- modules/lang/cc/config.el | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/lang/cc/config.el b/modules/lang/cc/config.el index 701acc96a..4698c382f 100644 --- a/modules/lang/cc/config.el +++ b/modules/lang/cc/config.el @@ -160,6 +160,10 @@ This is ignored by ccls.") ;; ;; Major modes +(use-package! cmake-mode + :defer t + :config (set-docsets! 'cmake-mode "CMake")) + (use-package! company-cmake ; for `cmake-mode' :when (featurep! :completion company) :after cmake-mode From 304506edcc94dcd9a4cc0a11ef5759075b454b48 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Tue, 19 Nov 2019 19:09:44 -0500 Subject: [PATCH 127/129] Fix first envvar set by doom-load-envvar-file Potentially fixes #2077 --- core/core.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/core.el b/core/core.el index 9a6f017db..6bc56a172 100644 --- a/core/core.el +++ b/core/core.el @@ -441,7 +441,7 @@ in interactive sessions, nil otherwise (but logs a warning)." (save-excursion (insert "\n") (insert-file-contents file)) - (while (re-search-forward "\n *\\([^#][^= \n]*\\)=" nil t) + (while (re-search-forward "\n *\\([^#= \n]*\\)=" nil t) (push (buffer-substring (match-beginning 1) (1- (or (save-excursion From 30f72da02adc7da9c36dffe35ad0f5f848763488 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Tue, 19 Nov 2019 20:25:54 -0500 Subject: [PATCH 128/129] Fix No such file org-version.el errors #2010 We generate an org-version.el file, rendering our old org-release hacks unnecessary. This may cause breakages for uses who do deep clones of org-plus-contrib; needs testing. --- modules/lang/org/autoload/org.el | 18 ------------------ modules/lang/org/config.el | 14 +------------- modules/lang/org/packages.el | 18 +++++++++++++++++- 3 files changed, 18 insertions(+), 32 deletions(-) diff --git a/modules/lang/org/autoload/org.el b/modules/lang/org/autoload/org.el index 98d919ea9..88241662f 100644 --- a/modules/lang/org/autoload/org.el +++ b/modules/lang/org/autoload/org.el @@ -1,23 +1,5 @@ ;;; lang/org/autoload/org.el -*- lexical-binding: t; -*- -;; HACK A necessary hack because org requires a compilation step after being -;; cloned, and during that compilation a org-version.el is generated with these -;; two functions, which return the output of a 'git describe ...' call in the -;; repo's root. Of course, this command won't work in a sparse clone, and more -;; than that, initiating these compilation step is a hassle, so... -;;;###autoload (defun +org--release-a () "9.3") -;;;###autoload (fset 'org-release #'+org--release-a) -;;;###autoload (fset 'org-git-version #'ignore) - -;; Org itself may override the above if it's loaded too early by packages that -;; depend on it, so we have to advise it once again: -;;;###autoload (advice-add #'org-release :override #'+org--release-a) -;;;###autoload (advice-add #'org-git-version :override #'ignore) -;;;###autoload (add-to-list 'load-path (dir!)) - -;;;###autoload (provide 'org-version) - - ;; ;;; Helpers diff --git a/modules/lang/org/config.el b/modules/lang/org/config.el index ceabd3a41..a52611d85 100644 --- a/modules/lang/org/config.el +++ b/modules/lang/org/config.el @@ -207,19 +207,7 @@ background (and foreground) match the current theme." ;; Fix 'require(...).print is not a function' error from `ob-js' when ;; executing JS src blocks - (setq org-babel-js-function-wrapper "console.log(require('util').inspect(function(){\n%s\n}()));") - - ;; Fix #2010: ob-async needs to initialize Doom Emacs at least minimally for - ;; its async babel sessions to run correctly. This cannot be a named function - ;; because it is interpolated directly into a closure to be evaluated on the - ;; async session. - (defadvice! +org-init-doom-during-async-executation-a (orig-fn &rest args) - :around #'ob-async-org-babel-execute-src-block - (let ((ob-async-pre-execute-src-block-hook - ;; Ensure our hook is always first - (cons `(lambda () (load ,(concat doom-emacs-dir "init.el"))) - ob-async-pre-execute-src-block-hook))) - (apply orig-fn args)))) + (setq org-babel-js-function-wrapper "console.log(require('util').inspect(function(){\n%s\n}()));")) (defun +org-init-babel-lazy-loader-h () diff --git a/modules/lang/org/packages.el b/modules/lang/org/packages.el index 15ef59d61..5f4a7f17e 100644 --- a/modules/lang/org/packages.el +++ b/modules/lang/org/packages.el @@ -6,7 +6,23 @@ (when-let (orglib (locate-library "org" nil doom--initial-load-path)) (setq load-path (delete (substring (file-name-directory orglib) 0 -1) load-path))) -(package! org-plus-contrib) ; install cutting-edge version of org-mode + +;; HACK A necessary hack because org requires a compilation step after being +;; cloned, and during that compilation a org-version.el is generated with +;; these two functions, which return the output of a 'git describe ...' +;; call in the repo's root. Of course, this command won't work in a sparse +;; clone, and more than that, initiating these compilation step is a +;; hassle, so... +(setq straight-fix-org nil) +(add-hook! 'straight-use-package-pre-build-functions + (defun +org-fix-package-h (package &rest _) + (when (member package '("org" "org-plus-contrib")) + (with-temp-file (expand-file-name "org-version.el" (straight--repos-dir "org")) + (insert "(fset 'org-release (lambda () \"9.3\"))\n" + "(fset 'org-git-version #'ignore)\n" + "(provide 'org-version)\n"))))) + +(package! org-plus-contrib) ; install cutting-edge version of org-mode (package! htmlize) (package! org-bullets :recipe (:host github :repo "Kaligule/org-bullets")) From b63e62ef49e3380da8e3fa1c8ebb32e4d17baf57 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Tue, 19 Nov 2019 20:37:49 -0500 Subject: [PATCH 129/129] config/literate: allow config.org to be a symlink #2079 --- modules/config/literate/init.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/config/literate/init.el b/modules/config/literate/init.el index 4dd961090..21898e443 100644 --- a/modules/config/literate/init.el +++ b/modules/config/literate/init.el @@ -18,7 +18,7 @@ byte-compiled from.") +literate-config-cache-file) force-p) (message "Compiling your literate config...") - (let* ((org (file-truename +literate-config-file)) + (let* ((org (expand-file-name +literate-config-file)) (dest (concat (file-name-sans-extension +literate-config-file) ".el")) (output (get-buffer-create "*org-tangle*"))) (unwind-protect