diff --git a/CHANGELOG.org b/CHANGELOG.org index 07df83255..36df225df 100644 --- a/CHANGELOG.org +++ b/CHANGELOG.org @@ -11,12 +11,19 @@ * Unreleased (develop) + *Module changes:* - + Split =lang/java= into two submodules: one for eclim, and another for - meghanada. The latter is still the default, however. Also, the eclim + + *BREAKING* Split =lang/java= into two submodules: one for eclim, and another for + meghanada. You will need to update your =init.el= to enable one. submodule is experimental, since I have few opportunities to test it. - + Add =ui/window-select= (and moved ace-window out of ~core-ui~), which offers - two submodules for interactive window selection/moving: ace-window and - switch-window. + + *BREAKING* Ace-window is no longer part of Doom core. It has been moved to + =ui/window-select=, which offers two submodules for interactive window + selection/moving: ace-window and switch-window. + + New module: =lang/nix=, adds support for editing nix configuration files. + Contributed by [[https://github.com/ocharles][ocharles]]. + + The =org/*= modules have been moved to =lang/org= and sub-modules therein. + With the introduction of module flags in 2.0.5, it was unnecessary that + org-mode had its own category. + + Any module can now have an =init.el=, which will be loaded before any other + modules are loaded. + =general= + New command naming convention: ~doom//...~ -- denotes that this an interactive command meant for: @@ -28,6 +35,17 @@ + Autoload files can now specify a predicate cookie to tell the compiler/autoload reader whether or not to ignore that file. They look like ~;;;###if (featurep! :feature evil)~. + + Removed all core def-setting! definitions, because ~set!~ was intended for + cross-module configuration, where modules may or may not be enabled. This + consideration is unnecessary for Doom core configuration. The following + settings have been removed: ~:editorconfig~, ~:theme~, ~:font~, + ~:variable-font~, ~:unicode-font~, ~:big-font~. + + Address various byte-compiler warnings that crop up in Emacs 26+, including + obsolete (if|when)-let macro warnings. + + Fix byte-compiler complaining that packages couldn't be found when that + package is unwanted (e.g. conditionally installed or disabled packages). + + =private/{user-login-name}= is no longer a "magic" module that is + automatically loaded. + =core-keybinds= Add :g flag to ~map!~ for defining global keybinds along with vim keybinds, so you don't have to repeat yourself, just for a global binding. @@ -36,15 +54,50 @@ (e.g. ELPA), and whose ~package!~ definition was later changed so that it should be handled by another (e.g. QUELPA). This would cause "FAILED" error messages while trying to install or update these packages (see [[https://github.com/hlissner/doom-emacs/issues/222][#222]]). + + =core-packages= *BREAKING* Packages are no longer deferred by default. i.e. + ~use-package-always-defer~ is now nil, as per the default. + + =core-popup= Fix window-live-p error when using ~doom/other-popup~ (or its + alias, ~other-popup~). + + =core-ui= Fix hl-line highlighting the rest of the window past end-of-file + in Emacs 26+. This is caused by a strange dynamic between hl-line and the + new line numbers feature. + =feature= + =file-templates= Disable file templates for .dir-locals.el files. + =jump= New command ~+jump/online-select~, which is like ~+jump/online~, but will always prompt for which provider to use. + + =version-control= Fix an issue with shackle not managing magit's popups + properly. This could cause the pointer to end up in the wrong places (e.g. + when you try to commit; the commit message and diff buffers pop up and the + pointer gets stuck in the diff window) (see [[https://github.com/hlissner/doom-emacs/issues/282][#282]]). ++ =completion= + + =helm= Implement ~:agcwd~, ~:rg~, and ~:rgcwd~ commands for searching with + helm. + + =ivy= + + Add C-SPC binding for "previewing" the selected candidate. Useful for + previewing files in ~counsel-find-file~ or ~counsel-projectile-find-file~. + This keybinding is defined in =private/hlissner/+bindings.el=. + + Disable "very magic" regular expressions in ivy. Specifically, parentheses + are now literal, and must be escaped to make them special. This is + consistent with evil-search regex. + + Fix a bug where ~:rgcwd~ wasn't showing any results, due to an incorrect + option argument in the ripgrep command string. + =ui= + =doom= This module no longer sets a default font. This is left to the user to set in their own private module. Use ~(set! :font "Font Name" :size N)~ to do so. + + =doom-modeline= Remove the let-binds for ~all-the-icons-scale-factor~, so + that users can customize it themselves (see [[https://github.com/hlissner/doom-emacs/issues/278][#278]]). ++ =tools= + + =password-store= Fix compatibility with Emacs 26. + =lang= + + =clojure= + + This module has been rewritten with improved Cider and clojurescript + support, as well as new refactoring commands. Thanks to [[https://github.com/teesloane][teesloane]]! + + =crystal= + + Add flycheck integration for the Crystal language, powered by + ~flycheck-crystal~. + + Use the ELPA source for ~crystal-mode~. The former QUELPA source + (dotmilk's fork) is no longer maintained. + =sh= + Improve how variables and subshells in double-quoted strings are fontified. @@ -52,6 +105,18 @@ + =java= + Polished meghanada-mode integration. + New (and optional) +eclim submodule and module flag. + + =org= + + Fix scenario where built-in (and incorrect) version of org-mode (8.x) was loaded + instead of 9.0+. + + This module is incredibly opinionated. More opinionated than I'd like, but + org-mode is an ongoing effort. To address this, =lang/org= has been + reorganized. Variables are now set with ~defvar~ instead of ~setq~, which + makes them more accessible for configuring from private modules. + + Use the ELPA source for ~ob-rust~. The former QUELPA source (zweifisch's + fork) is no longer maintained. + + Fix an over-aggressive smartparens config for org-mode that would cause + certain markers and delimiters (like spaces or square brackets) being + repeated in places you didn't want them to be, like inside a checkbox. + =rust= + Now checks the ~RUST_SRC_PATH~ environment variable before looking for Rust's source in ~+rust-src-dir~. diff --git a/Makefile b/Makefile index a53dc66e3..937fbd275 100644 --- a/Makefile +++ b/Makefile @@ -67,7 +67,7 @@ test-core $(patsubst %, test-%, $(MODULES)): init.el .local/autoloads.el # run tests interactively testi: init.el .local/autoloads.el - @$(EMACSI) -f doom//run-tests -f ert + @$(EMACSI) -f doom//run-tests ## Utility tasks diff --git a/core/autoload/buffers.el b/core/autoload/buffers.el index a052c2dd6..0b6815021 100644 --- a/core/autoload/buffers.el +++ b/core/autoload/buffers.el @@ -53,7 +53,7 @@ Inspired from http://demonastery.org/2013/04/emacs-evil-narrow-region/" If no project is active, return all buffers." (let ((buffers (doom-buffer-list))) - (if-let (project-root (if (doom-project-p) (doom-project-root))) + (if-let* ((project-root (if (doom-project-p) (doom-project-root)))) (cl-loop for buf in buffers if (projectile-project-buffer-p buf project-root) collect buf) @@ -148,7 +148,7 @@ real buffer is: c) is not a special buffer (its name isn't something like *Help*) If BUFFER-OR-NAME is omitted or nil, the current buffer is tested." - (when-let (buf (ignore-errors (window-normalize-buffer buffer-or-name))) + (when-let* ((buf (ignore-errors (window-normalize-buffer buffer-or-name)))) (or (buffer-local-value 'doom-real-buffer-p buf) (run-hook-with-args-until-success 'doom-real-buffer-functions buf) (not (or (doom-popup-p buf) diff --git a/core/autoload/debug.el b/core/autoload/debug.el index a6a7597e3..77b48b4c5 100644 --- a/core/autoload/debug.el +++ b/core/autoload/debug.el @@ -60,14 +60,14 @@ selection of all minor-modes, active or not." (interactive) (unless (string-match-p "\\_" system-configuration-features) (warn "gnutls support isn't built into Emacs, there may be problems")) - (if-let (bad-hosts - (cl-loop for bad - in '("https://wrong.host.badssl.com/" - "https://self-signed.badssl.com/") - if (condition-case _e - (url-retrieve bad (lambda (_retrieved) t)) - (error nil)) - collect bad)) + (if-let* ((bad-hosts + (cl-loop for bad + in '("https://wrong.host.badssl.com/" + "https://self-signed.badssl.com/") + if (condition-case _e + (url-retrieve bad (lambda (_retrieved) t)) + (error nil)) + collect bad))) (error (format "tls seems to be misconfigured (it got %s)." bad-hosts)) (url-retrieve "https://badssl.com" diff --git a/core/autoload/menu.el b/core/autoload/menu.el index cd2e2db23..c0ad798f2 100644 --- a/core/autoload/menu.el +++ b/core/autoload/menu.el @@ -12,7 +12,7 @@ PROMPT (a string) and COMMAND (a list of command plists; see `def-menu!').") (completing-read prompt (mapcar #'car commands))) (defun doom--menu-read (prompt commands) - (if-let (choice (funcall doom-menu-display-fn prompt commands)) + (if-let* ((choice (funcall doom-menu-display-fn prompt commands))) (cdr (assoc choice commands)) (user-error "Aborted"))) diff --git a/core/autoload/packages.el b/core/autoload/packages.el index abd4d0696..7fb7356ad 100644 --- a/core/autoload/packages.el +++ b/core/autoload/packages.el @@ -39,7 +39,7 @@ quelpa. Throws an error if NOERROR is nil and the package isn't installed." ((assq name package-alist) 'elpa) ((not noerror) - (error "%s package not installed" name)))) + (error "%s package is not installed" name)))) ;;;###autoload (defun doom-package-outdated-p (name) @@ -48,7 +48,7 @@ list, whose car is NAME, and cdr the current version list and latest version list of the package." (cl-assert (symbolp name) t) (doom-initialize-packages) - (when-let (desc (cadr (assq name package-alist))) + (when-let* ((desc (cadr (assq name package-alist)))) (let* ((old-version (package-desc-version desc)) (new-version (pcase (doom-package-backend name) @@ -57,7 +57,7 @@ list of the package." (dir (expand-file-name (symbol-name name) quelpa-build-dir)) (inhibit-message (not doom-debug-mode)) (quelpa-upgrade-p t)) - (if-let (ver (quelpa-checkout recipe dir)) + (if-let* ((ver (quelpa-checkout recipe dir))) (version-to-list ver) old-version))) ('elpa @@ -115,7 +115,7 @@ If INSTALLED-ONLY-P, only return packages that are installed." (defun doom-get-depending-on (name) "Return a list of packages that depend on the package named NAME." (doom-initialize) - (when-let (desc (cadr (assq name package-alist))) + (when-let* ((desc (cadr (assq name package-alist)))) (mapcar #'package-desc-name (package--used-elsewhere-p desc nil t)))) ;;;###autoload @@ -131,7 +131,7 @@ containing (PACKAGE-SYMBOL OLD-VERSION-LIST NEW-VERSION-LIST). If INCLUDE-FROZEN-P is non-nil, check frozen packages as well. -Used by `doom/packages-update'." +Used by `doom//packages-update'." (let (quelpa-pkgs elpa-pkgs) ;; Separate quelpa from elpa packages (dolist (pkg (doom-get-packages t)) @@ -164,7 +164,7 @@ Used by `doom/packages-update'." "Return a list of symbols representing packages that are no longer needed or depended on. -Used by `doom/packages-autoremove'." +Used by `doom//packages-autoremove'." (doom-initialize-packages t) (let ((package-selected-packages (append (mapcar #'car doom-packages) doom-core-packages))) @@ -183,7 +183,7 @@ the package symbol, and whose CDR is a plist taken from that package's If INCLUDE-IGNORED-P is non-nil, includes missing packages that are ignored, i.e. they have an :ignore property. -Used by `doom/packages-install'." +Used by `doom//packages-install'." (cl-loop for desc in (doom-get-packages) for (name . plist) = desc if (and (or include-ignored-p @@ -255,12 +255,13 @@ example; the package name can be omitted)." (when (doom-package-different-backend-p name) (doom-delete-package name t)) (user-error "%s is already installed" name)) - (let ((plist (or plist (cdr (assq name doom-packages)))) - (inhibit-message (not doom-debug-mode)) - (recipe (plist-get plist :recipe)) - quelpa-upgrade-p) - (cond (recipe (quelpa recipe)) - (t (package-install name))) + (let* ((inhibit-message (not doom-debug-mode)) + (plist (or plist (cdr (assq name doom-packages)))) + (recipe (plist-get plist :recipe)) + quelpa-upgrade-p) + (if recipe + (quelpa recipe) + (package-install name)) (when (package-installed-p name) (cl-pushnew (cons name plist) doom-packages :test #'eq :key #'car) t))) @@ -271,6 +272,8 @@ package.el as appropriate." (doom-initialize) (unless (package-installed-p name) (user-error "%s isn't installed" name)) + (when (doom-package-different-backend-p name) + (user-error "%s's backend has changed and must be uninstalled first" name)) (when (or force-p (doom-package-outdated-p name)) (let ((inhibit-message (not doom-debug-mode)) (desc (cadr (assq name package-alist)))) @@ -288,7 +291,7 @@ package.el as appropriate." (package-compute-transaction () (list (list archive)))))) (package-download-transaction packages)))) (unless (doom-package-outdated-p name) - (when-let (old-dir (package-desc-dir desc)) + (when-let* ((old-dir (package-desc-dir desc))) (when (file-directory-p old-dir) (delete-directory old-dir t))) t)))) @@ -352,7 +355,8 @@ package.el as appropriate." (message! "Installing %s" (car pkg)) (doom--condition-case! (message! " %s%s" - (cond ((package-installed-p (car pkg)) + (cond ((and (package-installed-p (car pkg)) + (not (doom-package-different-backend-p (car pkg)))) (dark (white "ALREADY INSTALLED"))) ((doom-install-package (car pkg) (cdr pkg)) (green "DONE")) @@ -494,7 +498,7 @@ calls." (user-error "All packages are up to date")))) (list (cdr (assq (car (assoc package package-alist)) packages))))) (cl-destructuring-bind (package old-version new-version) pkg - (if-let (desc (doom-package-outdated-p package)) + (if-let* ((desc (doom-package-outdated-p package))) (let ((old-v-str (package-version-join old-version)) (new-v-str (package-version-join new-version))) (if (y-or-n-p (format "%s will be updated from %s to %s. Update?" diff --git a/core/autoload/popups.el b/core/autoload/popups.el index 12617d28b..a182d50c7 100644 --- a/core/autoload/popups.el +++ b/core/autoload/popups.el @@ -4,7 +4,7 @@ (defun doom-popup-p (&optional target) "Return t if TARGET (a window or buffer) is a popup. Uses current window if omitted." - (when-let (target (or target (selected-window))) + (when-let* ((target (or target (selected-window)))) (cond ((bufferp target) (and (buffer-live-p target) (buffer-local-value 'doom-popup-mode target))) @@ -31,7 +31,7 @@ this popup, just the specified properties. Returns the new popup window." (defun doom-popup-switch-to-buffer (buffer) "Switch the current (or closest) pop-up window to BUFFER." (unless (doom-popup-p) - (if-let (popups (doom-popup-windows)) + (if-let* ((popups (doom-popup-windows))) (select-window (car popups)) (error "No popups to switch to"))) (set-window-dedicated-p nil nil) @@ -113,7 +113,7 @@ window parameter." ((or 'above 'below) (window-height window)))) (defun doom--popup-data (window) - (when-let (buffer (window-buffer window)) + (when-let* ((buffer (window-buffer window))) `(,(buffer-name buffer) :file ,(buffer-file-name buffer) :rules ,(window-parameter window 'popup) @@ -167,7 +167,7 @@ Returns t if popups were restored, nil otherwise." (size (plist-get (cdr spec) :size))) (when (and (not buffer) file) (setq buffer - (if-let (buf (get-file-buffer file)) + (if-let* ((buf (get-file-buffer file))) (clone-indirect-buffer (buffer-name buf) nil t) (find-file-noselect file t)))) (when size @@ -212,7 +212,7 @@ If FORCE-P is non-nil (or this function is called interactively), ignore popups' :autoclose property. This command will never close :static popups." (interactive (list (called-interactively-p 'interactive))) - (when-let (popups (doom-popup-windows t)) + (when-let* ((popups (doom-popup-windows t))) (let (success doom-popup-remember-history) (setq doom-popup-history (delq nil (mapcar #'doom--popup-data popups))) (dolist (window popups success) @@ -225,7 +225,7 @@ If FORCE-P is non-nil (or this function is called interactively), ignore popups' "Like `doom/popup-close-all', but kill *all* popups, including :static ones, without leaving any trace behind (muahaha)." (interactive) - (when-let (popups (doom-popup-windows)) + (when-let* ((popups (doom-popup-windows))) (let (doom-popup-remember-history) (setq doom-popup-history nil) (mapc #'delete-window popups)))) @@ -251,7 +251,7 @@ without leaving any trace behind (muahaha)." (defun doom/popup-toggle-messages () "Toggle *Messages* buffer." (interactive) - (if-let (win (get-buffer-window "*Messages*")) + (if-let* ((win (get-buffer-window "*Messages*"))) (doom/popup-close win) (doom-popup-buffer (get-buffer "*Messages*")))) @@ -259,11 +259,11 @@ without leaving any trace behind (muahaha)." (defun doom/other-popup (count) "Cycle through popup windows. Like `other-window', but for popups." (interactive "p") - (if-let (popups (if (doom-popup-p) - (cdr (memq (selected-window) doom-popup-windows)) - (setq doom-popup-other-window (selected-window)) - doom-popup-windows)) - (select-window (nth (mod (1- count) (length popups)) popups)) + (if-let* ((popups (if (doom-popup-p) + (cdr (memq (selected-window) doom-popup-windows)) + (setq doom-popup-other-window (selected-window)) + doom-popup-windows))) + (ignore-errors (select-window (nth (mod (1- count) (length popups)) popups))) (unless (eq (selected-window) doom-popup-other-window) (when doom-popup-other-window (select-window doom-popup-other-window t) @@ -419,6 +419,6 @@ properties." (with-selected-window window (doom-popup-mode -1) (when autokill-p - (when-let (process (get-buffer-process (current-buffer))) + (when-let* ((process (get-buffer-process (current-buffer)))) (set-process-query-on-exit-flag process nil)) (kill-buffer (current-buffer))))))) diff --git a/core/autoload/test.el b/core/autoload/test.el index c8c4035b5..60669a57e 100644 --- a/core/autoload/test.el +++ b/core/autoload/test.el @@ -16,7 +16,7 @@ If neither is available, run all tests in all enabled modules." (doom-initialize-modules nil)) ;; collect targets (cond ((and argv (equal (car argv) "--")) - (cl-loop for arg in argv + (cl-loop for arg in (cdr argv) if (equal arg "core") do (push (expand-file-name "test/" doom-core-dir) targets) else @@ -60,9 +60,9 @@ If neither is available, run all tests in all enabled modules." into items finally do (quiet! (mapc #'load-file items))) ;; run all loaded tests - (when noninteractive - (let (noninteractive) - (ert-run-tests-batch-and-exit)))) + (if noninteractive + (ert-run-tests-batch-and-exit) + (call-interactively #'ert-run-tests-interactively))) ('error (lwarn 'doom-test :error "%s -> %s" diff --git a/core/autoload/ui.el b/core/autoload/ui.el index bec5426bb..912a2bef6 100644 --- a/core/autoload/ui.el +++ b/core/autoload/ui.el @@ -36,8 +36,10 @@ If FORCE-P is omitted when `window-size-fixed' is non-nil, resizing will fail." ;;;###autoload (defun doom/window-zoom () - "Maximize and isolate the current buffer. Activate again to undo this. If the -window changes before then, the undo expires." + "Close other windows to focus on this one. Activate again to undo this. If the +window changes before then, the undo expires. + +Alternatively, use `doom/window-enlargen'." (interactive) (if (and (one-window-p) (assoc ?_ register-alist)) @@ -48,7 +50,8 @@ window changes before then, the undo expires." (defvar doom--window-enlargened nil) ;;;###autoload (defun doom/window-enlargen () - "Enlargen the current window. Activate again to undo." + "Enlargen the current window to focus on this one. Does not close other +windows (unlike `doom/window-zoom') Activate again to undo." (interactive) (setq doom--window-enlargened (if (and doom--window-enlargened diff --git a/core/core-editor.el b/core/core-editor.el index 3e2fcbbcc..4b178e97c 100644 --- a/core/core-editor.el +++ b/core/core-editor.el @@ -47,13 +47,10 @@ modes are active and the buffer is read-only.") (newline-mark ?\n [?¬ ?\n]) (space-mark ?\ [?·] [?.]))) -(defun doom|ediff-use-existing-frame () - "Use existing frame instead of creating a new one." - (setq ediff-diff-options "-w" - ediff-split-window-function #'split-window-horizontally - ;; no extra frames - ediff-window-setup-function #'ediff-setup-windows-plain)) -(add-hook 'ediff-load-hook #'doom|ediff-use-existing-frame) +;; ediff +(setq ediff-diff-options "-w" + ediff-split-window-function #'split-window-horizontally + ediff-window-setup-function #'ediff-setup-windows-plain) (defun doom|dont-kill-scratch-buffer () "Don't kill the scratch buffer." @@ -115,17 +112,6 @@ with functions that require it (like modeline segments)." buffer)) (advice-add #'make-indirect-buffer :around #'doom*set-indirect-buffer-filename) -(defun doom*delete-trailing-whitespace (orig-fn &rest args) - "Don't affect trailing whitespace on current line." - (let ((linestr (buffer-substring-no-properties - (line-beginning-position) - (line-end-position)))) - (apply orig-fn args) - (when (and (if (featurep 'evil) (evil-insert-state-p) t) - (string-match-p "^[\s\t]*$" linestr)) - (insert linestr)))) -(advice-add #'delete-trailing-whitespace :around #'doom*delete-trailing-whitespace) - (push '("/LICENSE$" . text-mode) auto-mode-alist) @@ -150,7 +136,7 @@ with functions that require it (like modeline segments)." ;; Keep track of recently opened files (def-package! recentf - :init (add-hook 'doom-init-hook #'recentf-mode) + :hook (doom-init . recentf-mode) :config (setq recentf-save-file (concat doom-etc-dir "recentf") recentf-max-menu-items 0 @@ -171,18 +157,6 @@ with functions that require it (like modeline segments)." ;; Handles whitespace (tabs/spaces) settings externally. This way projects can ;; specify their own formatting rules. (def-package! editorconfig - :demand t - :init - (def-setting! :editorconfig (action value) - ":add or :remove an entry in `editorconfig-indentation-alist'." - (cond ((eq action :add) - `(push ,value editorconfig-indentation-alist)) - ((eq action :remove) - `(setq editorconfig-indentation-alist - (assq-delete-all ,value editorconfig-indentation-alist))) - (t (error "%s is an invalid action for :editorconfig" - action)))) - :config (add-hook 'doom-init-hook #'editorconfig-mode) @@ -212,10 +186,12 @@ extension, try to guess one." (apply orig-fn args))) (advice-add #'editorconfig-call-editorconfig-exec :around #'doom*editorconfig-smart-detection) - ;; Editorconfig makes indentation weird in Lisp modes, so we disable it. It - ;; still applies other project settings (e.g. tabs vs spaces) though. - (set! :editorconfig :remove 'emacs-lisp-mode) - (set! :editorconfig :remove 'lisp-mode) + ;; Editorconfig makes indentation too rigid in Lisp modes, so tell + ;; editorconfig to ignore indentation. I prefer dynamic indentation support + ;; built into Emacs. + (dolist (mode '(emacs-lisp-mode lisp-mode)) + (setq editorconfig-indentation-alist + (assq-delete-all mode editorconfig-indentation-alist))) (defvar whitespace-style) (defun doom|editorconfig-whitespace-mode-maybe (&rest _) @@ -230,17 +206,16 @@ extension, try to guess one." ;; Auto-close delimiters and blocks as you type (def-package! smartparens - :demand t :config + (add-hook 'doom-init-hook #'smartparens-global-mode) + (require 'smartparens-config) + (setq sp-autowrap-region nil ; let evil-surround handle this sp-highlight-pair-overlay nil sp-cancel-autoskip-on-backward-movement nil sp-show-pair-delay 0 sp-max-pair-length 3) - (add-hook 'doom-init-hook #'smartparens-global-mode) - (require 'smartparens-config) - ;; disable smartparens in evil-mode's replace state (they conflict) (add-hook 'evil-replace-state-entry-hook #'turn-off-smartparens-mode) (add-hook 'evil-replace-state-exit-hook #'turn-on-smartparens-mode) @@ -250,10 +225,8 @@ extension, try to guess one." ;; Branching undo (def-package! undo-tree - :demand t :config - (global-undo-tree-mode +1) - + (add-hook 'doom-init-hook #'global-undo-tree-mode) ;; persistent undo history is known to cause undo history corruption, which ;; can be very destructive! So disable it! (setq undo-tree-auto-save-history nil @@ -288,15 +261,15 @@ extension, try to guess one." :commands (describe-buffer describe-command describe-file describe-keymap describe-option describe-option-of-type)) -(def-package! pcre2el :commands rxt-quote-pcre) +(def-package! pcre2el + :commands rxt-quote-pcre) (def-package! smart-forward :commands (smart-up smart-down smart-backward smart-forward)) (def-package! wgrep :commands (wgrep-setup wgrep-change-to-wgrep-mode) - :config - (setq wgrep-auto-save-buffer t)) + :config (setq wgrep-auto-save-buffer t)) (provide 'core-editor) ;;; core-editor.el ends here diff --git a/core/core-keybinds.el b/core/core-keybinds.el index b2f31fe6f..0b1310017 100644 --- a/core/core-keybinds.el +++ b/core/core-keybinds.el @@ -24,7 +24,6 @@ ;; (def-package! which-key - :demand t :config (setq which-key-sort-order #'which-key-prefix-then-key-order which-key-sort-uppercase-first nil @@ -38,7 +37,6 @@ (def-package! hydra - :demand t :init ;; In case I later need to wrap defhydra in any special functionality. (defalias 'def-hydra! 'defhydra) @@ -271,7 +269,7 @@ Example (dolist (keymap doom--keymaps) (when (memq 'global states) (push `(define-key ,keymap ,key ,def) forms)) - (when-let (states (delq 'global states)) + (when-let* ((states (delq 'global states))) (push `(,(if doom--defer 'evil-define-key 'evil-define-key*) ',states ,keymap ,key ,def) forms)))) diff --git a/core/core-lib.el b/core/core-lib.el index 0ffbca94d..4bf932203 100644 --- a/core/core-lib.el +++ b/core/core-lib.el @@ -1,28 +1,16 @@ ;;; core-lib.el -*- lexical-binding: t; -*- -;; I don't use use-package for these to save on the `fboundp' lookups it does -;; for its :commands property. I use dolists instead of mapc to avoid extra -;; stackframes allocated for lambdas. This is _definitely_ premature -;; optimization. -(dolist (sym '(async-start async-start-process async-byte-recompile-directory - async-inject-variables)) - (autoload sym "async")) - -(dolist (sym '(persistent-soft-exists-p persistent-soft-fetch - persistent-soft-flush persistent-soft-store)) - (autoload sym "persistent-soft")) - -(dolist (sym '(s-center s-pad-left s-pad-right s-truncate s-chop-suffix - s-chop-suffixes s-chop-prefix s-chop-prefixes s-join s-replace - s-replace-all s-capitalize s-titleize s-split-words - s-capitalized-words s-titleized-words)) - (autoload sym "s")) - -(dolist (sym '(when-let if-let string-trim string-join string-blank-p string-lessp)) - (autoload sym "subr-x" nil nil 'macro)) - +(require 'cl-lib) +(require 'subr-x) +(load "async-autoloads" nil t) +(load "persistent-soft-autoloads" nil t) (dolist (sym '(json-read json-read-file json-read-from-string json-encode)) (autoload sym "json")) +(eval-and-compile + (when (version< emacs-version "26") + (with-no-warnings + (defalias 'if-let* #'if-let) + (defalias 'when-let* #'when-let)))) ;; @@ -62,8 +50,8 @@ (if (listp exp) exp (list exp))) (defun doom-resolve-vim-path (file-name) - "Take a path and resolve any vim-like filename modifiers in it. This adds -support for these special modifiers: + "Take a path and resolve any vim-like filename modifiers in it. On top of the +classical vim modifiers, this adds support for: %:P Resolves to `doom-project-root'. @@ -114,7 +102,7 @@ See http://vimdoc.sourceforge.net/htmldoc/cmdline.html#filename-modifiers." (file-relative-name parent))))) ("s" (if (featurep 'evil) - (when-let (args (evil-delimited-arguments (substring flag 1) 2)) + (when-let* ((args (evil-delimited-arguments (substring flag 1) 2))) (let ((pattern (evil-transform-vim-style-regexp (car args))) (replace (cadr args))) (replace-regexp-in-string @@ -162,18 +150,17 @@ compilation." "Run FORMS without making any noise." `(if doom-debug-mode (progn ,@forms) - (fset 'doom--old-write-region-fn (symbol-function 'write-region)) - (cl-letf ((standard-output (lambda (&rest _))) - ((symbol-function 'load-file) (lambda (file) (load file nil t))) - ((symbol-function 'message) (lambda (&rest _))) - ((symbol-function 'write-region) - (lambda (start end filename &optional append visit lockname mustbenew) - (unless visit (setq visit 'no-message)) - (doom--old-write-region-fn - start end filename append visit lockname mustbenew))) - (inhibit-message t) - (save-silently t)) - ,@forms))) + (let ((old-fn (symbol-function 'write-region))) + (cl-letf* ((standard-output (lambda (&rest _))) + ((symbol-function 'load-file) (lambda (file) (load file nil t))) + ((symbol-function 'message) (lambda (&rest _))) + ((symbol-function 'write-region) + (lambda (start end filename &optional append visit lockname mustbenew) + (unless visit (setq visit 'no-message)) + (funcall old-fn start end filename append visit lockname mustbenew))) + (inhibit-message t) + (save-silently t)) + ,@forms)))) (defvar doom--transient-counter 0) (defmacro add-transient-hook! (hook &rest forms) @@ -242,10 +229,9 @@ Body forms can access the hook's arguments through the let-bound variable `(function ,fn) `(lambda (&rest _) ,@args))) (dolist (hook hooks) - (push (cond ((eq hook-fn 'remove-hook) - `(remove-hook ',hook ,fn ,local-p)) - (t - `(add-hook ',hook ,fn ,append-p ,local-p))) + (push (if (eq hook-fn 'remove-hook) + `(remove-hook ',hook ,fn ,local-p) + `(add-hook ',hook ,fn ,append-p ,local-p)) forms))) `(progn ,@(nreverse forms))))) @@ -287,16 +273,19 @@ Body forms can access the hook's arguments through the let-bound variable mode modes match files)))))) -;; I'm a fan of concise, hassle-free front-facing configuration. Rather than -;; littering my config with `after!' blocks, and checking if features and -;; modules are loaded before every line of config, I wrote `set!' as a more -;; robust alternative. If a setting doesn't exist at run-time, the `set!' call -;; is ignored. It also benefits from byte-compilation. +;; I needed a way to reliably cross-configure modules without worrying about +;; whether they were enabled or not, so I wrote `set!'. If a setting doesn't +;; exist at runtime, the `set!' call is ignored (and omitted when +;; byte-compiled). (defvar doom-settings nil) (defmacro def-setting! (keyword arglist &optional docstring &rest forms) - "Define a setting macro. Like `defmacro', this should return a form to be -executed when called with `set!'. FORMS are not evaluated until `set!' calls it." + "Define a setting. Like `defmacro', this should return a form to be executed +when called with `set!'. FORMS are not evaluated until `set!' calls it. + +See `doom/describe-setting' for a list of available settings. + +Do not use this for configuring Doom core." (declare (indent defun) (doc-string 3)) (unless (keywordp keyword) (error "Not a valid property name: %s" keyword)) @@ -308,7 +297,8 @@ executed when called with `set!'. FORMS are not evaluated until `set!' calls it. (cl-pushnew ',(cons keyword fn) doom-settings :test #'eq :key #'car)))) (defmacro set! (keyword &rest values) - "Set an option defined by `def-setting!'. Skip if doesn't exist." + "Set an option defined by `def-setting!'. Skip if doesn't exist. See +`doom/describe-setting' for a list of available settings." (declare (indent defun)) (unless values (error "Empty set! for %s" keyword)) diff --git a/core/core-packages.el b/core/core-packages.el index 4633d99cd..e7013fbc4 100644 --- a/core/core-packages.el +++ b/core/core-packages.el @@ -6,15 +6,15 @@ ;; ;; The three key commands are: ;; -;; + `make install` or `doom/packages-install': Installs packages that are +;; + `make install` or `doom//packages-install': Installs packages that are ;; wanted, but not installed. -;; + `make update` or `doom/packages-update': Updates packages that are +;; + `make update` or `doom//packages-update': Updates packages that are ;; out-of-date. -;; + `make autoremove` or `doom/packages-autoremove': Uninstalls packages that +;; + `make autoremove` or `doom//packages-autoremove': Uninstalls packages that ;; are no longer needed. ;; ;; This system reads packages.el files located in each activated module (and one -;; in `doom-core-dir'). These contain `package!` blocks that tell DOOM what +;; in `doom-core-dir'). These contain `package!' blocks that tell DOOM what ;; plugins to install and where from. ;; ;; Why all the trouble? Because: @@ -42,7 +42,7 @@ ;; + `package-reinstall': `doom/reinstall-package' ;; + `package-delete': `doom/delete-package' ;; + `package-update': `doom/update-package' -;; + `package-autoremove': `doom/packages-autoremove' +;; + `package-autoremove': `doom//packages-autoremove' ;; + `package-refresh-contents': `doom/refresh-packages' ;; ;; See core/autoload/packages.el for more functions. @@ -68,7 +68,7 @@ package's name as a symbol, and whose CDR is the plist supplied to its `package!' declaration. Set by `doom-initialize-packages'.") (defvar doom-core-packages - '(persistent-soft quelpa use-package async) + '(persistent-soft use-package quelpa async) "A list of packages that must be installed (and will be auto-installed if missing) and shouldn't be deleted.") @@ -92,8 +92,7 @@ base by `doom!' and for calculating how many packages exist.") (defvar doom--refreshed-p nil) -(setq load-prefer-newer (or noninteractive doom-debug-mode) - package--init-file-ensured t +(setq package--init-file-ensured t package-user-dir (expand-file-name "elpa" doom-packages-dir) package-enable-at-startup nil package-archives @@ -110,9 +109,6 @@ base by `doom!' and for calculating how many packages exist.") "gnutls-cli -p %p %h" "openssl s_client -connect %h:%p -no_ssl2 -no_ssl3 -ign_eof") - use-package-always-defer t - use-package-always-ensure nil - use-package-debug nil use-package-verbose doom-debug-mode use-package-minimum-reported-time (if doom-debug-mode 0 0.1) @@ -152,9 +148,9 @@ startup." (package-refresh-contents) (setq doom--refreshed-p t) (package-initialize t))) - ;; We could let `package-initialize' fill `load-path', but it costs precious - ;; milliseconds and does other stuff I don't need (like load autoload - ;; files). My premature optimization quota isn't filled yet. + ;; We could let `package-initialize' fill `load-path', but it does more than + ;; that alone (like load autoload files). If you want something prematurely + ;; optimizated right, ya gotta do it yourself. ;; ;; Also, in some edge cases involving package initialization during a ;; non-interactive session, `package-initialize' fails to fill `load-path'. @@ -251,9 +247,10 @@ This aggressively reloads core autoload files." (defun doom-module-from-path (path) "Get module cons cell (MODULE . SUBMODULE) for PATH, if possible." - (when (string-match (concat doom-modules-dir "\\([^/]+\\)/\\([^/]+\\)/") path) - (cons (intern (concat ":" (match-string 1 path))) - (intern (match-string 2 path))))) + (when-let* ((path (file-relative-name (file-truename path) (file-truename doom-modules-dir)))) + (let ((segments (split-string path "/"))) + (cons (intern (concat ":" (car segments))) + (intern (cadr segments)))))) (defun doom-module-paths (&optional append-file) "Returns a list of absolute file paths to activated modules, with APPEND-FILE @@ -263,14 +260,13 @@ added, if the file exists." if (file-exists-p path) collect path)) -(defun doom-module-flags (module submodule) +(defun doom-module-get (module submodule) "Returns a list of flags provided for MODULE SUBMODULE." - (and (hash-table-p doom-modules) - (gethash (cons module submodule) doom-modules))) + (gethash (cons module submodule) doom-modules)) -(defun doom-module-loaded-p (module submodule) +(defun doom-module-enabled-p (module submodule) "Returns t if MODULE->SUBMODULE is present in `doom-modules'." - (and (doom-module-flags module submodule) t)) + (and (doom-module-get module submodule) t)) (defun doom-module-enable (module submodule &optional flags) "Adds MODULE and SUBMODULE to `doom-modules', overwriting it if it exists. @@ -278,9 +274,12 @@ added, if the file exists." MODULE is a keyword, SUBMODULE is a symbol. e.g. :lang 'emacs-lisp. Used by `require!' and `depends-on!'." - (puthash (cons module submodule) - (doom-enlist (or flags t)) - doom-modules)) + (let ((key (cons module submodule))) + (puthash key + (or (doom-enlist flags) + (gethash key doom-modules) + '(t)) + doom-modules))) (defun doom-module-pairs () "Returns `doom-modules' as a list of (MODULE . SUBMODULE) cons cells. The list @@ -312,16 +311,15 @@ include all modules, enabled or otherwise." MODULES is an malformed plist of modules to load." (doom-initialize-modules modules) - (when (and user-login-name - (not (doom-module-loaded-p :private (intern user-login-name)))) - (doom-module-enable :private user-login-name)) `(let (file-name-handler-alist) (setq doom-modules ',doom-modules) (unless noninteractive - (load ,(doom-module-path :private user-login-name "init") t t) ,@(cl-loop for (module . submodule) in (doom-module-pairs) - collect `(require! ,module ,submodule nil t)) + for module-path = (doom-module-path module submodule) + collect `(load! init ,module-path t) into inits + collect `(load! config ,module-path t) into configs + finally return (append inits configs)) (when (display-graphic-p) (require 'server) @@ -332,13 +330,18 @@ MODULES is an malformed plist of modules to load." (message "Doom modules initialized")))) (defmacro def-package! (name &rest plist) - "A thin wrapper around `use-package'. - -Ignores the package if its NAME is present in `doom-disabled-packages'." + "A thin wrapper around `use-package'." + ;; Ignore package if NAME is in `doom-disabled-packages' (when (and (memq name doom-disabled-packages) (not (memq :disabled plist))) (setq plist (append (list :disabled t) plist))) - `(use-package ,name ,@plist)) + ;; If byte-compiling, ignore this package if it doesn't meet the condition. + ;; This avoids false-positive load errors. + (unless (and (bound-and-true-p byte-compile-current-file) + (or (and (plist-member plist :if) (not (eval (plist-get plist :if)))) + (and (plist-member plist :when) (not (eval (plist-get plist :when)))) + (and (plist-member plist :unless) (eval (plist-get plist :unless))))) + `(use-package ,name ,@plist))) (defmacro def-package-hook! (package when &rest body) "Reconfigures a package's `def-package!' block. @@ -404,20 +407,22 @@ If NOERROR is non-nil, don't throw an error if the file doesn't exist." "Loads the module specified by MODULE (a property) and SUBMODULE (a symbol). The module is only loaded once. If RELOAD-P is non-nil, load it again." - (let ((loaded-p (doom-module-loaded-p module submodule))) - (when (or reload-p (not loaded-p)) - (unless loaded-p - (doom-module-enable module submodule flags)) - `(condition-case-unless-debug ex - (load! config ,(doom-module-path module submodule) t) - ('error - (lwarn 'doom-modules :error - "%s in '%s %s' -> %s" - (car ex) ,module ',submodule - (error-message-string ex))))))) + (when (or reload-p (not (doom-module-enabled-p module submodule))) + (let ((module-path (doom-module-path module submodule))) + (if (not (file-directory-p module-path)) + (lwarn 'doom-modules :warning "Couldn't find module '%s %s'" + module submodule) + (doom-module-enable module submodule flags) + `(condition-case-unless-debug ex + (load! config ,module-path t) + ('error + (lwarn 'doom-modules :error + "%s in '%s %s' -> %s" + (car ex) ,module ',submodule + (error-message-string ex)))))))) (defmacro featurep! (module &optional submodule flag) - "A convenience macro wrapper for `doom-module-loaded-p'. It is evaluated at + "A convenience macro wrapper for `doom-module-enabled-p'. It is evaluated at compile-time/macro-expansion time." (unless submodule (let* ((path (or load-file-name byte-compile-current-file)) @@ -428,8 +433,8 @@ compile-time/macro-expansion time." module (car module-pair) submodule (cdr module-pair)))) (if flag - (and (memq flag (doom-module-flags module submodule)) t) - (doom-module-loaded-p module submodule))) + (and (memq flag (doom-module-get module submodule)) t) + (doom-module-enabled-p module submodule))) ;; @@ -466,7 +471,7 @@ Accepts the following properties: (when pkg-pin (plist-put plist :pin nil))) (dolist (prop '(:ignore :freeze)) - (when-let (val (plist-get plist prop)) + (when-let* ((val (plist-get plist prop))) (plist-put plist prop (eval val)))) `(progn (when ,(and pkg-pin t) @@ -495,8 +500,10 @@ loads MODULE SUBMODULE's packages.el file." "Returns the value of the ;;;###if predicate form in FILE." (with-temp-buffer (insert-file-contents-literally file nil 0 256) - (if (re-search-forward "^;;;###if " nil t) - (eval (sexp-at-point)) + (if (and (re-search-forward "^;;;###if " nil t) + (<= (line-number-at-pos) 3)) + (let ((load-file-name file)) + (eval (sexp-at-point))) t))) (defun doom-packages--async-run (fn) @@ -522,8 +529,8 @@ call `doom/reload-load-path' remotely (through emacsclient)." (cond (noninteractive (message "Reloading...") (require 'server) - (when (file-exists-p (if server-use-tcp server-auth-dir server-socket-dir)) - (server-eval-at "server" '(doom//reload-load-path)))) + (when (server-running-p) + (server-eval-at server-name '(doom//reload-load-path)))) (t (doom-initialize t) (message "Reloaded %d packages" (length doom--package-load-path)) @@ -544,9 +551,8 @@ This should be run whenever init.el or an autoload file is modified. Running ;; This function must not use autoloaded functions or external dependencies. ;; It must assume nothing is set up! (if (not noninteractive) - ;; This is done "asynchroniously" to protect the current session's state. - ;; This is because `doom-initialize-packages' rereads your emacs config, - ;; which has side effects. + ;; This is done in another instance to protect the current session's + ;; state. `doom-initialize-packages' will have side effects otherwise. (and (doom-packages--async-run 'doom//reload-autoloads) (load doom-autoload-file)) (doom-initialize-packages) @@ -556,22 +562,21 @@ This should be run whenever init.el or an autoload file is modified. Running (dolist (path (doom-module-paths)) (let ((auto-dir (expand-file-name "autoload" path)) (auto-file (expand-file-name "autoload.el" path))) - (when (and (file-exists-p auto-file) - (doom-packages--read-if-cookies auto-file)) + (when (file-exists-p auto-file) (push auto-file targets)) (when (file-directory-p auto-dir) - (dolist (file (file-expand-wildcards (expand-file-name "*.el" auto-dir) t)) - ;; Make evil*.el autoload files a special case; don't load - ;; them unless evil is enabled. - (when (doom-packages--read-if-cookies file) - (push file targets)))))) + (dolist (file (directory-files-recursively auto-dir "\\.el$")) + (push file targets))))) (when (file-exists-p doom-autoload-file) (delete-file doom-autoload-file) (message "Deleted old autoloads.el")) (dolist (file (reverse targets)) - (message (if (update-file-autoloads file nil doom-autoload-file) - "Nothing in %s" - "Scanned %s") + (message (cond ((not (doom-packages--read-if-cookies file)) + "Ignoring %s") + ((update-file-autoloads file nil doom-autoload-file) + "Nothing in %s") + (t + "Scanned %s")) (file-relative-name file doom-emacs-dir))) (let ((buf (get-file-buffer doom-autoload-file)) current-sexp) @@ -616,9 +621,8 @@ If RECOMPILE-P is non-nil, only recompile out-of-date files." (recompile-p (or recompile-p (and (member "-r" (cdr argv)) t)))) (if (not noninteractive) - ;; This is done "asynchroniously" to protect the current session's - ;; state. This is because `doom-initialize-packages' rereads your emacs - ;; config, which has side effects. + ;; This is done in another instance to protect the current session's + ;; state. `doom-initialize-packages' will have side effects otherwise. (doom-packages--async-run 'doom//byte-compile) (let ((total-ok 0) (total-fail 0) @@ -647,10 +651,9 @@ If RECOMPILE-P is non-nil, only recompile out-of-date files." (let ((elc-file (byte-compile-dest-file target))) (and (file-exists-p elc-file) (file-newer-than-file-p file elc-file)))) - (let ((result (if (and (string-match-p "/autoload/.*\\.el$" target) - (not (doom-packages--read-if-cookies target))) - 'no-byte-compile - (byte-compile-file target))) + (let ((result (if (doom-packages--read-if-cookies target) + (byte-compile-file target) + 'no-byte-compile)) (short-name (file-relative-name target doom-emacs-dir))) (cl-incf (cond ((eq result 'no-byte-compile) @@ -712,7 +715,7 @@ This excludes compiled packages in `doom-packages-dir'.'" (advice-add #'package-delete :after #'doom*package-delete) ;; It isn't safe to use `package-autoremove', so get rid of it -(advice-add #'package-autoremove :override #'doom/packages-autoremove) +(advice-add #'package-autoremove :override #'doom//packages-autoremove) (provide 'core-packages) ;;; core-packages.el ends here diff --git a/core/core-popups.el b/core/core-popups.el index f19d33ae5..210e27fea 100644 --- a/core/core-popups.el +++ b/core/core-popups.el @@ -46,6 +46,9 @@ that was/were open in `doom-popup-history'.") when their associated popup windows are closed, despite their :autokill property.") +(defvar doom-popup-mode-map (make-sparse-keymap) + "Active keymap in popup windows.") + (def-setting! :popup (&rest rules) "Prepend a new popup rule to `shackle-rules' (see for format details). @@ -80,12 +83,28 @@ recognized by DOOM's popup system. They are: `(push (list ,@rules) shackle-rules))) +;; +;; +;; + +(defvar doom-popup-parameters + '(:esc :modeline :transient :fit :align :size) + "TODO") + +(defvar doom-popup-whitelist + '(("^ ?\\*" :size 15 :noselect t :autokill t :autoclose t)) + "TODO") + +(defvar doom-popup-blacklist + '("^\\*magit") + "TODO") + + ;; ;; Bootstrap ;; (def-package! shackle - :demand t :init (setq shackle-default-alignment 'below shackle-default-size 8 @@ -114,7 +133,21 @@ recognized by DOOM's popup system. They are: ("^ ?\\*" :regexp t :size 15 :noselect t :autokill t :autoclose t))) :config - (add-hook 'doom-post-init-hook #'shackle-mode) + ;; NOTE This is a temporary fix while I rewrite core-popups + (defun doom-display-buffer-condition (buffer _action) + (and (cl-loop for re in doom-popup-blacklist + when (string-match-p re buffer) + return nil + finally return t) + (shackle-match buffer))) + + (defun doom-display-buffer-action (buffer alist) + (shackle-display-buffer buffer alist (shackle-match buffer))) + + (add-hook! doom-post-init + (setq display-buffer-alist + (cons '(doom-display-buffer-condition doom-display-buffer-action) + display-buffer-alist))) ;; no modeline in popups (add-hook 'doom-popup-mode-hook #'doom|hide-modeline-in-popup) @@ -133,20 +166,17 @@ recognized by DOOM's popup system. They are: (dolist (param `(popup ,@doom-popup-window-parameters)) (push (cons param 'writable) window-persistent-parameters)) - (defvar doom-popup-mode-map - (let ((map (make-sparse-keymap))) - (define-key map [escape] #'doom/popup-close-maybe) - (define-key map (kbd "ESC") #'doom/popup-close-maybe) - (define-key map [remap quit-window] #'doom/popup-close-maybe) - (define-key map [remap doom/kill-this-buffer] #'delete-window) - (define-key map [remap split-window-right] #'ignore) - (define-key map [remap split-window-below] #'ignore) - (define-key map [remap split-window-horizontally] #'ignore) - (define-key map [remap split-window-vertically] #'ignore) - (define-key map [remap mouse-split-window-horizontally] #'ignore) - (define-key map [remap mouse-split-window-vertically] #'ignore) - map) - "Active keymap in popup windows.")) + (let ((map doom-popup-mode-map)) + (define-key map [escape] #'doom/popup-close-maybe) + (define-key map (kbd "ESC") #'doom/popup-close-maybe) + (define-key map [remap quit-window] #'doom/popup-close-maybe) + (define-key map [remap doom/kill-this-buffer] #'delete-window) + (define-key map [remap split-window-right] #'ignore) + (define-key map [remap split-window-below] #'ignore) + (define-key map [remap split-window-horizontally] #'ignore) + (define-key map [remap split-window-vertically] #'ignore) + (define-key map [remap mouse-split-window-horizontally] #'ignore) + (define-key map [remap mouse-split-window-vertically] #'ignore))) ;; @@ -212,10 +242,10 @@ recognized by DOOM's popup system. They are: (defun doom|popup-close-maybe () "If current window is a popup, close it. If minibuffer is open, close it. If not in a popup, close all popups with an :autoclose property." - (cond ((doom-popup-p) - (unless (doom-popup-property :noesc) - (delete-window))) - (t (doom/popup-close-all)))) + (if (doom-popup-p) + (unless (doom-popup-property :noesc) + (delete-window)) + (doom/popup-close-all))) (add-hook '+evil-esc-hook #'doom|popup-close-maybe t) ;; Make evil-mode cooperate with popups @@ -340,37 +370,7 @@ the command buffer." (after! magit - (set! :popup "^\\*magit" :regexp t :size 0.5 :noesc t :autokill t) - - ;; magit doesn't need much coercing. It works with shackle as is, except for - ;; one problem: following non-file magit links tends to open additional - ;; popups. We want all this to be contained within one window, so... - (defun doom-magit-popup-buffer (buffer) - "Pop up the magit window with shackle." - (cond ((doom-popup-p) - (prog1 (doom-popup-switch-to-buffer buffer) - (doom-hide-modeline-mode +1))) - (t - (magit-display-buffer-traditional buffer)))) - - (defun doom-magit-quit-window (_kill-buffer) - "Close the current magit window properly." - (let ((last (current-buffer))) - (cond ((when-let (dest (doom-buffers-in-mode - 'magit-mode - (cl-loop for buf in (window-prev-buffers) - unless (eq (car buf) last) - collect (car buf)) - t)) - (doom-popup-switch-to-buffer (car dest))) - (kill-buffer last)) - (t - (mapc #'kill-buffer - (doom-buffers-in-mode '(magit-mode magit-process-mode) - (buffer-list) t)))))) - - (setq magit-display-buffer-function #'doom-magit-popup-buffer - magit-bury-buffer-function #'doom-magit-quit-window)) + (add-hook 'magit-mode-hook #'doom-hide-modeline-mode)) (after! mu4e @@ -415,7 +415,7 @@ that `doom*popup-save' won't break it." (defun doom*persp-mode-restore-popups (&rest _) "Restore popup windows when loading a perspective from file." (dolist (window (window-list)) - (when-let (plist (doom-popup-properties window)) + (when-let* ((plist (doom-popup-properties window))) (with-selected-window window (unless doom-popup-mode (setq-local doom-popup-rules plist) @@ -462,10 +462,10 @@ you came from." (advice-add #'plantuml-preview-string :around #'doom*plantuml-preview-in-popup-window)) -;; Ensure these settings are attached to org-load-hook as late as possible, -;; giving other modules a chance to add their own hooks. +;; Ensure these settings are loaded as late as possible, giving other modules a +;; chance to reconfigure org popup settings before the defaults kick in. (defun doom|init-org-popups () - (add-hook! 'org-load-hook + (add-hook! org-load (set! :popup '("*Calendar*" :size 0.4 :noselect t) '(" *Org todo*" :size 5 :noselect t) @@ -510,19 +510,18 @@ you came from." (t (error "Invalid buffer %s" buf)))))) (advice-add #'org-switch-to-buffer-other-window :override #'doom*org-pop-to-buffer) - (after! org-agenda - (setq org-agenda-window-setup 'other-window - org-agenda-restore-windows-after-quit nil) - + ;; org-agenda + (setq org-agenda-window-setup 'other-window + org-agenda-restore-windows-after-quit nil) ;; Hide modeline in org-agenda - (add-hook 'org-agenda-finalize-hook #'doom-hide-modeline-mode) - (add-hook 'org-agenda-finalize-hook #'org-fit-window-to-buffer) - ;; Don't monopolize frame! - (advice-add #'org-agenda :around #'doom*suppress-delete-other-windows) - ;; ensure quit keybindings work propertly - (map! :map org-agenda-mode-map - :m [escape] 'org-agenda-Quit - :m "ESC" 'org-agenda-Quit)))) + (add-hook 'org-agenda-finalize-hook #'doom-hide-modeline-mode) + (add-hook 'org-agenda-finalize-hook #'org-fit-window-to-buffer) + ;; Don't monopolize frame! + (advice-add #'org-agenda :around #'doom*suppress-delete-other-windows) + ;; ensure quit keybindings work propertly + (map! :map* org-agenda-mode-map + :m [escape] 'org-agenda-Quit + :m "ESC" 'org-agenda-Quit))) (add-hook 'doom-init-hook #'doom|init-org-popups) (provide 'core-popups) diff --git a/core/core-projects.el b/core/core-projects.el index f9eee1431..01e8e88f4 100644 --- a/core/core-projects.el +++ b/core/core-projects.el @@ -5,7 +5,6 @@ state are passed in.") (def-package! projectile - :demand t :init (setq projectile-cache-file (concat doom-cache-dir "projectile.cache") projectile-enable-caching (not noninteractive) diff --git a/core/core-ui.el b/core/core-ui.el index 7d965686e..a2f3f011a 100644 --- a/core/core-ui.el +++ b/core/core-ui.el @@ -7,16 +7,18 @@ "A symbol representing the color theme to load.") (defvar doom-font nil - "The default font to use. Expects a FONT-SPEC (`font-spec').") + "The default font to use. Expects a `font-spec'.") (defvar doom-big-font nil - "The default font to use. Expects a FONT-SPEC (`font-spec').") + "The default large font to use when `doom-big-font-mode' is enabled. Expects a +`font-spec'.") (defvar doom-variable-pitch-font nil - "The default font to use for variable-pitch text. Expects a FONT-SPEC (`font-spec').") + "The default font to use for variable-pitch text. Expects a `font-spec'.") (defvar doom-unicode-font nil - "Fallback font for unicode glyphs. Is ignored if :feature unicode is active.") + "Fallback font for unicode glyphs. Is ignored if :feature unicode is active. +Expects a `font-spec'.") (defvar doom-major-mode-names '((sh-mode . "sh") @@ -32,38 +34,6 @@ shorter major mode name in the mode-line. See `doom|set-mode-name'.") `doom//reload-theme').") -;; Settings -(def-setting! :theme (theme) - "Sets the current THEME (a symbol)." - `(unless doom-theme - (setq doom-theme ,theme))) - -(def-setting! :font (family &rest spec) - "Sets the default font (if one wasn't already set). FAMILY is the name of the -font, and SPEC is a `font-spec'." - `(unless doom-font - (setq doom-font (font-spec :family ,family ,@spec)))) - -(def-setting! :variable-pitch-font (family &rest spec) - "Sets the default font for the variable-pitch face and minor mode (if one -wasn't already set). FAMILY is the name of the font, and SPEC is a `font-spec'." - `(unless doom-variable-pitch-font - (setq doom-variable-pitch-font (font-spec :family ,family ,@spec)))) - -(def-setting! :big-font (family &rest spec) - "Sets the font to use for `doom-big-font-mode' (if one wasn't already set). -FAMILY is the name of the font, and SPEC is a `font-spec'." - `(unless doom-big-font - (setq doom-big-font (font-spec :family ,family ,@spec)))) - -(def-setting! :unicode-font (family &rest spec) - "Sets the font to use for unicode characters (if one wasn't already set). -FAMILY is the name of the font, and SPEC is a `font-spec'. This is ignored if -the ':ui unicode' module is enabled." - `(unless doom-unicode-font - (setq doom-unicode-font (font-spec :family ,family ,@spec)))) - - (setq-default bidi-display-reordering nil ; disable bidirectional text for tiny performance boost blink-matching-paren nil ; don't blink--too distracting @@ -177,7 +147,7 @@ local value, whether or not it's permanent-local. Therefore, we cycle ;; like diminish, but for major-modes. [pedantry intensifies] (defun doom|set-mode-name () "Set the major mode's `mode-name', as dictated by `doom-major-mode-names'." - (when-let (name (cdr (assq major-mode doom-major-mode-names))) + (when-let* ((name (cdr (assq major-mode doom-major-mode-names)))) (setq mode-name (cond ((functionp name) (funcall name)) ((stringp name) name) @@ -296,20 +266,42 @@ local value, whether or not it's permanent-local. Therefore, we cycle ;; Highlights the current line (def-package! hl-line ; built-in - :init (add-hook! (prog-mode text-mode conf-mode) #'hl-line-mode) + :hook ((prog-mode text-mode conf-mode) . hl-line-mode) :config ;; I don't need hl-line showing in other windows. This also offers a small ;; speed boost when buffer is displayed in multiple windows. (setq hl-line-sticky-flag nil global-hl-line-sticky-flag nil) + ;; On Emacs 26+, when point is on the last line, hl-line highlights bleed into + ;; the rest of the window after eob. This is the fix. + (when (boundp 'display-line-numbers) + (defun doom--line-range () + (cons (line-beginning-position) + (cond ((save-excursion + (goto-char (line-end-position)) + (and (eobp) (not (bolp)))) + (1- (line-end-position))) + ((or (eobp) (save-excursion (forward-line) (eobp))) + (line-end-position)) + (t + (line-beginning-position 2))))) + (setq hl-line-range-function #'doom--line-range)) + (after! evil + (defvar-local doom-buffer-hl-line-mode nil) + ;; Disable `hl-line' in evil-visual mode (temporarily). `hl-line' can make ;; the selection region harder to see while in evil visual mode. - (defun doom|disable-hl-line () (hl-line-mode -1)) + (defun doom|disable-hl-line () + (when hl-line-mode + (setq doom-buffer-hl-line-mode t) + (hl-line-mode -1))) + (defun doom|enable-hl-line-maybe () + (if doom-buffer-hl-line-mode (hl-line-mode +1))) (add-hook 'evil-visual-state-entry-hook #'doom|disable-hl-line) - (add-hook 'evil-visual-state-exit-hook #'hl-line-mode))) + (add-hook 'evil-visual-state-exit-hook #'doom|enable-hl-line-maybe))) ;; Helps us distinguish stacked delimiter pairs. Especially in parentheses-drunk ;; languages like Lisp. @@ -365,78 +357,76 @@ See `doom-line-numbers-style' to control the style of line numbers to display." (add-hook! (prog-mode text-mode conf-mode) #'doom|enable-line-numbers) ;; Emacs 26+ has native line number support. -(unless (boundp 'display-line-numbers) - ;; Line number column. A faster (or equivalent, in the worst case) line number - ;; plugin than `linum-mode'. - (def-package! nlinum - :commands nlinum-mode - :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. +;; Line number column. A faster (or equivalent, in the worst case) line number +;; plugin than `linum-mode'. +(def-package! nlinum + :unless (boundp 'display-line-numbers) + :commands nlinum-mode + :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) - :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)) - ;; 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', + (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) + (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) - (defun doom|init-nlinum-width () - "Calculate line number column width beforehand (optimization)." - (setq nlinum--width - (length (save-excursion (goto-char (point-max)) - (format-mode-line "%l"))))) - (add-hook 'nlinum-mode-hook #'doom|init-nlinum-width)) + (defun doom|init-nlinum-width () + "Calculate line number column width beforehand (optimization)." + (setq nlinum--width + (length (save-excursion (goto-char (point-max)) + (format-mode-line "%l"))))) + (add-hook 'nlinum-mode-hook #'doom|init-nlinum-width)) - ;; Fixes disappearing line numbers in nlinum and other quirks - (def-package! nlinum-hl - :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) +;; Fixes disappearing line numbers in nlinum and other quirks +(def-package! nlinum-hl + :unless (boundp 'display-line-numbers) + :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. + (advice-add #'set-frame-font :after #'nlinum-hl-flush-all-windows)) - ;; 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. - (advice-add #'set-frame-font :after #'nlinum-hl-flush-all-windows)) - - (def-package! nlinum-relative - :commands nlinum-relative-mode - :config - (after! evil - (nlinum-relative-setup-evil)))) +(def-package! nlinum-relative + :unless (boundp 'display-line-numbers) + :commands nlinum-relative-mode + :config + (after! evil (nlinum-relative-setup-evil))) ;; @@ -498,7 +488,7 @@ error if it doesn't exist." (defun doom-set-modeline (key &optional default) "Set the modeline format. Does nothing if the modeline KEY doesn't exist. If DEFAULT is non-nil, set the default mode-line for all buffers." - (when-let (modeline (doom-modeline key)) + (when-let* ((modeline (doom-modeline key))) (setf (if default (default-value 'mode-line-format) (buffer-local-value 'mode-line-format (current-buffer))) diff --git a/core/core.el b/core/core.el index 06b1cad4c..f3eaa03bd 100644 --- a/core/core.el +++ b/core/core.el @@ -18,7 +18,7 @@ ;; Autoloaded functions are in core/autoload/*.el and modules/*/*/autoload.el or ;; modules/*/*/autoload/*.el. -(defvar doom-version "2.0.7" +(defvar doom-version "2.0.8" "Current version of DOOM emacs.") (defvar doom-debug-mode (or (getenv "DEBUG") init-file-debug) @@ -94,6 +94,7 @@ melodramatic ex-vimmer disappointed with the text-editor status quo." enable-recursive-minibuffers nil debug-on-error (and (not noninteractive) doom-debug-mode) idle-update-delay 2 ; update ui less often + load-prefer-newer (or noninteractive doom-debug-mode) ;; keep the point out of the minibuffer minibuffer-prompt-properties '(read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt) ;; History & backup settings (save nothing, that's what git is for) @@ -174,9 +175,7 @@ ability to invoke the debugger in debug mode." gc-cons-percentage 0.6 file-name-handler-alist nil) - (require 'cl-lib) (require 'core-packages (concat doom-core-dir "core-packages")) - (eval-when-compile (doom-initialize)) (setq load-path (eval-when-compile load-path) diff --git a/core/packages.el b/core/packages.el index 3a5004ed5..054197e4a 100644 --- a/core/packages.el +++ b/core/packages.el @@ -1,10 +1,6 @@ ;; -*- no-byte-compile: t; -*- ;;; core/packages.el -;; core packages -(package! s) -(package! f) - ;; core-os.el ;; In case this config is shared across multiple computers (like mine is), let's ;; protect these from autoremoval. diff --git a/init.example.el b/init.example.el index 14e968b0d..b2ba07694 100644 --- a/init.example.el +++ b/init.example.el @@ -81,6 +81,7 @@ assembly ; assembly for fun or debugging cc ; C/C++/Obj-C madness crystal ; ruby at the speed of c + clojure ; java with a lisp csharp ; unity, .NET, and mono shenanigans data ; config/data formats elixir ; erlang done right @@ -97,6 +98,14 @@ lua ; one-based indices? one-based indices markdown ; writing docs for people to ignore ocaml ; an objective camel + (org ; organize your plain life in plain text + +attach ; custom attachment system + +babel ; running code in org + +capture ; org-capture in and outside of Emacs + +export ; centralized export system + more backends + +present ; Emacs for presentations + ;; TODO +publish + ) perl ; write code no one else can comprehend php ; make php less awful to work with plantuml ; diagrams for confusing people more @@ -111,25 +120,15 @@ typescript ; javascript, but better web ; the tubes - :org - org ; organize your plain life in plain text - org-babel ; executable code snippets in org-mode - org-attach ; a simpler attachment system - org-capture ; a better org-capture, in or outside of Emacs - org-export ; a custom, centralized export system - org-present ; using org-mode for presentations - ;org-sync ; TODO sync with mobile - ;org-publish ; TODO org + blogs - ;; Applications are complex and opinionated modules that transform Emacs ;; toward a specific purpose. They may have additional dependencies and ;; should be loaded last. :app - email ; emacs as an email client - irc ; how neckbeards socialize - rss ; emacs as an RSS reader - twitter ; twitter client https://twitter.com/vnought - write ; emacs as a word processor (latex + org + markdown) + ;email ; emacs as an email client + ;irc ; how neckbeards socialize + ;rss ; emacs as an RSS reader + ;twitter ; twitter client https://twitter.com/vnought + ;write ; emacs as a word processor (latex + org + markdown) ;; Private modules named after your username are loaded automatically. ;; Leaving this here is harmless though. diff --git a/init.test.el b/init.test.el index 9cba1cfc6..038114c87 100644 --- a/init.test.el +++ b/init.test.el @@ -13,10 +13,8 @@ password-store :lang - web - - :org org + web :private hlissner) diff --git a/modules/app/email/config.el b/modules/app/email/config.el index 59420770d..c447d2b0b 100644 --- a/modules/app/email/config.el +++ b/modules/app/email/config.el @@ -31,7 +31,7 @@ DEFAULT-P is a boolean. If non-nil, it marks that email account as the default/fallback account." `(after! mu4e (let ((account-vars ,letvars)) - (when-let (address (cdr (assq 'user-mail-address account-vars))) + (when-let* ((address (cdr (assq 'user-mail-address account-vars)))) (cl-pushnew address mu4e-user-mail-address-list :test #'equal)) (let ((context (make-mu4e-context :name ,label @@ -263,8 +263,7 @@ default/fallback account." (def-package! org-mu4e - :commands org-mu4e-compose-org-mode - :init (add-hook 'mu4e-compose-mode-hook #'org-mu4e-compose-org-mode) + :hook (mu4e-compose-mode . org-mu4e-compose-org-mode) :config (setq org-mu4e-link-query-in-headers-mode nil org-mu4e-convert-to-html t) diff --git a/modules/app/irc/config.el b/modules/app/irc/config.el index db4c039a5..35d02432c 100644 --- a/modules/app/irc/config.el +++ b/modules/app/irc/config.el @@ -30,8 +30,7 @@ playback.") (def-setting! :irc (server letvars) "Registers an irc server for circe." `(after! circe - (cl-pushnew (cons ,server ,letvars) circe-network-options - :test #'equal :key #'car))) + (push (cons ,server ,letvars) circe-network-options))) (defvar +irc--defer-timer nil) @@ -89,7 +88,7 @@ playback.") (defun +irc*circe-truncate-nicks () "Truncate long nicknames in chat output non-destructively." - (when-let (beg (text-property-any (point-min) (point-max) 'lui-format-argument 'nick)) + (when-let* ((beg (text-property-any (point-min) (point-max) 'lui-format-argument 'nick))) (goto-char beg) (let ((end (next-single-property-change beg 'lui-format-argument)) (nick (plist-get (plist-get (text-properties-at beg) 'lui-keywords) @@ -111,8 +110,7 @@ playback.") (def-package! circe-color-nicks - :commands enable-circe-color-nicks - :init (add-hook 'circe-channel-mode-hook 'enable-circe-color-nicks) + :hook (circe-channel-mode . enable-circe-color-nicks) :config (setq circe-color-nicks-min-constrast-ratio 4.5 circe-color-nicks-everywhere t)) @@ -161,7 +159,7 @@ after prompt marker." (add-hook! 'lui-mode-hook (add-hook 'evil-insert-state-entry-hook #'+irc|evil-insert nil t)) - (mapc (lambda (cmd) (cl-pushnew cmd +irc-scroll-to-bottom-on-commands)) + (mapc (lambda (cmd) (push cmd +irc-scroll-to-bottom-on-commands)) '(evil-paste-after evil-paste-before evil-open-above evil-open-below))) @@ -192,7 +190,7 @@ Courtesy of esh-mode.el" (defun +irc|init-lui-wrapping () (setq fringes-outside-margins t word-wrap t - wrap-prefix (s-repeat (+ +irc-left-padding 3) " "))) + wrap-prefix (make-string (+ +irc-left-padding 3) ? ))) (add-hook! 'lui-mode-hook #'(+irc|init-lui-margins +irc|init-lui-wrapping))) @@ -203,5 +201,4 @@ Courtesy of esh-mode.el" (def-package! lui-autopaste - :commands enable-lui-autopaste - :init (add-hook 'circe-channel-mode-hook 'enable-lui-autopaste)) + :hook (circe-channel-mode . enable-lui-autopaste)) diff --git a/modules/app/regex/autoload/regex.el b/modules/app/regex/autoload/regex.el index f9499a5da..7e43db77e 100644 --- a/modules/app/regex/autoload/regex.el +++ b/modules/app/regex/autoload/regex.el @@ -261,7 +261,7 @@ __DATA__ (overlay-put ov 'category '+regex)) (cl-incf i) (dotimes (i 10) - (when-let (text (match-string i)) + (when-let* ((text (match-string i))) (save-match-data (with-current-buffer +regex--groups-buffer (goto-char (point-max)) diff --git a/modules/app/rss/autoload.el b/modules/app/rss/autoload.el index 0de16a866..ed9e10fbe 100644 --- a/modules/app/rss/autoload.el +++ b/modules/app/rss/autoload.el @@ -11,7 +11,7 @@ (interactive) (doom-kill-matching-buffers "^\\*elfeed") (dolist (file +rss-elfeed-files) - (when-let (buf (get-file-buffer (expand-file-name file +rss-org-dir))) + (when-let* ((buf (get-file-buffer (expand-file-name file +rss-org-dir)))) (kill-buffer buf)))) ;;;###autoload @@ -37,11 +37,11 @@ (defun +rss-popup-pane (buf) "Display BUF in a popup." (doom-popup-buffer buf - :align +rss-split-direction - :size 0.75 - :select t - :autokill t - :autoclose t)) + '(:align +rss-split-direction + :size 0.75 + :select t + :autokill t + :autoclose t))) ;;;###autoload (defun +rss/open (entry) diff --git a/modules/app/rss/config.el b/modules/app/rss/config.el index 64a513fbc..343e74bd2 100644 --- a/modules/app/rss/config.el +++ b/modules/app/rss/config.el @@ -28,8 +28,8 @@ (make-directory elfeed-db-directory t) ;; Ensure elfeed buffers are treated as real - (cl-pushnew (lambda (buf) (string-match-p "^\\*elfeed" (buffer-name buf))) - doom-real-buffer-functions) + (push (lambda (buf) (string-match-p "^\\*elfeed" (buffer-name buf))) + doom-real-buffer-functions) ;; Enhance readability of a post (add-hook 'elfeed-show-mode-hook #'+rss|elfeed-wrap) diff --git a/modules/completion/helm/autoload/evil.el b/modules/completion/helm/autoload/evil.el index d1f1b5f59..d1c1841bd 100644 --- a/modules/completion/helm/autoload/evil.el +++ b/modules/completion/helm/autoload/evil.el @@ -7,21 +7,19 @@ (interactive "") (helm-swoop :$query search :$multiline bang)) -(defvar +helm--file-last-search nil) -;;;###autoload (autoload '+helm:ag "completion/helm/autoload/evil" nil t) -(evil-define-command +helm:ag (beg end query &optional bang directory) - "TODO" - (interactive "") +(defun +helm--file-search (beg end query &optional directory options) (require 'helm-ag) (helm-ag--init-state) (let ((helm-ag--default-directory (or directory (doom-project-root))) - (helm-ag--last-query (or query - (and beg end - (> (abs (- end beg)) 1) - (setq +helm--file-last-search - (rxt-quote-pcre (buffer-substring-no-properties beg end)))) - +helm--file-last-search)) - (helm-ag-command-option (concat helm-ag-command-option (if bang " -a ")))) + (query (or query + (if (evil-visual-state-p) + (and beg end + (> (abs (- end beg)) 1) + (rxt-quote-pcre (buffer-substring-no-properties beg end))) + +helm--file-last-query) + +helm--file-last-query)) + (helm-ag-command-option (concat helm-ag-command-option " " (string-join options " ")))) + (setq helm-ag--last-query query) (helm-attrset 'search-this-file nil helm-ag-source) (helm-attrset 'name (helm-ag--helm-header helm-ag--default-directory) helm-ag-source) (helm :sources '(helm-ag-source) @@ -30,16 +28,33 @@ :keymap helm-ag-map :history 'helm-ag--helm-history))) -;;;###autoload (autoload '+helm:ag-cwd "completion/helm/autoload/evil" nil t) -(evil-define-command +helm:ag-cwd (beg end query &optional bang directory) +(defvar +helm--file-last-search nil) +;;;###autoload (autoload '+helm:ag "completion/helm/autoload/evil" nil t) +(evil-define-command +helm:ag (beg end query &optional bang) "TODO" (interactive "") - (let ((helm-ag-command-option (if bang " -n "))) - (+helm:ag beg end query t default-directory))) + (+helm--file-search beg end query nil + (if bang (list "-a" "--hidden")))) -;;;###autoload -(defun +helm:rg (&rest _) (interactive) (error "Not implemented yet")) -;;;###autoload -(defun +helm:rg-cwd (&rest _) (interactive) (error "Not implemented yet")) -;;;###autoload -(defun +helm:todo (&rest _) (interactive) (error "Not implemented yet")) +;;;###autoload (autoload '+helm:ag-cwd "completion/helm/autoload/evil" nil t) +(evil-define-command +helm:ag-cwd (beg end query &optional bang) + "TODO" + (interactive "") + (+helm--file-search beg end query default-directory + (list "-n" (if bang "-a")))) + +;;;###autoload (autoload '+helm:rg "completion/helm/autoload/evil" nil t) +(evil-define-command +helm:rg (beg end query &optional bang) + "TODO" + (interactive "") + (let ((helm-ag-base-command "rg --no-heading")) + (+helm--file-search beg end query nil + (if bang (list "-uu"))))) + +;;;###autoload (autoload '+helm:rg-cwd "completion/helm/autoload/evil" nil t) +(evil-define-command +helm:rg-cwd (beg end query &optional bang) + "TODO" + (interactive "") + (let ((helm-ag-base-command "rg --no-heading --maxdepth 1")) + (+helm--file-search beg end query default-directory + (if bang (list "-uu"))))) diff --git a/modules/completion/helm/config.el b/modules/completion/helm/config.el index ba315c5d5..33890f1b1 100644 --- a/modules/completion/helm/config.el +++ b/modules/completion/helm/config.el @@ -11,7 +11,6 @@ ;; (def-package! helm - :demand t :init (setq helm-quick-update t ;; Speedier without fuzzy matching @@ -77,15 +76,18 @@ (def-package! helm-locate + :defer t :init (defvar helm-generic-files-map (make-sparse-keymap)) :config (set-keymap-parent helm-generic-files-map helm-map)) (def-package! helm-bookmark + :commands helm-bookmark :config (setq-default helm-bookmark-show-location t)) (def-package! helm-files + :defer t :config (setq helm-boring-file-regexp-list (append (list "\\.projects$" "\\.DS_Store$") @@ -93,6 +95,7 @@ (def-package! helm-ag + :defer t :config (map! :map helm-ag-edit-map [remap doom/kill-this-buffer] #'helm-ag--edit-abort diff --git a/modules/completion/ido/config.el b/modules/completion/ido/config.el index ea0bd3bca..5327920d3 100644 --- a/modules/completion/ido/config.el +++ b/modules/completion/ido/config.el @@ -22,11 +22,18 @@ (ido-mode 1) (ido-everywhere 1) (require 'ido-ubiquitous) + (ido-ubiquitous-mode 1) (defun +ido|init () (require 'ido-vertical-mode) + (ido-vertical-mode 1) + (require 'flx-ido) + (flx-ido-mode +1) + (require 'crm-custom) + (crm-custom-mode +1) + (map! :map (ido-common-completion-map ido-completion-map ido-file-completion-map) "C-n" #'ido-next-match "C-p" #'ido-prev-match @@ -55,12 +62,3 @@ (insert "~/") (call-interactively #'self-insert-command))))) (add-hook 'ido-setup-hook #'+ido|setup-home-keybind)) - - -(def-package! ido-ubiquitous :config (ido-ubiquitous-mode 1)) - -(def-package! ido-vertical-mode :config (ido-vertical-mode 1)) - -(def-package! flx-ido :config (flx-ido-mode +1)) - -(def-package! crm-custom :config (crm-custom-mode +1)) diff --git a/modules/completion/ivy/autoload/evil.el b/modules/completion/ivy/autoload/evil.el index 5abf326a3..b287a273a 100644 --- a/modules/completion/ivy/autoload/evil.el +++ b/modules/completion/ivy/autoload/evil.el @@ -58,7 +58,7 @@ (replace-regexp-in-string " -i " " -S " counsel-rg-base-command)) (args (concat (if all-files-p " -uu") - (unless recursion-p " --maxdepth 0")))) + (unless recursion-p " --maxdepth 1")))) (counsel-rg query directory args (format prompt args)))) ('pt) ;; TODO pt search engine (necessary?) (_ (error "No search engine specified"))))) diff --git a/modules/completion/ivy/autoload/ivy.el b/modules/completion/ivy/autoload/ivy.el index 277d140ff..8a008348d 100644 --- a/modules/completion/ivy/autoload/ivy.el +++ b/modules/completion/ivy/autoload/ivy.el @@ -73,9 +73,9 @@ If ARG (universal argument), open selection in other-window." (task-tags (mapcar #'car +ivy-task-tags)) (cmd (format "%s -H -S --no-heading -- %s %s" - (or (when-let (bin (executable-find "rg")) + (or (when-let* ((bin (executable-find "rg"))) (concat bin " --line-number")) - (when-let (bin (executable-find "ag")) + (when-let* ((bin (executable-find "ag"))) (concat bin " --numbers")) (error "ripgrep & the_silver_searcher are unavailable")) (shell-quote-argument @@ -144,8 +144,7 @@ counsel-rg)." (let ((default-directory counsel--git-dir) (regex (counsel-unquote-regex-parens (setq ivy--old-re - (ivy--regex - (counsel-unquote-regex-parens string)))))) ;; #2 + (ivy--regex string))))) (let* ((args-end (string-match " -- " extra-ag-args)) (file (if args-end (substring-no-properties extra-ag-args (+ args-end 3)) diff --git a/modules/completion/ivy/config.el b/modules/completion/ivy/config.el index 7c0bbe755..bcd027078 100644 --- a/modules/completion/ivy/config.el +++ b/modules/completion/ivy/config.el @@ -24,7 +24,6 @@ immediately runs it on the current candidate (ending the ivy session)." ;; (def-package! ivy - :demand t :init (add-hook 'doom-post-init-hook #'ivy-mode) :config @@ -57,8 +56,6 @@ immediately runs it on the current candidate (ending the ivy session)." [remap projectile-find-file] #'counsel-projectile-find-file [remap imenu-anywhere] #'ivy-imenu-anywhere [remap execute-extended-command] #'counsel-M-x - [remap describe-function] #'counsel-describe-function - [remap describe-variable] #'counsel-describe-variable [remap describe-face] #'counsel-describe-face) ;; Show more buffer information in switch-buffer commands @@ -67,23 +64,22 @@ immediately runs it on the current candidate (ending the ivy session)." (ivy-set-display-transformer #'+ivy/switch-workspace-buffer #'+ivy-buffer-transformer) (ivy-set-display-transformer #'counsel-recentf #'abbreviate-file-name) - (when (featurep! :feature workspaces) - (nconc ivy-sort-functions-alist - '((persp-kill-buffer . nil) - (persp-remove-buffer . nil) - (persp-add-buffer . nil) - (persp-switch . nil) - (persp-window-switch . nil) - (persp-frame-switch . nil) - (+workspace/switch-to . nil) - (+workspace/delete . nil))))) + (nconc ivy-sort-functions-alist + '((persp-kill-buffer . nil) + (persp-remove-buffer . nil) + (persp-add-buffer . nil) + (persp-switch . nil) + (persp-window-switch . nil) + (persp-frame-switch . nil) + (+workspace/switch-to . nil) + (+workspace/delete . nil)))) (def-package! swiper :commands (swiper swiper-all)) (def-package! counsel - :after ivy + :requires ivy :config (require 'counsel-projectile) (setq counsel-find-file-ignore-regexp "\\(?:^[#.]\\)\\|\\(?:[#~]$\\)\\|\\(?:^Icon?\\)") @@ -96,10 +92,8 @@ immediately runs it on the current candidate (ending the ivy session)." '(("O" +ivy-git-grep-other-window-action "open in other window")))) ;; 1. Remove character limit from `counsel-ag-function' - ;; 2. Disable ivy's over-zealous parentheses quoting behavior (if i want - ;; literal parentheses, I'll escape them myself). - ;; 3. This may need to be updated frequently, to meet changes upstream - ;; 4. counsel-ag, counsel-rg and counsel-pt all use this function + ;; 2. This may need to be updated frequently, to meet changes upstream + ;; 3. counsel-ag, counsel-rg and counsel-pt all use this function (advice-add #'counsel-ag-function :override #'+ivy*counsel-ag-function)) @@ -144,9 +138,9 @@ immediately runs it on the current candidate (ending the ivy session)." ("i" nil) ("TAB" ivy-alt-done :exit nil) ("C-j" ivy-alt-done :exit nil) - ;; ("d" ivy-done :exit t) ("RET" ivy-done :exit t) ("C-m" ivy-done :exit t) + ("C-SPC" ivy-call-and-recenter :exit nil) ("f" ivy-call) ("c" ivy-toggle-calling) ("m" ivy-toggle-fuzzy) diff --git a/modules/feature/eval/autoload/eval.el b/modules/feature/eval/autoload/eval.el index 45e4ebc34..75006b142 100644 --- a/modules/feature/eval/autoload/eval.el +++ b/modules/feature/eval/autoload/eval.el @@ -13,7 +13,7 @@ "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))) + (if-let* ((runner (cdr (assq major-mode +eval-runners)))) (funcall runner beg end) (quickrun-region beg end)))) diff --git a/modules/feature/eval/autoload/repl.el b/modules/feature/eval/autoload/repl.el index 8b396b172..5655a64f3 100644 --- a/modules/feature/eval/autoload/repl.el +++ b/modules/feature/eval/autoload/repl.el @@ -7,7 +7,7 @@ (or (eq (current-buffer) +eval-repl-buffer) (progn (if (and +eval-repl-buffer (buffer-live-p +eval-repl-buffer)) - (if-let (win (get-buffer-window +eval-repl-buffer)) + (if-let* ((win (get-buffer-window +eval-repl-buffer))) (select-window win) (doom-popup-buffer +eval-repl-buffer)) (when command @@ -29,7 +29,7 @@ "Opens (or reopens) the REPL associated with the current major-mode and place the cursor at the prompt." (interactive) - (when-let (command (cdr (assq major-mode +eval-repls))) + (when-let* ((command (cdr (assq major-mode +eval-repls)))) (when (+eval--ensure-in-repl-buffer command) (when (bound-and-true-p evil-mode) (call-interactively #'evil-append-line)) diff --git a/modules/feature/eval/config.el b/modules/feature/eval/config.el index 3f8176757..ba954353c 100644 --- a/modules/feature/eval/config.el +++ b/modules/feature/eval/config.el @@ -74,7 +74,7 @@ function that creates and returns the REPL buffer." (defun +eval*quickrun-auto-close (&rest _) "Allows us to silently re-run quickrun from within the quickrun buffer." - (when-let (win (get-buffer-window quickrun--buffer-name)) + (when-let* ((win (get-buffer-window quickrun--buffer-name))) (let ((inhibit-message t)) (quickrun--kill-running-process) (message "")) diff --git a/modules/feature/evil/autoload/files.el b/modules/feature/evil/autoload/files.el index 00f890900..c247f6f46 100644 --- a/modules/feature/evil/autoload/files.el +++ b/modules/feature/evil/autoload/files.el @@ -77,7 +77,7 @@ overwrite the destination file if it exists, without confirmation." (pcase (catch 'status (let ((old-path (buffer-file-name)) (new-path (expand-file-name new-path))) - (when-let (dest (+evil--copy-file old-path new-path force-p)) + (when-let* ((dest (+evil--copy-file old-path new-path force-p))) (delete-file old-path) (kill-this-buffer) (find-file new-path) @@ -95,7 +95,7 @@ overwrite the destination file if it exists, without confirmation." :repeat nil (interactive "") (pcase (catch 'status - (when-let (dest (+evil--copy-file (buffer-file-name) new-path force-p)) + (when-let* ((dest (+evil--copy-file (buffer-file-name) new-path force-p))) (message "File successfully copied to %s" dest))) ('overwrite-self (error "Cannot overwrite self")) ('aborted (message "Aborted")) diff --git a/modules/feature/evil/config.el b/modules/feature/evil/config.el index 907d47678..4d24b856e 100644 --- a/modules/feature/evil/config.el +++ b/modules/feature/evil/config.el @@ -21,7 +21,6 @@ (autoload 'goto-last-change-reverse "goto-chg") (def-package! evil - :demand t :init (setq evil-want-C-u-scroll t evil-want-visual-char-semi-exclusive t @@ -181,11 +180,11 @@ across windows." (evil-embrace-enable-evil-surround-integration) (defun +evil--embrace-get-pair (char) - (if-let (pair (cdr-safe (assoc (string-to-char char) evil-surround-pairs-alist))) + (if-let* ((pair (cdr-safe (assoc (string-to-char char) evil-surround-pairs-alist)))) pair - (if-let (pair (assoc-default char embrace--pairs-list)) - (if-let (real-pair (and (functionp (embrace-pair-struct-read-function pair)) - (funcall (embrace-pair-struct-read-function pair)))) + (if-let* ((pair (assoc-default char embrace--pairs-list))) + (if-let* ((real-pair (and (functionp (embrace-pair-struct-read-function pair)) + (funcall (embrace-pair-struct-read-function pair))))) real-pair (cons (embrace-pair-struct-left pair) (embrace-pair-struct-right pair))) (cons char char)))) @@ -209,13 +208,12 @@ across windows." (cons (format "(%s " (or (read-string "(") "")) ")")) ;; Add escaped-sequence support to embrace - (cl-pushnew (cons ?\\ (make-embrace-pair-struct - :key ?\\ - :read-function #'+evil--embrace-escaped - :left-regexp "\\[[{(]" - :right-regexp "\\[]})]")) - (default-value 'embrace--pairs-list) - :key #'car) + (push (cons ?\\ (make-embrace-pair-struct + :key ?\\ + :read-function #'+evil--embrace-escaped + :left-regexp "\\[[{(]" + :right-regexp "\\[]})]")) + (default-value 'embrace--pairs-list)) ;; Add extra pairs (add-hook 'LaTeX-mode-hook #'embrace-LaTeX-mode-hook) @@ -238,7 +236,7 @@ across windows." (add-hook 'doom-post-init-hook #'evil-escape-mode) :config ;; no `evil-escape' in minibuffer - (cl-pushnew #'minibufferp evil-escape-inhibit-functions :test #'eq) + (push #'minibufferp evil-escape-inhibit-functions) (map! :irvo "C-g" #'evil-escape)) diff --git a/modules/feature/file-templates/templates/gitignore-mode/__ b/modules/feature/file-templates/templates/gitignore-mode/__ index 372ce6795..cb95699c3 100644 --- a/modules/feature/file-templates/templates/gitignore-mode/__ +++ b/modules/feature/file-templates/templates/gitignore-mode/__ @@ -4,7 +4,7 @@ tmp/ `(let ((type-ignore (yas-choose-value '("(none)" "python" "ruby" "java" "js")))) - (s-join "\n" + (string-join (cond ((string= type-ignore "python") '("*.py[cod]" "*.egg" @@ -20,5 +20,5 @@ tmp/ '("*.class" "build")) ((string= type-ignore "js") - '("*.tern-port")) - )))` + '("*.tern-port"))) + "\n"))` diff --git a/modules/feature/file-templates/templates/makefile-gmake-mode/__cpp b/modules/feature/file-templates/templates/makefile-gmake-mode/__cpp index d5a3cb66e..d589c266e 100644 --- a/modules/feature/file-templates/templates/makefile-gmake-mode/__cpp +++ b/modules/feature/file-templates/templates/makefile-gmake-mode/__cpp @@ -13,7 +13,7 @@ RELEASE_FLAGS = -O2 -D NDEBUG -combile -fwhole-program RELEASE_DIR = ./build/release DEBUG_DIR = ./build/debug -TARGET = ${1:appname$(s-replace " " "" yas-text)} +TARGET = ${1:appname$(replace-regexp-in-string " " "" yas-text nil t)} HEADERS = \$(shell echo include/*.h) SOURCES = \$(shell echo src/*.cpp) \$(shell echo src/**/*.cpp) OBJECTS = \$(SOURCES:.cpp=.o) diff --git a/modules/feature/file-templates/templates/ruby-mode/__module b/modules/feature/file-templates/templates/ruby-mode/__module index 3c5bdaeb9..44cf0da3d 100644 --- a/modules/feature/file-templates/templates/ruby-mode/__module +++ b/modules/feature/file-templates/templates/ruby-mode/__module @@ -1,12 +1,12 @@ # `(progn - (setq-local pkgs (split-string (s-chop-prefix (concat (doom-project-root) "lib/") (file-name-sans-extension buffer-file-name)) "/" t)) + (setq-local pkgs (split-string (string-remove-prefix (concat (doom-project-root) "lib/") (file-name-sans-extension buffer-file-name)) "/" t)) (setq-local pkgs-p (eq (length pkgs) 1)) - (setq-local pkg-module (s-replace " " "::" (s-titleized-words (if pkgs-p (car pkgs) (string-join (butlast pkgs) " "))))) + (setq-local pkg-module (replace-regexp-in-string " " "::" (capitalize (if pkgs-p (car pkgs) (string-join (butlast pkgs) " "))) nil t)) (concat "lib/" (file-name-nondirectory buffer-file-name)))` module `pkg-module` -`(when pkgs-p " VERSION='0.0.1'\n\n")``(concat " class " (if pkgs-p "<< self" (s-capitalize (car (last pkgs)))))` +`(when pkgs-p " VERSION='0.0.1'\n\n")``(concat " class " (if pkgs-p "<< self" (capitalize (car (last pkgs)))))` `%`${0:# Code here} end end \ No newline at end of file diff --git a/modules/feature/jump/autoload/jump.el b/modules/feature/jump/autoload/jump.el index 3c83ee32c..21d951f3b 100644 --- a/modules/feature/jump/autoload/jump.el +++ b/modules/feature/jump/autoload/jump.el @@ -35,12 +35,11 @@ Tries xref and falls back to `dumb-jump', then rg/ag, then ((and (require 'dumb-jump nil t) ;; dumb-jump doesn't tell us if it succeeded or not - (let ((old-fn-sym (make-symbol "old-fn")) + (let ((old-fn (symbol-function 'dumb-jump-get-results)) successful) - (cl-letf ((old-fn-sym (symbol-function 'dumb-jump-get-results)) - ((symbol-function 'dumb-jump-get-results) + (cl-letf (((symbol-function 'dumb-jump-get-results) (lambda (&optional prompt) - (let* ((plist (funcall old-fn-sym prompt)) + (let* ((plist (funcall old-fn prompt)) (results (plist-get plist :results))) (when (and results (> (length results) 0)) (setq successful t)) diff --git a/modules/feature/jump/config.el b/modules/feature/jump/config.el index e763d4718..db7a65069 100644 --- a/modules/feature/jump/config.el +++ b/modules/feature/jump/config.el @@ -70,8 +70,8 @@ properties: (defun +jump|init () "Initialize `+jump-current-functions', used by `+jump/definition', `+jump/references' and `+jump/documentation'." - (when-let (plist (cdr (assq major-mode +jump-function-alist))) - (when-let (backend (plist-get plist :xref-backend)) + (when-let* ((plist (cdr (assq major-mode +jump-function-alist)))) + (when-let* ((backend (plist-get plist :xref-backend))) (make-variable-buffer-local 'xref-backend-functions) (cl-pushnew backend xref-backend-functions :test #'eq)) (setq-local +jump-current-functions plist))) diff --git a/modules/feature/snippets/autoload/evil.el b/modules/feature/snippets/autoload/evil.el index c8d5cfc7f..e0ef054b2 100644 --- a/modules/feature/snippets/autoload/evil.el +++ b/modules/feature/snippets/autoload/evil.el @@ -11,7 +11,7 @@ and switches to insert mode if there are editable fields." (cl-letf (((symbol-function 'region-beginning) (lambda () evil-visual-beginning)) ((symbol-function 'region-end) (lambda () evil-visual-end))) (yas-insert-snippet)) - (when-let (snippet (car-safe (yas-active-snippets))) + (when-let* ((snippet (car-safe (yas-active-snippets)))) (let ((fields (yas--snippet-fields snippet))) (evil-insert-state +1) (unless fields (evil-change-state 'normal))))) diff --git a/modules/feature/version-control/+git.el b/modules/feature/version-control/+git.el index f16a47d1d..4467441bf 100644 --- a/modules/feature/version-control/+git.el +++ b/modules/feature/version-control/+git.el @@ -1,4 +1,5 @@ ;;; feature/version-control/+git.el -*- lexical-binding: t; -*- +;;;###if (not (featurep! -git)) (def-package! gitconfig-mode :mode "/\\.?git/?config$" diff --git a/modules/feature/version-control/autoload.el b/modules/feature/version-control/autoload.el index 9f710f67b..6df86c3d0 100644 --- a/modules/feature/version-control/autoload.el +++ b/modules/feature/version-control/autoload.el @@ -27,7 +27,7 @@ repository root." (defun +vcs/git-browse-issues () "Open the github issues page for current repo." (interactive) - (if-let (root (+vcs-root)) + (if-let* ((root (+vcs-root))) (browse-url (concat root "/issues")) (user-error "No git root found!"))) diff --git a/modules/feature/version-control/config.el b/modules/feature/version-control/config.el index d99b54b4f..f13540e2e 100644 --- a/modules/feature/version-control/config.el +++ b/modules/feature/version-control/config.el @@ -20,15 +20,15 @@ (set! :evil-state 'vc-git-log-view-mode 'normal)) (def-package! smerge-mode - :init - (add-hook 'find-file-hook #'+vcs|enable-smerge-mode-maybe) + :hook (find-file . +vcs|enable-smerge-mode-maybe) :config (when (version< emacs-version "26") - (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)) + (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))) (def-hydra! +hydra-smerge (:hint nil :pre (smerge-mode 1) diff --git a/modules/feature/workspaces/autoload/workspaces.el b/modules/feature/workspaces/autoload/workspaces.el index 11cff9413..8566cd860 100644 --- a/modules/feature/workspaces/autoload/workspaces.el +++ b/modules/feature/workspaces/autoload/workspaces.el @@ -53,7 +53,7 @@ ;;;###autoload (defun +workspace-get (name &optional noerror) "Returns a workspace (perspective hash table) named NAME." - (when-let (persp (persp-get-by-name name)) + (when-let* ((persp (persp-get-by-name name))) (cond ((+workspace-p persp) persp) ((not noerror) (error "'%s' is an invalid workspace" name))))) diff --git a/modules/feature/workspaces/config.el b/modules/feature/workspaces/config.el index 759b7406b..6bcb58ffe 100644 --- a/modules/feature/workspaces/config.el +++ b/modules/feature/workspaces/config.el @@ -22,7 +22,6 @@ renamed.") ;; (def-package! persp-mode - :demand t :config (setq persp-autokill-buffer-on-remove 'kill-weak persp-nil-name "nil" @@ -92,7 +91,7 @@ Allows a perspective-specific buffer list via `+workspaces-buffer-list'." (not persp-temporarily-display-buffer) (doom-real-buffer-p buffer)) (persp-add-buffer buffer (get-current-persp) nil) - (redisplay))) + (force-mode-line-update t))) (advice-add #'switch-to-buffer :after #'+workspaces*auto-add-buffer) (advice-add #'display-buffer :after #'+workspaces*auto-add-buffer)) diff --git a/modules/lang/cc/config.el b/modules/lang/cc/config.el index 4a8e6369b..9563ef452 100644 --- a/modules/lang/cc/config.el +++ b/modules/lang/cc/config.el @@ -35,9 +35,9 @@ compilation database is present in the project.") (or (file-exists-p (expand-file-name (concat (file-name-sans-extension buffer-file-name) ".cpp"))) - (when-let (file (car-safe (projectile-get-other-files - buffer-file-name - (projectile-current-project-files)))) + (when-let* ((file (car-safe (projectile-get-other-files + buffer-file-name + (projectile-current-project-files))))) (equal (file-name-extension file) "cpp"))))) (defun +cc-objc-header-file-p () @@ -105,28 +105,24 @@ compilation database is present in the project.") (def-package! modern-cpp-font-lock - :commands modern-c++-font-lock-mode - :init (add-hook 'c++-mode-hook #'modern-c++-font-lock-mode)) + :hook (c++-mode . modern-c++-font-lock-mode)) (def-package! irony :after cc-mode :commands irony-install-server - :preface - (setq irony-server-install-prefix (concat doom-etc-dir "irony-server/")) - :init - (add-hook! (c-mode c++-mode objc-mode) #'irony-mode) + :preface (setq irony-server-install-prefix (concat doom-etc-dir "irony-server/")) + :hook ((c-mode c++-mode objc-mode) . irony-mode) :config (unless (file-directory-p irony-server-install-prefix) (warn "irony-mode: server isn't installed; run M-x irony-install-server")) - ;; Initialize compilation database, if present. Otherwise, fall back on ;; `+cc-compiler-options'. (add-hook 'irony-mode-hook #'+cc|irony-init-compile-options)) (def-package! irony-eldoc :after irony - :config (add-hook 'irony-mode-hook #'irony-eldoc)) + :hook (irony-mode . irony-eldoc)) (def-package! flycheck-irony :when (featurep! :feature syntax-checker) @@ -157,8 +153,7 @@ compilation database is present in the project.") (def-package! opencl-mode :mode "\\.cl$") (def-package! demangle-mode - :commands demangle-mode - :init (add-hook 'llvm-mode-hook #'demangle-mode)) + :hook llvm-mode) (def-package! glsl-mode :mode "\\.glsl$" diff --git a/modules/lang/clojure/config.el b/modules/lang/clojure/config.el index 5d90ae371..5dd2ec8c5 100644 --- a/modules/lang/clojure/config.el +++ b/modules/lang/clojure/config.el @@ -1,9 +1,44 @@ ;;; lang/clojure/config.el -*- lexical-binding: t; -*- (def-package! clojure-mode - :mode "\\.clj$") + :mode "\\.clj$" + :mode ("\\.cljs$" . clojurescript-mode) + :config + (map! :map clojure-mode-map + (:localleader + :n "'" #'cider-jack-in + :n "\"" #'cider-jack-in-clojurescript + :n "B" #'cider-switch-to-repl-buffer + :n "b" #'cider-eval-buffer + :n "n" #'cider-repl-set-ns + :n "j" #'cider-find-var + :n "d" #'cider-doc + :n "c" #'cider-repl-clear-buffer + :n "p" #'cider-eval-sexp-at-point + :n "r" #'cider-eval-region))) + + +(def-package! clj-refactor + :after clojure-mode + :config + ;; setup some extra namespace auto completion for great awesome + (dolist (mapping '(("re-frame" . "re-frame.core") + ("reagent" . "reagent.core") + ("str" . "clojure.str"))) + (add-to-list 'cljr-magic-require-namespaces mapping t))) + (def-package! cider - :commands (cider-jack-in cider-mode) + ;; NOTE: if you don't have an org directory set (the dir doesn't exist), cider jack in won't work. + :commands (cider-jack-in cider-mode cider-jack-in-clojurescript) :config - (setq nrepl-hide-special-buffers t)) + (setq nrepl-hide-special-buffers t) + + ;; settings for cider repl as a popup (prevent it from being closed on escape, especially.) + (set! :popup "^\\*cider" :regexp t :noselect t :noesc t) + + ;; Setup cider for clojurescript / figwheel dev. + (setq cider-cljs-lein-repl + "(do (require 'figwheel-sidecar.repl-api) + (figwheel-sidecar.repl-api/start-figwheel!) + (figwheel-sidecar.repl-api/cljs-repl))")) diff --git a/modules/lang/clojure/packages.el b/modules/lang/clojure/packages.el index bc69c2464..a61dc39ed 100644 --- a/modules/lang/clojure/packages.el +++ b/modules/lang/clojure/packages.el @@ -2,4 +2,5 @@ ;;; lang/clojure/packages.el (package! cider) +(package! clj-refactor) diff --git a/modules/lang/crystal/config.el b/modules/lang/crystal/config.el index b6b047aa1..61618d2bf 100644 --- a/modules/lang/crystal/config.el +++ b/modules/lang/crystal/config.el @@ -9,3 +9,7 @@ (:exec . "%c %s") (:description . "Run Crystal script")))) + +(def-package! flycheck-crystal + :after crystal-mode + :config (add-hook 'crystal-mode-hook #'flycheck-mode)) diff --git a/modules/lang/crystal/packages.el b/modules/lang/crystal/packages.el index e2c61e67d..d0fd6e985 100644 --- a/modules/lang/crystal/packages.el +++ b/modules/lang/crystal/packages.el @@ -1,5 +1,6 @@ ;; -*- no-byte-compile: t; -*- ;;; lang/crystal/packages.el -(package! crystal-mode :recipe (:fetcher github :repo "dotmilk/emacs-crystal-mode")) +(package! crystal-mode) +(package! flycheck-crystal) diff --git a/modules/lang/elm/config.el b/modules/lang/elm/config.el index e8537e043..f205c9b45 100644 --- a/modules/lang/elm/config.el +++ b/modules/lang/elm/config.el @@ -9,7 +9,6 @@ (def-package! flycheck-elm - :after elm-mode - :config - (add-hook 'flycheck-mode-hook #'flycheck-elm-setup)) + :after (:all flycheck elm-mode) + :hook (flycheck-mode . flycheck-elm-setup)) diff --git a/modules/lang/emacs-lisp/config.el b/modules/lang/emacs-lisp/config.el index 7cdf28216..f602a494b 100644 --- a/modules/lang/emacs-lisp/config.el +++ b/modules/lang/emacs-lisp/config.el @@ -72,6 +72,7 @@ (def-package! slime + :defer t :config (setq inferior-lisp-program "clisp") (require 'slime-fuzzy)) diff --git a/modules/lang/go/config.el b/modules/lang/go/config.el index e2d3f37df..2cb8222a9 100644 --- a/modules/lang/go/config.el +++ b/modules/lang/go/config.el @@ -65,9 +65,7 @@ (def-package! go-eldoc - :after go-mode - :commands go-eldoc-setup - :config (add-hook 'go-mode-hook #'go-eldoc-setup)) + :hook (go-mode . go-eldoc-setup)) (def-package! go-guru diff --git a/modules/lang/haskell/+dante.el b/modules/lang/haskell/+dante.el index bf2d61fa1..9e580ae51 100644 --- a/modules/lang/haskell/+dante.el +++ b/modules/lang/haskell/+dante.el @@ -1,10 +1,12 @@ ;;; lang/haskell/+dante.el -*- lexical-binding: t; -*- +;;;###if (featurep! +dante) (def-package! dante :after haskell-mode - :init - (add-hook! 'haskell-mode-hook #'(dante-mode interactive-haskell-mode)) + :hook (haskell-mode . dante-mode) :config + (add-hook 'haskell-mode-hook #'interactive-haskell-mode) + (unless (executable-find "cabal") (warn "haskell-mode: couldn't find cabal") (remove-hook 'haskell-mode-hook #'dante-mode)) diff --git a/modules/lang/haskell/+intero.el b/modules/lang/haskell/+intero.el index 5adb63d25..666ef0355 100644 --- a/modules/lang/haskell/+intero.el +++ b/modules/lang/haskell/+intero.el @@ -1,9 +1,8 @@ ;;; lang/haskell/+intero.el -*- lexical-binding: t; -*- +;;;###if (featurep! +intero) (def-package! intero - :commands intero-mode - :init - (add-hook 'haskell-mode-hook #'intero-mode) + :hook (haskell-mode . intero-mode) :config (unless (executable-find "stack") (warn "haskell-mode: couldn't find stack, disabling intero") @@ -16,6 +15,4 @@ (def-package! hindent - :commands hindent-mode - :init - (add-hook 'haskell-mode-hook #'hindent-mode)) + :hook (haskell-mode . hindent-mode)) diff --git a/modules/lang/java/+eclim.el b/modules/lang/java/+eclim.el index 3e9c97dc9..8bacaa9d6 100644 --- a/modules/lang/java/+eclim.el +++ b/modules/lang/java/+eclim.el @@ -1,10 +1,10 @@ ;;; lang/java/+eclim.el -*- lexical-binding: t; -*- +;;;###if (featurep! +eclim) ;; NOTE This submodule is incomplete (def-package! eclim - :init - (add-hook 'java-mode-hook #'eclim-mode) + :hook (java-mode . eclim-mode) :config (set! :jump 'java-mode :definition #'eclim-java-find-declaration @@ -53,6 +53,6 @@ (def-package! company-emacs-eclim :when (featurep! :completion company) - :after java + :after java-mode :config (set! :company-backend 'java-mode '(company-emacs-eclim))) diff --git a/modules/lang/java/+meghanada.el b/modules/lang/java/+meghanada.el index 1c78e7ba5..4b7fe91cf 100644 --- a/modules/lang/java/+meghanada.el +++ b/modules/lang/java/+meghanada.el @@ -1,9 +1,8 @@ ;;; lang/java/+meghanada.el -*- lexical-binding: t; -*- +;;;###if (featurep! +meghanada) (def-package! meghanada - :commands meghanada-mode - :init - (add-hook! 'java-mode-hook #'(meghanada-mode rainbow-delimiters-mode)) + :hook (java-mode . meghanada-mode) :config (setq meghanada-server-install-dir (concat doom-etc-dir "meghanada-server/") meghanada-use-company (featurep! :completion company) @@ -11,11 +10,14 @@ meghanada-use-eldoc t meghanada-use-auto-start t) + (add-hook 'java-mode-hook #'rainbow-delimiters-mode) + ;; Setup on first use - (meghanada-install-server) - (if (file-exists-p (meghanada--locate-server-jar)) - (add-hook! 'meghanada-mode-hook #'(flycheck-mode eldoc-mode)) - (warn "java-mode: meghanada-server not installed, java-mode will run with reduced functionality")) + (unless (bound-and-true-p byte-compile-current-file) + (meghanada-install-server) + (if (file-exists-p (meghanada--locate-server-jar)) + (add-hook! 'meghanada-mode-hook #'(flycheck-mode eldoc-mode)) + (warn "java-mode: meghanada-server not installed, java-mode will run with reduced functionality"))) (set! :jump 'java-mode :definition #'meghanada-jump-declaration diff --git a/modules/lang/javascript/autoload.el b/modules/lang/javascript/autoload.el index 2a8ead5a6..3df1ecd03 100644 --- a/modules/lang/javascript/autoload.el +++ b/modules/lang/javascript/autoload.el @@ -10,14 +10,14 @@ ignore the cache." (or (and (not refresh-p) (gethash project-root +javascript-npm-conf)) (let ((package-file (expand-file-name "package.json" project-root))) - (when-let (json (and (file-exists-p package-file) - (json-read-file package-file))) + (when-let* ((json (and (file-exists-p package-file) + (json-read-file package-file)))) (puthash project-root json +javascript-npm-conf)))))) ;;;###autoload (defun +javascript-npm-dep-p (packages &optional project-root refresh-p) - (when-let (data (and (bound-and-true-p +javascript-npm-mode) - (+javascript-npm-conf project-root refresh-p))) + (when-let* ((data (and (bound-and-true-p +javascript-npm-mode) + (+javascript-npm-conf project-root refresh-p)))) (let ((deps (append (cdr (assq 'dependencies data)) (cdr (assq 'devDependencies data))))) (cond ((listp packages) diff --git a/modules/lang/javascript/config.el b/modules/lang/javascript/config.el index abcca44ab..772976ae9 100644 --- a/modules/lang/javascript/config.el +++ b/modules/lang/javascript/config.el @@ -15,8 +15,8 @@ (set! :electric 'js2-mode :chars '(?\} ?\) ?.)) (set! :jump 'js2-mode :xref-backend #'xref-js2-xref-backend) - ;; Conform switch-case indentation to editorconfig's config - (set! :editorconfig :add '(js2-mode js2-basic-offset js-switch-indent-offset)) + ;; Conform switch-case indentation to js2 normal indent + (defvaralias 'js-switch-indent-offset 'js2-basic-offset) (sp-with-modes '(js2-mode rjsx-mode) (sp-local-pair "/* " " */" :post-handlers '(("| " "SPC")))) @@ -27,8 +27,8 @@ (defun +javascript|init-flycheck-eslint () "Favor local eslint over global installs and configure flycheck for eslint." (when (derived-mode-p 'js-mode) - (when-let ((exec-path (list (doom-project-expand "node_modules/.bin"))) - (eslint (executable-find "eslint"))) + (when-let* ((exec-path (list (doom-project-expand "node_modules/.bin"))) + (eslint (executable-find "eslint"))) (setq-local flycheck-javascript-eslint-executable eslint)) (when (flycheck-find-checker-executable 'javascript-eslint) ;; Flycheck has it's own trailing command and semicolon warning that was @@ -93,8 +93,7 @@ (def-package! tern - :commands tern-mode - :init (add-hook 'js2-mode-hook #'tern-mode) + :hook (js2-mode . tern-mode) :config (advice-add #'tern-project-dir :override #'doom-project-root)) diff --git a/modules/lang/latex/config.el b/modules/lang/latex/config.el index c160305cb..75d10c658 100644 --- a/modules/lang/latex/config.el +++ b/modules/lang/latex/config.el @@ -67,6 +67,7 @@ (def-package! bibtex ; built-in + :defer t :config (setq bibtex-dialect 'biblatex bibtex-align-at-equal-sign t diff --git a/modules/lang/ledger/config.el b/modules/lang/ledger/config.el index f76966619..5db4e7c71 100644 --- a/modules/lang/ledger/config.el +++ b/modules/lang/ledger/config.el @@ -2,14 +2,12 @@ (def-package! ledger-mode :mode "\\.ledger$" - :commands ledger-mode :config (setq ledger-clear-whole-transactions 1)) (def-package! evil-ledger :when (featurep! :feature evil) - :after ledger-mode - :config (add-hook 'ledger-mode-hook #'evil-ledger-mode)) + :hook (ledger-mode . evil-ledger-mode)) (def-package! flycheck-ledger diff --git a/modules/lang/lua/config.el b/modules/lang/lua/config.el index dd5d423cb..fdc6ad623 100644 --- a/modules/lang/lua/config.el +++ b/modules/lang/lua/config.el @@ -3,12 +3,11 @@ (def-package! lua-mode :mode "\\.lua$" :interpreter "lua" - :init - (add-hook 'lua-mode-hook #'flycheck-mode) :config + (add-hook 'lua-mode-hook #'flycheck-mode) + (set! :electric 'lua-mode :words '("else" "end")) (set! :repl 'lua-mode #'+lua/repl) - ;; sp's lua-specific rules are obnoxious, so we disable them (setq sp-pairs (delete (assq 'lua-mode sp-pairs) sp-pairs)) @@ -23,16 +22,14 @@ (def-package! company-lua - :when (featurep! :completion company) - :after lua-mode + :after (:all company lua-mode) :config (set! :company-backend 'lua-mode '(company-lua company-yasnippet))) (def-package! moonscript :mode ("\\.moon$" . moonscript-mode) - :config - (set! :editorconfig :add '(moonscript-mode moonscript-indent-offset))) + :config (defvaralias 'moonscript-indent-offset 'tab-width)) ;; diff --git a/modules/lang/nix/config.el b/modules/lang/nix/config.el new file mode 100644 index 000000000..e9d090fc3 --- /dev/null +++ b/modules/lang/nix/config.el @@ -0,0 +1,4 @@ +;;; lang/nix/config.el -*- lexical-binding: t; -*- + +(def-package! nix-mode + :mode "\\.nix$") diff --git a/modules/lang/ocaml/config.el b/modules/lang/ocaml/config.el index e43eb4135..22067cffb 100644 --- a/modules/lang/ocaml/config.el +++ b/modules/lang/ocaml/config.el @@ -6,5 +6,4 @@ (def-package! merlin :after tuareg - :config - (add-hook 'tuareg-mode-hook #'merlin-mode)) + :hook (tuareg-mode . merlin-mode)) diff --git a/modules/org/org-attach/config.el b/modules/lang/org/+attach.el similarity index 82% rename from modules/org/org-attach/config.el rename to modules/lang/org/+attach.el index 6f5dda9c5..94988d99e 100644 --- a/modules/org/org-attach/config.el +++ b/modules/lang/org/+attach.el @@ -1,10 +1,4 @@ -;;; org/org-attach/config.el -*- lexical-binding: t; -*- - -(defvar +org-attach-dir (expand-file-name ".attach/" +org-dir) - "Where to store attachments (relative to current org file).") - - -(add-hook 'org-load-hook #'+org-attach|init t) +;;; lang/org/+attach.el -*- lexical-binding: t; -*- ;; I believe Org's native attachment system is over-complicated and litters ;; files with metadata I don't want. So I wrote my own, which: @@ -21,6 +15,10 @@ ;; + `+org-attach/url' ;; + :org [FILE/URL] +(defvar +org-attach-dir (expand-file-name ".attach/" +org-dir) + "Where to store attachments (relative to current org file).") + + (def-package! org-download :commands (org-download-dnd org-download-dnd-base64) :init @@ -39,10 +37,11 @@ (setq org-download-screenshot-method (cond (IS-MAC "screencapture -i %s") (IS-LINUX - (cond ((executable-find "maim") - "maim -s %s") - ((executable-find "scrot") - "scrot -s %s"))))) + (cond ((executable-find "maim") "maim -s %s") + ((executable-find "scrot") "scrot -s %s"))))) + + ;; Ensure that relative inline image paths are relative to the attachment folder. + (advice-add #'org-display-inline-images :around #'+org-attach*relative-to-attach-dir) ;; Handle non-image files a little differently. Images should be inserted ;; as-is, as image previews. Other files, like pdfs or zips, should be linked @@ -61,10 +60,11 @@ :filter-return #'+org-attach*download-fullname)) ;; -(defun +org-attach|init () +(after! org (setq org-attach-directory +org-attach-dir) - (push +org-attach-dir projectile-globally-ignored-directories) + (push (car (last (split-string +org-attach-dir "/" t))) + projectile-globally-ignored-directories) (after! recentf (push (format "%s.+$" (regexp-quote +org-attach-dir)) diff --git a/modules/org/org-babel/config.el b/modules/lang/org/+babel.el similarity index 78% rename from modules/org/org-babel/config.el rename to modules/lang/org/+babel.el index fd1d39c87..73a7dba78 100644 --- a/modules/org/org-babel/config.el +++ b/modules/lang/org/+babel.el @@ -1,6 +1,4 @@ -;;; org/org-babel/config.el -*- lexical-binding: t; -*- - -(add-hook 'org-load-hook #'+org-babel|init t) +;;; lang/org/+babel.el -*- lexical-binding: t; -*- (defvar +org-babel-languages '(calc @@ -24,7 +22,8 @@ translate) ; ob-translate "A list of org-babel languages to load.") -(defun +org-babel|init () + +(after! org (setq org-src-fontify-natively t ; make code pretty org-src-preserve-indentation t ; use native major-mode indentation org-src-tab-acts-natively t @@ -46,9 +45,4 @@ (cl-loop with fn = (if others #'not #'identity) for p in params if (funcall fn (eq (car p) key)) - collect p)) - - (defun +org|src-mode-remove-header () - "Remove header-line with keybinding help; I know the keybinds." - (setq header-line-format nil)) - (add-hook 'org-src-mode-hook #'+org|src-mode-remove-header)) + collect p))) diff --git a/modules/org/org-capture/config.el b/modules/lang/org/+capture.el similarity index 57% rename from modules/org/org-capture/config.el rename to modules/lang/org/+capture.el index d52f60b7e..b7c34a869 100644 --- a/modules/org/org-capture/config.el +++ b/modules/lang/org/+capture.el @@ -1,6 +1,4 @@ -;;; org/org-capture/config.el -*- lexical-binding: t; -*- - -(add-hook 'org-load-hook #'+org-capture|init t) +;;; lang/org/+capture.el -*- lexical-binding: t; -*- ;; Sets up two `org-capture' workflows that I like: ;; @@ -12,17 +10,24 @@ ;; anywhere I can call org-capture (whether or not Emacs is open/running), ;; like, say, from qutebrowser, vimperator, dmenu or a global keybinding. -(setq org-default-notes-file (concat +org-dir "notes.org") - org-capture-templates - '(("t" "Todo" entry - (file+headline (expand-file-name "todo.org" +org-dir) "Inbox") - "* [ ] %?\n%i" :prepend t :kill-buffer t) +(defvar +org-default-notes-file "notes.org" + "TODO") - ("n" "Notes" entry - (file+headline org-default-notes-file "Inbox") - "* %u %?\n%i" :prepend t :kill-buffer t))) +(defvar org-capture-templates + '(("t" "Todo" entry + (file+headline (expand-file-name "todo.org" +org-dir) "Inbox") + "* [ ] %?\n%i" :prepend t :kill-buffer t) + + ("n" "Notes" entry + (file+headline org-default-notes-file "Inbox") + "* %u %?\n%i" :prepend t :kill-buffer t))) + + +(after! org + (defvaralias 'org-default-notes-file '+org-default-notes-file) + + (setq org-default-notes-file (expand-file-name +org-default-notes-file +org-dir)) -(defun +org-capture|init () (add-hook 'org-capture-after-finalize-hook #'+org-capture|cleanup-frame) (when (featurep! :feature evil) diff --git a/modules/org/org-export/config.el b/modules/lang/org/+export.el similarity index 81% rename from modules/org/org-export/config.el rename to modules/lang/org/+export.el index a366d61d2..d2e69db4d 100644 --- a/modules/org/org-export/config.el +++ b/modules/lang/org/+export.el @@ -1,6 +1,4 @@ -;;; org/org-export/config.el -*- lexical-binding: t; -*- - -(add-hook 'org-load-hook #'+org-export|init t) +;;; lang/org/+export.el -*- lexical-binding: t; -*- ;; I don't have any beef with org's built-in export system, but I do wish it ;; would export to a central directory, rather than `default-directory'. This is @@ -8,16 +6,19 @@ ;; refer back to old exports if needed. (def-package! ox-pandoc + :defer t :config - (unless (executable-find "pandoc") - (warn "org-export: couldn't find pandoc, disabling pandoc export")) + (when (executable-find "pandoc") + (push 'pandoc org-export-backends)) (setq org-pandoc-options '((standalone . t) (mathjax . t) (parse-raw . t)))) ;; -(defun +org-export|init () +(after! org + (add-transient-hook! #'org-export-dispatch (require 'ox-pandoc)) + (setq org-export-directory (expand-file-name ".export" +org-dir) org-export-backends '(ascii html latex md) org-export-with-toc t diff --git a/modules/org/org-present/config.el b/modules/lang/org/+present.el similarity index 89% rename from modules/org/org-present/config.el rename to modules/lang/org/+present.el index 560cd8dc3..daec968aa 100644 --- a/modules/org/org-present/config.el +++ b/modules/lang/org/+present.el @@ -1,16 +1,15 @@ -;;; org/org-present/config.el -*- lexical-binding: t; -*- +;;; lang/org/+present.el -*- lexical-binding: t; -*- (defvar +org-present-text-scale 7 "The `text-scale-amount' for `org-tree-slide-mode'.") -(add-hook 'org-load-hook #'+org-present|init t) - ;; ;; Plugins ;; (def-package! ox-reveal + :defer t :config (setq org-reveal-root "http://cdn.jsdelivr.net/reveal.js/3.0.0/" org-reveal-mathjax t)) @@ -44,7 +43,7 @@ ;; Bootstrap ;; -(defun +org-present|init () +(after! org (require 'ox-reveal) (map! :map org-mode-map "" #'+org-present/start)) diff --git a/modules/lang/org/README.org b/modules/lang/org/README.org new file mode 100644 index 000000000..e69de29bb diff --git a/modules/org/org-attach/autoload/evil.el b/modules/lang/org/autoload/evil.el similarity index 61% rename from modules/org/org-attach/autoload/evil.el rename to modules/lang/org/autoload/evil.el index b32920298..62bfca831 100644 --- a/modules/org/org-attach/autoload/evil.el +++ b/modules/lang/org/autoload/evil.el @@ -1,9 +1,9 @@ -;; org/org-attach/autoload/evil.el -*- lexical-binding: t; -*- +;;; lang/org/autoload/evil.el -*- lexical-binding: t; -*- ;;;###if (featurep! :feature evil) ;; TODO +org-attach:find -;;;###autoload (autoload '+org-attach:uri "org/org-attach/autoload/evil" nil t) +;;;###autoload (autoload '+org-attach:uri "lang/org/autoload/evil" nil t) (evil-define-command +org-attach:uri (uri) "Downloads the file at URL and places an org link to it at the cursor." (interactive "") diff --git a/modules/org/org-attach/autoload/org-attach.el b/modules/lang/org/autoload/org-attach.el similarity index 82% rename from modules/org/org-attach/autoload/org-attach.el rename to modules/lang/org/autoload/org-attach.el index 783ee2d99..0cd9a7380 100644 --- a/modules/org/org-attach/autoload/org-attach.el +++ b/modules/lang/org/autoload/org-attach.el @@ -1,4 +1,5 @@ -;;; org/org-attach/autoload/org-attach.el -*- lexical-binding: t; -*- +;;; lang/org/autoload/org-attach.el -*- lexical-binding: t; -*- +;;;###if (featurep! +attach) (defun +org-attach--icon (path) (char-to-string @@ -34,8 +35,8 @@ ;; (goto-char (point-min)) ;; (while (progn (org-next-link) (not org-link-search-failed)) ;; (setq element (org-element-context)) -;; (when-let (file (and (eq (org-element-type element) 'link) -;; (expand-file-name (org-element-property :path element)))) +;; (when-let* (file (and (eq (org-element-type element) 'link) +;; (expand-file-name (org-element-property :path element)))) ;; (when (and (string= (org-element-property :type element) "file") ;; (string= (concat (file-name-base (directory-file-name (file-name-directory file))) "/") ;; org-attach-directory) @@ -97,6 +98,8 @@ the cursor." (delete-region (match-beginning 0) (match-end 0)) (newline)) (cond ((image-type-from-file-name filename) + (when (file-in-directory-p filename +org-attach-dir) + (setq filename (file-relative-name filename +org-dir))) (insert (concat (if (= org-download-image-html-width 0) "" @@ -114,3 +117,17 @@ the cursor." (file-relative-name filename buffer-file-name) (file-name-nondirectory (directory-file-name rel-path))))))) +;;;###autoload +(defun +org-attach*relative-to-attach-dir (orig-fn &rest args) + "TODO" + (if (file-in-directory-p buffer-file-name +org-dir) + (let* ((context (save-match-data (org-element-context))) + (file (org-link-unescape (org-element-property :path context))) + (default-directory + (if (string-prefix-p + (concat "./" (car (last (split-string +org-attach-dir "/" t)))) + file) + +org-dir + default-directory))) + (apply orig-fn args)) + (apply orig-fn args))) diff --git a/modules/org/org-babel/autoload.el b/modules/lang/org/autoload/org-babel.el similarity index 79% rename from modules/org/org-babel/autoload.el rename to modules/lang/org/autoload/org-babel.el index 489f4f3b3..8bf723f4e 100644 --- a/modules/org/org-babel/autoload.el +++ b/modules/lang/org/autoload/org-babel.el @@ -1,4 +1,5 @@ -;;; org/org-babel/autoload.el -*- lexical-binding: t; -*- +;;; lang/org/autoload/org-babel.el -*- lexical-binding: t; -*- +;;;###if (featurep! +babel) ;;;###autoload (defun +org-babel/edit (arg) diff --git a/modules/org/org-capture/autoload/org-capture.el b/modules/lang/org/autoload/org-capture.el similarity index 72% rename from modules/org/org-capture/autoload/org-capture.el rename to modules/lang/org/autoload/org-capture.el index 2c884357a..bd7dce4d4 100644 --- a/modules/org/org-capture/autoload/org-capture.el +++ b/modules/lang/org/autoload/org-capture.el @@ -1,4 +1,15 @@ -;;; org/org-capture/autoload/org-capture.el -*- lexical-binding: t; -*- +;;; lang/org/autoload/org-capture.el -*- lexical-binding: t; -*- +;;;###if (featurep! +capture) + +(when (featurep! :feature evil) +;;;###autoload (autoload '+org-capture:open "lang/org/autoload/org-capture" nil t) + (evil-define-operator +org-capture:open (&optional beg end) + "Evil ex interface to `+org-capture/dwim'." + :move-point nil :type inclusive + (interactive "") + (+org-capture/open + (unless (or (evil-normal-state-p) (evil-insert-state-p)) + (buffer-substring beg end))))) ;;;###autoload (defun +org-capture/open (&optional string key) @@ -7,12 +18,12 @@ Uses the capture template specified by KEY. Otherwise, prompts you for one." (interactive) (let ((key (or key "n"))) - (if-let (string (cond ((not (equal string "")) - string) - ((region-active-p) - (buffer-substring-no-properties - (region-beginning) - (region-end))))) + (if-let* ((string (cond ((not (equal string "")) + string) + ((region-active-p) + (buffer-substring-no-properties + (region-beginning) + (region-end)))))) (org-capture-string string key) (org-capture nil key)))) diff --git a/modules/org/org/autoload/org-link.el b/modules/lang/org/autoload/org-link.el similarity index 100% rename from modules/org/org/autoload/org-link.el rename to modules/lang/org/autoload/org-link.el diff --git a/modules/org/org-present/autoload.el b/modules/lang/org/autoload/org-present.el similarity index 97% rename from modules/org/org-present/autoload.el rename to modules/lang/org/autoload/org-present.el index b50786d45..61ca7216d 100644 --- a/modules/org/org-present/autoload.el +++ b/modules/lang/org/autoload/org-present.el @@ -1,4 +1,5 @@ -;;; org/org-present/autoload.el -*- lexical-binding: t; -*- +;;; lang/org/autoload/org-present.el -*- lexical-binding: t; -*- +;;;###if (featurep! +present) (defvar +org-present--overlays nil) ;;;###autoload diff --git a/modules/org/org/autoload/org.el b/modules/lang/org/autoload/org.el similarity index 98% rename from modules/org/org/autoload/org.el rename to modules/lang/org/autoload/org.el index da252317a..eb351f8cc 100644 --- a/modules/org/org/autoload/org.el +++ b/modules/lang/org/autoload/org.el @@ -290,8 +290,8 @@ with `org-cycle'). Also: (save-excursion (let ((remove (list (match-beginning 0) (match-end 0))) (description (if (match-end 3) - (org-match-string-no-properties 3) - (org-match-string-no-properties 1)))) + (match-string-no-properties 3) + (match-string-no-properties 1)))) (apply #'delete-region remove) (insert description)))) diff --git a/modules/org/org/autoload/tables.el b/modules/lang/org/autoload/tables.el similarity index 100% rename from modules/org/org/autoload/tables.el rename to modules/lang/org/autoload/tables.el diff --git a/modules/lang/org/config.el b/modules/lang/org/config.el new file mode 100644 index 000000000..182afcf31 --- /dev/null +++ b/modules/lang/org/config.el @@ -0,0 +1,265 @@ +;;; lang/org/config.el -*- lexical-binding: t; -*- + +(defvar +org-dir (expand-file-name "~/work/org/") + "The directory where org files are kept.") + +;; Ensure ELPA org is prioritized above built-in org. +(when-let* ((path (locate-library "org" nil doom--package-load-path))) + (setq load-path (delete path load-path)) + (push (file-name-directory path) load-path)) + +;; Sub-modules +(if (featurep! +attach) (load! +attach)) +(if (featurep! +babel) (load! +babel)) +(if (featurep! +capture) (load! +capture)) +(if (featurep! +export) (load! +export)) +(if (featurep! +present) (load! +present)) +;; TODO (if (featurep! +publish) (load! +publish)) + + +;; +;; Plugins +;; + +(def-package! toc-org + :commands toc-org-enable) + +(def-package! org-crypt ; built-in + :commands org-crypt-use-before-save-magic + :config + (setq org-tags-exclude-from-inheritance '("crypt") + org-crypt-key user-mail-address + epa-file-encrypt-to user-mail-address)) + +(def-package! org-bullets + :commands org-bullets-mode) + + +;; +;; Bootstrap +;; + +(after! org + ;; Occasionally, Emacs encounters an error loading the built-in org, aborting + ;; the load. This results in a broken, partially loaded state. This require + ;; tries to set it straight. + (require 'org) + + (defvaralias 'org-directory '+org-dir) + + (org-crypt-use-before-save-magic) + (+org-init-ui) + (+org-init-keybinds) + (+org-hacks)) + +(add-hook! org-mode + #'(doom|disable-line-numbers ; no line numbers + org-bullets-mode ; "prettier" bullets + org-indent-mode ; margin-based indentation + toc-org-enable ; auto-table of contents + visual-line-mode ; line wrapping + + +org|enable-auto-reformat-tables + +org|enable-auto-update-cookies + +org|smartparens-compatibility-config + +org|unfold-to-2nd-level-or-point + +org|show-paren-mode-compatibility + )) + + +;; +;; Config hooks +;; + +(defun +org|unfold-to-2nd-level-or-point () + "My version of the 'overview' #+STARTUP option: expand first-level headings. +Expands the first level, but no further. If point was left somewhere deeper, +unfold to point on startup." + (unless org-agenda-inhibit-startup + (when (eq org-startup-folded t) + (outline-hide-sublevels 2)) + (when (outline-invisible-p) + (ignore-errors + (save-excursion + (outline-previous-visible-heading 1) + (org-show-subtree)))))) + +(defun +org|smartparens-compatibility-config () + "Instruct `smartparens' not to impose itself in org-mode." + (defun +org-sp-point-in-checkbox-p (_id action _context) + (when (eq action 'insert) + (sp--looking-at-p "\\s-*]"))) + + ;; make delimiter auto-closing a little more conservative + (sp-with-modes 'org-mode + (sp-local-pair "*" nil :unless '(sp-point-after-word-p sp-point-before-word-p sp-point-at-bol-p)) + (sp-local-pair "_" nil :unless '(sp-point-after-word-p sp-point-before-word-p)) + (sp-local-pair "/" nil :unless '(sp-point-after-word-p sp-point-before-word-p +org-sp-point-in-checkbox-p)) + (sp-local-pair "~" nil :unless '(sp-point-after-word-p sp-point-before-word-p)) + (sp-local-pair "=" nil :unless '(sp-point-after-word-p sp-point-before-word-p)))) + +(defun +org|enable-auto-reformat-tables () + "Realign tables exiting insert mode (`evil-mode')." + (when (featurep 'evil) + (add-hook 'evil-insert-state-exit-hook #'+org|realign-table-maybe nil t))) + +(defun +org|enable-auto-update-cookies () + "Update statistics cookies when saving or exiting insert mode (`evil-mode')." + (when (featurep 'evil) + (add-hook 'evil-insert-state-exit-hook #'+org|update-cookies nil t)) + (add-hook 'before-save-hook #'+org|update-cookies nil t)) + +(defun +org|show-paren-mode-compatibility () + "`show-paren-mode' causes flickering with indentation margins made by +`org-indent-mode', so we simply turn off show-paren-mode altogether." + (set (make-local-variable 'show-paren-mode) nil)) + + +;; +(defun +org-init-ui () + "Configures the UI for `org-mode'." + (setq-default + org-adapt-indentation nil + org-agenda-dim-blocked-tasks nil + org-agenda-files (directory-files +org-dir t "\\.org$" t) + org-agenda-inhibit-startup t + org-agenda-skip-unavailable-files nil + org-cycle-include-plain-lists t + org-cycle-separator-lines 1 + org-entities-user '(("flat" "\\flat" nil "" "" "266D" "♭") ("sharp" "\\sharp" nil "" "" "266F" "♯")) + ;; org-ellipsis " ... " + org-fontify-done-headline t + org-fontify-quote-and-verse-blocks t + org-fontify-whole-heading-line t + org-footnote-auto-label 'plain + org-hidden-keywords nil + org-hide-emphasis-markers nil + org-hide-leading-stars t + org-hide-leading-stars-before-indent-mode t + org-image-actual-width nil + org-indent-indentation-per-level 2 + org-indent-mode-turns-on-hiding-stars t + org-pretty-entities nil + org-pretty-entities-include-sub-superscripts t + org-priority-faces + `((?a . ,(face-foreground 'error)) + (?b . ,(face-foreground 'warning)) + (?c . ,(face-foreground 'success))) + org-startup-folded t + org-startup-indented t + org-startup-with-inline-images nil + org-tags-column 0 + org-todo-keywords + '((sequence "[ ](t)" "[-](p)" "[?](m)" "|" "[X](d)") + (sequence "TODO(T)" "|" "DONE(D)") + (sequence "NEXT(n)" "ACTIVE(a)" "WAITING(w)" "LATER(l)" "|" "CANCELLED(c)")) + org-use-sub-superscripts '{} + outline-blank-line t + + ;; LaTeX previews are too small and usually render to light backgrounds, so + ;; this enlargens them and ensures their background (and foreground) match the + ;; current theme. + org-preview-latex-image-directory (concat doom-cache-dir "org-latex/") + org-format-latex-options (plist-put org-format-latex-options :scale 1.5) + org-format-latex-options + (plist-put org-format-latex-options + :background (face-attribute (or (cadr (assq 'default face-remapping-alist)) + 'default) + :background nil t))) + + ;; Custom links + (org-link-set-parameters + "org" + :complete (lambda () (+org-link-read-file "org" +org-dir)) + :follow (lambda (link) (find-file (expand-file-name link +org-dir))) + :face (lambda (link) + (if (file-exists-p (expand-file-name link +org-dir)) + 'org-link + 'error)))) + +(defun +org-init-keybinds () + "Sets up org-mode and evil keybindings. Tries to fix the idiosyncrasies +between the two." + (map! :map org-mode-map + "RET" #'org-return-indent + "C-c C-S-l" #'+org/remove-link + :n "C-c C-i" #'org-toggle-inline-images + + :n "RET" #'+org/dwim-at-point + + ;; Navigate table cells (from insert-mode) + :i "C-l" #'+org/table-next-field + :i "C-h" #'+org/table-previous-field + :i "C-k" #'+org/table-previous-row + :i "C-j" #'+org/table-next-row + ;; Expand tables (or shiftmeta move) + :ni "C-S-l" #'+org/table-append-field-or-shift-right + :ni "C-S-h" #'+org/table-prepend-field-or-shift-left + :ni "C-S-k" #'org-metaup + :ni "C-S-j" #'org-metadown + + :n [tab] #'+org/toggle-fold + :i [tab] #'+org/indent-or-next-field-or-yas-expand + :i [backtab] #'+org/dedent-or-prev-field + + :ni [M-return] (λ! (+org/insert-item 'below)) + :ni [S-M-return] (λ! (+org/insert-item 'above)) + + :m "]]" (λ! (org-forward-heading-same-level nil) (org-beginning-of-line)) + :m "[[" (λ! (org-backward-heading-same-level nil) (org-beginning-of-line)) + :m "]l" #'org-next-link + :m "[l" #'org-previous-link + :m "$" #'org-end-of-line + :m "^" #'org-beginning-of-line + :n "gQ" #'org-fill-paragraph + :n "<" #'org-metaleft + :n ">" #'org-metaright + :v "<" (λ! (org-metaleft) (evil-visual-restore)) + :v ">" (λ! (org-metaright) (evil-visual-restore)) + + ;; Fix code-folding keybindings + :n "za" #'+org/toggle-fold + :n "zA" #'org-shifttab + :n "zc" #'outline-hide-subtree + :n "zC" (λ! (outline-hide-sublevels 1)) + :n "zd" (lambda (&optional arg) (interactive "p") (outline-hide-sublevels (or arg 3))) + :n "zm" (λ! (outline-hide-sublevels 1)) + :n "zo" #'outline-show-subtree + :n "zO" #'outline-show-all + :n "zr" #'outline-show-all + + (:after org-agenda + (:map org-agenda-mode-map + :e "" #'org-agenda-Quit + :e "m" #'org-agenda-month-view + :e "C-j" #'org-agenda-next-item + :e "C-k" #'org-agenda-previous-item + :e "C-n" #'org-agenda-next-item + :e "C-p" #'org-agenda-previous-item)))) + +;; +(defun +org-hacks () + "Getting org to behave." + ;; Don't open separate windows + (push '(file . find-file) org-link-frame-setup) + + ;; Let OS decide what to do with files when opened + (setq org-file-apps + `(("\\.org$" . emacs) + (t . ,(cond (IS-MAC "open -R \"%s\"") + (IS-LINUX "xdg-open \"%s\""))))) + + (defun +org|remove-occur-highlights () + "Remove org occur highlights on ESC in normal mode." + (when (and (derived-mode-p 'org-mode) + org-occur-highlights) + (org-remove-occur-highlights))) + (add-hook '+evil-esc-hook #'+org|remove-occur-highlights) + + (after! recentf + ;; Don't clobber recentf with agenda files + (defun +org-is-agenda-file (filename) + (cl-find (file-truename filename) org-agenda-files + :key #'file-truename + :test #'equal)) + (add-to-list 'recentf-exclude #'+org-is-agenda-file))) diff --git a/modules/lang/org/packages.el b/modules/lang/org/packages.el new file mode 100644 index 000000000..84999f094 --- /dev/null +++ b/modules/lang/org/packages.el @@ -0,0 +1,33 @@ +;; -*- no-byte-compile: t; -*- +;;; lang/org/packages.el + +;; NOTE This is an insecure source, but unavoidable if we want org 9.0+ (which +;; this module requires). orgmode.org offers no secure access to this repo. If +;; this bothers you, comment out this `package!' block and download +;; org-plus-contrib from orgmode.org. +(package! org-plus-contrib :recipe (:fetcher git :url "http://orgmode.org/org-mode.git")) + +(package! org-bullets :recipe (:fetcher github :repo "hlissner/org-bullets")) +(package! toc-org) + +(when (featurep! +attach) + (package! org-download)) + +(when (featurep! +babel) + (package! ob-go) + (package! ob-mongo) + (package! ob-redis) + (package! ob-restclient) + (package! ob-rust) + (package! ob-sql-mode) + (package! ob-translate)) + +(when (featurep! +export) + (package! ox-pandoc)) + +(when (featurep! +present) + (package! centered-window-mode) + (package! org-tree-slide) + (package! ox-reveal)) + +;; (when (featurep! +publish)) diff --git a/modules/org/org/test/autoload-org.el b/modules/lang/org/test/autoload-org.el similarity index 97% rename from modules/org/org/test/autoload-org.el rename to modules/lang/org/test/autoload-org.el index d9ac443d0..2402f9aac 100644 --- a/modules/org/org/test/autoload-org.el +++ b/modules/lang/org/test/autoload-org.el @@ -1,5 +1,5 @@ ;; -*- no-byte-compile: t; -*- -;;; org/org/test/autoload-org.el +;;; lang/org/test/autoload-org.el (defmacro should-org-buffer! (source expected &rest body) `(should-buffer! ,source ,expected diff --git a/modules/lang/org/test/org.el b/modules/lang/org/test/org.el new file mode 100644 index 000000000..e69f7a261 --- /dev/null +++ b/modules/lang/org/test/org.el @@ -0,0 +1,7 @@ +;;; lang/org/test/org.el -*- lexical-binding: t; -*- + +(when (featurep 'org) + (unload-feature 'org t)) +(require! :lang org) + +(require 'org (locate-library "org" nil doom--package-load-path)) diff --git a/modules/lang/perl/config.el b/modules/lang/perl/config.el index e8cd654ca..b0b7dec3c 100644 --- a/modules/lang/perl/config.el +++ b/modules/lang/perl/config.el @@ -5,11 +5,10 @@ (add-hook 'perl-mode-hook #'flycheck-mode)) -(def-package! perl6-mode - :init (require 'perl6-detect)) +(def-package! perl6-detect) (def-package! flycheck-perl6 - :after perl6-mode :when (featurep! :feature syntax-checker) + :after perl6-mode :config (add-hook 'perl6-mode-hook #'flycheck-mode)) diff --git a/modules/lang/php/autoload.el b/modules/lang/php/autoload.el index c9e272e4a..fc2fd8ca9 100644 --- a/modules/lang/php/autoload.el +++ b/modules/lang/php/autoload.el @@ -9,6 +9,6 @@ ignore the cache." (let ((project-root (or project-root (doom-project-root)))) (or (and (not refresh-p) (gethash project-root +php-composer-conf)) (let ((package-file (expand-file-name "composer.json" project-root))) - (when-let (data (and (file-exists-p package-file) - (json-read-file package-file))) + (when-let* ((data (and (file-exists-p package-file) + (json-read-file package-file)))) (puthash project-root data +php-composer-conf)))))) diff --git a/modules/lang/php/config.el b/modules/lang/php/config.el index 5bfe186af..33b9d3373 100644 --- a/modules/lang/php/config.el +++ b/modules/lang/php/config.el @@ -7,11 +7,11 @@ (def-package! php-mode - :mode ("\\.php[s345]?$" "\\.inc$") + :mode "\\.php[s345]?$" + :mode "\\.inc$" :interpreter "php" :config - (add-hook! 'php-mode-hook - #'(ac-php-core-eldoc-setup flycheck-mode)) + (add-hook! php-mode #'(ac-php-core-eldoc-setup flycheck-mode)) (setq php-template-compatibility nil) @@ -68,8 +68,7 @@ (def-package! php-refactor-mode - :commands php-refactor-mode - :init (add-hook 'php-mode-hook #'php-refactor-mode)) + :hook php-mode) (def-package! phpunit diff --git a/modules/lang/purescript/config.el b/modules/lang/purescript/config.el index d94eb44c9..e4cb6ea54 100644 --- a/modules/lang/purescript/config.el +++ b/modules/lang/purescript/config.el @@ -14,7 +14,5 @@ ;; (add-hook 'flycheck-mode-hook #'flycheck-purescript-setup)) (def-package! psc-ide - :after purescript-mode - :config - (add-hook 'purescript-mode-hook #'psc-ide-mode)) + :hook (purescript-mode . psc-ide-mode)) diff --git a/modules/lang/python/config.el b/modules/lang/python/config.el index b92eb752b..1b2ff7983 100644 --- a/modules/lang/python/config.el +++ b/modules/lang/python/config.el @@ -21,7 +21,6 @@ is loaded.") (setq python-environment-directory doom-cache-dir python-indent-guess-indent-offset-verbose nil python-shell-interpreter "python") - :config (add-hook! 'python-mode-hook #'(flycheck-mode highlight-numbers-mode)) @@ -56,7 +55,7 @@ is loaded.") (defun +python|detect-pyenv-version () "Detect the pyenv version for the current project and set the relevant environment variables." - (when-let (version-str (shell-command-to-string "python --version 2>&1 | cut -d' ' -f2")) + (when-let* ((version-str (shell-command-to-string "python --version 2>&1 | cut -d' ' -f2"))) (setq version-str (string-trim version-str) +python-current-version version-str) (let ((pyenv-current-path (concat +python-pyenv-root "/versions/" version-str))) @@ -73,17 +72,14 @@ environment variables." (def-package! anaconda-mode :after python + :hook python-mode :init - (add-hook 'python-mode-hook #'anaconda-mode) - (add-hook 'anaconda-mode-hook #'anaconda-eldoc-mode) (setq anaconda-mode-installation-directory (concat doom-etc-dir "anaconda/") anaconda-mode-eldoc-as-single-line t) - :config + (add-hook 'anaconda-mode-hook #'anaconda-eldoc-mode) (set! :popup "*anaconda-mode*" :size 10 :noselect t :autoclose t :autokill t) - (map! :map anaconda-mode-map :m "gd" #'anaconda-mode-find-definitions) - (advice-add #'anaconda-mode-doc-buffer :after #'doom*anaconda-mode-doc-buffer)) diff --git a/modules/lang/ruby/config.el b/modules/lang/ruby/config.el index 865d1ea37..38de8171e 100644 --- a/modules/lang/ruby/config.el +++ b/modules/lang/ruby/config.el @@ -12,11 +12,12 @@ ;; (def-package! ruby-mode - :mode ("\\.rb$" "\\.rake$" "\\.gemspec$" "\\.?pryrc$" - "/\\(Gem\\|Cap\\|Vagrant\\|Rake\\|Pod\\|Puppet\\|Berks\\)file$") + :mode "\\.rb$" + :mode "\\.rake$" + :mode "\\.gemspec$" + :mode "\\.\\(pry\\|irb\\)rc$" + :mode "/\\(Gem\\|Cap\\|Vagrant\\|Rake\\|Pod\\|Puppet\\|Berks\\)file$" :interpreter "ruby" - :init - (add-hook 'ruby-mode-hook #'flycheck-mode) :config (set! :company-backend 'ruby-mode '(company-dabbrev-code)) (set! :electric 'ruby-mode :words '("else" "end" "elseif")) @@ -24,6 +25,8 @@ ;; Don't interfere with my custom RET behavior (define-key ruby-mode-map [?\n] nil) + (add-hook 'ruby-mode-hook #'flycheck-mode) + ;; Version management with rbenv (defun +ruby|add-version-to-modeline () "Add version string to the major mode in the modeline." @@ -40,7 +43,7 @@ (defun +ruby|detect-rbenv-version () "Detect the rbenv version for the current project and set the relevant environment variables." - (when-let (version-str (shell-command-to-string "ruby --version 2>&1 | cut -d' ' -f2")) + (when-let* ((version-str (shell-command-to-string "ruby --version 2>&1 | cut -d' ' -f2"))) (setq version-str (string-trim version-str) +ruby-current-version version-str) (when (member version-str +ruby-rbenv-versions) @@ -67,9 +70,7 @@ environment variables." ;; Highlight doc comments -(def-package! yard-mode - :commands yard-mode - :init (add-hook 'ruby-mode-hook #'yard-mode)) +(def-package! yard-mode :hook ruby-mode) (def-package! rspec-mode diff --git a/modules/lang/rust/config.el b/modules/lang/rust/config.el index 7afabf06e..bde7c4602 100644 --- a/modules/lang/rust/config.el +++ b/modules/lang/rust/config.el @@ -20,10 +20,10 @@ (def-package! racer :after rust-mode - :preface - :init - (add-hook! 'rust-mode-hook #'(racer-mode eldoc-mode flycheck-rust-setup)) + :hook (rust-mode . racer-mode) :config + (add-hook 'rust-mode-hook #'eldoc-mode) + (setq racer-cmd (or (executable-find "racer") (expand-file-name "racer/target/release/racer" +rust-src-dir)) racer-rust-src-path (or (getenv "RUST_SRC_PATH") @@ -44,5 +44,6 @@ (def-package! flycheck-rust :when (featurep! :feature syntax-checker) :after rust-mode + :hook (flycheck-mode . flycheck-rust-setup) :config (add-hook 'rust-mode-hook #'flycheck-mode)) diff --git a/modules/lang/scala/config.el b/modules/lang/scala/config.el index 89319c383..b656ebbf6 100644 --- a/modules/lang/scala/config.el +++ b/modules/lang/scala/config.el @@ -2,17 +2,18 @@ (def-package! scala-mode :mode "\\.s\\(cala\\|bt\\)$" - :config - (setq scala-indent:align-parameters t)) + :config (setq scala-indent:align-parameters t)) (def-package! sbt-mode :after scala-mode) (def-package! ensime - :after scala-mode - :commands (ensime ensime-mode ensime-scala-mode-hook) + :commands (ensime ensime-scala-mode-hook) + :hook (scala-mode . ensime-mode) :config + (add-hook 'ensime-mode-hook #'eldoc-mode) + (set! :company-backend 'scala-mode '(ensime-company company-yasnippet)) (setq ensime-startup-snapshot-notification nil @@ -21,9 +22,6 @@ ;; let DOOM handle company setup ensime-completion-style nil) - (add-hook 'scala-mode-hook #'ensime-mode) - (add-hook 'ensime-mode-hook #'eldoc-mode) - ;; Fix void-variable imenu-auto-rescan error caused by `ensime--setup-imenu' ;; trying to make imenu variables buffer local before imenu is loaded. (require 'imenu)) diff --git a/modules/lang/swift/config.el b/modules/lang/swift/config.el index 140dc926e..9daae8f3a 100644 --- a/modules/lang/swift/config.el +++ b/modules/lang/swift/config.el @@ -4,11 +4,10 @@ (def-package! swift-mode :mode "\\.swift$" - :init - (add-hook 'swift-mode-hook #'flycheck-mode) :config + (add-hook 'swift-mode-hook #'flycheck-mode) (set! :repl 'swift-mode #'swift-mode-run-repl) ; TODO test this - (cl-pushnew 'swift flycheck-checkers)) + (push 'swift flycheck-checkers)) (def-package! company-sourcekit diff --git a/modules/lang/typescript/config.el b/modules/lang/typescript/config.el index 255357382..5c42d36e9 100644 --- a/modules/lang/typescript/config.el +++ b/modules/lang/typescript/config.el @@ -2,9 +2,9 @@ (def-package! typescript-mode :mode "\\.ts$" - :init - (add-hook 'typescript-mode-hook #'rainbow-delimiters-mode) :config + (add-hook 'typescript-mode-hook #'rainbow-delimiters-mode) + (set! :electric 'typescript-mode :chars '(?\} ?\)) :words '("||" "&&")) ;; TODO tide-jump-back diff --git a/modules/lang/web/+css.el b/modules/lang/web/+css.el index 181d1a5d8..8f4d51e07 100644 --- a/modules/lang/web/+css.el +++ b/modules/lang/web/+css.el @@ -5,8 +5,9 @@ (add-hook! (css-mode sass-mode) #'(yas-minor-mode-on flycheck-mode highlight-numbers-mode)) -(sp-with-modes '(css-mode scss-mode less-css-mode stylus-mode) - (sp-local-pair "/*" "*/" :post-handlers '(("[d-3]||\n[i]" "RET") ("| " "SPC")))) +(after! smartparens + (sp-with-modes '(css-mode scss-mode less-css-mode stylus-mode) + (sp-local-pair "/*" "*/" :post-handlers '(("[d-3]||\n[i]" "RET") ("| " "SPC"))))) (map! :map* (css-mode-map scss-mode-map less-css-mode-map) :n "M-R" #'+css/web-refresh-browser @@ -21,15 +22,14 @@ (def-package! counsel-css :when (featurep! :completion ivy) :commands (counsel-css counsel-css-imenu-setup) + :hook (css-mode . counsel-css-imenu-setup) :init - (add-hook 'css-mode-hook #'counsel-css-imenu-setup) (map! :map* (css-mode-map scss-mode-map less-css-mode-map) :localleader :n ";" #'counsel-css)) (def-package! rainbow-mode - :commands rainbow-mode - :init (add-hook! (css-mode sass-mode) #'rainbow-mode)) + :hook (css-mode sass-mode)) (def-package! css-mode diff --git a/modules/lang/web/+html.el b/modules/lang/web/+html.el index 8b66dd9e1..73ba50cf6 100644 --- a/modules/lang/web/+html.el +++ b/modules/lang/web/+html.el @@ -9,9 +9,8 @@ :mode "\\.mustache$" :mode "\\.tsx$" :mode "wp-content/themes/.+/.+\\.php$" - :init - (add-hook 'web-mode-hook #'turn-off-smartparens-mode) :config + (add-hook 'web-mode-hook #'turn-off-smartparens-mode) (set! :company-backend 'web-mode '(company-web-html company-yasnippet)) (setq web-mode-enable-html-entities-fontification t) diff --git a/modules/lang/web/config.el b/modules/lang/web/config.el index c31022e4c..391063ba1 100644 --- a/modules/lang/web/config.el +++ b/modules/lang/web/config.el @@ -16,9 +16,7 @@ (def-package! emmet-mode :commands emmet-mode :preface (defvar emmet-mode-keymap (make-sparse-keymap)) - :init - (add-hook! (css-mode web-mode html-mode haml-mode nxml-mode rjsx-mode) - 'emmet-mode) + :hook (css-mode web-mode html-mode haml-mode nxml-mode rjsx-mode) :config (setq emmet-move-cursor-between-quotes t) (map! :map emmet-mode-keymap diff --git a/modules/org/org-attach/packages.el b/modules/org/org-attach/packages.el deleted file mode 100644 index 6dce4d54f..000000000 --- a/modules/org/org-attach/packages.el +++ /dev/null @@ -1,4 +0,0 @@ -;; -*- no-byte-compile: t; -*- -;;; org/org-attach/packages.el - -(package! org-download) diff --git a/modules/org/org-babel/packages.el b/modules/org/org-babel/packages.el deleted file mode 100644 index d9d792ba3..000000000 --- a/modules/org/org-babel/packages.el +++ /dev/null @@ -1,10 +0,0 @@ -;; -*- no-byte-compile: t; -*- -;;; org/org-babel/packages.el - -(package! ob-go) -(package! ob-mongo) -(package! ob-redis) -(package! ob-restclient) -(package! ob-rust :recipe (:fetcher github :repo "zweifisch/ob-rust")) -(package! ob-sql-mode) -(package! ob-translate) diff --git a/modules/org/org-capture/autoload/evil.el b/modules/org/org-capture/autoload/evil.el deleted file mode 100644 index b6efbb629..000000000 --- a/modules/org/org-capture/autoload/evil.el +++ /dev/null @@ -1,11 +0,0 @@ -;;; org/org-capture/autoload/evil.el -*- lexical-binding: t; -*- -;;;###if (featurep! :feature evil) - -;;;###autoload (autoload '+org-capture:open "org/org-capture/autoload/evil" nil t) -(evil-define-operator +org-capture:open (&optional beg end) - "Evil ex interface to `+org-capture/dwim'." - :move-point nil :type inclusive - (interactive "") - (+org-capture/open - (unless (or (evil-normal-state-p) (evil-insert-state-p)) - (buffer-substring beg end)))) diff --git a/modules/org/org-export/packages.el b/modules/org/org-export/packages.el deleted file mode 100644 index 66f62ee84..000000000 --- a/modules/org/org-export/packages.el +++ /dev/null @@ -1,4 +0,0 @@ -;; -*- no-byte-compile: t; -*- -;;; org/org-export/packages.el - -(package! ox-pandoc) diff --git a/modules/org/org-present/packages.el b/modules/org/org-present/packages.el deleted file mode 100644 index 2459aa651..000000000 --- a/modules/org/org-present/packages.el +++ /dev/null @@ -1,6 +0,0 @@ -;; -*- no-byte-compile: t; -*- -;;; org/org-present/packages.el - -(package! centered-window-mode) -(package! org-tree-slide) -(package! ox-reveal) diff --git a/modules/org/org/config.el b/modules/org/org/config.el deleted file mode 100644 index 46ae32b43..000000000 --- a/modules/org/org/config.el +++ /dev/null @@ -1,240 +0,0 @@ -;;; org/org/config.el -*- lexical-binding: t; -*- - -;; Ensure ELPA org is prioritized above built-in org. -(when-let (path (locate-library "org" nil doom--package-load-path)) - (setq load-path (delete path load-path)) - (push (file-name-directory path) load-path)) - -;; Custom variables -(defvar +org-dir (expand-file-name "~/work/org/") - "The directory where org files are kept.") -(defvaralias 'org-directory '+org-dir) - -(add-hook 'org-load-hook #'+org|init) -(add-hook 'org-mode-hook #'+org|hook) - - -;; -;; Plugins -;; - -(def-package! toc-org - :commands toc-org-enable - :init (add-hook 'org-mode-hook #'toc-org-enable)) - -(def-package! org-crypt ; built-in - :commands org-crypt-use-before-save-magic - :init (add-hook 'org-load-hook #'org-crypt-use-before-save-magic) - :config - (setq org-tags-exclude-from-inheritance '("crypt") - org-crypt-key user-mail-address - epa-file-encrypt-to user-mail-address)) - -;; The standard unicode characters are usually misaligned depending on the font. -;; This bugs me. Personally, markdown #-marks for headlines are more elegant, so -;; we use those. -(def-package! org-bullets - :commands org-bullets-mode - :init (add-hook 'org-mode-hook #'org-bullets-mode) - :config (setq org-bullets-bullet-list '("#"))) - - -;; -;; Hooks & bootstraps -;; - -(defun +org|hook () - "Run everytime `org-mode' is enabled." - (when (featurep! :feature evil) - (add-hook 'evil-insert-state-exit-hook #'+org|realign-table-maybe nil t) - (add-hook 'evil-insert-state-exit-hook #'+org|update-cookies nil t) - (+org-evil-mode +1)) - - ;; TODO Add filesize checks (possibly too expensive in big org files) - (add-hook 'before-save-hook #'+org|update-cookies nil t) - - ;; - (setq line-spacing 1) - (visual-line-mode +1) - (org-indent-mode +1) - (doom|disable-line-numbers) - - ;; show-paren-mode causes problems for org-indent-mode, so disable it - (set (make-local-variable 'show-paren-mode) nil) - - (unless org-agenda-inhibit-startup - ;; My version of the 'overview' #+STARTUP option: expand first-level - ;; headings. Expands the first level, but no further. - (when (eq org-startup-folded t) - (outline-hide-sublevels 2)) - - ;; If saveplace places the point in a folded position, unfold it on load - (when (outline-invisible-p) - (ignore-errors - (save-excursion - (outline-previous-visible-heading 1) - (org-show-subtree)))))) - -(defun +org|init () - "Run once, when org is first loaded." - (define-minor-mode +org-evil-mode - "Evil-mode bindings for org-mode." - :init-value nil - :lighter " !" - :keymap (make-sparse-keymap) - :group 'evil-org) - - (+org-init-ui) - (+org-init-keybinds) - (+org-hacks)) - -;; -(defun +org-init-ui () - "Configures the UI for `org-mode'." - (setq-default - org-adapt-indentation nil - org-agenda-dim-blocked-tasks nil - org-agenda-files (directory-files +org-dir t "\\.org$" t) - org-agenda-inhibit-startup t - org-agenda-skip-unavailable-files nil - org-cycle-include-plain-lists t - org-cycle-separator-lines 1 - org-entities-user '(("flat" "\\flat" nil "" "" "266D" "♭") ("sharp" "\\sharp" nil "" "" "266F" "♯")) - org-ellipsis "  " - org-fontify-done-headline t - org-fontify-quote-and-verse-blocks t - org-fontify-whole-heading-line t - org-footnote-auto-label 'plain - org-hidden-keywords nil - org-hide-emphasis-markers nil - org-hide-leading-stars t - org-hide-leading-stars-before-indent-mode t - org-image-actual-width nil - org-indent-indentation-per-level 2 - org-indent-mode-turns-on-hiding-stars t - org-pretty-entities nil - org-pretty-entities-include-sub-superscripts t - org-priority-faces - `((?a . ,(face-foreground 'error)) - (?b . ,(face-foreground 'warning)) - (?c . ,(face-foreground 'success))) - org-startup-folded t - org-startup-indented t - org-startup-with-inline-images nil - org-tags-column 0 - org-todo-keywords - '((sequence "[ ](t)" "[-](p)" "[?](m)" "|" "[X](d)") - (sequence "TODO(T)" "|" "DONE(D)") - (sequence "NEXT(n)" "ACTIVE(a)" "WAITING(w)" "LATER(l)" "|" "CANCELLED(c)")) - org-use-sub-superscripts '{} - outline-blank-line t - - ;; LaTeX previews are too small and usually render to light backgrounds, so - ;; this enlargens them and ensures their background (and foreground) match the - ;; current theme. - org-format-latex-options (plist-put org-format-latex-options :scale 1.5) - org-format-latex-options - (plist-put org-format-latex-options - :background (face-attribute (or (cadr (assq 'default face-remapping-alist)) - 'default) - :background nil t))) - - ;; Custom links - (org-link-set-parameters - "org" - :complete (lambda () (+org-link-read-file "org" +org-dir)) - :follow (lambda (link) (find-file (expand-file-name link +org-dir))) - :face (lambda (link) - (if (file-exists-p (expand-file-name link +org-dir)) - 'org-link - 'error)))) - -(defun +org-init-keybinds () - "Sets up org-mode and evil keybindings. Tries to fix the idiosyncrasies -between the two." - (map! (:map org-mode-map - "RET" #'org-return-indent - "C-c C-S-l" #'+org/remove-link - :n "j" "gj" - :n "k" "gk") - - (:map +org-evil-mode-map - :n "RET" #'+org/dwim-at-point - - ;; Navigate table cells (from insert-mode) - :i "C-l" #'+org/table-next-field - :i "C-h" #'+org/table-previous-field - :i "C-k" #'+org/table-previous-row - :i "C-j" #'+org/table-next-row - ;; Expand tables (or shiftmeta move) - :ni "C-S-l" #'+org/table-append-field-or-shift-right - :ni "C-S-h" #'+org/table-prepend-field-or-shift-left - :ni "C-S-k" #'org-metaup - :ni "C-S-j" #'org-metadown - - :n [tab] #'+org/toggle-fold - :i [tab] #'+org/indent-or-next-field-or-yas-expand - :i [backtab] #'+org/dedent-or-prev-field - - :ni [M-return] (λ! (+org/insert-item 'below)) - :ni [S-M-return] (λ! (+org/insert-item 'above)) - - :m "]]" (λ! (org-forward-heading-same-level nil) (org-beginning-of-line)) - :m "[[" (λ! (org-backward-heading-same-level nil) (org-beginning-of-line)) - :m "]l" #'org-next-link - :m "[l" #'org-previous-link - :m "$" #'org-end-of-line - :m "^" #'org-beginning-of-line - :n "gQ" #'org-fill-paragraph - :n "<" #'org-metaleft - :n ">" #'org-metaright - :v "<" (λ! (org-metaleft) (evil-visual-restore)) - :v ">" (λ! (org-metaright) (evil-visual-restore)) - :m "" #'org-cycle - - ;; Fix code-folding keybindings - :n "za" #'+org/toggle-fold - :n "zA" #'org-shifttab - :n "zc" #'outline-hide-subtree - :n "zC" (λ! (outline-hide-sublevels 1)) - :n "zd" (lambda (&optional arg) (interactive "p") (outline-hide-sublevels (or arg 3))) - :n "zm" (λ! (outline-hide-sublevels 1)) - :n "zo" #'outline-show-subtree - :n "zO" #'outline-show-all - :n "zr" #'outline-show-all) - - (:after org-agenda - (:map org-agenda-mode-map - :e "" #'org-agenda-Quit - :e "m" #'org-agenda-month-view - :e "C-j" #'org-agenda-next-item - :e "C-k" #'org-agenda-previous-item - :e "C-n" #'org-agenda-next-item - :e "C-p" #'org-agenda-previous-item)))) - -;; -(defun +org-hacks () - "Getting org to behave." - ;; Don't open separate windows - (cl-pushnew '(file . find-file) org-link-frame-setup) - - ;; Let OS decide what to do with files when opened - (setq org-file-apps - `(("\\.org$" . emacs) - (t . ,(cond (IS-MAC "open -R \"%s\"") - (IS-LINUX "xdg-open \"%s\""))))) - - (defun +org|remove-occur-highlights () - "Remove org occur highlights on ESC in normal mode." - (when (and (derived-mode-p 'org-mode) - org-occur-highlights) - (org-remove-occur-highlights))) - (add-hook '+evil-esc-hook #'+org|remove-occur-highlights) - - (after! recentf - ;; Don't clobber recentf with agenda files - (defun +org-is-agenda-file (filename) - (cl-find (file-truename filename) org-agenda-files - :key #'file-truename - :test #'equal)) - (add-to-list 'recentf-exclude #'+org-is-agenda-file))) diff --git a/modules/org/org/packages.el b/modules/org/org/packages.el deleted file mode 100644 index cf4164710..000000000 --- a/modules/org/org/packages.el +++ /dev/null @@ -1,11 +0,0 @@ -;; -*- no-byte-compile: t; -*- -;;; org/org/packages.el - -;; NOTE This is an insecure source, but unavoidable if we want org 9.0+. -;; orgmode.org offers no secure access to this repo. If this bothers you, -;; comment out this `package!' block and download org-plus-contrib from -;; orgmode.org. -(package! org-plus-contrib :recipe (:fetcher git :url "http://orgmode.org/org-mode.git")) - -(package! org-bullets :recipe (:fetcher github :repo "hlissner/org-bullets")) -(package! toc-org) diff --git a/modules/org/org/test/org.el b/modules/org/org/test/org.el deleted file mode 100644 index d91044ff9..000000000 --- a/modules/org/org/test/org.el +++ /dev/null @@ -1,5 +0,0 @@ -;;; org/org/test/org.el -*- lexical-binding: t; -*- - -(when (featurep 'org) (unload-feature 'org t)) -(require! :org org) -(require 'org (locate-library "org" nil doom--package-load-path)) diff --git a/modules/private/hlissner/+bindings.el b/modules/private/hlissner/+bindings.el index b1a0623cd..7ad4807d2 100644 --- a/modules/private/hlissner/+bindings.el +++ b/modules/private/hlissner/+bindings.el @@ -198,7 +198,7 @@ (:desc "help" :prefix "h" :n "h" help-map :desc "Apropos" :n "a" #'apropos - :desc "Reload theme" :n "R" #'doom/reload-theme + :desc "Reload theme" :n "R" #'doom//reload-theme :desc "Find library" :n "l" #'find-library :desc "Toggle Emacs log" :n "m" #'doom/popup-toggle-messages :desc "Command log" :n "L" #'global-command-log-mode @@ -385,8 +385,8 @@ ;; counsel (:after counsel (:map counsel-ag-map - [backtab] #'+ivy/wgrep-occur ; search/replace on results - "C-SPC" #'counsel-git-grep-recenter ; preview + [backtab] #'+ivy/wgrep-occur ; search/replace on results + "C-SPC" #'ivy-call-and-recenter ; preview "M-RET" (+ivy-do-action! #'+ivy-git-grep-other-window-action))) ;; evil-commentary @@ -536,6 +536,8 @@ (:after ivy :map ivy-minibuffer-map [escape] #'keyboard-escape-quit + "C-SPC" #'ivy-call-and-recenter + "TAB" #'ivy-partial "M-v" #'yank "M-z" #'undo "C-r" #'evil-paste-from-register @@ -758,7 +760,7 @@ :i [remap delete-backward-char] #'doom/deflate-space-maybe :i [remap newline] #'doom/newline-and-indent - (:after org-mode + (:after org (:map org-mode-map :i [remap doom/inflate-space-maybe] #'org-self-insert-command :i "C-e" #'org-end-of-line diff --git a/modules/private/hlissner/autoload/hlissner.el b/modules/private/hlissner/autoload/hlissner.el index 2ff00d069..236676fc2 100644 --- a/modules/private/hlissner/autoload/hlissner.el +++ b/modules/private/hlissner/autoload/hlissner.el @@ -12,7 +12,7 @@ private/hlissner/snippets." (defun +hlissner/yank-buffer-filename () "Copy the current buffer's path to the kill ring." (interactive) - (if-let (filename (or buffer-file-name (bound-and-true-p list-buffers-directory))) + (if-let* ((filename (or buffer-file-name (bound-and-true-p list-buffers-directory)))) (message (kill-new (abbreviate-file-name filename))) (error "Couldn't find filename in current buffer"))) diff --git a/modules/private/hlissner/config.el b/modules/private/hlissner/config.el index 469399338..b034ad8c9 100644 --- a/modules/private/hlissner/config.el +++ b/modules/private/hlissner/config.el @@ -1,11 +1,17 @@ ;;; private/hlissner/config.el -*- lexical-binding: t; -*- +(defvar +hlissner-dir (file-name-directory load-file-name)) +(defvar +hlissner-snippets-dir (expand-file-name "snippets/" +hlissner-dir)) + +;; (when (featurep! :feature evil) (load! +bindings) ; my key bindings (load! +commands)) ; my custom ex commands -(defvar +hlissner-dir (file-name-directory load-file-name)) -(defvar +hlissner-snippets-dir (expand-file-name "snippets/" +hlissner-dir)) + +;; +;; Global config +;; (setq epa-file-encrypt-to user-mail-address auth-sources (list (expand-file-name ".authinfo.gpg" +hlissner-dir)) @@ -17,9 +23,13 @@ (apply orig-fn args))) (advice-add #'tramp-read-passwd :around #'+hlissner*no-authinfo-for-tramp) + ;; +;; Modules +;; + (after! smartparens - ;; Auto-close more conservatively + ;; Auto-close more conservatively and expand braces on RET (let ((unless-list '(sp-point-before-word-p sp-point-after-word-p sp-point-before-same-p))) @@ -32,30 +42,32 @@ (sp-pair "[" nil :post-handlers '(("| " " ")) :unless '(sp-point-before-word-p sp-point-before-same-p))) - -;; -(after! doom-themes - ;; Since Fira Mono doesn't have an italicized variant, highlight it instead - (set-face-attribute 'italic nil - :weight 'ultra-light - :foreground "#ffffff" - :background (doom-color 'current-line))) - - +;; feature/evil (after! evil-mc - ;; if I'm in insert mode, chances are I want cursors to resume + ;; Make evil-mc resume its cursors when I switch to insert mode (add-hook! 'evil-mc-before-cursors-created (add-hook 'evil-insert-state-entry-hook #'evil-mc-resume-cursors nil t)) (add-hook! 'evil-mc-after-cursors-deleted (remove-hook 'evil-insert-state-entry-hook #'evil-mc-resume-cursors t))) - -;; Don't use default snippets, use mine. +;; feature/snippets (after! yasnippet + ;; Don't use default snippets, use mine. (setq yas-snippet-dirs (append (list '+hlissner-snippets-dir) (delq 'yas-installed-snippets-dir yas-snippet-dirs)))) +;; completion/helm +(after! helm + ;; Hide header lines in helm. I don't like them + (set-face-attribute 'helm-source-header nil :height 0.1)) + +;; lang/org +(after! org-bullets + ;; The standard unicode characters are usually misaligned depending on the + ;; font. This bugs me. Personally, markdown #-marks for headlines are more + ;; elegant, so we use those. + (setq org-bullets-bullet-list '("#"))) ;; app/irc (after! circe @@ -69,7 +81,6 @@ :sasl-password ,(+pass-get-secret "irc/snoonet.org") :channels (:after-auth "#ynought")))) - ;; app/email (after! mu4e (setq smtpmail-stream-type 'starttls diff --git a/modules/private/hlissner/init.el b/modules/private/hlissner/init.el index caf5a33fc..37eb5c43a 100644 --- a/modules/private/hlissner/init.el +++ b/modules/private/hlissner/init.el @@ -1,26 +1,52 @@ ;;; private/hlissner/init.el -*- lexical-binding: t; -*- -;; I've swapped these keys on my keyboard -(setq x-super-keysym 'alt - x-alt-keysym 'meta - - user-mail-address "henrik@lissner.net" - user-full-name "Henrik Lissner") - ;; An extra measure to prevent the flash of unstyled mode-line while Emacs is ;; booting up (when Doom is byte-compiled). (setq-default mode-line-format nil) -;; host-specific settings +;; I've swapped these keys on my keyboard +(setq x-super-keysym 'alt + x-alt-keysym 'meta) + +(setq user-mail-address "henrik@lissner.net" + user-full-name "Henrik Lissner") + +(setq doom-big-font (font-spec :family "Fira Mono" :size 19)) + (pcase (system-name) - ;; ("triton") - ((or "proteus" "halimede") - ;; smaller screen, smaller fonts - (set! :font "Fira Mono" :size 10) - (set! :variable-font "Fira Sans" :size 10) - (set! :unicode-font "DejaVu Sans Mono" :size 10) - (setq +doom-modeline-height 25)) - ;; ("nereid") - ;; ("io") - ;; ("sao") - ) + ("proteus" + ;; My 13" laptop has very little screen estate, so we use a bitmap font + ;; there. For Doom, that means we need to take up less space! + (setq-default line-spacing 1) + + (setq doom-font (font-spec :family "kakwa kakwafont" :size 12) + doom-variable-pitch-font (font-spec :family "kakwa kakwafont") + doom-unicode-font (font-spec :family "UT Ttyp0") + ;; ui/doom-modeline + +doom-modeline-height 23 + ;; `doom-themes' + doom-neotree-enable-variable-pitch nil + doom-neotree-project-size 1.2 + doom-neotree-line-spacing 0 + doom-neotree-folder-size 1.0 + doom-neotree-chevron-size 0.6) + (add-hook! doom-big-font-mode + (setq +doom-modeline-height (if doom-big-font-mode 37 23))) + + ;; No highlighted bar in the mode-line + (setq +doom-modeline-bar-width 1) + (custom-set-faces '(doom-modeline-bar ((t (:background nil)))))) + + (_ + ;; Everywhere else, I have big displays and plenty of space, so use it! + (setq doom-font (font-spec :family "Fira Mono" :size 12) + doom-variable-pitch-font (font-spec :family "Fira Sans") + doom-unicode-font (font-spec :family "DejaVu Sans Mono") + org-ellipsis "  ") + + ;; Fira Mono doesn't have italics, so we highlight it instead. + (add-hook! doom-post-init + (set-face-attribute 'italic nil :weight 'ultra-light :foreground "#ffffff")) + + (add-hook! doom-big-font-mode + (setq +doom-modeline-height (if doom-big-font-mode 37 29))))) diff --git a/modules/tools/dired/config.el b/modules/tools/dired/config.el index 493a8cf18..e7e7f5657 100644 --- a/modules/tools/dired/config.el +++ b/modules/tools/dired/config.el @@ -59,8 +59,3 @@ (add-hook 'dired-initial-position-hook #'dired-k) (add-hook 'dired-after-readin-hook #'dired-k-no-revert)) - -(def-package! stripe-buffer - :commands stripe-buffer-mode - :init (add-hook 'dired-mode-hook #'stripe-buffer-mode)) - diff --git a/modules/tools/dired/packages.el b/modules/tools/dired/packages.el index 7f9baf245..c1ed6be70 100644 --- a/modules/tools/dired/packages.el +++ b/modules/tools/dired/packages.el @@ -2,5 +2,4 @@ ;;; emacs/dired/packages.el (package! dired-k) -(package! stripe-buffer) diff --git a/modules/tools/electric-indent/config.el b/modules/tools/electric-indent/config.el index 1a7bf5ade..809b07800 100644 --- a/modules/tools/electric-indent/config.el +++ b/modules/tools/electric-indent/config.el @@ -16,7 +16,7 @@ (backward-word) (looking-at-p (concat "\\<" (regexp-opt doom-electric-indent-words)))))) -(cl-pushnew #'+electric-indent|char electric-indent-functions :test #'eq) +(push #'+electric-indent|char electric-indent-functions) (def-setting! :electric (modes &rest plist) "Declare :words (list of strings) or :chars (lists of chars) in MODES that diff --git a/modules/tools/eshell/autoload/eshell.el b/modules/tools/eshell/autoload/eshell.el index 7029f74ba..84a8e54b8 100644 --- a/modules/tools/eshell/autoload/eshell.el +++ b/modules/tools/eshell/autoload/eshell.el @@ -41,8 +41,8 @@ module to be loaded." (user-error ":feature workspaces is required, but disabled")) (unless (+workspace-get "eshell" t) (+workspace/new "eshell")) - (if-let (buf (cl-find-if (lambda (it) (string-match-p "^\\*doom:eshell" (buffer-name (window-buffer it)))) - (doom-visible-windows))) + (if-let* ((buf (cl-find-if (lambda (it) (string-match-p "^\\*doom:eshell" (buffer-name (window-buffer it)))) + (doom-visible-windows)))) (select-window (get-buffer-window buf)) (+eshell/open)) (doom/workspace-display) diff --git a/modules/tools/eshell/config.el b/modules/tools/eshell/config.el index f2d82aa40..49efa7074 100644 --- a/modules/tools/eshell/config.el +++ b/modules/tools/eshell/config.el @@ -67,10 +67,6 @@ redefines its keys every time `eshell-mode' is enabled." [remap +workspace/close-window-or-workspace] #'eshell-life-is-too-much)) (add-hook 'eshell-mode-hook #'+eshell|init-keymap) - (add-hook! eshell-mode - (add-hook 'evil-insert-state-exit-hook #'hl-line-mode nil t) - (add-hook 'evil-insert-state-entry-hook (lambda () (hl-line-mode -1)) nil t)) - ;; Aliases (setq eshell-command-aliases-list '(("q" "exit") diff --git a/modules/tools/gist/autoload/gist.el b/modules/tools/gist/autoload/gist.el index c9e192985..1202b003a 100644 --- a/modules/tools/gist/autoload/gist.el +++ b/modules/tools/gist/autoload/gist.el @@ -4,7 +4,7 @@ (defun +gist/open-current () (interactive) (gist-fetch-current) - (when-let (win (get-buffer-window "*github:gists*")) + (when-let* ((win (get-buffer-window "*github:gists*"))) (doom/popup-close win))) ;;;###autoload diff --git a/modules/tools/gist/config.el b/modules/tools/gist/config.el index 4554d5a92..cc7837de3 100644 --- a/modules/tools/gist/config.el +++ b/modules/tools/gist/config.el @@ -8,8 +8,6 @@ :commands (gist-list gist-region-or-buffer-private gist-region-or-buffer) :config (set! :popup "*github:gists*" :size 15 :select t :autokill t) - - ;; evil-ify gist listing (set! :evil-state 'gist-list-mode 'normal) (defun +gist*list-render (orig-fn &rest args) diff --git a/modules/tools/neotree/autoload.el b/modules/tools/neotree/autoload.el index cfc12e91c..3a3c87ee9 100644 --- a/modules/tools/neotree/autoload.el +++ b/modules/tools/neotree/autoload.el @@ -21,7 +21,7 @@ (defun +neotree/collapse-or-up () "Collapse an expanded directory node or go to the parent node." (interactive) - (when-let (node (neo-buffer--get-filename-current-line)) + (when-let* ((node (neo-buffer--get-filename-current-line))) (if (file-directory-p node) (if (neo-buffer--expanded-node-p node) (+neotree/collapse) @@ -32,7 +32,7 @@ (defun +neotree/collapse () "Collapse a neotree node." (interactive) - (when-let (node (neo-buffer--get-filename-current-line)) + (when-let* ((node (neo-buffer--get-filename-current-line))) (when (file-directory-p node) (neo-buffer--set-expand node nil) (neo-buffer--refresh t)) @@ -43,7 +43,7 @@ (defun +neotree/expand-or-open () "Expand or open a neotree node." (interactive) - (when-let (node (neo-buffer--get-filename-current-line)) + (when-let* ((node (neo-buffer--get-filename-current-line))) (cond ((file-directory-p node) (neo-buffer--set-expand node t) (neo-buffer--refresh t) diff --git a/modules/tools/password-store/autoload.el b/modules/tools/password-store/autoload.el index 9317b2310..6705fa6a8 100644 --- a/modules/tools/password-store/autoload.el +++ b/modules/tools/password-store/autoload.el @@ -10,14 +10,19 @@ (t (pass)))) +;;;###autoload +(defalias '+pass--get-entry + (if (featurep 'auth-store-pass) + #'auth-source-pass-parse-entry + #'auth-pass-parse-entry)) + ;;;###autoload (defun +pass-get-field (entry fields) - (unless noninteractive - (if-let (data (if (listp entry) entry (auth-pass-parse-entry entry))) - (cl-loop for key in (doom-enlist fields) - when (assoc key data) - return (cdr it)) - (error "Couldn't find entry: %s" entry)))) + (if-let* ((data (if (listp entry) entry (+pass--get-entry entry)))) + (cl-loop for key in (doom-enlist fields) + when (assoc key data) + return (cdr it)) + (error "Couldn't find entry: %s" entry))) ;;;###autoload (defun +pass-get-user (entry) @@ -28,14 +33,14 @@ (+pass-get-field entry 'secret)) (defun +pass-ivy-action--open-url (entry) - (if-let (url (+pass-get-field entry +pass-url-fields)) + (if-let* ((url (+pass-get-field entry +pass-url-fields))) (and (or (string-match-p "https?://" url) (error "Field for %s doesn't look like an url" item)) (browse-url url)) (error "Username not found."))) (defun +pass-ivy-action--get-field (item) - (let* ((data (auth-pass-parse-entry item)) + (let* ((data (+pass--get-entry item)) (field (if data (completing-read "Field: " (mapcar #'car data) nil t)))) (if data (progn @@ -48,7 +53,7 @@ (error "Couldn't find entry: %s" item)))) (defun +pass-ivy-action--copy-username (entry) - (if-let (user (+pass-get-field entry +pass-user-fields)) + (if-let* ((user (+pass-get-field entry +pass-user-fields))) (progn (password-store-clear) (message "Copied username to the kill ring.") (kill-new user)) diff --git a/modules/tools/password-store/config.el b/modules/tools/password-store/config.el index 9782e7dd0..28a69a17a 100644 --- a/modules/tools/password-store/config.el +++ b/modules/tools/password-store/config.el @@ -12,6 +12,7 @@ ;; (def-package! password-store + :defer t :config (setq password-store-password-length 12)) @@ -38,5 +39,4 @@ (if (require 'auth-store-pass nil t) (auth-source-pass-enable) (def-package! auth-password-store - :demand t :config (auth-pass-enable))) diff --git a/modules/tools/password-store/test/autoload-pass.el b/modules/tools/password-store/test/autoload-pass.el index 33d539259..083c2f0d8 100644 --- a/modules/tools/password-store/test/autoload-pass.el +++ b/modules/tools/password-store/test/autoload-pass.el @@ -1,10 +1,12 @@ ;; -*- no-byte-compile: t; -*- ;;; tools/password-store/test/autoload-pass.el +(load! ../autoload) + (defmacro -with-passwords! (buffer-args &rest body) (declare (indent defun)) `(cl-letf - (((symbol-function 'auth-pass-parse-entry) + (((symbol-function '+pass--get-entry) (lambda (entry) (when (equal entry "fake/source") '((secret . "defuse-account-gad") @@ -17,17 +19,22 @@ ;; (def-test! get-field (-with-passwords! - (should (equal (+pass-get-field "fake/source" "login") - "HL2532-GANDI")) - (should (equal (+pass-get-field "fake/source" "email") - "henrik@lissner.net")) - (should (equal (+pass-get-field "fake/source" '("alt-login" "email")) - "hlissner")) - (should (equal (+pass-get-field "fake/source" '("username" "email")) - "henrik@lissner.net")) - (should-not (+pass-get-field "fake/source" '("x" "y" "z"))) + (should (equal (+pass-get-field "fake/source" "login") + "HL2532-GANDI")) + (should (equal (+pass-get-field "fake/source" "email") + "henrik@lissner.net")) + (should (equal (+pass-get-field "fake/source" '("alt-login" "email")) + "hlissner")) + (should (equal (+pass-get-field "fake/source" '("username" "email")) + "henrik@lissner.net")))) - (should-error (+pass-get-field "nonexistent/source" "login")))) +(def-test! missing-fields-return-nil + (-with-passwords! + (should-not (+pass-get-field "fake/source" '("x" "y" "z"))))) + +(def-test! missing-entries-throw-error + (-with-passwords! + (should-error (+pass-get-field "nonexistent/source" "login")))) (def-test! get-login (-with-passwords! diff --git a/modules/tools/tmux/autoload/tmux.el b/modules/tools/tmux/autoload/tmux.el index 3560dd91b..2cab93d2e 100644 --- a/modules/tools/tmux/autoload/tmux.el +++ b/modules/tools/tmux/autoload/tmux.el @@ -108,11 +108,11 @@ but do not execute them." ;;;###autoload (defun +tmux-list-windows (&optional session) - (if-let (lines - (+tmux (format "list-windows %s -F '#{window_id};#{session_id};#{window_active};#{window_name};#{window_activity_flag}'" - (if session - (concat "-t " (car session)) - "-a")))) + (if-let* ((lines + (+tmux (format "list-windows %s -F '#{window_id};#{session_id};#{window_active};#{window_name};#{window_activity_flag}'" + (if session + (concat "-t " (car session)) + "-a"))))) (cl-loop for line in (string-split lines "\n" t) collect (let ((window (string-split line ";"))) (list (nth 0 window) @@ -124,13 +124,13 @@ but do not execute them." ;;;###autoload (defun +tmux-list-panes (&optional sess-or-win) - (if-let (lines - (+tmux (format "list-panes %s -F '#{pane_id};#{window_id};#{session_id};#{pane_active};#{pane_title};#{pane_current_path}'" - (if sess-or-win - (concat (if (string-prefix-p "$" (car sess-or-win)) "-s ") - "-t " - (car sess-or-win)) - "-a")))) + (if-let* ((lines + (+tmux (format "list-panes %s -F '#{pane_id};#{window_id};#{session_id};#{pane_active};#{pane_title};#{pane_current_path}'" + (if sess-or-win + (concat (if (string-prefix-p "$" (car sess-or-win)) "-s ") + "-t " + (car sess-or-win)) + "-a"))))) (cl-loop for line in (string-split lines "\n" t) collect (let ((pane (split-string line ";"))) (list (nth 0 pane) diff --git a/modules/tools/upload/config.el b/modules/tools/upload/config.el index c6ea97524..a82cdf325 100644 --- a/modules/tools/upload/config.el +++ b/modules/tools/upload/config.el @@ -37,7 +37,6 @@ (when ssh-deploy-automatically-detect-remote-changes (ssh-deploy-remote-changes-handler)))) (add-hook 'find-file-hook #'+upload|init-find-file) - :config (setq ssh-deploy-revision-folder (concat doom-cache-dir "ssh-revisions/") ssh-deploy-on-explicit-save t diff --git a/modules/ui/doom-dashboard/config.el b/modules/ui/doom-dashboard/config.el index 6ce0ff134..1929f5438 100644 --- a/modules/ui/doom-dashboard/config.el +++ b/modules/ui/doom-dashboard/config.el @@ -73,8 +73,6 @@ whose dimensions may not be fully initialized by the time this is run." (add-hook 'window-setup-hook #'+doom-dashboard|init) (add-hook 'after-make-frame-functions #'+doom-dashboard|make-frame) (add-hook 'server-visit-hook #'+doom-dashboard|server-visit) -(when (featurep! :ui vi-tilde-fringe) - (add-hook '+doom-dashboard-mode-hook #'+vi-tilde-fringe|disable)) ;; diff --git a/modules/ui/doom-modeline/config.el b/modules/ui/doom-modeline/config.el index 0bc4e9a93..5e21e6bf8 100644 --- a/modules/ui/doom-modeline/config.el +++ b/modules/ui/doom-modeline/config.el @@ -1,7 +1,6 @@ ;;; ui/doom-modeline/config.el -*- lexical-binding: t; -*- (def-package! eldoc-eval - :demand t :config (defun +doom-modeline-eldoc (text) (concat (when (display-graphic-p) @@ -21,14 +20,14 @@ mode-line-in-non-selected-windows) (force-mode-line-update) (sit-for eldoc-show-in-mode-line-delay)))) - (setq eldoc-in-minibuffer-show-fn #'+doom-modeline--show-eldoc) + (eldoc-in-minibuffer-mode +1)) ;; anzu and evil-anzu expose current/total state that can be displayed in the ;; mode-line. (def-package! evil-anzu - :when (featurep 'evil) + :requires evil :init (add-transient-hook! #'evil-ex-start-search (require 'evil-anzu)) (add-transient-hook! #'evil-ex-start-word-search (require 'evil-anzu)) @@ -36,13 +35,11 @@ (setq anzu-cons-mode-line-p nil anzu-minimum-input-length 1 anzu-search-threshold 250) - ;; Avoid anzu conflicts across buffers (mapc #'make-variable-buffer-local '(anzu--total-matched anzu--current-position anzu--state anzu--cached-count anzu--cached-positions anzu--last-command anzu--last-isearch-string anzu--overflow-p)) - ;; Ensure anzu state is cleared when searches & iedit are done (add-hook 'isearch-mode-end-hook #'anzu--reset-status t) (add-hook '+evil-esc-hook #'anzu--reset-status t) @@ -53,7 +50,7 @@ (defvar +doom-modeline-current-window (frame-selected-window)) (defun +doom-modeline|set-selected-window (&rest _) "Sets `+doom-modeline-current-window' appropriately" - (let ((win (frame-selected-window))) + (when-let* ((win (frame-selected-window))) (unless (minibuffer-window-active-p win) (setq +doom-modeline-current-window win)))) @@ -312,35 +309,34 @@ buffer where knowing the current project directory is important." (def-modeline-segment! buffer-info "Combined information about the current buffer, including the current working directory, the file name, and its state (modified, read-only or non-existent)." - (let ((all-the-icons-scale-factor 1.2)) - (concat (cond (buffer-read-only - (concat (all-the-icons-octicon - "lock" - :face 'doom-modeline-warning - :v-adjust -0.05) - " ")) - ((buffer-modified-p) - (concat (all-the-icons-faicon - "floppy-o" - :face 'doom-modeline-buffer-modified - :v-adjust -0.0575) - " ")) - ((and buffer-file-name - (not (file-exists-p buffer-file-name))) - (concat (all-the-icons-octicon - "circle-slash" - :face 'doom-modeline-urgent - :v-adjust -0.05) - " ")) - ((buffer-narrowed-p) - (concat (all-the-icons-octicon - "fold" - :face 'doom-modeline-warning - :v-adjust -0.05) - " "))) - (if buffer-file-name - (+doom-modeline-buffer-file-name) - "%b")))) + (concat (cond (buffer-read-only + (concat (all-the-icons-octicon + "lock" + :face 'doom-modeline-warning + :v-adjust -0.05) + " ")) + ((buffer-modified-p) + (concat (all-the-icons-faicon + "floppy-o" + :face 'doom-modeline-buffer-modified + :v-adjust -0.0575) + " ")) + ((and buffer-file-name + (not (file-exists-p buffer-file-name))) + (concat (all-the-icons-octicon + "circle-slash" + :face 'doom-modeline-urgent + :v-adjust -0.05) + " ")) + ((buffer-narrowed-p) + (concat (all-the-icons-octicon + "fold" + :face 'doom-modeline-warning + :v-adjust -0.05) + " "))) + (if buffer-file-name + (+doom-modeline-buffer-file-name) + "%b"))) ;; (def-modeline-segment! buffer-info-simple @@ -384,7 +380,6 @@ directory, the file name, and its state (modified, read-only or non-existent)." (state (vc-state buffer-file-name backend))) (let ((face 'mode-line-inactive) (active (active)) - (all-the-icons-scale-factor 1.0) (all-the-icons-default-adjust -0.1)) (concat " " (cond ((memq state '(edited added)) @@ -392,7 +387,6 @@ directory, the file name, and its state (modified, read-only or non-existent)." (all-the-icons-octicon "git-compare" :face face - :height 1.2 :v-adjust -0.05)) ((eq state 'needs-merge) (if active (setq face 'doom-modeline-info)) @@ -408,7 +402,6 @@ directory, the file name, and its state (modified, read-only or non-existent)." (all-the-icons-octicon "git-compare" :face face - :height 1.2 :v-adjust -0.05))) " " (propertize (substring vc-mode (+ (if (eq backend 'Hg) 2 3) 2)) @@ -634,6 +627,6 @@ Returns \"\" to not break --no-window-system." (add-hook 'doom-scratch-buffer-hook #'+doom-modeline|set-special-modeline) (add-hook '+doom-dashboard-mode-hook #'+doom-modeline|set-project-modeline) -(add-hook 'org-src-mode-hook #'+doom-modeline|set-special-modeline) (add-hook 'image-mode-hook #'+doom-modeline|set-media-modeline) +(add-hook 'org-src-mode-hook #'+doom-modeline|set-special-modeline) (add-hook 'circe-mode-hook #'+doom-modeline|set-special-modeline) diff --git a/modules/ui/doom/README.org b/modules/ui/doom/README.org index 7900474a8..5eb47ad2c 100644 --- a/modules/ui/doom/README.org +++ b/modules/ui/doom/README.org @@ -5,54 +5,48 @@ This module modifies Emacs' user interface. Doom's look is loosely inspired by Atom's One Dark theme, and is largely contained in the] plugin. + A colorscheme inspired by Atom's One Dark theme (now available in a separate plugin: [[https://github.com/hlissner/emacs-doom-theme/][doom-themes]]) -+ Uses the [[https://github.com/mozilla/Fira][Fira Mono and Fira Sans]] fonts, and [[https://dejavu-fonts.github.io/][DejaVu Sans Mono]] for unicode symbols. + A custom folded-region indicator for ~hideshow~ + "Thin bar" fringe bitmaps for ~git-gutter-fringe~ + File-visiting buffers are slightly brighter (powered by solaire-mode) * Table of Contents :TOC: -- [[#install][Install]] - - [[#macos][MacOS]] - - [[#arch-linux][Arch Linux]] - [[#configuration][Configuration]] + - [[#changing-theme][Changing theme]] - [[#changing-fonts][Changing fonts]] - [[#troubleshooting][Troubleshooting]] - [[#strange-font-symbols][Strange font symbols]] -* Install -This module optionally depends on: - -+ The [[https://github.com/mozilla/Fira][Fira Mono]] family of fonts -+ [[https://dejavu-fonts.github.io/][DejaVu Sans Mono]] - -You don't have to install these if you use a different font. - -** MacOS -#+BEGIN_SRC sh :tangle (if (doom-system-os 'macos) "yes") -brew tap caskroom/fonts -brew cask install font-fira-{sans,mono} font-dejavu-sans -#+END_SRC - -** Arch Linux -#+BEGIN_SRC sh :dir /sudo:: :tangle (if (doom-system-os 'arch) "yes") -sudo pacman --noconfirm --needed -S ttf-fira-{sans,mono} ttf-dejavu -#+END_SRC - * Configuration -** Changing fonts -There are four font settings you can change: +** Changing theme +Although this module uses the ~doom-one~ theme by default, [[https://github.com/hlissner/emacs-doom-theme/][doom-themes]] offers a number of alternatives: -+ ~:font~ :: the default font. -+ ~:big-font~ :: the font to use when ~doom-big-font-mode~ is enabled. -+ ~:variable-font~ :: the font to use when ~variable-pitch-mode~ is active (or where the ~variable-pitch~ face is used). -+ ~:unicode-font~ :: the font used to display unicode symbols. This is ignored if the =:ui unicode= module is enabled. ++ *doom-one:* doom-themes' flagship theme, inspired by [[https://atom.io/][Atom's]] One Dark themes ++ *doom-vibrant:* a more vibrant version of doom-one ++ *doom-molokai:* based on Textmate's monokai ++ *doom-nova:* adapted from [[https://trevordmiller.com/projects/nova][Nova]] ++ *doom-one-light:* light version of doom-one ++ *doom-peacock:* based on Peacock from [[https://daylerees.github.io/][daylerees' themes]] ++ *doom-tomorrow-night:* by [[https://github.com/ChrisKempson/Tomorrow-Theme][Chris Kempson]] + +This can be changed by changing the ~doom-theme~ variable, e.g. #+BEGIN_SRC emacs-lisp -;; These are the defaults of this module -(set! :font "Fira Mono" :size 12) -(set! :big-font "Fira Mono" :size 18) -(set! :variable-font "Fira Sans" :size 12) -(set! :unicode-font "DejaVu Sans Mono" :size 12) +(setq doom-theme 'doom-molokai) +#+END_SRC + +** Changing fonts +core/core-ui.el has four relevant variables: + ++ ~doom-font~ :: the default font to use in Doom Emacs. ++ ~doom-big-font~ :: the font to use when ~doom-big-font-mode~ is enabled. ++ ~doom-variable-font~ :: the font to use when ~variable-pitch-mode~ is active (or where the ~variable-pitch~ face is used). ++ ~doom-unicode-font~ :: the font used to display unicode symbols. This is ignored if the =:ui unicode= module is enabled. + +#+BEGIN_SRC emacs-lisp +(setq doom-font (font-spec :family "Fira Mono" :size 12) + doom-variable-pitch-font (font-spec :family "Fira Sans") + doom-unicode-font (font-spec :family "DejaVu Sans Mono") + doom-big-font (font-spec :family "Fira Mono" :size 19)) #+END_SRC * Troubleshooting diff --git a/modules/ui/doom/config.el b/modules/ui/doom/config.el index 50ca45325..0e73270c9 100644 --- a/modules/ui/doom/config.el +++ b/modules/ui/doom/config.el @@ -2,27 +2,29 @@ ;; (def-package! doom-themes - :demand t :config - (set! :theme 'doom-one) + (unless doom-theme + (setq doom-theme 'doom-one) + (after! solaire-mode + (add-hook 'doom-init-ui-hook #'solaire-mode-swap-bg t))) ;; Ensure `doom/reload-load-path' reloads common faces - (defun +doom|reload-theme () - (load "doom-themes-common.el" nil t)) + (defun +doom|reload-theme () (load "doom-themes-common.el" nil t)) (add-hook 'doom-pre-reload-theme-hook #'+doom|reload-theme) - ;; improve integration with org-mode + ;; improve integration w/ org-mode (add-hook 'doom-init-ui-hook #'doom-themes-org-config) - ;; blink mode-line on errors - ;; (add-hook 'doom-init-ui-hook #'doom-themes-visual-bell-config) - - ;; Add file icons to doom-neotree + ;; more Atom-esque file icons for neotree (add-hook 'doom-init-ui-hook #'doom-themes-neotree-config) (setq doom-neotree-enable-variable-pitch t doom-neotree-file-icons 'simple doom-neotree-line-spacing 2) + ;; blink mode-line on errors + ;; FIXME Breaks modeline + ;; (add-hook 'doom-init-ui-hook #'doom-themes-visual-bell-config) + (after! neotree (defun +doom|neotree-fix-popup () "Ensure the fringe settings are maintained on popup restore." @@ -32,25 +34,16 @@ (def-package! solaire-mode - :commands (solaire-mode turn-on-solaire-mode turn-off-solaire-mode) - :init - (add-hook 'after-change-major-mode-hook #'turn-on-solaire-mode) - (add-hook 'doom-popup-mode-hook #'turn-off-solaire-mode) + :hook (after-change-major-mode . turn-on-solaire-mode) + :hook (doom-popup-mode . turn-off-solaire-mode) :config (setq solaire-mode-real-buffer-fn #'doom-real-buffer-p) - (add-hook 'doom-init-ui-hook #'solaire-mode-swap-bg t) ;; Prevent color glitches when reloading either DOOM or the theme - (defun +doom|reset-solaire-mode (&rest _) (solaire-mode-reset)) - (advice-add #'load-theme :after #'+doom|reset-solaire-mode) (add-hook! '(doom-init-ui-hook doom-reload-hook) #'solaire-mode-reset) - ;; Extra modes to activate doom-buffer-mode in - (add-hook! (gist-mode - twittering-mode - mu4e-view-mode - org-tree-slide-mode - +regex-mode) + (add-hook! + (gist-mode twittering-mode mu4e-view-mode org-tree-slide-mode +regex-mode) #'solaire-mode)) diff --git a/modules/ui/evil-goggles/config.el b/modules/ui/evil-goggles/config.el index 77a99cd02..2a1b7a1eb 100644 --- a/modules/ui/evil-goggles/config.el +++ b/modules/ui/evil-goggles/config.el @@ -2,8 +2,7 @@ (def-package! evil-goggles :when (featurep! :feature evil) - :commands evil-goggles-mode + :hook (doom-post-init . evil-goggles-mode) :init (setq evil-goggles-duration 0.1 - evil-goggles-enable-delete nil) - (add-hook 'doom-post-init-hook #'evil-goggles-mode t)) + evil-goggles-enable-delete nil)) diff --git a/modules/ui/hl-todo/config.el b/modules/ui/hl-todo/config.el index 8321cfc90..a2a445f2b 100644 --- a/modules/ui/hl-todo/config.el +++ b/modules/ui/hl-todo/config.el @@ -1,8 +1,7 @@ ;;; ui/hl-todo/packages.el -*- lexical-binding: t; -*- (def-package! hl-todo - :commands hl-todo-mode - :init (add-hook 'prog-mode-hook #'hl-todo-mode) + :hook (prog-mode . hl-todo-mode) :config (setq hl-todo-keyword-faces `(("TODO" . ,(face-foreground 'warning)) diff --git a/modules/ui/nav-flash/config.el b/modules/ui/nav-flash/config.el index 23e0ae4b6..cf2ce8be0 100644 --- a/modules/ui/nav-flash/config.el +++ b/modules/ui/nav-flash/config.el @@ -9,6 +9,8 @@ (advice-add #'recenter :around #'+doom*blink-cursor-maybe) (after! evil + (advice-add #'evil--jumps-jump :after #'+doom/blink-cursor) + (advice-add #'evil-window-top :after #'+doom/blink-cursor) (advice-add #'evil-window-middle :after #'+doom/blink-cursor) (advice-add #'evil-window-bottom :after #'+doom/blink-cursor))) diff --git a/modules/ui/tabbar/config.el b/modules/ui/tabbar/config.el index d225f1316..bb694c5c4 100644 --- a/modules/ui/tabbar/config.el +++ b/modules/ui/tabbar/config.el @@ -5,7 +5,6 @@ ;; find ivy (or helm) or even `buffer-menu' is better suited for this purpose. (def-package! tabbar - :demand t :config (setq tabbar-use-images nil) (tabbar-mode) diff --git a/modules/ui/unicode/config.el b/modules/ui/unicode/config.el index 047c23ff6..06636b3e9 100644 --- a/modules/ui/unicode/config.el +++ b/modules/ui/unicode/config.el @@ -7,7 +7,7 @@ (defun +unicode|init-fonts (&optional frame) "Initialize `unicode-fonts', if in a GUI session." - (when (display-graphic-p frame) + (when (and frame (display-graphic-p frame)) (with-selected-frame frame (require 'unicode-fonts) ;; NOTE will impact startup time on first run diff --git a/modules/ui/vi-tilde-fringe/config.el b/modules/ui/vi-tilde-fringe/config.el index 3467a770d..25ec00771 100644 --- a/modules/ui/vi-tilde-fringe/config.el +++ b/modules/ui/vi-tilde-fringe/config.el @@ -2,10 +2,10 @@ ;; indicators for empty lines past EOF (def-package! vi-tilde-fringe - :commands (global-vi-tilde-fringe-mode vi-tilde-fringe-mode) - :init - (add-hook 'doom-init-ui-hook #'global-vi-tilde-fringe-mode) + :commands vi-tilde-fringe-mode + :hook (doom-init-ui . global-vi-tilde-fringe-mode) :config - (defun +vi-tilde-fringe|disable () - (vi-tilde-fringe-mode -1))) + (add-hook! +doom-dashboard-mode + (when (bound-and-true-p vi-tilde-fringe-mode) + (vi-tilde-fringe-mode -1))))