diff --git a/README.md b/README.md index 07ebcf50b..bad317d39 100644 --- a/README.md +++ b/README.md @@ -146,8 +146,6 @@ commands you should know about: + `doom env` to dump a snapshot of your shell environment to a file that Doom will load at startup. This allows Emacs to inherit your `PATH`, among other things. -+ `doom build` to recompile all installed packages (use this if you up/downgrade - Emacs). # Roadmap diff --git a/bin/doom b/bin/doom index f9d1841e6..8104260a8 100755 --- a/bin/doom +++ b/bin/doom @@ -271,10 +271,8 @@ SEE ALSO: (defcli-autoload! ((profiles profile))) (defcli-autoload! ((upgrade up))) (defcli-autoload! (env)) - (defcli-autoload! ((build b purge p rollback)) "packages") + (defcli-autoload! ((build b purge p gc rollback)) "packages") (defcli-autoload! ((install i))) - (defcli-autoload! ((compile c))) - (defcli-autoload! (clean) "compile") ;; TODO Post-3.0 commands ;; (load! "gc" dir) @@ -282,8 +280,6 @@ SEE ALSO: ;; (load! "nuke" dir) ;; (load! "package" dir) ;; (load! "profile" dir) - ;; (defcli-obsolete! ((compile c)) (sync "--compile") "v3.0.0") - ;; (defcli-obsolete! ((build b)) (sync "--rebuild") "v3.0.0") ) (defcli-group! "Diagnostics" diff --git a/docs/faq.org b/docs/faq.org index 480ae45a0..5179ccb86 100644 --- a/docs/faq.org +++ b/docs/faq.org @@ -402,14 +402,13 @@ This command is never needed for changes to =$DOOMDIR/config.el=. ** Copy or sync my config to another system? *Short answer:* it is safe to sync =$DOOMDIR= across systems, but not -=$EMACSDIR=. Once moved, use ~$ doom sync && doom build~ to ensure everything is -set up correctly. +=$EMACSDIR=. Once moved, use ~$ doom sync~ to ensure everything is set up +correctly. *Long answer:* packages can contain baked-in absolute paths and non-portable byte-code. It is never a good idea to mirror it across multiple systems, unless they are all the same (same OS, same version of Emacs, same paths). Most issues -should be solved by running ~$ doom sync && doom build~ on the other end, once -moved. +should be solved by running ~$ doom sync~ on the other end, once moved. ** Start over, in case something went terribly wrong? Delete =$EMACSDIR/.local/straight= and run ~$ doom sync~. diff --git a/lisp/cli/compile.el b/lisp/cli/compile.el deleted file mode 100644 index 88cfed2d9..000000000 --- a/lisp/cli/compile.el +++ /dev/null @@ -1,214 +0,0 @@ -;;; lisp/cli/commands/byte-compile.el -*- lexical-binding: t; -*- - -;; -;;; Variables - -;; None yet! - - -;; -;;; Commands - -(defcli! ((compile c)) - ((recompile-p ("-r" "--recompile")) - (core-p ("-c" "--core")) - (private-p ("-p" "--private")) - (verbose-p ("-v" "--verbose"))) - "Byte-compiles your config or selected modules. - - compile [TARGETS...] - compile :core :user lang/python - compile feature lang - -Accepts :core and :user as special arguments, which target Doom's core files -and your private config files, respectively. To recompile your packages, use -'doom build' instead." - (doom-cli-compile - (if (or core-p private-p) - (append (if core-p (doom-glob doom-emacs-dir "init.el")) - (if core-p (list doom-core-dir)) - (if private-p (list doom-user-dir))) - (or (y-or-n-p - (concat "WARNING: Changes made to your config after compiling it won't take effect until\n" - "this command is rerun or you run 'doom clean'! It will also make error backtraces\n" - "much more difficult to decipher.\n\n" - "If you intend to use it anyway, remember this or it will come back to bite you!\n\n" - "Continue anyway?")) - (user-error "Aborted")) - (append (doom-glob doom-emacs-dir "init.el") - (list doom-core-dir) - (seq-filter - ;; Only compile Doom's modules - (doom-rpartial #'file-in-directory-p doom-emacs-dir) - ;; Omit `doom-user-dir', which is always first - (doom-module-load-path)))) - recompile-p - verbose-p)) - -(defcli! clean () - "Delete all *.elc files." - (doom-compile-clean)) - - -;; -;;; Helpers - -(cl-defun doom-cli-compile (&optional targets recompile-p verbose-p) - "Byte compiles your emacs configuration. - -init.el is always byte-compiled by this. - -If TARGETS is specified, as a list of direcotries - -If MODULES is specified (a list of module strings, e.g. \"lang/php\"), those are -byte-compiled. Otherwise, all enabled modules are byte-compiled, including Doom -core. It always ignores unit tests and files with `no-byte-compile' enabled. - -WARNING: byte-compilation yields marginal gains and makes debugging new issues -difficult. It is recommended you don't use it unless you understand the -reprecussions. - -Use `doom-compile-clean' or `make clean' to reverse -byte-compilation. - -If RECOMPILE-P is non-nil, only recompile out-of-date files." - (let* ((default-directory doom-emacs-dir) - (targets (nreverse (delete-dups targets))) - ;; In case it is changed during compile-time - (auto-mode-alist auto-mode-alist) - kill-emacs-hook kill-buffer-query-functions) - - (let ((after-load-functions - (if (null targets) - after-load-functions - ;; Assemble el files we want to compile, and preserve in the order - ;; they are loaded in, so we don't run into any scary catch-22s - ;; while byte-compiling, like missing macros. - (cons (let ((target-dirs (seq-filter #'file-directory-p targets))) - (lambda (path) - (and (not (doom-compile--ignore-file-p path)) - (seq-find (doom-partial #'file-in-directory-p path) - target-dirs) - (cl-pushnew path targets)))) - after-load-functions)))) - (doom-log "Reloading Doom in preparation for byte-compilation") - ;; But first we must be sure that Doom and your private config have been - ;; fully loaded. Which usually aren't so in an noninteractive session. - (let ((load-prefer-newer t)) - (require 'doom-start))) - - (if (null targets) - (print! (item "No targets to %scompile" (if recompile-p "re" ""))) - (print! (start "%scompiling your config...") - (if recompile-p "Re" "Byte-")) - - (dolist (dir - (cl-remove-if-not #'file-directory-p targets) - (setq targets (cl-remove-if #'file-directory-p targets))) - (prependq! targets - (doom-files-in - dir :match "\\.el" :filter #'doom-compile--ignore-file-p))) - - (print-group! - (require 'use-package) - (condition-case-unless-debug e - (let* ((total-ok 0) - (total-fail 0) - (total-noop 0) - (byte-compile-verbose nil) - (byte-compile-warnings '(not free-vars unresolved noruntime lexical make-local)) - (byte-compile-dynamic-docstrings t) - (use-package-compute-statistics nil) - (use-package-defaults use-package-defaults) - (use-package-expand-minimally t) - (targets (delete-dups targets)) - (modules (seq-group-by #'doom-module-from-path targets)) - (total-files (length targets)) - (total-modules (length modules)) - (i 0) - last-module) - ;; Prevent packages from being loaded at compile time if they - ;; don't meet their own predicates. - (push (list :no-require t - (lambda (_name args) - (or (when-let (pred (or (plist-get args :if) - (plist-get args :when))) - (not (eval pred t))) - (when-let (pred (plist-get args :unless)) - (eval pred t))))) - use-package-defaults) - (dolist (module-files modules) - (cl-incf i) - (dolist (target (cdr module-files)) - (let ((elc-file (byte-compile-dest-file target))) - (cl-incf - (if (and recompile-p (not (file-newer-than-file-p target elc-file))) - total-noop - (pcase (if (not (doom-file-cookie-p target "if" t)) - 'no-byte-compile - (unless (equal last-module (car module-files)) - (print! (success "(% 3d/%d) Compiling %s") - i total-modules - (if-let (m (caar module-files)) - (format "%s %s module..." m (cdar module-files)) - (format "%d stand alone elisp files..." - (length (cdr module-files)))) - (caar module-files) (cdar module-files)) - (setq last-module (car module-files))) - (if verbose-p - (byte-compile-file target) - (quiet! (byte-compile-file target)))) - (`no-byte-compile - (doom-log "(% 3d/%d) Ignored %s" i total-modules target) - total-noop) - (`nil - (print! (error "(% 3d/%d) Failed to compile %s") - i total-modules (relpath target)) - total-fail) - (_ total-ok))))))) - (print! (class (if (= total-fail 0) 'success 'warn) - "%s %d/%d file(s) (%d ignored)") - (if recompile-p "Recompiled" "Byte-compiled") - total-ok total-files - total-noop) - (= total-fail 0)) - ((debug error) - (print! (error "There were breaking errors.\n\n%s") - "Reverting changes...") - (signal 'doom-error (list 'byte-compile e)))))))) - -(defun doom-compile--ignore-file-p (path) - (let ((filename (file-name-nondirectory path))) - (or (not (equal (file-name-extension path) "el")) - (member filename (list doom-module-packages-file "doctor.el")) - (string-prefix-p "." filename) - (string-prefix-p "test-" filename) - (string-prefix-p "flycheck_" filename) - (string-suffix-p ".example.el" filename)))) - -(defun doom-compile-clean () - "Delete all the compiled elc files in your Emacs configuration and private -module. This does not include your byte-compiled, third party packages.'" - (require 'doom-modules) - (print! (start "Cleaning .elc files")) - (print-group! - (cl-loop with default-directory = doom-emacs-dir - with success = 0 - with esc = (if init-file-debug "" "\033[1A") - for path - in (append (doom-glob doom-emacs-dir "*.elc") - (doom-files-in doom-user-dir :match "\\.elc$" :depth 1) - (doom-files-in doom-core-dir :match "\\.elc$") - (doom-files-in doom-module-load-path :match "\\.elc$" :depth 4)) - if (file-exists-p path) - do (delete-file path) - and do (print! (success "\033[KDeleted %s%s") (relpath path) esc) - and do (cl-incf success) - finally do - (print! (if (> success 0) - (success "\033[K%d elc files deleted" success) - (item "\033[KNo elc files to clean")))) - t)) - -(provide 'doom-cli-compile) -;;; compile.el ends here diff --git a/lisp/cli/help.el b/lisp/cli/help.el deleted file mode 100644 index 0d58aa974..000000000 --- a/lisp/cli/help.el +++ /dev/null @@ -1,466 +0,0 @@ -;;; lisp/cli/help.el -*- lexical-binding: t; -*- -;;; Commentary: -;; -;; This file defines special commands that the Doom CLI will invoke when a -;; command is passed with -?, --help, or --version. They can also be aliased to -;; a sub-command to make more of its capabilities accessible to users, with: -;; -;; (defcli-alias! (myscript (help h)) (:help)) -;; -;; You can define your own command-specific help handlers, e.g. -;; -;; (defcli! (:help myscript subcommand) () ...) -;; -;; And it will be invoked instead of the generic one. -;; -;;; Code: - -;; -;;; Variables - -(defvar doom-help-commands '("%p %c {-?,--help}") - "A list of help commands recognized for the running script. - -Recognizes %p (for the prefix) and %c (for the active command).") - - -;; -;;; Commands - -(defcli! (:root :help) - ((localonly? ("-g" "--no-global") "Hide global options") - (manpage? ("--manpage") "Generate in manpage format") - (commands? ("--commands") "List all known commands") - &multiple - (sections ("--synopsis" "--subcommands" "--similar" "--envvars" - "--postamble") - "Show only the specified sections.") - &context context - &args command) - "Show documentation for a Doom CLI command. - -OPTIONS: - --synopsis, --subcommands, --similar, --envvars, --postamble - TODO" - (doom-cli-load-all) - (when (doom-cli-context-error context) - (terpri)) - (let* ((command (cons (doom-cli-context-prefix context) command)) - (cli (doom-cli-get command t)) - (rcli (doom-cli-get cli)) - (fallbackcli (cl-loop with targets = (doom-cli--command-expand (butlast command) t) - for cmd in (cons command targets) - if (doom-cli-get cmd t) - return it))) - (cond (commands? - (let ((cli (or cli (doom-cli-get (doom-cli-context-prefix context))))) - (print! "Commands under '%s':\n%s" - (doom-cli-command-string cli) - (indent (doom-cli-help--render-commands - (or (doom-cli-subcommands cli) - (user-error "No commands found")) - :prefix (doom-cli-command cli) - :inline? t - :docs? t))))) - ((null sections) - (if (null cli) - (signal 'doom-cli-command-not-found-error command) - (doom-cli-help--print cli context manpage? localonly?) - (exit! :pager?))) - ((dolist (section sections) - (unless (equal section (car sections)) (terpri)) - (pcase section - ("--synopsis" - (print! "%s" (doom-cli-help--render-synopsis - (doom-cli-help--synopsis cli) - "Usage: "))) - ("--subcommands" - (print! "%s\n%s" (bold "Available commands:") - (indent (doom-cli-help--render-commands - (doom-cli-subcommands rcli 1) - :prefix command - :grouped? t - :docs? t) - doom-print-indent-increment))) - ("--similar" - (unless command - (user-error "No command specified")) - (let ((similar (doom-cli-help-similar-commands command 0.4))) - (print! "Similar commands:") - (if (not similar) - (print! (indent (warn "Can't find any!"))) - (dolist (command (seq-take similar 10)) - (print! (indent (item "(%d%%) %s")) - (* (car command) 100) - (doom-cli-command-string (cdr command))))))) - ("--envvars" - (let* ((key "ENVIRONMENT VARIABLES") - (clis (if command (doom-cli-find command) (hash-table-values doom-cli--table))) - (clis (seq-remove #'doom-cli-alias clis)) - (clis (seq-filter (fn! (cdr (assoc key (doom-cli-docs %)))) clis)) - (clis (seq-group-by #'doom-cli-command clis))) - (print! "List of environment variables for %s:\n" command) - (if (null clis) - (print! (indent "None!")) - (dolist (group clis) - (print! (bold "%s%s:" - (doom-cli-command-string (car group)) - (if (doom-cli-fn (doom-cli-get (car group))) - "" " *"))) - (dolist (cli (cdr group)) - (print! (indent "%s") (markup (cdr (assoc key (doom-cli-docs cli)))))))))) - ("--postamble" - (print! "See %s for documentation." - (join (cl-loop with spec = - `((?p . ,(doom-cli-context-prefix context)) - (?c . ,(doom-cli-command-string (cdr (doom-cli-command (or cli fallbackcli)))))) - for cmd in doom-help-commands - for formatted = (trim (format-spec cmd spec)) - collect (replace-regexp-in-string - " +" " " (format "'%s'" formatted))) - " or "))))))))) - -(defcli! (:root :version) - ((simple? ("--simple")) - &context context) - "Show installed versions of Doom, Doom modules, and Emacs." - (doom/version) - (unless simple? - (terpri) - (with-temp-buffer - (insert-file-contents (doom-path doom-emacs-dir "LICENSE")) - (re-search-forward "^Copyright (c) ") - (print! "%s\n" (trim (thing-at-point 'line t))) - (print! (p "Doom Emacs uses the MIT license and is provided without warranty " - "of any kind. You may redistribute and modify copies if " - "given proper attribution. See the LICENSE file for details."))))) - - -;; -;;; Helpers - -(defun doom-cli-help (cli) - "Return an alist of documentation summarizing CLI (a `doom-cli')." - (let* ((rcli (doom-cli-get cli)) - (docs (doom-cli-docs rcli))) - `((command . ,(doom-cli-command-string cli)) - (summary . ,(or (cdr (assoc "SUMMARY" docs)) "TODO")) - (description . ,(or (cdr (assoc "MAIN" docs)) "TODO")) - (synopsis . ,(doom-cli-help--synopsis cli)) - (arguments . ,(doom-cli-help--arguments rcli)) - (options . ,(doom-cli-help--options rcli)) - (commands . ,(doom-cli-subcommands cli 1)) - (sections . ,(seq-filter #'cdr (cddr docs)))))) - -(defun doom-cli-help-similar-commands (command &optional maxscore) - "Return N commands that are similar to COMMAND." - (seq-take-while - (fn! (>= (car %) (or maxscore 0.0))) - (seq-sort-by - #'car #'> - (cl-loop with prefix = (seq-find #'doom-cli-get (nreverse (doom-cli--command-expand command t))) - with input = (doom-cli-command-string (cdr (doom-cli--command command t))) - for command in (hash-table-keys doom-cli--table) - if (doom-cli-fn (doom-cli-get command)) - if (equal prefix (seq-take command (length prefix))) - collect (cons (doom-cli-help--similarity - input (doom-cli-command-string (cdr command))) - command))))) - -(defun doom-cli-help--similarity (s1 s2) - ;; Ratcliff-Obershelp similarity - (let* ((s1 (downcase s1)) - (s2 (downcase s2)) - (s1len (length s1)) - (s2len (length s2))) - (if (or (zerop s1len) - (zerop s2len)) - 0.0 - (/ (let ((i 0) (j 0) (score 0) jlast) - (while (< i s1len) - (unless jlast (setq jlast j)) - (if (and (< j s2len) - (= (aref s1 i) (aref s2 j))) - (progn (cl-incf score) - (cl-incf i) - (cl-incf j)) - (setq m 0) - (cl-incf j) - (when (>= j s2len) - (setq j (or jlast j) - jlast nil) - (cl-incf i)))) - (* 2.0 score)) - (+ (length s1) - (length s2)))))) - -;;; Help: printers -;; TODO Parameterize optional args with `cl-defun' -(defun doom-cli-help--print (cli context &optional manpage? noglobal?) - "Write CLI's documentation in a manpage-esque format to stdout." - (let-alist (doom-cli-help cli) - (let* ((alist - `(,@(if manpage? - `((nil . ,(let* ((title (cadr (member "--load" command-line-args))) - (width (floor (/ (- (doom-cli-context-width context) - (length title)) - 2.0)))) - ;; FIXME Who am I fooling? - (format (format "%%-%ds%%s%%%ds" width width) - "DOOM(1)" title "DOOM(1)"))) - ("NAME" . ,(concat .command " - " .summary)) - ("SYNOPSIS" . ,(doom-cli-help--render-synopsis .synopsis nil t)) - ("DESCRIPTION" . ,.description)) - `((nil . ,(doom-cli-help--render-synopsis .synopsis "Usage: ")) - (nil . ,(string-join (seq-remove #'string-empty-p (list .summary .description)) - "\n\n")))) - ("ARGUMENTS" . ,(doom-cli-help--render-arguments .arguments)) - ("COMMANDS" - . ,(doom-cli-help--render-commands - .commands :prefix (doom-cli-command cli) :grouped? t :docs? t)) - ("OPTIONS" - . ,(doom-cli-help--render-options - (if (or (not (doom-cli-fn cli)) noglobal?) - `(,(assq 'local .options)) - .options) - cli)))) - (command (doom-cli-command cli))) - (letf! (defun printsection (section) - (print! "%s\n" - (if (null section) - (dark "TODO") - (markup - (format-spec - section `((?p . ,(car command)) - (?c . ,(doom-cli-command-string (cdr command)))) - 'ignore))))) - (pcase-dolist (`(,label . ,contents) alist) - (when (and contents (not (string-blank-p contents))) - (when label - (print! (bold "%s%s") label (if manpage? "" ":"))) - (print-group! :if label (printsection contents)))) - (pcase-dolist (`(,label . ,contents) .sections) - (when (and contents (not (assoc label alist))) - (print! (bold "%s:") label) - (print-group! (printsection contents)))))))) - -;;; Help: synopsis -(defun doom-cli-help--synopsis (cli &optional all-options?) - (let* ((rcli (doom-cli-get cli)) - (opts (doom-cli-help--options rcli)) - (opts (mapcar #'car (if all-options? (mapcan #'cdr opts) (alist-get 'local opts)))) - (opts (cl-loop for opt in opts - for args = (cdar opt) - for switches = (mapcar #'car opt) - for multi? = (member "..." args) - if args - collect (format (if multi? "[%s %s]..." "[%s %s]") - (string-join switches "|") - (string-join (remove "..." args) "|")) - else collect (format "[%s]" (string-join switches "|")))) - (args (doom-cli-arguments rcli)) - (subcommands? (doom-cli-subcommands rcli 1 :predicate? t))) - `((command . ,(doom-cli-command cli)) - (options ,@opts) - (required ,@(mapcar (fn! (upcase (format "`%s'" %))) (if subcommands? '(command) (alist-get '&required args)))) - (optional ,@(mapcar (fn! (upcase (format "[`%s']" %)))(alist-get '&optional args))) - (rest ,@(mapcar (fn! (upcase (format "[`%s'...]" %))) (if subcommands? '(args) (alist-get '&args args))))))) - -(defun doom-cli-help--render-synopsis (synopsis &optional prefix) - (let-alist synopsis - (let ((doom-print-indent 0) - (prefix (or prefix "")) - (command (doom-cli-command-string .command))) - (string-trim-right - (format! "%s\n\n" - (fill (concat (bold prefix) - (format "%s " command) - (markup - (join (append .options - (and .options - (or .required - .optional - .rest) - (list (dark "[--]"))) - .required - .optional - .rest)))) - 80 (1+ (length (concat prefix command))))))))) - -;;; Help: arguments -(defun doom-cli-help--arguments (cli &optional all?) - (doom-cli-help--parse-docs (doom-cli-find cli t) "ARGUMENTS")) - -(defun doom-cli-help--render-arguments (arguments) - (mapconcat (lambda (arg) - (format! "%-20s\n%s" - (underscore (car arg)) - (indent (if (equal (cdr arg) "TODO") - (dark (cdr arg)) - (cdr arg)) - doom-print-indent-increment))) - arguments - "\n")) - -;;; Help: commands -(cl-defun doom-cli-help--render-commands (commands &key prefix grouped? docs? (inline? t)) - (with-temp-buffer - (let* ((doom-print-indent 0) - (commands (seq-group-by (fn! (if grouped? (doom-cli-prop (doom-cli-get % t) :group))) - (nreverse commands))) - (toplevel (assq nil commands)) - (rest (remove toplevel commands)) - (drop (if prefix (length prefix) 0)) - (minwidth - (apply - #'max (or (cl-loop for cmd in (apply #'append (mapcar #'cdr commands)) - for cmd = (seq-drop cmd drop) - collect (length (doom-cli-command-string cmd))) - (list 15)))) - (ellipsis (doom-print--style 'dark " […]")) - (ellipsislen (- (length ellipsis) (if (eq doom-print-backend 'ansi) 2 4)))) - (dolist (group (cons toplevel rest)) - (let ((label (if (car-safe group) (cdr commands)))) - (when label - (insert! ((bold "%s:") (car group)) "\n")) - (print-group! :if label - (dolist (command (cdr group)) - (let* ((cli (doom-cli-get command t)) - (rcli (doom-cli-get command)) - (summary (doom-cli-short-docs rcli)) - (subcommands? (doom-cli-subcommands cli 1 :predicate? t))) - (insert! ((format "%%-%ds%%s%%s" - (+ (- minwidth doom-print-indent) - doom-print-indent-increment - (if subcommands? ellipsislen 0))) - (concat (doom-cli-command-string (seq-drop command drop)) - (if subcommands? ellipsis)) - (if inline? " " "\n") - (indent (if (and (doom-cli-alias cli) - (not (doom-cli-type rcli))) - (dark "-> %s" (doom-cli-command-string cli)) - (when docs? - (if summary (markup summary) (dark "TODO")))))) - "\n"))) - (when (cdr rest) - (insert "\n"))))) - (string-trim-right (buffer-string))))) - -;;; Help: options -(defun doom-cli-help--options (cli &optional noformatting?) - "Return an alist summarizing CLI's options. - -The alist's CAR are lists of formatted switches plus their arguments, e.g. -'((\"`--foo'\" \"`BAR'\") ...). Their CDR is their formatted documentation." - (let* ((docs (doom-cli-help--parse-docs (doom-cli-find cli t) "OPTIONS")) - (docs (mapcar (fn! (cons (split-string (car %) ", ") - (cdr %))) - docs)) - (strfmt (if noformatting? "%s" "`%s'")) - local-options - global-options - seen) - (dolist (neighbor (nreverse (doom-cli-find cli))) - (dolist (option (doom-cli-options neighbor)) - (when-let* ((switches (cl-loop for sw in (doom-cli-option-switches option) - if (and (doom-cli-option-flag-p option) - (string-prefix-p "--" sw)) - collect (format "--[no-]%s" (substring sw 2)) - else collect sw)) - (switches (seq-difference switches seen))) - (dolist (switch switches) (push switch seen)) - (push (cons (cl-loop for switch in switches - if (doom-cli-option-arguments option) - collect (cons (format strfmt switch) - (append (doom-cli-help--parse-args it noformatting?) - (when (doom-cli-option-multiple-p option) - (list "...")))) - else collect (list (format strfmt switch))) - (string-join - (or (delq - nil (cons (when-let (docs (doom-cli-option-docs option)) - (concat docs ".")) - (cl-loop for (flags . docs) in docs - unless (equal (seq-difference flags switches) flags) - collect docs))) - '("TODO")) - "\n\n")) - (if (equal (doom-cli-command neighbor) - (doom-cli-command cli)) - local-options - global-options))))) - `((local . ,(nreverse local-options)) - (global . ,(nreverse global-options))))) - -(defun doom-cli-help--render-options (options &optional cli) - (let ((doom-print-indent 0) - (local (assq 'local options)) - (global (assq 'global options))) - (when (or (cdr local) (cdr global)) - (letf! (defun printopts (opts) - (pcase-dolist (`(,switches . ,docs) (cdr opts)) - (let (multiple?) - (insert! - ("%s%s\n%s" - (mapconcat - (fn! (when (member "..." (cdr %)) - (setq multiple? t)) - (string-trim-right - (format "%s %s" - (doom-print--cli-markup (car %)) - (doom-print--cli-markup - (string-join (remove "..." (cdr %)) "|"))))) - switches - ", ") - (if multiple? ", ..." "") - (indent (fill (markup docs)) doom-print-indent-increment)) - "\n\n")))) - (with-temp-buffer - (if (null (cdr local)) - (insert (if global "This command has no local options.\n" "") "\n") - (printopts local)) - (when (cdr global) - (insert! ((bold "Global options:\n"))) - (print-group! (printopts global))) - (string-trim-right (buffer-string))))))) - -;;; Help: internal -(defun doom-cli-help--parse-args (args &optional noformatting?) - (cl-loop for arg in args - if (listp arg) - collect (string-join (doom-cli-help--parse-args arg noformatting?) "|") - else if (symbolp arg) - collect (format (if noformatting? "%s" "`%s'") (upcase (symbol-name arg))) - else collect arg)) - -(defun doom-cli-help--parse-docs (cli-list section-name) - (cl-check-type section-name string) - (let (alist) - (dolist (cli cli-list (nreverse alist)) - (when-let (section (cdr (assoc section-name (doom-cli-docs cli)))) - (with-temp-buffer - (save-excursion (insert section)) - (let ((lead (current-indentation)) - (buffer (current-buffer))) - (while (not (eobp)) - (let ((heading (string-trim (buffer-substring (point-at-bol) (point-at-eol)))) - (beg (point-at-bol 2)) - end) - (forward-line 1) - (while (and (not (eobp)) - (/= (current-indentation) lead) - (forward-line 1))) - (setf (alist-get heading alist nil nil #'equal) - (string-join - (delq - nil (list (alist-get heading alist nil nil #'equal) - (let ((end (point))) - (with-temp-buffer - (insert-buffer-substring buffer beg end) - (goto-char (point-min)) - (indent-rigidly (point-min) (point-max) (- (current-indentation))) - (string-trim-right (buffer-string)))))) - "\n\n")))))))))) - -(provide 'doom-cli-help) -;;; help.el ends here diff --git a/lisp/cli/install.el b/lisp/cli/install.el index 79dddaf8b..27dad9bc9 100644 --- a/lisp/cli/install.el +++ b/lisp/cli/install.el @@ -96,7 +96,7 @@ Change `$DOOMDIR' with the `--doomdir' option, e.g. (if (eq install? :no) (print! (warn "Not installing plugins, as requested")) (print! "Installing plugins") - (doom-packages-install)) + (doom-packages-ensure)) (print! "Regenerating autoloads files") (doom-profile-generate) diff --git a/lisp/cli/packages.el b/lisp/cli/packages.el index 1cd6d4d45..26018ae91 100644 --- a/lisp/cli/packages.el +++ b/lisp/cli/packages.el @@ -13,28 +13,12 @@ ;; ;;; Commands -(defcli! (:before (build b purge p)) (&context context) - (require 'comp nil t) - (doom-initialize-core-packages)) +(defcli-obsolete! ((build b)) (sync "--rebuild") "v3.0.0") -;; DEPRECATED Replace with "doom sync --rebuild" -(defcli! ((build b)) - ((rebuild-p ("-r") "Only rebuild packages that need rebuilding") - (jobs ("-j" "--jobs" num) "How many CPUs to use for native compilation")) - "Byte-compiles & symlinks installed packages. - -This ensures that all needed files are symlinked from their package repo and -their elisp files are byte-compiled. This is especially necessary if you upgrade -Emacs (as byte-code is generally not forward-compatible)." - :benchmark t - (when jobs - (setq native-comp-async-jobs-number (truncate jobs))) - (when (doom-packages-build (not rebuild-p)) - (doom-profile-generate)) - t) +(defcli-obsolete! ((purge p)) (gc) "v3.0.0") ;; TODO Rename to "doom gc" and move to its own file -(defcli! ((purge p)) +(defcli! (gc) ((nobuilds-p ("-b" "--no-builds") "Don't purge unneeded (built) packages") (noelpa-p ("-p" "--no-elpa") "Don't purge ELPA packages") (norepos-p ("-r" "--no-repos") "Don't purge unused straight repos") @@ -50,6 +34,8 @@ possible. It is a good idea to occasionally run this doom purge -g to ensure your package list remains lean." :benchmark t + (require 'comp nil t) + (doom-initialize-core-packages) (straight-check-all) (when (doom-packages-purge (not noelpa-p) @@ -242,154 +228,149 @@ list remains lean." (defun doom-packages--write-missing-eln-errors () "Write .error files for any expected .eln files that are missing." - (when (featurep 'native-compile) - (cl-loop for file in doom-packages--eln-output-expected - for eln-name = (doom-packages--eln-file-name file) - for eln-file = (doom-packages--eln-output-file eln-name) - for error-file = (doom-packages--eln-error-file eln-name) - for error-dir = (file-name-directory error-file) - unless (or (file-exists-p eln-file) - (file-newer-than-file-p error-file file) - (not (file-writable-p error-dir))) - do (make-directory error-dir 'parents) - (write-region "" nil error-file) - (doom-log "Wrote %s" error-file)) - (setq doom-packages--eln-output-expected nil))) + (cl-loop for file in doom-packages--eln-output-expected + for eln-name = (doom-packages--eln-file-name file) + for eln-file = (doom-packages--eln-output-file eln-name) + for error-file = (doom-packages--eln-error-file eln-name) + for error-dir = (file-name-directory error-file) + unless (or (file-exists-p eln-file) + (file-newer-than-file-p error-file file) + (not (file-writable-p error-dir))) + do (make-directory error-dir 'parents) + (write-region "" nil error-file) + (doom-log "Wrote %s" error-file)) + (setq doom-packages--eln-output-expected nil)) (defun doom-packages--compile-site-files () "Queue async compilation for all non-doom Elisp files." - (when (featurep 'native-compile) - (cl-loop with paths = (cl-loop for path in load-path - unless (file-in-directory-p path doom-local-dir) - collect path) - for file in (doom-files-in paths :match "\\.el\\(?:\\.gz\\)?$") - if (and (file-exists-p (byte-compile-dest-file file)) - (not (doom-packages--find-eln-file (doom-packages--eln-file-name file))) - (not (cl-some (fn! (string-match-p % file)) - native-comp-deferred-compilation-deny-list))) do - (doom-log "Compiling %s" file) - (native-compile-async file)))) + (cl-loop with paths = (cl-loop for path in load-path + unless (file-in-directory-p path doom-local-dir) + collect path) + for file in (doom-files-in paths :match "\\.el\\(?:\\.gz\\)?$") + if (and (file-exists-p (byte-compile-dest-file file)) + (not (doom-packages--find-eln-file (doom-packages--eln-file-name file))) + (not (cl-some (fn! (string-match-p % file)) + native-comp-deferred-compilation-deny-list))) do + (doom-log "Compiling %s" file) + (native-compile-async file))) -(defun doom-packages-install () - "Installs missing packages. - -This function will install any primary package (i.e. a package with a `package!' -declaration) or dependency thereof that hasn't already been." +(defun doom-packages-ensure (&optional force-p) + "Ensure packages are installed, built" (doom-initialize-packages) - (print! (start "Installing packages...")) - (let ((pinned (doom-package-pinned-list))) - (print-group! - (add-hook 'native-comp-async-cu-done-functions #'doom-packages--native-compile-done-h) - (if-let (built - (doom-packages--with-recipes (doom-package-recipe-list) - (recipe package type local-repo) - (unless (file-directory-p (straight--repos-dir local-repo)) - (doom-packages--cli-recipes-update)) - (condition-case-unless-debug e - (let ((straight-use-package-pre-build-functions - (cons (lambda (pkg &rest _) - (when-let (commit (cdr (assoc pkg pinned))) - (print! (item "Checked out %s: %s") pkg commit))) - straight-use-package-pre-build-functions))) - (straight-use-package (intern package)) - ;; HACK Line encoding issues can plague repos with dirty - ;; worktree prompts when updating packages or "Local - ;; variables entry is missing the suffix" errors when - ;; installing them (see hlissner/doom-emacs#2637), so - ;; have git handle conversion by force. - (when (and doom--system-windows-p (stringp local-repo)) - (let ((default-directory (straight--repos-dir local-repo))) - (when (file-in-directory-p default-directory straight-base-dir) - (straight--process-run "git" "config" "core.autocrlf" "true"))))) - (error - (signal 'doom-package-error (list package e)))))) - (progn - (when (featurep 'native-compile) - (doom-packages--compile-site-files) - (doom-packages--wait-for-native-compile-jobs) - (doom-packages--write-missing-eln-errors)) - (print! (success "\033[KInstalled %d packages") (length built))) - (print! (item "No packages need to be installed")) - nil)))) - - -(defun doom-packages-build (&optional force-p) - "(Re)build all packages." - (doom-initialize-packages) - (print! (start "(Re)building %spackages...") (if force-p "all " "")) + (if (not (file-directory-p (straight--repos-dir))) + (print! (start "Installing all packages for the first time (this may take a while)...")) + (if force-p + (print! (start "Rebuilding all packages (this may take a while)...")) + (print! (start "Ensuring packages are installed and built...")))) (print-group! - (let ((straight-check-for-modifications - (when (file-directory-p (straight--modified-dir)) - '(find-when-checking))) - (straight--allow-find - (and straight-check-for-modifications - (executable-find straight-find-executable) - t)) - (straight--packages-not-to-rebuild - (or straight--packages-not-to-rebuild (make-hash-table :test #'equal))) - (straight--packages-to-rebuild - (or (if force-p :all straight--packages-to-rebuild) - (make-hash-table :test #'equal))) - (recipes (doom-package-recipe-list))) - (add-hook 'native-comp-async-cu-done-functions #'doom-packages--native-compile-done-h) - (unless force-p - (straight--make-build-cache-available)) - (if-let (built - (doom-packages--with-recipes recipes (package local-repo recipe) - (unless force-p - ;; Ensure packages with outdated files/bytecode are rebuilt - (let* ((build-dir (straight--build-dir package)) - (repo-dir (straight--repos-dir local-repo)) - (build (if (plist-member recipe :build) - (plist-get recipe :build) - t)) - (want-byte-compile - (or (eq build t) - (memq 'compile build))) - (want-native-compile - (or (eq build t) - (memq 'native-compile build)))) - (and (eq (car-safe build) :not) - (setq want-byte-compile (not want-byte-compile) - want-native-compile (not want-native-compile))) - (unless (featurep 'native-compile) - (setq want-native-compile nil)) - (and (or want-byte-compile want-native-compile) - (or (file-newer-than-file-p repo-dir build-dir) - (file-exists-p (straight--modified-dir (or local-repo package))) - (cl-loop with outdated = nil - for file in (doom-files-in build-dir :match "\\.el$" :full t) - if (or (if want-byte-compile (doom-packages--elc-file-outdated-p file)) - (if want-native-compile (doom-packages--eln-file-outdated-p file))) - do (setq outdated t) + (let ((straight-check-for-modifications + (when (file-directory-p (straight--modified-dir)) + '(find-when-checking))) + (straight--allow-find + (and straight-check-for-modifications + (executable-find straight-find-executable) + t)) + (straight--packages-not-to-rebuild + (or straight--packages-not-to-rebuild (make-hash-table :test #'equal))) + (straight--packages-to-rebuild + (or (if force-p :all straight--packages-to-rebuild) + (make-hash-table :test #'equal))) + (recipes (doom-package-recipe-list)) + (pinned (doom-package-pinned-list))) + (add-hook 'native-comp-async-cu-done-functions #'doom-packages--native-compile-done-h) + (straight--make-build-cache-available) + (if-let (built + (doom-packages--with-recipes recipes (package local-repo recipe) + (let ((repo-dir (straight--repos-dir (or local-repo package))) + (build-dir (straight--build-dir package))) + (unless force-p + ;; Ensure packages with outdated files/bytecode are rebuilt + (let* ((build (if (plist-member recipe :build) + (plist-get recipe :build) + t)) + (want-byte-compile + (or (eq build t) + (memq 'compile build))) + (want-native-compile + (or (eq build t) + (memq 'native-compile build)))) + (and (eq (car-safe build) :not) + (setq want-byte-compile (not want-byte-compile) + want-native-compile (not want-native-compile))) + (unless (featurep 'native-compile) + (setq want-native-compile nil)) + (and (or want-byte-compile want-native-compile) + (or (file-newer-than-file-p repo-dir build-dir) + (file-exists-p (straight--modified-dir (or local-repo package))) + (cl-loop with outdated = nil + for file in (doom-files-in build-dir :match "\\.el$" :full t) + if (or (if want-byte-compile (doom-packages--elc-file-outdated-p file)) + (if want-native-compile (doom-packages--eln-file-outdated-p file))) + do (setq outdated t) (when want-native-compile (push file doom-packages--eln-output-expected)) - finally return outdated)) - (puthash package t straight--packages-to-rebuild)))) - (straight-use-package (intern package)))) - (progn - (when (featurep 'native-compile) - (doom-packages--compile-site-files) - (doom-packages--wait-for-native-compile-jobs) - (doom-packages--write-missing-eln-errors)) - ;; HACK Every time you save a file in a package that straight tracks, - ;; it is recorded in ~/.emacs.d/.local/straight/modified/. - ;; Typically, straight will clean these up after rebuilding, but - ;; Doom's use-case circumnavigates that, leaving these files - ;; there and causing a rebuild of those packages each time `doom - ;; sync' or similar is run, so we clean it up ourselves: - (delete-directory (straight--modified-dir) 'recursive) - (print! (success "\033[KRebuilt %d package(s)") (length built))) - (print! (item "No packages need rebuilding")) - nil)))) + finally return outdated)) + (puthash package t straight--packages-to-rebuild)))) + (unless (file-directory-p repo-dir) + (doom-packages--cli-recipes-update)) + (condition-case-unless-debug e + (let ((straight-vc-git-post-clone-hook + (cons (lambda! (&key repo-dir commit) + (print-group! + (if-let (pin (cdr (assoc package pinned))) + (print! (item "Pinned to %s") pin) + (print! (item "Checked out %s") commit))) + ;; HACK: Line encoding issues can plague + ;; repos with dirty worktree prompts + ;; when updating packages or "Local + ;; variables entry is missing the + ;; suffix" errors when installing them + ;; (see #2637), so have git handle + ;; conversion by force. + (when (and doom--system-windows-p (stringp repo-dir)) + (let ((default-directory repo-dir)) + (when (file-in-directory-p default-directory straight-base-dir) + (straight--process-run "git" "config" "core.autocrlf" "true"))))) + straight-vc-git-post-clone-hook))) + (straight-use-package (intern package)) + ;; HACK: Straight can sometimes fail to clone a repo, + ;; leaving behind an empty directory which, in future + ;; invocations, it will assume indicates a successful + ;; clone (causing load errors later). + (let ((try 0)) + (while (or (not (file-directory-p repo-dir)) + (directory-empty-p repo-dir)) + (when (= try 3) + (error "Failed to clone package")) + (print! "Failed to clone %S, trying again (attempt #%d)..." package (1+ try)) + (delete-directory repo-dir t) + (delete-directory build-dir t) + (straight-use-package (intern package)) + (cl-incf try)))) + (error + (signal 'doom-package-error (list package e))))))) + (progn + (when (featurep 'native-compile) + (doom-packages--compile-site-files) + (doom-packages--wait-for-native-compile-jobs) + (doom-packages--write-missing-eln-errors)) + ;; HACK: Every time you save a file in a package that straight + ;; tracks, it is recorded in ~/.emacs.d/.local/straight/modified/. + ;; Typically, straight will clean these up after rebuilding, but + ;; Doom's use-case circumnavigates that, leaving these files there + ;; and causing a rebuild of those packages each time `doom sync' + ;; or similar is run, so we clean it up ourselves: + (delete-directory (straight--modified-dir) 'recursive) + (print! (success "\033[KBuilt %d package(s)") (length built))) + (print! (item "No packages need attention")) + nil)))) -(defun doom-packages-update () +(defun doom-packages-update (&optional pinned-only-p) "Updates packages." (doom-initialize-packages) (doom-packages--barf-if-incomplete) - (doom-packages--cli-recipes-update) (let* ((repo-dir (straight--repos-dir)) (pinned (doom-package-pinned-list)) (recipes (doom-package-recipe-list)) @@ -397,9 +378,10 @@ declaration) or dependency thereof that hasn't already been." (repos-to-rebuild (make-hash-table :test 'equal)) (total (length recipes)) (esc (unless init-file-debug "\033[1A")) - (i 0) - errors) - (print! (start "Updating packages (this may take a while)...")) + (i 0)) + (if pinned-only-p + (print! (start "Updating pinned packages...")) + (print! (start "Updating all packages (this may take a while)..."))) (doom-packages--with-recipes recipes (recipe package type local-repo) (cl-incf i) (print-group! @@ -412,11 +394,13 @@ declaration) or dependency thereof that hasn't already been." (cl-return)) (let ((default-directory (straight--repos-dir local-repo))) (unless (file-in-directory-p default-directory repo-dir) - (print! (warn "(%d/%d) Skipping %s because it is local") i total package) + (print! (warn "(%d/%d) Skipping %s because it is out-of-tree...") i total package) (cl-return)) (when (eq type 'git) (unless (file-exists-p ".git") (error "%S is not a valid repository" package))) + (when (and pinned-only-p (not (assoc local-repo pinned))) + (cl-return)) (condition-case-unless-debug e (let ((ref (straight-vc-get-commit type local-repo)) (target-ref @@ -430,13 +414,6 @@ declaration) or dependency thereof that hasn't already been." (doom-packages--straight-with (straight-vc-fetch-from-remote recipe) (when .it (straight-merge-package package) - ;; (condition-case e - ;; (straight-merge-package package) - ;; (wrong-type-argument - ;; (if (not (equal (cdr e) '(arrayp nil))) - ;; (signal (car e) (cdr e)) - ;; (delete-directory (straight--build-dir local-repo) t) - ;; (straight-use-package (intern package))))) (setq target-ref (straight-vc-get-commit type local-repo)) (setq output (doom-packages--commit-log-between ref target-ref) commits (length (split-string output "\n" t))) @@ -464,7 +441,7 @@ declaration) or dependency thereof that hasn't already been." (straight-vc-git-default-clone-depth 'full)) (delete-directory repo 'recursive) (print-group! - (straight-use-package (intern package) nil 'no-build)) + (straight-use-package (intern package) nil 'no-build)) (prog1 (file-directory-p repo) (or (not (eq type 'git)) (setq output (doom-packages--commit-log-between ref target-ref) @@ -520,13 +497,14 @@ declaration) or dependency thereof that hasn't already been." (princ "\033[K") (if (hash-table-empty-p packages-to-rebuild) (ignore (print! (success "All %d packages are up-to-date") total)) + (doom-packages--cli-recipes-update) (straight--transaction-finalize) (let ((default-directory (straight--build-dir))) (mapc (doom-rpartial #'delete-directory 'recursive) (hash-table-keys packages-to-rebuild))) (print! (success "Updated %d package(s)") (hash-table-count packages-to-rebuild)) - (doom-packages-build) + (doom-packages-ensure) t)))) diff --git a/lisp/cli/sync.el b/lisp/cli/sync.el index 5b042d3bb..f74a97923 100644 --- a/lisp/cli/sync.el +++ b/lisp/cli/sync.el @@ -14,18 +14,21 @@ (defvar doom-before-sync-hook () "Hooks run before 'doom sync' synchronizes the user's config with Doom.") +(defvar doom-cli-sync-info-file (file-name-concat doom-profile-data-dir "sync")) + ;; ;;; Commands -(defcli-alias! (:before (sync s)) (:before build)) - (defcli! ((sync s)) ((noenvvar? ("-e") "Don't regenerate the envvar file") - (noelc? ("-c") "Don't recompile config") - (update? ("-u") "Update installed packages after syncing") - (purge? ("-p") "Purge orphaned package repos & regraft them") - (jobs ("-j" "--jobs" num) "How many CPUs to use for native compilation")) + (update? ("-u") "Update all installed packages after syncing") + (noupdate? ("-U") "Don't update any packages") + (purge? ("--gc") "Purge orphaned package repos & regraft them") + (jobs ("-j" "--jobs" num) "How many threads to use for native compilation") + (rebuild? ("-b" "--rebuild") "Rebuild, compile, & symlink installed packages") + (auto? ("-B") "Rebuild packages, but only if necessary") + &context context) "Synchronize your config with Doom Emacs. This is the equivalent of running autoremove, install, autoloads, then @@ -33,8 +36,10 @@ recompile. Run this whenever you: 1. Modify your `doom!' block, 2. Add or remove `package!' blocks to your config, - 3. Add or remove autoloaded functions in module autoloaded files. - 4. Update Doom outside of Doom (e.g. with git) + 3. Add or remove autoloaded functions in module autoloaded files, + 4. Update Doom outside of Doom (e.g. with git), + 5. Move your Doom config (either $EMACSDIR or $DOOMDIR) to a new location. + 6. When you up (or down) grade Emacs itself. It will ensure that unneeded packages are removed, all needed packages are installed, autoloads files are up-to-date and no byte-compiled files have gone @@ -47,26 +52,45 @@ OPTIONS: :benchmark t (when (doom-profiles-bootloadable-p) (call! '(profiles sync "--reload"))) - (run-hooks 'doom-before-sync-hook) - (add-hook 'kill-emacs-hook #'doom-sync--abort-warning-h) + (when (doom-cli-context-suppress-prompts-p context) + (setq auto? t)) (when jobs (setq native-comp-async-jobs-number (truncate jobs))) - (print! (start "Synchronizing %S profile..." ) - (or (car doom-profile) "default")) + (run-hooks 'doom-before-sync-hook) + (add-hook 'kill-emacs-hook #'doom-sync--abort-warning-h) + (print! (item "Using Emacs %s @ %s") emacs-version (path invocation-directory invocation-name)) + (print! (start "Synchronizing %S profile..." ) (or (car doom-profile) "default")) (unwind-protect (print-group! - (when (and (not noenvvar?) - (file-exists-p doom-env-file)) - (call! '(env))) - (doom-packages-install) - (doom-packages-build) - (when update? - (doom-packages-update)) - (doom-packages-purge purge? purge? purge? purge? purge?) - (when (doom-profile-generate) - (print! (item "Restart Emacs or use 'M-x doom/reload' for changes to take effect")) - (run-hooks 'doom-after-sync-hook)) - t) + ;; If the user has up/downgraded Emacs since last sync, or copied their + ;; config to a different system, then their packages need to be + ;; recompiled. This is necessary because Emacs byte-code is not + ;; necessarily back/forward compatible across major versions, and many + ;; packages bake in hardcoded data at compile-time. + (pcase-let ((`(,old-version . ,old-host) (doom-file-read doom-cli-sync-info-file :by 'read :noerror t)) + (to-rebuild nil)) + (when (and old-version (not (equal old-version emacs-version))) + (print! (warn "Emacs version has changed since last sync (from %s to %s)") old-version emacs-version) + (setq to-rebuild t)) + (when (and old-host (not (equal old-host (system-name)))) + (print! (warn "Your system has changed since last sync")) + (setq to-rebuild t)) + (when (and to-rebuild (not auto?)) + (or (y-or-n-p + (format! " %s" "Your installed packages will need to be recompiled. Do so now?")) + (exit! 0)) + (setq rebuild? t))) + (when (and (not noenvvar?) + (file-exists-p doom-env-file)) + (call! '(env))) + (doom-packages-ensure rebuild?) + (unless noupdate? (doom-packages-update (not update?))) + (doom-packages-purge purge? purge? purge? purge? purge?) + (when (doom-profile-generate) + (print! (item "Restart Emacs or use 'M-x doom/reload' for changes to take effect")) + (run-hooks 'doom-after-sync-hook)) + (with-temp-file doom-cli-sync-info-file (prin1 (cons emacs-version (system-name)) (current-buffer))) + t) (remove-hook 'kill-emacs-hook #'doom-sync--abort-warning-h))) diff --git a/lisp/cli/upgrade.el b/lisp/cli/upgrade.el index f8584a583..9f44d6e93 100644 --- a/lisp/cli/upgrade.el +++ b/lisp/cli/upgrade.el @@ -3,7 +3,6 @@ ;;; Code: (load! "packages") -(load! "compile") ;; @@ -33,7 +32,7 @@ following shell commands: doom clean doom sync -u" (let* ((force? (doom-cli-context-suppress-prompts-p context)) - (sync-cmd (append '("sync" "-u") (if jobs `("-j" ,num))))) + (sync-cmd (append '("sync" "-u" "-B") (if jobs `("-j" ,num))))) (cond (packages? ;; HACK It's messy to use straight to upgrade straight, due to the diff --git a/lisp/doom-cli.el b/lisp/doom-cli.el index 7d5bff2f7..eab017d69 100644 --- a/lisp/doom-cli.el +++ b/lisp/doom-cli.el @@ -1783,7 +1783,7 @@ See `defcli!' for information about COMMANDSPEC. TARGET is simply a command list. WHEN specifies what version this command was rendered obsolete." `(let ((ncommand (doom-cli-command-normalize (backquote ,target) doom-cli--group-plist))) - (defcli! ,commandspec (&context context &cli cli &rest args) + (defcli! ,commandspec (&context _context &cli cli &rest args) :docs (format "An obsolete alias for '%s'." (doom-cli-command-string ncommand)) :hide t (print! (warn "'%s' was deprecated in %s") diff --git a/lisp/doom-keybinds.el b/lisp/doom-keybinds.el index a448e89c8..856ea72bb 100644 --- a/lisp/doom-keybinds.el +++ b/lisp/doom-keybinds.el @@ -15,6 +15,12 @@ "An alternative leader prefix key, used for Insert and Emacs states, and for non-evil users.") +(defvar doom-leader-key-states '(normal visual motion) + "which evil modes to activate the leader key for") + +(defvar doom-leader-alt-key-states '(emacs insert) + "which evil modes to activate the alternative leader key for") + (defvar doom-localleader-key "SPC m" "The localleader prefix key, for major-mode specific commands.") @@ -259,12 +265,9 @@ localleader prefix." (set-keymap-parent doom-leader-map mode-specific-map)) ((equal doom-leader-alt-key "C-x") (set-keymap-parent doom-leader-map ctl-x-map))) - (define-key map (kbd doom-leader-alt-key) #'doom-leader-map) - (define-key map (kbd doom-localleader-alt-key) #'doom-localleader-map)) - (evil-define-key* '(normal visual motion) map (kbd doom-leader-key) #'doom-leader-map) - (evil-define-key* '(emacs insert) map (kbd doom-leader-alt-key) #'doom-leader-map) - (evil-define-key* '(normal visual motion) map (kbd doom-localleader-key) #'doom-localleader-map) - (evil-define-key* '(emacs insert) map (kbd doom-localleader-alt-key) #'doom-localleader-map)) + (define-key map (kbd doom-leader-alt-key) 'doom/leader)) + (evil-define-key* doom-leader-key-states map (kbd doom-leader-key) 'doom/leader) + (evil-define-key* doom-leader-alt-key-states map (kbd doom-leader-alt-key) 'doom/leader)) (general-override-mode +1)))) diff --git a/lisp/doom-projects.el b/lisp/doom-projects.el index 4d434e32d..ad498b5da 100644 --- a/lisp/doom-projects.el +++ b/lisp/doom-projects.el @@ -23,6 +23,10 @@ debian, and derivatives). On most it's 'fd'.") ;; ;;; Packages +(after! project + (setq project-list-file (file-name-concat doom-data-dir "projects"))) + +;; DEPRECATED: Will be replaced with project.el (use-package! projectile :commands (projectile-project-root projectile-project-name diff --git a/lisp/lib/print.el b/lisp/lib/print.el index 2a0dffaf2..e74c7fce6 100644 --- a/lisp/lib/print.el +++ b/lisp/lib/print.el @@ -84,7 +84,8 @@ and `format!' into colored output, where COLOR is any car of this list (or (doom-print--indent (if args (apply #'format str args) str) "> "))) - (path . abbreviate-file-name) + (path . (lambda (&rest segments) + (abbreviate-file-name (apply #'doom-path segments)))) (symbol . symbol-name) (relpath . (lambda (str &optional dir) (if (or (not str) diff --git a/lisp/packages.el b/lisp/packages.el index dd908a10d..748c7faad 100644 --- a/lisp/packages.el +++ b/lisp/packages.el @@ -2,8 +2,13 @@ ;;; lisp/packages.el ;; doom.el -(package! auto-minor-mode :pin "17cfa1b54800fdef2975c0c0531dad34846a5065") -(package! gcmh :pin "0089f9c3a6d4e9a310d0791cf6fa8f35642ecfd9") +(package! auto-minor-mode + :pin "17cfa1b54800fdef2975c0c0531dad34846a5065") +(package! compat + :recipe (:host github :repo "emacs-compat/compat") + :pin "8d4e8a366681def88751f5e9975738ecd3180deb") +(package! gcmh + :pin "0089f9c3a6d4e9a310d0791cf6fa8f35642ecfd9") ;; doom-packages.el (package! straight @@ -13,10 +18,10 @@ :branch ,straight-repository-branch :local-repo "straight.el" :files ("straight*.el")) - :pin "b3760f5829dba37e855add7323304561eb57a3d4") + :pin "b1062df10ba4c10ff7a3c61b9e124b3242b11bb2") ;; doom-ui.el -(package! nerd-icons :pin "c6a4acf19454b415cba1c43daf4bfca8fccdd9ba") +(package! nerd-icons :pin "8095215a503d8048739de8b4ea4066598edb8cbb") (package! hide-mode-line :pin "bc5d293576c5e08c29e694078b96a5ed85631942") (package! highlight-numbers :pin "8b4744c7f46c72b1d3d599d4fb75ef8183dee307") (package! rainbow-delimiters :pin "f40ece58df8b2f0fb6c8576b527755a552a5e763") @@ -24,10 +29,10 @@ ;; doom-editor.el (package! better-jumper :pin "47622213783ece37d5337dc28d33b530540fc319") -(package! dtrt-indent :pin "0230ec503283b895bd3df6c1e30b35a01aa0b9af") +(package! dtrt-indent :pin "5d1b44f9a1a484ca229cc14f8062609a10ef4891") (package! helpful :pin "a32a5b3d959a7fccf09a71d97b3d7c888ac31c69") -(package! pcre2el :pin "018531ba0cf8e2b28d1108136a0e031b6a45f1c1") -(package! smartparens :pin "0778a8a84064cf2bc3a9857bd0e7a4619cc1e5c3") +(package! pcre2el :pin "380723b2701cceb75c266440fb8db918f3340d50") +(package! smartparens :pin "ddc6233ea6fc2da7a3a8e44face465c15631b02b") (package! ws-butler ;; Use my fork of ws-butler, which has a few choice improvements and ;; optimizations (the original has been abandoned). @@ -35,13 +40,9 @@ :pin "572a10c11b6cb88293de48acbb59a059d36f9ba5") ;; doom-projects.el -(package! projectile :pin "e45f0b0cc43fdc066e7971ff3ed3bf4c78015ed0") -(package! project :pin "10a6b691e36ff897fb2a4b48896e08818afa77b0") +(package! projectile :pin "0163b335a18af0f077a474d4dc6b36e22b5e3274") +(package! project :pin "b6989856abe9411872bdff5c8aa190bef4d86409") ;; doom-keybinds.el -(package! general :pin "bda777cd303db217fd2fbf2087eff40ec4aafda1") -(package! which-key :pin "4d20bc852545a2e602f59084a630f888542052b1") - -(package! compat - :recipe (:host github :repo "emacs-compat/compat") - :pin "eb8fbfa5582a8e5880e2eaa66d15d498bca6a45a") +(package! general :pin "ced143c30de8e20f5a3761a465e684a1dc48471e") +(package! which-key :pin "96911a1d3faf8426a33241f4821319e98421f380") diff --git a/modules/app/everywhere/config.el b/modules/app/everywhere/config.el index d0512f754..9f5052784 100644 --- a/modules/app/everywhere/config.el +++ b/modules/app/everywhere/config.el @@ -36,7 +36,7 @@ (doom-modeline-def-modeline 'emacs-everywhere '(bar modals emacs-everywhere buffer-position word-count parrot selection-info) - '(input-method major-mode checker + '(input-method major-mode check #(" " 0 1 ; "Exit to app" icon + a little padding (rear-nonsticky t display (raise -0.25) diff --git a/modules/completion/vertico/config.el b/modules/completion/vertico/config.el index 098e01835..2e4dc5bf5 100644 --- a/modules/completion/vertico/config.el +++ b/modules/completion/vertico/config.el @@ -199,10 +199,13 @@ orderless." (use-package! consult-dir - :bind (([remap list-directory] . consult-dir) + :defer t + :init + (map! [remap list-directory] #'consult-dir + (:after vertico :map vertico-map - ("C-x C-d" . consult-dir) - ("C-x C-j" . consult-dir-jump-file)) + "C-x C-d" #'consult-dir + "C-x C-j" #'consult-dir-jump-file)) :config (when (modulep! :tools docker) ;; TODO: Replace with `tramp-container--completion-function' when we drop diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index d79c6e084..35b3f1f99 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -432,10 +432,11 @@ ;;; c --- code (:prefix-map ("c" . "code") (:when (and (modulep! :tools lsp) (not (modulep! :tools lsp +eglot))) - :desc "LSP" "l" #'+default/lsp-command-map :desc "LSP Execute code action" "a" #'lsp-execute-code-action :desc "LSP Organize imports" "o" #'lsp-organize-imports + :desc "LSP" "l" #'+default/lsp-command-map :desc "LSP Rename" "r" #'lsp-rename + :desc "Symbols" "S" #'lsp-treemacs-symbols (:when (modulep! :completion ivy) :desc "Jump to symbol in current workspace" "j" #'lsp-ivy-workspace-symbol :desc "Jump to symbol in any workspace" "J" #'lsp-ivy-global-workspace-symbol) @@ -449,10 +450,7 @@ :desc "Errors list" "X" #'lsp-treemacs-errors-list :desc "Incoming call hierarchy" "y" #'lsp-treemacs-call-hierarchy :desc "Outgoing call hierarchy" "Y" (cmd!! #'lsp-treemacs-call-hierarchy t) - :desc "References tree" "R" (cmd!! #'lsp-treemacs-references t) - :desc "Symbols" "S" #'lsp-treemacs-symbols - :desc "LSP" "l" #'+default/lsp-command-map - :desc "LSP Rename" "r" #'lsp-rename)) + :desc "References tree" "R" (cmd!! #'lsp-treemacs-references t))) (:when (modulep! :tools lsp +eglot) :desc "LSP Execute code action" "a" #'eglot-code-actions :desc "LSP Rename" "r" #'eglot-rename diff --git a/modules/tools/docker/README.org b/modules/tools/docker/README.org index 3af7085c8..bc42c463d 100644 --- a/modules/tools/docker/README.org +++ b/modules/tools/docker/README.org @@ -95,14 +95,8 @@ C-x C-f /docker:$USER@$CONTAINER:/path/to/file Thanks to [[https://github.com/magit/magit-popup][magit-popup]], all the popups default arguments can be customized. For example, here is how to customize the arguments for =docker-image-run-popup=: #+begin_src emacs-lisp -(setq docker-image-run-arguments '("-i" "-t" "--rm")) -#+end_src - -or inside a =use-package= declaration: -#+begin_src emacs-lisp -(use-package! docker - :bind ("C-c d" . docker) - :custom (docker-image-run-arguments '("-i" "-t" "--rm"))) +(after! docker + (setq docker-image-run-arguments '("-i" "-t" "--rm"))) #+end_src *** Other useful variables diff --git a/modules/tools/tree-sitter/packages.el b/modules/tools/tree-sitter/packages.el index db244eba5..fbd858c50 100644 --- a/modules/tools/tree-sitter/packages.el +++ b/modules/tools/tree-sitter/packages.el @@ -2,9 +2,9 @@ ;;; tools/tree-sitter/packages.el (package! tree-sitter :pin "3cfab8a0e945db9b3df84437f27945746a43cc71") -(package! tree-sitter-langs :pin "20fbbb85735a9196ba3e7fb33f99b3a904b363ba") +(package! tree-sitter-langs :pin "c56cb511045d50e30f78508c54494e025d6af2cb") (package! tree-sitter-indent :pin "4ef246db3e4ff99f672fe5e4b416c890f885c09e") (when (modulep! :editor evil +everywhere) (package! evil-textobj-tree-sitter - :pin "220ceae065852ef4f717fa41efd1ab51ca2346d3")) + :pin "a19ab9d89a00f4a04420f9b5d61b66f04fea5261")) diff --git a/modules/ui/deft/packages.el b/modules/ui/deft/packages.el index ba3427f57..459447348 100644 --- a/modules/ui/deft/packages.el +++ b/modules/ui/deft/packages.el @@ -1,4 +1,4 @@ ;; -*- no-byte-compile: t; -*- ;;; ui/deft/packages.el -(package! deft :pin "28be94d89bff2e1c7edef7244d7c5ba0636b1296") +(package! deft :pin "bb1a16b87c3e0fe70fade6227e47dd7712b89bf6") diff --git a/modules/ui/doom/packages.el b/modules/ui/doom/packages.el index 15cc260ba..744147bf2 100644 --- a/modules/ui/doom/packages.el +++ b/modules/ui/doom/packages.el @@ -1,5 +1,5 @@ ;; -*- no-byte-compile: t; -*- ;;; ui/doom/packages.el -(package! doom-themes :pin "ff26f26ea3d761375f5fc4070438fbd0f3473d33") +(package! doom-themes :pin "37d2182f5078d29fb22bbace346e523bb84b2c4e") (package! solaire-mode :pin "8af65fbdc50b25ed3214da949b8a484527c7cc14") diff --git a/modules/ui/modeline/README.org b/modules/ui/modeline/README.org index 128babe4f..f472fa83e 100644 --- a/modules/ui/modeline/README.org +++ b/modules/ui/modeline/README.org @@ -96,7 +96,7 @@ Some possible solutions: (after! doom-modeline (doom-modeline-def-modeline 'main '(bar matches buffer-info remote-host buffer-position parrot selection-info) - '(misc-info minor-modes checker input-method buffer-encoding major-mode process vcs " "))) ; <-- added padding here + '(misc-info minor-modes check input-method buffer-encoding major-mode process vcs " "))) ; <-- added padding here #+end_src 2. Use another font for the mode line (or a different ~:height~) (source) diff --git a/modules/ui/modeline/packages.el b/modules/ui/modeline/packages.el index 8bdce9b70..1bc523b24 100644 --- a/modules/ui/modeline/packages.el +++ b/modules/ui/modeline/packages.el @@ -2,7 +2,7 @@ ;;; ui/modeline/packages.el (unless (modulep! +light) - (package! doom-modeline :pin "bf880ae56f3f6aab7bd334de9bd9b455c63a24c0")) + (package! doom-modeline :pin "e09b8e989fa5fc1d98320aaa29d7138631b20ae5")) (package! anzu :pin "26fb50b429ee968eb944b0615dd0aed1dd66172c") (when (modulep! :editor evil) (package! evil-anzu :pin "d1e98ee6976437164627542909a25c6946497899")) diff --git a/modules/ui/treemacs/packages.el b/modules/ui/treemacs/packages.el index 59c5fbdea..123adc09c 100644 --- a/modules/ui/treemacs/packages.el +++ b/modules/ui/treemacs/packages.el @@ -1,7 +1,7 @@ ;; -*- no-byte-compile: t; -*- ;;; ui/treemacs/packages.el -(package! treemacs :pin "df26b6ab9a0f467e5ff99f7ed97551ccf756e06c") +(package! treemacs :pin "8c6df39f01a4d47fda2cc943645fa067f771b748") (package! treemacs-nerd-icons :pin "9876cb478145a0ec4e36f64ff6583f3de7126216") ;; These packages have no :pin because they're in the same repo (when (modulep! :editor evil +everywhere) diff --git a/modules/ui/vc-gutter/packages.el b/modules/ui/vc-gutter/packages.el index 2651562a6..3ed651912 100644 --- a/modules/ui/vc-gutter/packages.el +++ b/modules/ui/vc-gutter/packages.el @@ -2,5 +2,5 @@ ;;; ui/vc-gutter/packages.el (if (modulep! +diff-hl) - (package! diff-hl :pin "b8b2727a72fdf64ac98e6cfa136a43cb0cacf72f") + (package! diff-hl :pin "96620839430c1205cbb8c92dd54973397f70f9d2") (package! git-gutter-fringe :pin "648cb5b57faec55711803cdc9434e55a733c3eba"))