Major optimization refactor, across the board

+ enable lexical-scope everywhere (lexical-binding = t): ~5-10% faster
  startup; ~5-20% general boost
+ reduce consing, function calls & garbage collection by preferring
  cl-loop & dolist over lambda closures (for mapc[ar], add-hook, and
  various cl-lib filter/map/reduce functions) -- where possible
+ prefer functions with dedicated opcodes, like assq (see byte-defop's
  in bytecomp.el for more)
+ prefer pcase & cond (faster) over cl-case
+ general refactor for code readability
+ ensure naming & style conventions are adhered to
+ appease byte-compiler by marking unused variables with underscore
+ defer minor mode activation to after-init, emacs-startup or
  window-setup hooks; a customization opportunity for users + ensures
  custom functionality won't interfere with startup.
This commit is contained in:
Henrik Lissner 2017-06-08 11:47:56 +02:00
parent 64a142b3fc
commit c7254e7bdc
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
154 changed files with 1101 additions and 1118 deletions

View file

@ -1,4 +1,4 @@
;;; autoload.el ;;; core/autoload/buffers.el -*- lexical-binding: t; -*-
(defvar-local doom-buffer--narrowed-origin nil) (defvar-local doom-buffer--narrowed-origin nil)
@ -25,19 +25,18 @@ the buffer (if narrowed).
Inspired from http://demonastery.org/2013/04/emacs-evil-narrow-region/" Inspired from http://demonastery.org/2013/04/emacs-evil-narrow-region/"
(interactive "r") (interactive "r")
(if (region-active-p) (cond ((region-active-p)
(progn
(deactivate-mark) (deactivate-mark)
(when clone-p (when clone-p
(let ((old-buf (current-buffer))) (let ((old-buf (current-buffer)))
(switch-to-buffer (clone-indirect-buffer nil nil)) (switch-to-buffer (clone-indirect-buffer nil nil))
(setq doom-buffer--narrowed-origin old-buf))) (setq doom-buffer--narrowed-origin old-buf)))
(narrow-to-region beg end)) (narrow-to-region beg end))
(if doom-buffer--narrowed-origin (doom-buffer--narrowed-origin
(progn
(kill-this-buffer) (kill-this-buffer)
(switch-to-buffer doom-buffer--narrowed-origin) (switch-to-buffer doom-buffer--narrowed-origin)
(setq doom-buffer--narrowed-origin nil)) (setq doom-buffer--narrowed-origin nil))
(t
(widen)))) (widen))))
@ -52,11 +51,12 @@ the current workspace."
(persp-buffer-list-restricted) (persp-buffer-list-restricted)
(buffer-list))) (buffer-list)))
(project-root (and project-p (doom-project-root t)))) (project-root (and project-p (doom-project-root t))))
(if project-root (cond (project-root
(funcall (if (eq project-p 'not) #'cl-remove-if #'cl-remove-if-not) (cl-loop for buf in buffers
(lambda (b) (projectile-project-buffer-p b project-root)) if (projectile-project-buffer-p buf project-root)
buffers) collect buf))
buffers))) (t
buffers))))
;;;###autoload ;;;###autoload
(defun doom-real-buffers-list (&optional buffer-list) (defun doom-real-buffers-list (&optional buffer-list)
@ -99,8 +99,9 @@ only the buried buffers in BUFFER-LIST (a list of BUFFER-OR-NAMEs)."
(defun doom-matching-buffers (pattern &optional buffer-list) (defun doom-matching-buffers (pattern &optional buffer-list)
"Get a list of all buffers (in the current workspace OR in BUFFER-LIST) that "Get a list of all buffers (in the current workspace OR in BUFFER-LIST) that
match the regex PATTERN." match the regex PATTERN."
(cl-remove-if-not (lambda (buf) (string-match-p pattern (buffer-name buf))) (cl-loop for buf in (or buffer-list (doom-buffer-list))
(or buffer-list (doom-buffer-list)))) when (string-match-p pattern (buffer-name buf))
collect buf))
(defun doom--cycle-real-buffers (&optional n) (defun doom--cycle-real-buffers (&optional n)
"Switch to the next buffer N times (previous, if N < 0), skipping over unreal "Switch to the next buffer N times (previous, if N < 0), skipping over unreal
@ -119,7 +120,7 @@ buffers. If there's nothing left, switch to `doom-fallback-buffer'. See
;; BUFFERS? Because `switch-to-next-buffer' and ;; BUFFERS? Because `switch-to-next-buffer' and
;; `switch-to-prev-buffer' properly update buffer list order. ;; `switch-to-prev-buffer' properly update buffer list order.
(while (not (memq (current-buffer) buffers)) (while (not (memq (current-buffer) buffers))
(dotimes (i (abs n)) (dotimes (_i (abs n))
(funcall move-func)))))) (funcall move-func))))))
(when (eq (current-buffer) (doom-fallback-buffer)) (when (eq (current-buffer) (doom-fallback-buffer))
(cd project-dir)) (cd project-dir))
@ -201,14 +202,15 @@ switched to a real buffer."
;;;###autoload ;;;###autoload
(defun doom-kill-buffer-and-windows (buffer) (defun doom-kill-buffer-and-windows (buffer)
"Kill the buffer and delete all the windows it's displayed in." "Kill the buffer and delete all the windows it's displayed in."
(dolist (window (get-buffer-window-list buffer))
(unless (one-window-p t) (unless (one-window-p t)
(mapc (lambda (win) (unless (one-window-p t) (delete-window win))) (delete-window window)))
(get-buffer-window-list buffer)))
(kill-buffer buffer)) (kill-buffer buffer))
;;;###autoload ;;;###autoload
(defun doom-kill-process-buffers () (defun doom-kill-process-buffers ()
"Kill all processes that have no visible associated buffers." "Kill all processes that have no visible associated buffers. Return number of
processes killed."
(interactive) (interactive)
(let ((n 0)) (let ((n 0))
(dolist (p (process-list)) (dolist (p (process-list))
@ -220,7 +222,7 @@ switched to a real buffer."
(not (buffer-live-p process-buffer))))) (not (buffer-live-p process-buffer)))))
(message "Killing %s" (process-name p)) (message "Killing %s" (process-name p))
(delete-process p) (delete-process p)
(setq n (1+ n))))) (cl-incf n))))
n)) n))
;;;###autoload ;;;###autoload
@ -253,11 +255,11 @@ belong to the current project in this workspace."
"Kill all other buffers in this workspace. If PROJECT-P, kill only the other "Kill all other buffers in this workspace. If PROJECT-P, kill only the other
buffers that belong to the current project." buffers that belong to the current project."
(interactive "P") (interactive "P")
(let ((buffers (doom-buffer-list project-p))) (let ((buffers (doom-buffer-list project-p))
(mapc (lambda (buf) (current-buffer (current-buffer)))
(unless (eq buf (current-buffer)) (dolist (buf buffers)
(unless (eq buf current-buffer)
(doom-kill-buffer-and-windows buf))) (doom-kill-buffer-and-windows buf)))
buffers)
(when (called-interactively-p 'interactive) (when (called-interactively-p 'interactive)
(message "Killed %s buffers" (length buffers))))) (message "Killed %s buffers" (length buffers)))))

View file

@ -1,4 +1,4 @@
;;; debug.el ;;; core/autoload/debug.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun doom/what-face (&optional pos) (defun doom/what-face (&optional pos)
@ -22,8 +22,9 @@
;;;###autoload ;;;###autoload
(defun doom-active-minor-modes () (defun doom-active-minor-modes ()
"Get a list of active minor-mode symbols." "Get a list of active minor-mode symbols."
(cl-remove-if (lambda (m) (and (boundp m) (symbol-value m))) (cl-loop for mode in minor-mode-list
minor-mode-list)) unless (and (boundp mode) (symbol-value mode))
collect mode))
;;;###autoload ;;;###autoload
(defun doom/what-minor-mode (mode) (defun doom/what-minor-mode (mode)
@ -44,11 +45,11 @@ selection of all minor-modes, active or not."
(declare (interactive-only t)) (declare (interactive-only t))
(interactive) (interactive)
(if-let (bad-hosts (if-let (bad-hosts
(loop for bad (cl-loop for bad
in `("https://wrong.host.badssl.com/" in '("https://wrong.host.badssl.com/"
"https://self-signed.badssl.com/") "https://self-signed.badssl.com/")
if (condition-case e if (condition-case _e
(url-retrieve bad (lambda (retrieved) t)) (url-retrieve bad (lambda (_retrieved) t))
(error nil)) (error nil))
collect bad)) collect bad))
(error (format "tls seems to be misconfigured (it got %s)." (error (format "tls seems to be misconfigured (it got %s)."

View file

@ -1,4 +1,4 @@
;;; editor.el ;;; core/autoload/editor.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun doom/sudo-find-file (file) (defun doom/sudo-find-file (file)
@ -65,7 +65,7 @@ If already there, do nothing."
(looking-at-p match-str)))) (looking-at-p match-str))))
;;;###autoload ;;;###autoload
(defun doom/dumb-indent (&optional smart) (defun doom/dumb-indent ()
"Inserts a tab character (or spaces x tab-width)." "Inserts a tab character (or spaces x tab-width)."
(interactive) (interactive)
(if indent-tabs-mode (if indent-tabs-mode
@ -142,11 +142,13 @@ possible, or just one char if that's not possible."
"Checks if point is surrounded by {} [] () delimiters and adds a "Checks if point is surrounded by {} [] () delimiters and adds a
space on either side of the point if so." space on either side of the point if so."
(interactive) (interactive)
(let ((command (or (command-remapping #'self-insert-command) #'self-insert-command))) (let ((command (or (command-remapping #'self-insert-command)
(if (doom--surrounded-p) #'self-insert-command)))
(progn (call-interactively command) (cond ((doom--surrounded-p)
(call-interactively command)
(save-excursion (call-interactively command))) (save-excursion (call-interactively command)))
(call-interactively command)))) (t
(call-interactively command)))))
;;;###autoload ;;;###autoload
(defun doom/deflate-space-maybe () (defun doom/deflate-space-maybe ()
@ -155,7 +157,7 @@ spaces on either side of the point if so. Resorts to
`doom/backward-delete-whitespace-to-column' otherwise." `doom/backward-delete-whitespace-to-column' otherwise."
(interactive) (interactive)
(save-match-data (save-match-data
(if (doom--surrounded-p) (cond ((doom--surrounded-p)
(let ((whitespace-match (match-string 1))) (let ((whitespace-match (match-string 1)))
(cond ((not whitespace-match) (cond ((not whitespace-match)
(call-interactively #'delete-backward-char)) (call-interactively #'delete-backward-char))
@ -164,13 +166,15 @@ spaces on either side of the point if so. Resorts to
(point-at-bol) (point)) (point-at-bol) (point))
(call-interactively #'delete-backward-char) (call-interactively #'delete-backward-char)
(save-excursion (call-interactively #'delete-char))) (save-excursion (call-interactively #'delete-char)))
(t (just-one-space 0)))) (t (just-one-space 0)))))
(doom/backward-delete-whitespace-to-column)))) (t
(doom/backward-delete-whitespace-to-column)))))
;;;###autoload ;;;###autoload
(defun doom/newline-and-indent () (defun doom/newline-and-indent ()
"Inserts a newline and possibly indents it. Also cotinues comments if executed "Inserts a newline and possibly indents it. Also continues comments if
from a commented line." executed from a commented line; handling special cases for certain languages
with weak native support."
(interactive) (interactive)
(cond ((sp-point-in-string) (cond ((sp-point-in-string)
(newline)) (newline))

View file

@ -1,4 +1,4 @@
;;; ../core/autoload/help.el ;;; core/autoload/help.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun doom/describe-setting (setting) (defun doom/describe-setting (setting)

View file

@ -1,4 +1,4 @@
;;; memoize.el ;;; core/autoload/memoize.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defvar doom-memoized-table (make-hash-table :test 'equal :size 10) (defvar doom-memoized-table (make-hash-table :test 'equal :size 10)
@ -23,7 +23,9 @@ and the value is the function's return value.")
"Create a memoize'd function. NAME, ARGLIST, DOCSTRING and BODY "Create a memoize'd function. NAME, ARGLIST, DOCSTRING and BODY
have the same meaning as in `defun'." have the same meaning as in `defun'."
(declare (indent defun) (doc-string 3)) (declare (indent defun) (doc-string 3))
`(progn `(,(if (bound-and-true-p byte-compile-current-file)
'with-no-warnings
'progn)
(defun ,name ,arglist ,@body) (defun ,name ,arglist ,@body)
(doom-memoize ',name))) (doom-memoize ',name)))

View file

@ -1,4 +1,4 @@
;;; message.el ;;; core/autoload/message.el -*- lexical-binding: t; -*-
(defconst doom-message-fg (defconst doom-message-fg
'((reset . 0) '((reset . 0)
@ -40,12 +40,12 @@
"An alternative to `format' that strips out ANSI codes if used in an "An alternative to `format' that strips out ANSI codes if used in an
interactive session." interactive session."
`(cl-flet* `(cl-flet*
(,@(mapcar (,@(cl-loop for rule
(lambda (rule) in (append doom-message-fg doom-message-bg doom-message-fx)
collect
`(,(car rule) `(,(car rule)
(lambda (message &rest args) (lambda (message &rest args)
(apply #'doom-ansi-apply ',(car rule) message args)))) (apply #'doom-ansi-apply ',(car rule) message args))))
(append doom-message-fg doom-message-bg doom-message-fx))
(color (symbol-function 'doom-ansi-apply))) (color (symbol-function 'doom-ansi-apply)))
(format ,message ,@args))) (format ,message ,@args)))

View file

@ -1,4 +1,4 @@
;;; ../core/autoload/minibuffer.el ;;; core/autoload/minibuffer.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun doom/minibuffer-kill-word () (defun doom/minibuffer-kill-word ()

View file

@ -1,5 +1,4 @@
;; -*- no-byte-compile: t; -*- ;;; core/autoload/packages.el -*- lexical-binding: t; -*-
;;; packages.el
(defvar doom--last-refresh nil) (defvar doom--last-refresh nil)
@ -15,10 +14,11 @@
(progn (progn
(message "Refreshing package archives") (message "Refreshing package archives")
(package-refresh-contents (not doom-debug-mode)) (package-refresh-contents (not doom-debug-mode))
(let ((i 0)) (cl-loop for i from 0
(while package--downloads-in-progress while (and package--downloads-in-progress
(sleep-for 0 250)) (<= i 10))
(persistent-soft-store 'last-pkg-refresh t "emacs" 900))) do (sleep-for 0 250))
(persistent-soft-store 'last-pkg-refresh t "emacs" 900))
(error (error
(doom-refresh-clear-cache) (doom-refresh-clear-cache)
(message "Failed to refresh packages: %s" (cadr ex)))))) (message "Failed to refresh packages: %s" (cadr ex))))))
@ -85,7 +85,7 @@ list of the package."
(plist-get (cdr (assq name doom-packages)) :freeze)) (plist-get (cdr (assq name doom-packages)) :freeze))
;;;###autoload ;;;###autoload
(defun doom-get-packages (&optional backend) (defun doom-get-packages ()
"Retrieves a list of explicitly installed packages (i.e. non-dependencies). "Retrieves a list of explicitly installed packages (i.e. non-dependencies).
Each element is a cons cell, whose car is the package symbol and whose cdr is Each element is a cons cell, whose car is the package symbol and whose cdr is
the quelpa recipe (if any). the quelpa recipe (if any).
@ -96,12 +96,12 @@ the packages relevant to that backend.
Warning: this function is expensive; it re-evaluates all of doom's config files. Warning: this function is expensive; it re-evaluates all of doom's config files.
Be careful not to use it in a loop." Be careful not to use it in a loop."
(doom-initialize-packages t) (doom-initialize-packages t)
(delq nil (cl-loop with packages = (append doom-core-packages (mapcar #'car doom-packages))
(mapcar (lambda (pkgsym) for sym in (cl-delete-duplicates packages)
(or (assq pkgsym doom-packages) if (or (assq sym doom-packages)
(list (car (assq pkgsym package-alist))))) (and (assq sym package-alist)
(cl-delete-duplicates (list sym)))
(append doom-core-packages (mapcar #'car doom-packages)))))) collect it))
;;;###autoload ;;;###autoload
(defun doom-get-depending-on (name) (defun doom-get-depending-on (name)
@ -124,11 +124,11 @@ containing (PACKAGE-SYMBOL OLD-VERSION-LIST NEW-VERSION-LIST).
If INCLUDE-FROZEN-P is non-nil, check frozen packages as well. If INCLUDE-FROZEN-P is non-nil, check frozen packages as well.
Used by `doom/packages-update'." Used by `doom/packages-update'."
(let ((pkgs (mapcar #'car (doom-get-packages)))) (cl-loop for pkg in (doom-get-packages)
(delq nil if (or (and (doom-package-frozen-p (car pkg))
(mapcar #'doom-package-outdated-p include-frozen-p)
(if include-frozen-p pkgs (doom-package-outdated-p (car pkg)))
(cl-remove-if #'doom-package-frozen-p pkgs)))))) collect it))
;;;###autoload ;;;###autoload
(defun doom-get-orphaned-packages () (defun doom-get-orphaned-packages ()
@ -152,13 +152,14 @@ If INCLUDE-IGNORED-P is non-nil, includes missing packages that are ignored,
i.e. they have an :ignore property. i.e. they have an :ignore property.
Used by `doom/packages-install'." Used by `doom/packages-install'."
(cl-remove-if (lambda (pkgsym) (cl-loop for pkgsym in (doom-get-packages)
unless
(let ((pkg (car pkgsym))) (let ((pkg (car pkgsym)))
(or (assq pkg package-alist) (or (assq pkg package-alist)
(unless include-ignored-p (doom-package-ignored-p pkg)) (unless include-ignored-p (doom-package-ignored-p pkg))
(and (not (plist-get (assq pkg doom-packages) :pin)) (and (not (plist-get (assq pkg doom-packages) :pin))
(assq pkg package--builtins))))) (assq pkg package--builtins))))
(doom-get-packages))) collect pkgsym))
;;;###autoload ;;;###autoload
(defun doom*package-delete (desc &rest _) (defun doom*package-delete (desc &rest _)
@ -180,16 +181,14 @@ Used by `doom/packages-install'."
(defun doom--packages-choose (prompt) (defun doom--packages-choose (prompt)
(doom-initialize) (doom-initialize)
(let* ((table (mapcar (let ((table (cl-loop for pkg in package-alist
(lambda (p) (cons (package-desc-full-name p) p)) unless (package-built-in-p (cdr pkg))
(delq nil collect (cons (package-desc-full-name (cdr pkg))
(mapcar (lambda (p) (unless (package-built-in-p p) p)) (cdr pkg)))))
(apply #'append (mapcar #'cdr package-alist)))))) (cdr (assoc (completing-read prompt
(name (completing-read
prompt
(mapcar #'car table) (mapcar #'car table)
nil t))) nil t)
(cdr (assoc name table)))) table))))
(defmacro doom--condition-case! (&rest body) (defmacro doom--condition-case! (&rest body)
`(condition-case ex `(condition-case ex
@ -229,20 +228,21 @@ example; the package name can be omitted)."
(user-error "%s is already installed" name)) (user-error "%s is already installed" name))
(let ((plist (or plist (cdr (assq name doom-packages)))) (let ((plist (or plist (cdr (assq name doom-packages))))
(inhibit-message (not doom-debug-mode)) (inhibit-message (not doom-debug-mode))
(recipe (plist-get plist :recipe))) (recipe (plist-get plist :recipe))
quelpa-upgrade-p)
(cond (recipe (quelpa recipe)) (cond (recipe (quelpa recipe))
(t (package-install name)))) (t (package-install name)))
(when (package-installed-p name) (when (package-installed-p name)
(cl-pushnew (cons name plist) doom-packages :test #'eq :key #'car) (cl-pushnew (cons name plist) doom-packages :test #'eq :key #'car)
t)) t)))
(defun doom-update-package (name) (defun doom-update-package (name &optional force-p)
"Updates package NAME if it is out of date, using quelpa or package.el as "Updates package NAME if it is out of date, using quelpa or package.el as
appropriate." appropriate."
(doom-initialize) (doom-initialize)
(unless (package-installed-p name) (unless (package-installed-p name)
(user-error "%s isn't installed" name)) (user-error "%s isn't installed" name))
(when (doom-package-outdated-p name) (when (or force-p (doom-package-outdated-p name))
(let ((inhibit-message (not doom-debug-mode)) (let ((inhibit-message (not doom-debug-mode))
(desc (cadr (assq name package-alist)))) (desc (cadr (assq name package-alist))))
(pcase (doom-package-backend name) (pcase (doom-package-backend name)
@ -258,12 +258,11 @@ appropriate."
(package-compute-transaction (list archive) (package-desc-reqs archive)) (package-compute-transaction (list archive) (package-desc-reqs archive))
(package-compute-transaction () (list (list archive)))))) (package-compute-transaction () (list (list archive))))))
(package-download-transaction packages)))) (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) (when (file-directory-p old-dir)
(delete-directory old-dir t))) (delete-directory old-dir t)))
(version-list-< t))))
(package-desc-version desc)
(package-desc-version (cadr (assq name package-alist)))))))
(defun doom-delete-package (name &optional force-p) (defun doom-delete-package (name &optional force-p)
"Uninstalls package NAME if it exists, and clears it from `quelpa-cache'." "Uninstalls package NAME if it exists, and clears it from `quelpa-cache'."
@ -358,7 +357,7 @@ appropriate."
(message! "Updating %s" (car pkg)) (message! "Updating %s" (car pkg))
(doom--condition-case! (doom--condition-case!
(message! (message!
(let ((result (doom-update-package (car pkg)))) (let ((result (doom-update-package (car pkg) t)))
(color (if result 'green 'red) (color (if result 'green 'red)
" %s" " %s"
(if result "DONE" "FAILED")))))) (if result "DONE" "FAILED"))))))
@ -450,7 +449,7 @@ calls."
(if (y-or-n-p (format "%s will be updated from %s to %s. Update?" (if (y-or-n-p (format "%s will be updated from %s to %s. Update?"
package old-v-str new-v-str)) package old-v-str new-v-str))
(message "%s %s (%s => %s)" (message "%s %s (%s => %s)"
(if (doom-update-package package) "Updated" "Failed to update") (if (doom-update-package package t) "Updated" "Failed to update")
package old-v-str new-v-str) package old-v-str new-v-str)
(message "Aborted"))) (message "Aborted")))
(message "%s is up-to-date" package)))) (message "%s is up-to-date" package))))

View file

@ -1,4 +1,4 @@
;;; popups.el ;;; core/autoload/popups.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun doom-popup-p (&optional target) (defun doom-popup-p (&optional target)
@ -13,7 +13,8 @@ current window if omitted."
;;;###autoload ;;;###autoload
(defun doom-popup-buffer (buffer &rest plist) (defun doom-popup-buffer (buffer &rest plist)
"Display BUFFER in a shackle popup. See `shackle-rules' for possible rules." "Display BUFFER in a shackle popup. See `shackle-rules' for possible rules.
Returns the new popup window."
(declare (indent defun)) (declare (indent defun))
(unless (bufferp buffer) (unless (bufferp buffer)
(error "%s is not a valid buffer" buffer)) (error "%s is not a valid buffer" buffer))
@ -106,9 +107,7 @@ only close popups that have an :autoclose property in their rule (see
`shackle-rules')." `shackle-rules')."
(interactive) (interactive)
(when-let (popups (doom-popup-windows)) (when-let (popups (doom-popup-windows))
(let ((orig-win (selected-window)) (let (success doom-popup-remember-history)
success
doom-popup-remember-history)
(setq doom-popup-history (mapcar #'doom--popup-data popups)) (setq doom-popup-history (mapcar #'doom--popup-data popups))
(dolist (window popups) (dolist (window popups)
(when (or force-p (when (or force-p
@ -145,6 +144,7 @@ only close popups that have an :autoclose property in their rule (see
;;;###autoload ;;;###autoload
(defun doom-popup-prop (prop &optional window) (defun doom-popup-prop (prop &optional window)
"Returns a `doom-popup-rules' PROPerty from WINDOW."
(or (plist-get (or (if window (or (plist-get (or (if window
(buffer-local-value 'doom-popup-rules (window-buffer window)) (buffer-local-value 'doom-popup-rules (window-buffer window))
doom-popup-rules) doom-popup-rules)
@ -157,6 +157,7 @@ only close popups that have an :autoclose property in their rule (see
;;;###autoload ;;;###autoload
(defun doom-popup-side (&optional window) (defun doom-popup-side (&optional window)
"Return what side a popup WINDOW came from ('left 'right 'above or 'below)."
(let ((align (doom-popup-prop :align window))) (let ((align (doom-popup-prop :align window)))
(when (eq align t) (when (eq align t)
(setq align shackle-default-alignment)) (setq align shackle-default-alignment))
@ -166,6 +167,7 @@ only close popups that have an :autoclose property in their rule (see
;;;###autoload ;;;###autoload
(defun doom-popup-size (&optional window) (defun doom-popup-size (&optional window)
"Return the size of a popup WINDOW."
(let ((side (doom-popup-side window))) (let ((side (doom-popup-side window)))
(cond ((memq side '(left right)) (cond ((memq side '(left right))
(window-width window)) (window-width window))

View file

@ -1,5 +1,4 @@
;;; system.el ;;; core/autoload/system.el -*- lexical-binding: t; -*-
(provide 'core-lib-system)
;;;###autoload ;;;###autoload
(defun doom-system-os (&optional os) (defun doom-system-os (&optional os)
@ -17,8 +16,7 @@ is given, returns t if it matches the current system, and nil otherwise."
((memq system-type '(windows-nt cygwin)) ((memq system-type '(windows-nt cygwin))
'windows) 'windows)
(t (error "Unknown OS: %s" system-type))))) (t (error "Unknown OS: %s" system-type)))))
(if os (or (and os (eq os type))
(eq os type)
type))) type)))
;;;###autoload ;;;###autoload
@ -34,6 +32,7 @@ is given, returns t if it matches the current system, and nil otherwise."
(t (t
(princ (shell-command-to-string (apply #'format command args))))))) (princ (shell-command-to-string (apply #'format command args)))))))
(defvar tramp-verbose)
;;;###autoload ;;;###autoload
(defun doom-sudo (command &rest args) (defun doom-sudo (command &rest args)
"Like `doom-sh', but runs as root (prompts for password)." "Like `doom-sh', but runs as root (prompts for password)."

View file

@ -1,4 +1,4 @@
;;; ../core/autoload/test.el ;;; core/autoload/test.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defmacro def-test-group! (name &rest body) (defmacro def-test-group! (name &rest body)

View file

@ -1,4 +1,4 @@
;;; ui.el ;;; core/autoload/ui.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun doom/toggle-fullscreen () (defun doom/toggle-fullscreen ()
@ -15,7 +15,7 @@
(interactive "P") (interactive "P")
(cond ((featurep 'nlinum) (cond ((featurep 'nlinum)
(nlinum-mode (or arg (if nlinum-mode -1 +1)))) (nlinum-mode (or arg (if nlinum-mode -1 +1))))
((featurep 'linum-mode) ((featurep 'linum)
(linum-mode (or arg (if linum-mode -1 +1)))) (linum-mode (or arg (if linum-mode -1 +1))))
(t (t
(error "No line number plugin detected")))) (error "No line number plugin detected"))))
@ -38,7 +38,6 @@ window changes before then, the undo expires."
(delete-other-windows))) (delete-other-windows)))
(defvar doom--window-enlargened nil) (defvar doom--window-enlargened nil)
;;;###autoload ;;;###autoload
(defun doom/window-enlargen () (defun doom/window-enlargen ()
"Enlargen the current window. Activate again to undo." "Enlargen the current window. Activate again to undo."

View file

@ -1,4 +1,4 @@
;;; core-editor.el --- filling the editor shaped hole in the Emacs OS ;;; core-editor.el -*- lexical-binding: t; -*-
(defvar doom-large-file-size 1 (defvar doom-large-file-size 1
"Size (in MB) above which the user will be prompted to open the file literally "Size (in MB) above which the user will be prompted to open the file literally
@ -48,10 +48,12 @@ modes are active and the buffer is read-only.")
vc-follow-symlinks t) vc-follow-symlinks t)
;; ediff: use existing frame instead of creating a new one ;; ediff: use existing frame instead of creating a new one
(add-hook! 'ediff-load-hook (defun doom|init-ediff ()
(setq ediff-diff-options "-w" (setq ediff-diff-options "-w"
ediff-split-window-function #'split-window-horizontally ediff-split-window-function #'split-window-horizontally
ediff-window-setup-function #'ediff-setup-windows-plain)) ; no extra frames ;; no extra frames
ediff-window-setup-function #'ediff-setup-windows-plain))
(add-hook 'ediff-load-hook #'doom|init-ediff)
(defun doom|dont-kill-scratch-buffer () (defun doom|dont-kill-scratch-buffer ()
"Don't kill the scratch buffer." "Don't kill the scratch buffer."
@ -61,8 +63,7 @@ modes are active and the buffer is read-only.")
(defun doom*delete-trailing-whitespace (orig-fn &rest args) (defun doom*delete-trailing-whitespace (orig-fn &rest args)
"Don't affect trailing whitespace on current line." "Don't affect trailing whitespace on current line."
(let ((spaces (1- (current-column))) (let ((linestr (buffer-substring-no-properties
(linestr (buffer-substring-no-properties
(line-beginning-position) (line-beginning-position)
(line-end-position)))) (line-end-position))))
(apply orig-fn args) (apply orig-fn args)
@ -106,7 +107,7 @@ fundamental-mode) for performance sake."
savehist-autosave-interval nil ; save on kill only savehist-autosave-interval nil ; save on kill only
savehist-additional-variables '(kill-ring search-ring regexp-search-ring) savehist-additional-variables '(kill-ring search-ring regexp-search-ring)
save-place-file (concat doom-cache-dir "saveplace")) save-place-file (concat doom-cache-dir "saveplace"))
(add-hook! 'after-init-hook #'(savehist-mode save-place-mode)) (add-hook! 'emacs-startup-hook #'(savehist-mode save-place-mode))
;; Keep track of recently opened files ;; Keep track of recently opened files
(def-package! recentf (def-package! recentf
@ -145,10 +146,12 @@ fundamental-mode) for performance sake."
(t (error "%s is an invalid action for :editorconfig" action))))) (t (error "%s is an invalid action for :editorconfig" action)))))
:config :config
(editorconfig-mode +1) (add-hook 'emacs-startup-hook #'editorconfig-mode)
;; Show whitespace in tabs indentation mode
(add-hook! 'editorconfig-custom-hooks (defun doom|editorconfig-whitespace-mode-maybe (&rest _)
(if indent-tabs-mode (whitespace-mode +1)))) "Show whitespace-mode when file uses TABS (ew)."
(if indent-tabs-mode (whitespace-mode +1)))
(add-hook 'editorconfig-custom-hooks #'doom|editorconfig-whitespace-mode-maybe))
;; Auto-close delimiters and blocks as you type ;; Auto-close delimiters and blocks as you type
(def-package! smartparens (def-package! smartparens
@ -161,7 +164,7 @@ fundamental-mode) for performance sake."
sp-max-pair-length 3) sp-max-pair-length 3)
:config :config
(smartparens-global-mode 1) (add-hook 'emacs-startup-hook #'smartparens-global-mode)
(require 'smartparens-config) (require 'smartparens-config)
;; Smartparens interferes with Replace mode ;; Smartparens interferes with Replace mode
(add-hook 'evil-replace-state-entry-hook #'turn-off-smartparens-mode) (add-hook 'evil-replace-state-entry-hook #'turn-off-smartparens-mode)

View file

@ -1,8 +1,8 @@
;;; core-keybinds.el ;;; core-keybinds.el -*- lexical-binding: t; -*-
;; A centralized keybinds system, integrated with `which-key' to preview ;; A centralized keybinds system, integrated with `which-key' to preview
;; available keys, and `evil', if it's enabled. All built into one powerful ;; available keybindings. All built into one powerful macro: `map!'. If evil is
;; macro: `map!'. ;; never loaded, then evil bindings set with `map!' will be ignored.
(defvar doom-leader-key "SPC" (defvar doom-leader-key "SPC"
"The leader prefix key, for global commands.") "The leader prefix key, for global commands.")
@ -11,13 +11,13 @@
"The localleader prefix key, for major-mode specific commands.") "The localleader prefix key, for major-mode specific commands.")
(defvar doom-evil-state-alist (defvar doom-evil-state-alist
'(("n" . normal) '((?n . normal)
("v" . visual) (?v . visual)
("i" . insert) (?i . insert)
("e" . emacs) (?e . emacs)
("o" . operator) (?o . operator)
("m" . motion) (?m . motion)
("r" . replace)) (?r . replace))
"A list of cons cells that map a letter to a evil state symbol.") "A list of cons cells that map a letter to a evil state symbol.")
@ -33,7 +33,7 @@
;; embolden local bindings ;; embolden local bindings
(set-face-attribute 'which-key-local-map-description-face nil :weight 'bold) (set-face-attribute 'which-key-local-map-description-face nil :weight 'bold)
(which-key-setup-side-window-bottom) (which-key-setup-side-window-bottom)
(which-key-mode +1)) (add-hook 'window-setup-hook #'which-key-mode))
;; ;;
@ -56,14 +56,11 @@ IGNORE is a list of keyword letters that should be ignored.
For example, :nvi will map to (list 'normal 'visual 'insert). See For example, :nvi will map to (list 'normal 'visual 'insert). See
`doom-evil-state-alist' to customize this." `doom-evil-state-alist' to customize this."
(delq nil (cl-loop for l across (substring (symbol-name keyword) 1)
(mapcar (lambda (l) if (cdr (assq l doom-evil-state-alist))
(let ((state (cdr (assoc l doom-evil-state-alist)))) collect it
(unless state else if (not (or (eq ignore t) (member l ignore)))
(unless (or (eq ignore t) (member l ignore)) do (error "not a valid state: %s" l)))
(error "not a valid state: %s" l)))
state))
(split-string (substring (symbol-name keyword) 1) "" t))))
;; Register keywords for proper indentation (see `map!') ;; Register keywords for proper indentation (see `map!')
@ -79,6 +76,11 @@ For example, :nvi will map to (list 'normal 'visual 'insert). See
(put ':localleader 'lisp-indent-function 'defun) (put ':localleader 'lisp-indent-function 'defun)
(put ':textobj 'lisp-indent-function 'defun) (put ':textobj 'lisp-indent-function 'defun)
;; specials
(defvar doom--keymaps nil)
(defvar doom--prefix nil)
(defvar doom--defer nil)
(defmacro map! (&rest rest) (defmacro map! (&rest rest)
"A nightmare of a key-binding macro that will use `evil-define-key*', "A nightmare of a key-binding macro that will use `evil-define-key*',
`define-key', `local-set-key' and `global-set-key' depending on context and `define-key', `local-set-key' and `global-set-key' depending on context and
@ -130,9 +132,9 @@ Example
(:when IS-MAC (:when IS-MAC
:n \"M-s\" 'some-fn :n \"M-s\" 'some-fn
:i \"M-o\" (lambda (interactive) (message \"Hi\"))))" :i \"M-o\" (lambda (interactive) (message \"Hi\"))))"
(let ((keymaps (if (boundp 'keymaps) keymaps)) (let ((doom--keymaps doom--keymaps)
(prefix (if (boundp 'prefix) prefix)) (doom--prefix doom--prefix)
(defer (if (boundp 'defer) defer)) (doom--defer doom--defer)
local key def states forms desc modes) local key def states forms desc modes)
(while rest (while rest
(setq key (pop rest)) (setq key (pop rest))
@ -156,19 +158,19 @@ Example
(:unless (push `(if (not ,(pop rest)) ,(macroexpand `(map! ,@rest))) forms) (setq rest '())) (:unless (push `(if (not ,(pop rest)) ,(macroexpand `(map! ,@rest))) forms) (setq rest '()))
(:after (push `(after! ,(pop rest) ,(macroexpand `(map! ,@rest))) forms) (setq rest '())) (:after (push `(after! ,(pop rest) ,(macroexpand `(map! ,@rest))) forms) (setq rest '()))
(:desc (setq desc (pop rest))) (:desc (setq desc (pop rest)))
(:map* (setq defer t) (push :map rest)) (:map* (setq doom--defer t) (push :map rest))
(:map (:map
(setq keymaps (setq doom--keymaps
(let ((car (pop rest))) (let ((car (pop rest)))
(if (listp car) car (list car))))) (if (listp car) car (list car)))))
(:mode (:mode
(setq modes (setq modes
(let ((car (pop rest))) (let ((car (pop rest)))
(if (listp car) car (list car)))) (if (listp car) car (list car))))
(unless keymaps (unless doom--keymaps
(setq keymaps (setq doom--keymaps
(mapcar (lambda (m) (intern (format "%s-map" (symbol-name m)))) (cl-loop for m in modes
modes)))) collect (intern (format "%s-map" (symbol-name m)))))))
(:textobj (:textobj
(let* ((key (pop rest)) (let* ((key (pop rest))
(inner (pop rest)) (inner (pop rest))
@ -178,20 +180,20 @@ Example
forms))) forms)))
(:prefix (:prefix
(let ((def (pop rest))) (let ((def (pop rest)))
(setq prefix `(vconcat ,prefix (kbd ,def))) (setq doom--prefix `(vconcat ,doom--prefix (kbd ,def)))
(when desc (when desc
(push `(doom--keybind-register ,(key-description (eval prefix)) (push `(doom--keybind-register ,(key-description (eval doom--prefix))
,desc ',modes) ,desc ',modes)
forms) forms)
(setq desc nil)))) (setq desc nil))))
(otherwise ; might be a state prefix (_ ; might be a state doom--prefix
(setq states (doom--keyword-to-states key '("L"))) (setq states (doom--keyword-to-states key '("L")))
(let (case-fold-search) (let (case-fold-search)
(when (string-match-p "L" (symbol-name key)) (when (string-match-p "L" (symbol-name key))
(setq local t) (setq local t)
(cond ((= (length states) 0) (cond ((= (length states) 0)
(user-error "local keybinding for %s must accompany another state" key)) (user-error "local keybinding for %s must accompany another state" key))
((> (length keymaps) 0) ((> (length doom--keymaps) 0)
(user-error "local keybinding for %s cannot accompany a keymap" key)))))))) (user-error "local keybinding for %s cannot accompany a keymap" key))))))))
;; It's a key-def pair ;; It's a key-def pair
@ -205,8 +207,8 @@ Example
(setq key `(kbd ,key))) (setq key `(kbd ,key)))
((stringp key) ((stringp key)
(setq key (kbd key)))) (setq key (kbd key))))
(when prefix (when doom--prefix
(setq key (append prefix (list key)))) (setq key (append doom--prefix (list key))))
(unless (> (length rest) 0) (unless (> (length rest) 0)
(user-error "map! has no definition for %s key" key)) (user-error "map! has no definition for %s key" key))
(setq def (pop rest)) (setq def (pop rest))
@ -214,10 +216,10 @@ Example
(push `(doom--keybind-register ,(key-description (eval key)) (push `(doom--keybind-register ,(key-description (eval key))
,desc ',modes) ,desc ',modes)
forms)) forms))
(cond ((and keymaps states) (cond ((and doom--keymaps states)
(unless (featurep 'evil) (throw 'skip 'evil)) (unless (featurep 'evil) (throw 'skip 'evil))
(dolist (keymap keymaps) (dolist (keymap doom--keymaps)
(push `(,(if defer 'evil-define-key 'evil-define-key*) (push `(,(if doom--defer 'evil-define-key 'evil-define-key*)
',states ,keymap ,key ,def) ',states ,keymap ,key ,def)
forms))) forms)))
(states (states
@ -227,8 +229,8 @@ Example
,(intern (format "evil-%s-state-%smap" state (if local "local-" ""))) ,(intern (format "evil-%s-state-%smap" state (if local "local-" "")))
,key ,def) ,key ,def)
forms))) forms)))
(keymaps (doom--keymaps
(dolist (keymap keymaps) (dolist (keymap doom--keymaps)
(push `(define-key ,keymap ,key ,def) forms))) (push `(define-key ,keymap ,key ,def) forms)))
(t (push `(,(if local 'local-set-key 'global-set-key) ,key ,def) (t (push `(,(if local 'local-set-key 'global-set-key) ,key ,def)
forms)))) forms))))

View file

@ -1,4 +1,4 @@
;;; core-lib.el ;;; core-lib.el -*- lexical-binding: t; -*-
;; I don't use use-package for these to save on the `fboundp' lookups it does ;; 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 ;; for its :commands property. I use dolists instead of mapc to avoid extra
@ -35,23 +35,21 @@
'default-directory 'default-directory
(or root `(doom-project-root)))))) (or root `(doom-project-root))))))
((listp paths) ((listp paths)
(let (forms) (cl-loop for i in paths
(dolist (i paths (nreverse forms)) collect (doom--resolve-paths i root)))
(push (doom--resolve-paths i root) forms))))
(t paths))) (t paths)))
(defun doom--resolve-hooks (hooks) (defun doom--resolve-hooks (hooks)
(let ((quoted-p (eq (car-safe hooks) 'quote)) (let ((quoted-p (eq (car-safe hooks) 'quote)))
ret-hooks)
(when quoted-p (when quoted-p
(setq hooks (cadr hooks))) (setq hooks (cadr hooks)))
(dolist (hook (if (listp hooks) hooks (list hooks)) (nreverse ret-hooks)) (cl-loop with hooks = (if (listp hooks) hooks (list hooks))
(push (cond ((eq (car-safe hook) 'quote) for hook in hooks
(cadr hook)) if (eq (car-safe hook) 'quote)
(quoted-p hook) collect (cadr hook)
(t else if quoted-p
(intern (format "%s-hook" (symbol-name hook))))) collect hook
ret-hooks)))) else collect (intern (format "%s-hook" (symbol-name hook))))))
;; ;;
@ -67,8 +65,7 @@
"A smart wrapper around `with-eval-after-load'. Supresses warnings during "A smart wrapper around `with-eval-after-load'. Supresses warnings during
compilation." compilation."
(declare (indent defun) (debug t)) (declare (indent defun) (debug t))
`(,(if (or (not (boundp 'byte-compile-current-file)) `(,(if (or (not (bound-and-true-p byte-compile-current-file))
(not byte-compile-current-file)
(if (symbolp feature) (if (symbolp feature)
(require feature nil :no-error) (require feature nil :no-error)
(load feature :no-message :no-error))) (load feature :no-message :no-error)))
@ -139,12 +136,13 @@ Examples:
Body forms can access the hook's arguments through the let-bound variable Body forms can access the hook's arguments through the let-bound variable
`args'." `args'."
(declare (indent defun) (debug t)) (declare (indent defun) (debug t))
(let ((hook-fn (if (boundp 'hook-fn) hook-fn)) (let ((hook-fn 'add-hook)
hook append-p local-p) append-p local-p)
(while (keywordp (car args)) (while (keywordp (car args))
(pcase (pop args) (pcase (pop args)
(:append (setq append-p t)) (:append (setq append-p t))
(:local (setq local-p t)))) (:local (setq local-p t))
(:remove (setq hook-fn 'remove-hook))))
(let ((hooks (doom--resolve-hooks (pop args))) (let ((hooks (doom--resolve-hooks (pop args)))
(funcs (funcs
(let ((val (car args))) (let ((val (car args)))
@ -157,7 +155,7 @@ Body forms can access the hook's arguments through the let-bound variable
(dolist (fn funcs) (dolist (fn funcs)
(setq fn (if (symbolp fn) (setq fn (if (symbolp fn)
`(function ,fn) `(function ,fn)
`(lambda (&rest args) ,@args))) `(lambda (&rest _) ,@args)))
(dolist (hook hooks) (dolist (hook hooks)
(push (cond ((eq hook-fn 'remove-hook) (push (cond ((eq hook-fn 'remove-hook)
`(remove-hook ',hook ,fn ,local-p)) `(remove-hook ',hook ,fn ,local-p))
@ -169,14 +167,13 @@ Body forms can access the hook's arguments through the let-bound variable
(defmacro remove-hook! (&rest args) (defmacro remove-hook! (&rest args)
"Convenience macro for `remove-hook'. Takes the same arguments as "Convenience macro for `remove-hook'. Takes the same arguments as
`add-hook!'." `add-hook!'."
(let ((hook-fn 'remove-hook)) `(add-hook! :remove ,@args))
(macroexpand `(add-hook! ,@args))))
(defmacro associate! (mode &rest plist) (defmacro associate! (mode &rest plist)
"Associate a minor mode to certain patterns and project files." "Associate a minor mode to certain patterns and project files."
(declare (indent 1)) (declare (indent 1))
(unless noninteractive (unless noninteractive
(let* ((modes (plist-get plist :modes)) (let ((modes (plist-get plist :modes))
(match (plist-get plist :match)) (match (plist-get plist :match))
(files (plist-get plist :files)) (files (plist-get plist :files))
(pred-form (plist-get plist :when))) (pred-form (plist-get plist :when)))
@ -196,9 +193,8 @@ Body forms can access the hook's arguments through the let-bound variable
,(or pred-form t)) ,(or pred-form t))
(,mode 1))) (,mode 1)))
,@(if (and modes (listp modes)) ,@(if (and modes (listp modes))
(let (forms) (cl-loop for hook in (doom--resolve-hooks modes)
(dolist (hook (doom--resolve-hooks modes) (nreverse forms)) collect `(add-hook ',hook ',hook-name))
(push `(add-hook ',hook ',hook-name) forms)))
`((add-hook 'after-change-major-mode-hook ',hook-name)))))) `((add-hook 'after-change-major-mode-hook ',hook-name))))))
(match (match
`(push (cons ,match ',mode) doom-auto-minor-mode-alist)) `(push (cons ,match ',mode) doom-auto-minor-mode-alist))

View file

@ -1,4 +1,4 @@
;;; core-os.el ;;; core-os.el -*- lexical-binding: t; -*-
(defconst IS-MAC (eq system-type 'darwin)) (defconst IS-MAC (eq system-type 'darwin))
(defconst IS-LINUX (eq system-type 'gnu/linux)) (defconst IS-LINUX (eq system-type 'gnu/linux))

View file

@ -1,4 +1,4 @@
;;; core-packages.el ;;; core-packages.el --- package management system -*- lexical-binding: t; -*-
;; Emacs package management is opinionated. Unfortunately, so am I. I've bound ;; Emacs package management is opinionated. Unfortunately, so am I. I've bound
;; together `use-package', `quelpa' and package.el to create my own, ;; together `use-package', `quelpa' and package.el to create my own,
@ -76,7 +76,7 @@ base by `doom!' and for calculating how many packages exist.")
(defvar doom--refresh-p nil) (defvar doom--refresh-p nil)
(setq load-prefer-newer noninteractive (setq load-prefer-newer (or noninteractive doom-debug-mode)
package--init-file-ensured t package--init-file-ensured t
package-user-dir (expand-file-name "elpa" doom-packages-dir) package-user-dir (expand-file-name "elpa" doom-packages-dir)
package-enable-at-startup nil package-enable-at-startup nil
@ -96,7 +96,7 @@ base by `doom!' and for calculating how many packages exist.")
use-package-always-defer t use-package-always-defer t
use-package-always-ensure nil use-package-always-ensure nil
use-package-expand-minimally (eval-when-compile (not doom-debug-mode)) use-package-expand-minimally (not doom-debug-mode)
use-package-debug nil use-package-debug nil
use-package-verbose doom-debug-mode use-package-verbose doom-debug-mode
use-package-minimum-reported-time (if doom-debug-mode 0 0.1) use-package-minimum-reported-time (if doom-debug-mode 0 0.1)
@ -144,7 +144,7 @@ to speed up startup."
;; Also, in some edge cases involving package initialization during a ;; Also, in some edge cases involving package initialization during a
;; non-interactive session, `package-initialize' fails to fill `load-path'. ;; non-interactive session, `package-initialize' fails to fill `load-path'.
;; If we want something done right, do it ourselves! ;; If we want something done right, do it ourselves!
(setq doom--package-load-path (directory-files package-user-dir t "^\\w" t) (setq doom--package-load-path (directory-files package-user-dir t "^[^.]" t)
load-path (append load-path doom--package-load-path)) load-path (append load-path doom--package-load-path))
;; Ensure core packages are installed ;; Ensure core packages are installed
@ -164,7 +164,7 @@ to speed up startup."
(setq doom-init-p t))) (setq doom-init-p t)))
(defun doom-initialize-autoloads (&optional inhibit-reload-p) (defun doom-initialize-autoloads ()
"Ensures that `doom-autoload-file' exists and is loaded. Otherwise run "Ensures that `doom-autoload-file' exists and is loaded. Otherwise run
`doom/reload-autoloads' to generate it." `doom/reload-autoloads' to generate it."
(unless (file-exists-p doom-autoload-file) (unless (file-exists-p doom-autoload-file)
@ -189,15 +189,16 @@ This aggressively reloads core autoload files."
(funcall load-fn (expand-file-name "init.el" doom-emacs-dir)) (funcall load-fn (expand-file-name "init.el" doom-emacs-dir))
(funcall load-fn (doom-module-path :private user-login-name "init.el")) (funcall load-fn (doom-module-path :private user-login-name "init.el"))
(when load-p (when load-p
(mapc (lambda (file) (funcall load-fn file t)) (cl-loop for file
(append (nreverse (file-expand-wildcards (concat doom-core-dir "core*.el"))) in (append (nreverse (file-expand-wildcards (expand-file-name "core*.el" doom-core-dir)))
(file-expand-wildcards (concat doom-core-dir "autoload/*.el")) (file-expand-wildcards (expand-file-name "autoload/*.el" doom-core-dir))
(doom--module-paths "config.el"))))) (doom--module-paths "config.el"))
do (funcall load-fn file t))))
(when (or force-p (not doom-packages)) (when (or force-p (not doom-packages))
(setq doom-packages nil) (setq doom-packages nil)
(funcall load-fn (expand-file-name "packages.el" doom-core-dir)) (funcall load-fn (expand-file-name "packages.el" doom-core-dir))
(mapc (lambda (file) (funcall load-fn file t)) (dolist (file (doom--module-paths "packages.el"))
(doom--module-paths "packages.el"))))) (funcall load-fn file t)))))
(defun doom-initialize-modules (modules) (defun doom-initialize-modules (modules)
"Adds MODULES to `doom-modules'. MODULES must be in mplist format. "Adds MODULES to `doom-modules'. MODULES must be in mplist format.
@ -213,15 +214,12 @@ This aggressively reloads core autoload files."
(error "No namespace specified on `doom!' for %s" m)) (error "No namespace specified on `doom!' for %s" m))
((eq m '*) ((eq m '*)
(doom-initialize-modules (doom-initialize-modules
(cons mode (cl-loop with modpath = (expand-file-name (substring (symbol-name mode) 1) doom-modules-dir)
(mapcar for path in (directory-files modpath t "^\\w")
(lambda (dir) (intern (file-name-nondirectory dir))) if (file-directory-p path)
(cl-remove-if-not collect (intern (file-name-nondirectory path)) into paths
#'file-directory-p finally return (cons mode paths)
(directory-files (expand-file-name finally do (message "== %s %s" mode paths))))
(substring (symbol-name mode) 1)
doom-modules-dir)
t "^\\w"))))))
(t (t
(doom--enable-module mode m)))))) (doom--enable-module mode m))))))
@ -243,11 +241,9 @@ This aggressively reloads core autoload files."
(defun doom--module-pairs () (defun doom--module-pairs ()
"Returns `doom-modules' as a list of (MODULE . SUBMODULE) cons cells. The list "Returns `doom-modules' as a list of (MODULE . SUBMODULE) cons cells. The list
is sorted by order of insertion." is sorted by order of insertion."
(let (pairs)
(when (hash-table-p doom-modules) (when (hash-table-p doom-modules)
(maphash (lambda (key value) (push (cons (car key) (cdr key)) pairs)) (cl-loop for key being the hash-keys of doom-modules
doom-modules) collect (cons (car key) (cdr key)))))
(nreverse pairs))))
(defun doom--module-paths (&optional append-file) (defun doom--module-paths (&optional append-file)
"Returns a list of absolute file paths to modules, with APPEND-FILE added, if "Returns a list of absolute file paths to modules, with APPEND-FILE added, if
@ -291,19 +287,17 @@ byte-compilation."
(unless noninteractive (unless noninteractive
(load ,(doom-module-path :private user-login-name "init") t t) (load ,(doom-module-path :private user-login-name "init") t t)
,@(let (forms) ,@(cl-loop for (module . submodule) in (doom--module-pairs)
(dolist (module (doom--module-pairs)) collect `(require! ,module ,submodule t))
(push `(require! ,(car module) ,(cdr module) t) forms)) ,(unless (doom-module-loaded-p :private (intern user-login-name))
(unless (doom-module-loaded-p :private (intern user-login-name)) `(require! :private ,user-login-name t))
(push `(require! :private ,user-login-name t) forms))
(nreverse forms))
(when (display-graphic-p) (when (display-graphic-p)
(require 'server) (require 'server)
(unless (server-running-p) (unless (server-running-p)
(server-start))) (server-start)))
(add-hook 'after-init-hook #'doom--display-benchmark t)))) (add-hook 'emacs-startup-hook #'doom--display-benchmark t))))
(defmacro def-package! (name &rest plist) (defmacro def-package! (name &rest plist)
"A thin wrapper around `use-package'." "A thin wrapper around `use-package'."
@ -425,7 +419,7 @@ SUBMODULE is a symbol."
;; Commands ;; Commands
;; ;;
(defun doom/reload (&optional ignorable-p) (defun doom/reload ()
"Reload `load-path' and recompile files (if necessary). Useful if you "Reload `load-path' and recompile files (if necessary). Useful if you
modify/update packages outside of emacs. Automatically called (through the modify/update packages outside of emacs. Automatically called (through the
server, if necessary) by `doom/packages-install', `doom/packages-update' and server, if necessary) by `doom/packages-install', `doom/packages-update' and
@ -434,7 +428,7 @@ server, if necessary) by `doom/packages-install', `doom/packages-update' and
(cond (noninteractive (cond (noninteractive
(message "Reloading...") (message "Reloading...")
(require 'server) (require 'server)
(unless (ignore-errors (server-eval-at "server" '(doom/reload t))) (unless (ignore-errors (server-eval-at "server" '(doom/reload)))
(message "Recompiling") (message "Recompiling")
(doom/recompile))) (doom/recompile)))
(t (t
@ -454,35 +448,34 @@ In modules, checks modules/*/autoload.el and modules/*/autoload/*.el.
Rerun this whenever init.el is modified. You can also use `make autoloads` from Rerun this whenever init.el is modified. You can also use `make autoloads` from
the commandline." the commandline."
(interactive) (interactive)
;; This function must not use `cl-lib', autoloaded functions or external ;; This function must not use autoloaded functions or external dependencies.
;; dependencies. It must assume nothing is set up! ;; It must assume nothing is set up!
(doom-initialize-packages (not noninteractive)) (doom-initialize-packages (not noninteractive))
(let ((generated-autoload-file doom-autoload-file) (let ((evil-p (featurep! :feature evil))
(autoload-files (targets
(file-expand-wildcards (file-expand-wildcards
(expand-file-name "autoload/*.el" doom-core-dir)))) (expand-file-name "autoload/*.el" doom-core-dir))))
(dolist (path (doom--module-paths)) (dolist (path (doom--module-paths))
(let ((auto-dir (expand-file-name "autoload" path)) (let ((auto-dir (expand-file-name "autoload" path))
(auto-file (expand-file-name "autoload.el" path))) (auto-file (expand-file-name "autoload.el" path)))
(when (file-exists-p auto-file) (when (file-exists-p auto-file)
(push auto-file autoload-files)) (push auto-file targets))
(when (file-directory-p auto-dir) (when (file-directory-p auto-dir)
(mapc (lambda (file) (dolist (file (file-expand-wildcards (expand-file-name "*.el" auto-dir) t))
;; Make evil*.el autoload files a special case; don't load ;; Make evil*.el autoload files a special case; don't load
;; them unless evil is enabled. ;; them unless evil is enabled.
(unless (and (string-prefix-p "evil" (file-name-nondirectory file)) (unless (and (string-prefix-p "evil" (file-name-nondirectory file))
(not (featurep! :feature evil))) (not evil-p))
(push file autoload-files))) (push file targets))))))
(file-expand-wildcards (expand-file-name "*.el" auto-dir) t))))) (when (file-exists-p doom-autoload-file)
(when (file-exists-p generated-autoload-file) (delete-file doom-autoload-file)
(delete-file generated-autoload-file)
(message "Deleted old autoloads.el")) (message "Deleted old autoloads.el"))
(dolist (file (nreverse autoload-files)) (dolist (file (nreverse targets))
(let ((inhibit-message (not doom-debug-mode))) (let ((inhibit-message (not doom-debug-mode)))
(update-file-autoloads file)) (update-file-autoloads file nil doom-autoload-file))
(message "Scanned %s" (file-relative-name file doom-emacs-dir))) (message "Scanned %s" (file-relative-name file doom-emacs-dir)))
(condition-case ex (condition-case ex
(let ((buf (get-file-buffer generated-autoload-file))) (let ((buf (get-file-buffer doom-autoload-file)))
(unwind-protect (unwind-protect
(with-current-buffer buf (with-current-buffer buf
(save-buffer) (save-buffer)
@ -490,7 +483,7 @@ the commandline."
(message "Finished generating autoloads.el!")) (message "Finished generating autoloads.el!"))
(kill-buffer buf))) (kill-buffer buf)))
('error ('error
(delete-file generated-autoload-file) (delete-file doom-autoload-file)
(error "Couldn't evaluate autoloads.el: %s" (cadr ex)))))) (error "Couldn't evaluate autoloads.el: %s" (cadr ex))))))
(defun doom/compile (&optional lite-p only-recompile-p) (defun doom/compile (&optional lite-p only-recompile-p)
@ -506,13 +499,25 @@ If ONLY-RECOMPILE-P is non-nil, only recompile out-of-date files."
;; Ensure all relevant config files are loaded and up-to-date. This way we ;; Ensure all relevant config files are loaded and up-to-date. This way we
;; don't need eval-when-compile and require blocks scattered all over. ;; don't need eval-when-compile and require blocks scattered all over.
(doom-initialize-packages t t) (doom-initialize-packages t t)
(let ((targets (append (list "init.el" doom-core-dir) (let ((targets
(unless lite-p (doom--module-paths)))) (cond ((equal (car command-line-args-left) "--")
(cl-loop for file in command-line-args-left
if (file-exists-p file)
collect (expand-file-name file)
finally do (setq command-line-args-list nil)) )
(t
(append (list (expand-file-name "init.el" doom-emacs-dir)
doom-core-dir)
(unless lite-p (doom--module-paths))))))
(total-success 0) (total-success 0)
(total-fail 0) (total-fail 0)
(total-nocomp 0) (total-nocomp 0))
el-files) (let ((el-files (cl-loop for path in targets
(mapc (lambda (file) if (file-directory-p path)
nconc (nreverse (directory-files-recursively path "\\.el$"))
else if (file-exists-p path)
collect path)))
(dolist (file el-files)
(when (or (not only-recompile-p) (when (or (not only-recompile-p)
(let ((elc-file (byte-compile-dest-file file))) (let ((elc-file (byte-compile-dest-file file)))
(and (file-exists-p elc-file) (and (file-exists-p elc-file)
@ -529,23 +534,15 @@ If ONLY-RECOMPILE-P is non-nil, only recompile out-of-date files."
(t (t
(message! (green "Compiled %s" short-name)) (message! (green "Compiled %s" short-name))
total-success)))))) total-success))))))
(dolist (path targets (reverse el-files))
(let ((path (expand-file-name path doom-emacs-dir)))
(cond ((file-directory-p path)
(setq el-files (append (directory-files-recursively path "\\.el$") el-files)))
((file-exists-p path)
(push path el-files))
(t
(error "Invalid path: %s" path))))))
(message! (message!
(bold (bold
(color (if (zerop total-fail) 'green 'red) (color (if (= total-fail 0) 'green 'red)
"%s %s file(s) %s" "%s %s file(s) %s"
(if only-recompile-p "Recompiled" "Compiled") (if only-recompile-p "Recompiled" "Compiled")
(format (if el-files "%d/%d" "%d") (format (if el-files "%d/%d" "%d")
total-success total-success
(- (length el-files) total-nocomp)) (- (length el-files) total-nocomp))
(format "(%s not compiled)" total-nocomp)))))) (format "(%s ignored)" total-nocomp)))))))
(defun doom/recompile () (defun doom/recompile ()
"Recompile any compiled *.el files in your Emacs configuration." "Recompile any compiled *.el files in your Emacs configuration."
@ -554,12 +551,6 @@ If ONLY-RECOMPILE-P is non-nil, only recompile out-of-date files."
;; In case `load-path' has changed (e.g. after an update) ;; In case `load-path' has changed (e.g. after an update)
(byte-recompile-file (expand-file-name "core.el" doom-core-dir) t)) (byte-recompile-file (expand-file-name "core.el" doom-core-dir) t))
(defun doom/compile-lite ()
"A light-weight version of `doom/compile' which only compiles core files in
your emacs configuration (init.el and core/**/*.el)."
(interactive)
(doom/compile t))
(defun doom/clean-cache () (defun doom/clean-cache ()
"Clear local cache (`doom-cache-dir'). You may need to restart Emacs for some "Clear local cache (`doom-cache-dir'). You may need to restart Emacs for some
components to feel its effects." components to feel its effects."
@ -571,15 +562,14 @@ components to feel its effects."
"Delete all compiled elc files in DOOM emacs, excluding compiled ELPA/QUELPA "Delete all compiled elc files in DOOM emacs, excluding compiled ELPA/QUELPA
package files." package files."
(interactive) (interactive)
(let ((elc-files (append (let ((targets (append (list (expand-file-name "init.elc" doom-emacs-dir))
(let ((init-elc (expand-file-name "init.elc" doom-emacs-dir)))
(if (file-exists-p init-elc) (list init-elc)))
(directory-files-recursively doom-core-dir "\\.elc$") (directory-files-recursively doom-core-dir "\\.elc$")
(directory-files-recursively doom-modules-dir "\\.elc$")))) (directory-files-recursively doom-modules-dir "\\.elc$"))))
(if elc-files (unless (cl-loop for path in targets
(dolist (file elc-files) if (file-exists-p path)
(delete-file file) collect path
(message "Deleting %s" (file-relative-name file doom-emacs-dir))) and do (delete-file path)
and do (message "Deleted %s" (file-relative-name path)))
(message "Everything is clean")))) (message "Everything is clean"))))

View file

@ -1,15 +1,16 @@
;;; core-popups.el --- taming sudden yet inevitable windows ;;; core-popups.el -*- lexical-binding: t; -*-
;; I want a "real"-buffer-first policy in my Emacsian utpoia; popup buffers ;; I want a "real"-buffer-first policy in my Emacsian utpoia; popup buffers
;; ought to be second-class citizens to "real" buffers. No need for a wall or ;; ought to be second-class citizens to "real" buffers. No need for a wall or
;; controversial immigration policies -- all we need is `shackle'. ;; controversial immigration policies -- all we need is `shackle' (and it will
;; actually work).
;; ;;
;; The gist is: popups should always be displayed on one side of the frame, away ;; The gist is: popups should be displayed on one side of the frame, away from
;; from 'real' buffers; they should be easy to dispose of when we don't want to ;; 'real' buffers. They should be easy to dispose of when we don't want to see
;; see them; and easily brought back in case we change our minds. Also, popups ;; them and easily brought back in case we change our minds. Also, popups should
;; should typically have no mode-line. ;; typically have no mode-line.
;; ;;
;; Be warned, this requires a lot of hackery and voodoo that could break with an ;; Be warned, this requires a lot of hackery voodoo that could break with an
;; emacs update or an update to any of the packages it tries to tame (like helm ;; emacs update or an update to any of the packages it tries to tame (like helm
;; or org-mode). ;; or org-mode).
@ -43,7 +44,8 @@ is enabled/disabled.'")
;; Bootstrap ;; Bootstrap
;; ;;
(def-package! shackle :demand t (def-package! shackle
:demand t
:init :init
(setq shackle-default-alignment 'below (setq shackle-default-alignment 'below
shackle-default-size 8 shackle-default-size 8
@ -85,10 +87,8 @@ is enabled/disabled.'")
("^ \\*" :regexp t :size 12 :noselect t :autokill t :autoclose t))) ("^ \\*" :regexp t :size 12 :noselect t :autokill t :autoclose t)))
:config :config
(if (display-graphic-p)
(shackle-mode +1)
(add-transient-hook! 'after-make-frame-functions (shackle-mode +1)) (add-transient-hook! 'after-make-frame-functions (shackle-mode +1))
(add-hook 'after-init-hook 'shackle-mode)) (add-hook 'window-setup-hook #'shackle-mode)
(defun doom*shackle-always-align (plist) (defun doom*shackle-always-align (plist)
"Ensure popups are always aligned and selected by default. Eliminates the need "Ensure popups are always aligned and selected by default. Eliminates the need
@ -418,7 +418,7 @@ the command buffer."
(t (t
(magit-display-buffer-traditional buffer)))) (magit-display-buffer-traditional buffer))))
(defun doom-magit-quit-window (kill-buffer) (defun doom-magit-quit-window (_kill-buffer)
"Close the current magit window properly." "Close the current magit window properly."
(let ((last (current-buffer))) (let ((last (current-buffer)))
(cond ((when-let (dest (doom-buffers-in-mode (cond ((when-let (dest (doom-buffers-in-mode
@ -438,7 +438,7 @@ the command buffer."
(after! mu4e (after! mu4e
(defun doom*mu4e-popup-window (buf height) (defun doom*mu4e-popup-window (buf _height)
(doom-popup-buffer buf :size 10 :noselect t) (doom-popup-buffer buf :size 10 :noselect t)
buf) buf)
(advice-add #'mu4e~temp-window :override #'doom*mu4e-popup-window)) (advice-add #'mu4e~temp-window :override #'doom*mu4e-popup-window))
@ -501,7 +501,7 @@ you came from."
;; Ensure these settings are attached to org-load-hook as late as possible, ;; Ensure these settings are attached to org-load-hook as late as possible,
;; giving other modules a chance to add their own hooks. ;; giving other modules a chance to add their own hooks.
(add-hook! 'after-init-hook (add-hook! 'emacs-startup-hook
(add-hook! 'org-load-hook (add-hook! 'org-load-hook
(set! :popup (set! :popup
'("*Calendar*" :size 0.4 :noselect t) '("*Calendar*" :size 0.4 :noselect t)
@ -532,7 +532,7 @@ you came from."
;; `org-edit-src-code' simply clones and narrows the buffer to a src block, ;; `org-edit-src-code' simply clones and narrows the buffer to a src block,
;; so we are secretly manipulating the same buffer. Since truely killing it ;; so we are secretly manipulating the same buffer. Since truely killing it
;; would kill the original org buffer we've got to do things differently. ;; would kill the original org buffer we've got to do things differently.
(defun doom*org-src-switch-to-buffer (buffer context) (defun doom*org-src-switch-to-buffer (buffer _context)
(if (eq org-src-window-setup 'switch-invisibly) (if (eq org-src-window-setup 'switch-invisibly)
(set-buffer buffer) (set-buffer buffer)
(pop-to-buffer buffer))) (pop-to-buffer buffer)))

View file

@ -1,14 +1,11 @@
;;; core-projects.el --- tools for getting around your project ;;; core-projects.el -*- lexical-binding: t; -*-
;; I want Emacs to be aware of the projects. `projectile' provides tools for
;; digging through project files and exposing an API I can use to make other
;; plugins/features project-aware.
(defvar doom-project-hook nil (defvar doom-project-hook nil
"Hook run when a project is enabled. The name of the project's mode and its "Hook run when a project is enabled. The name of the project's mode and its
state are passed in.") state are passed in.")
(def-package! projectile :demand t (def-package! projectile
:demand t
:init :init
(setq projectile-cache-file (concat doom-cache-dir "projectile.cache") (setq projectile-cache-file (concat doom-cache-dir "projectile.cache")
projectile-enable-caching (not noninteractive) projectile-enable-caching (not noninteractive)
@ -24,7 +21,7 @@ state are passed in.")
"build.gradle")) "build.gradle"))
:config :config
(projectile-mode +1) (add-hook 'after-init-hook #'projectile-mode)
(setq projectile-other-file-alist (setq projectile-other-file-alist
(append '(("less" "css") (append '(("less" "css")

View file

@ -1,4 +1,4 @@
;; core-ui.el --- draw me like one of your French editors ;; core-ui.el -*- lexical-binding: t; -*-
(defvar doom-ui-fringe-size '4 "Default fringe width") (defvar doom-ui-fringe-size '4 "Default fringe width")
@ -40,9 +40,6 @@
(fset #'yes-or-no-p #'y-or-n-p) ; y/n instead of yes/no (fset #'yes-or-no-p #'y-or-n-p) ; y/n instead of yes/no
;; auto-enabled in Emacs 25+; I'd rather enable it manually
(global-eldoc-mode -1)
;; show typed keystrokes in minibuffer ;; show typed keystrokes in minibuffer
(setq echo-keystrokes 0.02) (setq echo-keystrokes 0.02)
;; ...but hide them while isearch is active ;; ...but hide them while isearch is active
@ -94,7 +91,7 @@ local value, whether or not it's permanent-local. Therefore, we cycle
(setq show-paren-delay 0.1 (setq show-paren-delay 0.1
show-paren-highlight-openparen t show-paren-highlight-openparen t
show-paren-when-point-inside-paren t) show-paren-when-point-inside-paren t)
(show-paren-mode +1) (add-hook 'window-setup-hook #'show-paren-mode)
;;; More reliable inter-window border ;;; More reliable inter-window border
;; The native border "consumes" a pixel of the fringe on righter-most splits, ;; The native border "consumes" a pixel of the fringe on righter-most splits,
@ -102,7 +99,7 @@ local value, whether or not it's permanent-local. Therefore, we cycle
(setq-default window-divider-default-places t (setq-default window-divider-default-places t
window-divider-default-bottom-width 1 window-divider-default-bottom-width 1
window-divider-default-right-width 1) window-divider-default-right-width 1)
(window-divider-mode +1) (add-hook 'window-setup-hook #'window-divider-mode)
;; like diminish, but for major-modes. [pedantry intensifies] ;; like diminish, but for major-modes. [pedantry intensifies]
(defvar doom-ui-mode-names (defvar doom-ui-mode-names
@ -122,6 +119,10 @@ mode is detected.")
;; Bootstrap ;; Bootstrap
;; ;;
;; auto-enabled in Emacs 25+; I'd rather enable it manually
(global-eldoc-mode -1)
;; draw me like one of your French editors
(tooltip-mode -1) ; relegate tooltips to echo area only (tooltip-mode -1) ; relegate tooltips to echo area only
(menu-bar-mode -1) (menu-bar-mode -1)
(when (fboundp 'tool-bar-mode) (when (fboundp 'tool-bar-mode)
@ -191,7 +192,7 @@ file."
(set-buffer-modified-p nil)) (set-buffer-modified-p nil))
nil) nil)
(add-hook! (highlight-indentation-mode highlight-indentation-current-column-mode) (defun doom|init-highlight-indentation ()
(if (or highlight-indentation-mode highlight-indentation-current-column-mode) (if (or highlight-indentation-mode highlight-indentation-current-column-mode)
(progn (progn
(doom|inject-trailing-whitespace) (doom|inject-trailing-whitespace)
@ -199,7 +200,9 @@ file."
(add-hook 'after-save-hook #'doom|inject-trailing-whitespace nil t)) (add-hook 'after-save-hook #'doom|inject-trailing-whitespace nil t))
(remove-hook 'before-save-hook #'delete-trailing-whitespace t) (remove-hook 'before-save-hook #'delete-trailing-whitespace t)
(remove-hook 'after-save-hook #'doom|inject-trailing-whitespace t) (remove-hook 'after-save-hook #'doom|inject-trailing-whitespace t)
(delete-trailing-whitespace)))) (delete-trailing-whitespace)))
(add-hook! (highlight-indentation-mode highlight-indentation-current-column-mode)
#'doom|init-highlight-indentation))
;; For modes that don't adequately highlight numbers ;; For modes that don't adequately highlight numbers
(def-package! highlight-numbers :commands highlight-numbers-mode) (def-package! highlight-numbers :commands highlight-numbers-mode)
@ -265,8 +268,8 @@ file."
;; indicators for empty lines past EOF ;; indicators for empty lines past EOF
(def-package! vi-tilde-fringe (def-package! vi-tilde-fringe
:when (display-graphic-p) :when (display-graphic-p)
:demand t :commands global-vi-tilde-fringe-mode
:config (global-vi-tilde-fringe-mode t)) :init (add-hook 'window-setup-hook #'global-vi-tilde-fringe-mode))
;; For a distractions-free-like UI, that dynamically resizes margets and can ;; For a distractions-free-like UI, that dynamically resizes margets and can
;; center a buffer. ;; center a buffer.
@ -292,12 +295,11 @@ file."
(byte-compile #',sym)))))) (byte-compile #',sym))))))
(defsubst doom--prepare-modeline-segments (segments) (defsubst doom--prepare-modeline-segments (segments)
(let (segs) (cl-loop for seg in segments
(dolist (seg segments (nreverse segs)) if (stringp seg)
(push (if (stringp seg) collect seg
seg else
(list (intern (format "doom-modeline-segment--%s" (symbol-name seg))))) collect (list (intern (format "doom-modeline-segment--%s" (symbol-name seg))))))
segs))))
(defmacro def-modeline! (name lhs &optional rhs) (defmacro def-modeline! (name lhs &optional rhs)
"Defines a modeline format and byte-compiles it. NAME is a symbol to identify "Defines a modeline format and byte-compiles it. NAME is a symbol to identify

View file

@ -1,16 +1,16 @@
;;; core.el --- The heart of the beast ;;; core.el --- the heart of the beast -*- lexical-binding: t; -*-
;;; Naming conventions: ;;; Naming conventions:
;; ;;
;; doom-... public variables or functions (non-interactive) ;; doom-... public variables or non-interactive functions
;; doom--... private anything (non-interactive), not safe for direct use ;; doom--... private anything (non-interactive), not safe for direct use
;; doom/... an interactive function ;; doom/... an interactive function; safe for M-x or keybinding
;; doom:... an evil operator, motion or command ;; doom:... an evil operator, motion or command
;; doom|... hook function ;; doom|... hook function
;; doom*... advising functions ;; doom*... advising functions
;; ...! a macro or function that configures DOOM ;; ...! a macro or function that configures DOOM
;; %... functions used for in-snippet logic ;; %... functions used for in-snippet logic
;; +... Any of the above, but part of a module, e.g. +emacs-lisp|init-hook ;; +... Any of the above but part of a module, e.g. `+emacs-lisp|init-hook'
;; ;;
;; Autoloaded functions are in core/autoload/*.el and modules/*/*/autoload.el or ;; Autoloaded functions are in core/autoload/*.el and modules/*/*/autoload.el or
;; modules/*/*/autoload/*.el. ;; modules/*/*/autoload/*.el.
@ -94,7 +94,7 @@ there are problems.")
;; History & backup settings (save nothing, that's what git is for) ;; History & backup settings (save nothing, that's what git is for)
auto-save-default nil auto-save-default nil
create-lockfiles nil create-lockfiles nil
history-length 1000 history-length 500
make-backup-files nil make-backup-files nil
;; files ;; files
abbrev-file-name (concat doom-local-dir "abbrev.el") abbrev-file-name (concat doom-local-dir "abbrev.el")
@ -117,6 +117,7 @@ there are problems.")
(advice-add #'display-startup-echo-area-message :override #'ignore) (advice-add #'display-startup-echo-area-message :override #'ignore)
(setq inhibit-startup-message t (setq inhibit-startup-message t
inhibit-startup-echo-area-message user-login-name inhibit-startup-echo-area-message user-login-name
inhibit-default-init t
initial-major-mode 'fundamental-mode initial-major-mode 'fundamental-mode
initial-scratch-message nil) initial-scratch-message nil)
@ -150,34 +151,41 @@ enable multiple minor modes for the same regexp.")
;;; ;;;
;; Bootstrap ;; Bootstrap
(setq gc-cons-threshold 402653184 (eval-and-compile
gc-cons-percentage 0.6) (defvar doom--file-name-handler-alist file-name-handler-alist)
(setq gc-cons-threshold 402653184
gc-cons-percentage 0.6
file-name-handler-alist nil)
(let (file-name-handler-alist)
(require 'cl-lib) (require 'cl-lib)
(eval-and-compile
(require 'core-packages (concat doom-core-dir "core-packages"))) (require 'core-packages (concat doom-core-dir "core-packages")))
(eval-when-compile
(eval-when-compile
(doom-initialize)) (doom-initialize))
(setq load-path (eval-when-compile load-path)
(setq load-path (eval-when-compile load-path)
doom--package-load-path (eval-when-compile doom--package-load-path)) doom--package-load-path (eval-when-compile doom--package-load-path))
;;; Let 'er rip ;;; Let 'er rip
(require 'core-lib) (require 'core-lib)
(require 'core-os) ; consistent behavior across Oses (require 'core-os) ; consistent behavior across Oses
(with-demoted-errors "AUTOLOAD ERROR: %s" (with-demoted-errors "AUTOLOAD ERROR: %s"
(require 'autoloads doom-autoload-file t)) (require 'autoloads doom-autoload-file t))
(unless noninteractive (unless noninteractive
(require 'core-ui) ; draw me like one of your French editors (require 'core-ui) ; draw me like one of your French editors
(require 'core-popups) ; taming sudden yet inevitable windows (require 'core-popups) ; taming sudden yet inevitable windows
(require 'core-editor) ; baseline configuration for text editing (require 'core-editor) ; baseline configuration for text editing
(require 'core-projects) ; making Emacs project-aware (require 'core-projects) ; making Emacs project-aware
(require 'core-keybinds))) ; centralized keybind system + which-key (require 'core-keybinds)) ; centralized keybind system + which-key
(add-hook! '(after-init-hook doom-reload-hook) (defun doom|init ()
(setq gc-cons-threshold 16777216 (setq gc-cons-threshold 16777216
gc-cons-percentage 0.1)) gc-cons-percentage 0.1
file-name-handler-alist doom--file-name-handler-alist))
(add-hook! '(emacs-startup-hook doom-reload-hook)
#'doom|init)
(provide 'core) (provide 'core)
;;; core.el ends here ;;; core.el ends here

View file

@ -1,4 +1,4 @@
;;; init.el ;;; init.el -*- lexical-binding: t; -*-
;; ;;
;; Author: Henrik Lissner <henrik@lissner.net> ;; Author: Henrik Lissner <henrik@lissner.net>
;; URL: https://github.com/hlissner/.emacs.d ;; URL: https://github.com/hlissner/.emacs.d

View file

@ -1,15 +1,15 @@
;;; app/email/autoload/email.el ;;; app/email/autoload/email.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun =email () (defun =email ()
"Start email client." "Start email client."
(interactive) (interactive)
(call-interactively 'mu4e)) (call-interactively #'mu4e))
;;;###autoload ;;;###autoload
(defun +email/compose () (defun +email/compose ()
"Compose a new email." "Compose a new email."
(interactive) (interactive)
;; TODO Interactively select email account ;; TODO Interactively select email account
(call-interactively 'mu4e-compose-new)) (call-interactively #'mu4e-compose-new))

View file

@ -1,4 +1,4 @@
;;; app/email/autoload/evil.el ;;; app/email/autoload/evil.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun +email/mark (&optional beg end) (defun +email/mark (&optional beg end)
@ -8,11 +8,12 @@
(let* ((beg (or (and (region-active-p) evil-visual-beginning) (line-beginning-position))) (let* ((beg (or (and (region-active-p) evil-visual-beginning) (line-beginning-position)))
(end (or (and (region-active-p) evil-visual-end) (line-end-position))) (end (or (and (region-active-p) evil-visual-end) (line-end-position)))
(key (this-command-keys)) (key (this-command-keys))
(command (car (cl-find-if (lambda (mark) (equal (car (plist-get (cdr mark) :char)) key)) (command
(car (cl-find-if (lambda (mark) (equal (car (plist-get (cdr mark) :char)) key))
mu4e-marks)))) mu4e-marks))))
(unless command (unless command
(error "Not a valid mark command: %s" key)) (error "Not a valid mark command: %s" key))
(when (featurep 'evil) (when (bound-and-true-p evil-mode)
(evil-normal-state)) (evil-normal-state))
(goto-char beg) (goto-char beg)
(dotimes (_ (count-lines beg end)) (dotimes (_ (count-lines beg end))

View file

@ -1,4 +1,4 @@
;;; app/email/config.el ;;; app/email/config.el -*- lexical-binding: t; -*-
;; I want to live in Emacs. Living is incomplete without email, so Emacs needs ;; I want to live in Emacs. Living is incomplete without email, so Emacs needs
;; to give me the ability to read, search, write and send my email. It does so ;; to give me the ability to read, search, write and send my email. It does so
@ -16,9 +16,9 @@
(def-setting! :email (label letvars &optional default) (def-setting! :email (label letvars &optional default)
"Registers an email address for mu4e." "Registers an email address for mu4e."
(let* ((name (or (cdr (assq 'user-full-name letvars)) user-full-name)) (let ((name (or (cdr (assq 'user-full-name letvars)) user-full-name))
(address (cdr (assq 'user-mail-address letvars)))) (address (cdr (assq 'user-mail-address letvars))))
(dolist (var letvars letvars) (dolist (var letvars)
(let ((val (cdr var))) (let ((val (cdr var)))
(when (and (stringp val) (string-match-p "%s" val)) (when (and (stringp val) (string-match-p "%s" val))
(setcdr var (format val label))))) (setcdr var (format val label)))))
@ -96,7 +96,7 @@
("mime:image/*" "Messages with images" ?p))) ("mime:image/*" "Messages with images" ?p)))
;; Add a column to display what email account the email belongs to. ;; Add a column to display what email account the email belongs to.
(push '(:account (cl-pushnew '(:account
:name "Account" :name "Account"
:shortname "Account" :shortname "Account"
:help "Which account this email belongs to" :help "Which account this email belongs to"

View file

@ -1,4 +1,4 @@
;;; app/present/autoload.el ;;; app/present/autoload.el -*- lexical-binding: t; -*-
;; --- impatient-mode ------------------------------------------------------------- ;; --- impatient-mode -------------------------------------------------------------
@ -14,8 +14,9 @@
(+present--cleanup-impatient-mode))) (+present--cleanup-impatient-mode)))
(defun +present--cleanup-impatient-mode () (defun +present--cleanup-impatient-mode ()
(unless (cl-remove-if-not (lambda (buf) (buffer-local-value 'impatient-mode buf)) (unless (cl-loop for buf in (doom-buffer-list)
(doom-buffer-list)) if (buffer-local-value 'impatient-mode buf)
return t)
(httpd-stop) (httpd-stop)
(remove-hook 'kill-buffer-hook '+present--cleanup-impatient-mode))) (remove-hook 'kill-buffer-hook '+present--cleanup-impatient-mode)))
@ -60,8 +61,9 @@
(text-scale-set +present-scale))) (text-scale-set +present-scale)))
(defun +present--cleanup-org-tree-slides-mode () (defun +present--cleanup-org-tree-slides-mode ()
(unless (cl-remove-if-not (lambda (buf) (buffer-local-value 'org-tree-slide-mode buf)) (unless (cl-loop for buf in (doom-buffers-in-mode 'org-mode)
(doom-buffers-in-mode 'org-mode)) if (buffer-local-value 'org-tree-slide-mode buf)
return t)
(org-tree-slide-mode -1) (org-tree-slide-mode -1)
(remove-hook 'kill-buffer-hook #'+present--cleanup-org-tree-slides-mode))) (remove-hook 'kill-buffer-hook #'+present--cleanup-org-tree-slides-mode)))

View file

@ -1,4 +1,4 @@
;;; app/present/config.el ;;; app/present/config.el -*- lexical-binding: t; -*-
;; Sometimes you just get that urge to show off. I don't have a fancy car, so ;; Sometimes you just get that urge to show off. I don't have a fancy car, so
;; my code or Emacs will have to do. ;; my code or Emacs will have to do.
@ -68,7 +68,8 @@
(add-hook! 'org-tree-slide-mode-after-narrow-hook (add-hook! 'org-tree-slide-mode-after-narrow-hook
#'(+present|detect-slide +present|add-overlays org-display-inline-images)) #'(+present|detect-slide +present|add-overlays org-display-inline-images))
(add-hook! 'org-tree-slide-mode-hook (defun +present|org-tree-present-mode ()
"TODO"
(doom/window-zoom) (doom/window-zoom)
(let ((arg (if org-tree-slide-mode +1 -1))) (let ((arg (if org-tree-slide-mode +1 -1)))
(centered-window-mode arg) (centered-window-mode arg)
@ -87,8 +88,10 @@
(set-face-attribute 'org-level-2 nil :height 1.0) (set-face-attribute 'org-level-2 nil :height 1.0)
(+present|remove-overlays) (+present|remove-overlays)
(org-remove-inline-images))))) (org-remove-inline-images)))))
(add-hook 'org-tree-slide-mode-hook #'+present|org-tree-present-mode)
(defun +present*org-tree-slide-narrow-exclude-header (orig-fn &rest args) (defun +present*org-tree-slide-narrow-exclude-header (orig-fn &rest args)
"TODO"
(cl-letf (((symbol-function 'org-narrow-to-subtree) (cl-letf (((symbol-function 'org-narrow-to-subtree)
(lambda () (save-excursion (lambda () (save-excursion
(save-match-data (save-match-data

View file

@ -1,4 +1,4 @@
;;; app/rss/autoload.el ;;; app/rss/autoload.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun =rss () (defun =rss ()

View file

@ -1,4 +1,4 @@
;;; app/rss/config.el ;;; app/rss/config.el -*- lexical-binding: t; -*-
;; This is an opinionated workflow that turns Emacs into an RSS reader, inspired ;; This is an opinionated workflow that turns Emacs into an RSS reader, inspired
;; by apps Reeder and Readkit. It can be invoked via `=rss'. Otherwise, if you ;; by apps Reeder and Readkit. It can be invoked via `=rss'. Otherwise, if you
@ -31,7 +31,7 @@
(make-directory elfeed-db-directory t) (make-directory elfeed-db-directory t)
;; Ensure elfeed buffers are treated as real ;; Ensure elfeed buffers are treated as real
(push (lambda (buf) (string-match-p "^\\*elfeed" (buffer-name buf))) (cl-pushnew (lambda (buf) (string-match-p "^\\*elfeed" (buffer-name buf)))
doom-real-buffer-functions) doom-real-buffer-functions)
;; Enhance readability of a post ;; Enhance readability of a post

View file

@ -1,4 +1,4 @@
;;; app/twitter/autoload.el ;;; app/twitter/autoload.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun =twitter () (defun =twitter ()
@ -7,7 +7,7 @@
(delete-other-windows) (delete-other-windows)
(condition-case ex (condition-case ex
(progn (progn
(call-interactively 'twit) (call-interactively #'twit)
(unless (get-buffer (car twittering-initial-timeline-spec-string)) (unless (get-buffer (car twittering-initial-timeline-spec-string))
(error "Failed to open twitter")) (error "Failed to open twitter"))
(switch-to-buffer (car twittering-initial-timeline-spec-string)) (switch-to-buffer (car twittering-initial-timeline-spec-string))

View file

@ -1,4 +1,4 @@
;;; app/twitter/config.el ;;; app/twitter/config.el -*- lexical-binding: t; -*-
(def-package! twittering-mode (def-package! twittering-mode
:commands twit :commands twit

View file

@ -1,7 +1,8 @@
;;; app/write/autoload.el ;;; app/write/autoload.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(define-minor-mode +write-mode (define-minor-mode +write-mode
"TODO"
:init-value nil :init-value nil
:keymap nil :keymap nil
(let ((arg (if +write-mode +1 -1)) (let ((arg (if +write-mode +1 -1))

View file

@ -1,4 +1,4 @@
;;; company.el ;;; completion/company/autoload.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun +company/complete () (defun +company/complete ()
@ -15,17 +15,18 @@
C-x C-l." C-x C-l."
(interactive (list 'interactive)) (interactive (list 'interactive))
(require 'company) (require 'company)
(unless (bound-and-true-p company-mode) (company-mode)) (pcase command
(let ((lines (split-string ('interactive (company-begin-backend '+company/whole-lines))
('prefix (company-grab-line "^[\t\s]*\\(.+\\)" 1))
('candidates
(all-completions
arg
(split-string
(replace-regexp-in-string (replace-regexp-in-string
"^[\t\s]+" "" "^[\t\s]+" ""
(concat (buffer-substring-no-properties (point-min) (line-beginning-position)) (concat (buffer-substring-no-properties (point-min) (line-beginning-position))
(buffer-substring-no-properties (line-end-position) (point-max)))) (buffer-substring-no-properties (line-end-position) (point-max))))
"\\(\r\n\\|[\n\r]\\)" t))) "\\(\r\n\\|[\n\r]\\)" t)))))
(cl-case command
(interactive (company-begin-backend '+company/whole-lines))
(prefix (company-grab-line "^[\t\s]*\\(.+\\)" 1))
(candidates (all-completions arg lines)))))
;;;###autoload ;;;###autoload
(defun +company/dict-or-keywords () (defun +company/dict-or-keywords ()

View file

@ -1,12 +1,11 @@
;;; completion/company/config.el ;;; completion/company/config.el -*- lexical-binding: t; -*-
(def-setting! :company-backend (modes backends) (def-setting! :company-backend (modes backends)
"Register company BACKENDS to MODES." "Register company BACKENDS to MODES."
(let* ((modes (if (listp modes) modes (list modes))) (let* ((modes (if (listp modes) modes (list modes)))
(backends (if (listp backends) backends (list backends))) (backends (if (listp backends) backends (list backends)))
(def-name (intern (format "doom--init-company-%s" (def-name (intern (format "doom--init-company-%s"
(mapconcat #'identity (mapcar #'symbol-name modes) "-")))) (mapconcat #'identity (mapcar #'symbol-name modes) "-")))))
(quoted (eq (car-safe backends) 'quote)))
;; TODO more type checks ;; TODO more type checks
`(prog1 `(prog1
(defun ,def-name () (defun ,def-name ()

View file

@ -1,7 +1,7 @@
;;; emacs/ido/config.el ;;; completion/ido/config.el -*- lexical-binding: t; -*-
(def-package! ido (def-package! ido
:init :config
(setq ido-ignore-buffers (setq ido-ignore-buffers
'("\\` " "^\\*ESS\\*" "^\\*Messages\\*" "^\\*Help\\*" "^\\*Buffer" '("\\` " "^\\*ESS\\*" "^\\*Messages\\*" "^\\*Help\\*" "^\\*Buffer"
"^\\*.*Completions\\*$" "^\\*Ediff" "^\\*tramp" "^\\*cvs-" "^\\*.*Completions\\*$" "^\\*Ediff" "^\\*tramp" "^\\*cvs-"
@ -16,7 +16,6 @@
ido-enable-last-directory-history t ido-enable-last-directory-history t
ido-save-directory-list-file (concat doom-cache-dir "ido.last")) ido-save-directory-list-file (concat doom-cache-dir "ido.last"))
:config
(push "\\`.DS_Store$" ido-ignore-files) (push "\\`.DS_Store$" ido-ignore-files)
(push "Icon\\?$" ido-ignore-files) (push "Icon\\?$" ido-ignore-files)
@ -24,15 +23,15 @@
(ido-everywhere 1) (ido-everywhere 1)
(require 'ido-ubiquitous) (require 'ido-ubiquitous)
(add-hook! ido-setup (defun +ido|init ()
(require 'ido-vertical-mode) (require 'ido-vertical-mode)
(require 'flx-ido) (require 'flx-ido)
(require 'crm-custom) (require 'crm-custom)
(map! :map (ido-common-completion-map ido-completion-map ido-file-completion-map) (map! :map (ido-common-completion-map ido-completion-map ido-file-completion-map)
"C-n" #'ido-next-match "C-n" #'ido-next-match
"C-p" #'ido-prev-match "C-p" #'ido-prev-match
"C-w" #'ido-delete-backward-word-updir)) "C-w" #'ido-delete-backward-word-updir))
(add-hook 'ido-setup-hook #'+ido|init)
(defun +ido*sort-mtime () (defun +ido*sort-mtime ()
"Sort ido filelist by mtime instead of alphabetically." "Sort ido filelist by mtime instead of alphabetically."
@ -43,16 +42,16 @@
(sixth (file-attributes (concat ido-current-directory b))) (sixth (file-attributes (concat ido-current-directory b)))
(sixth (file-attributes (concat ido-current-directory a))))))) (sixth (file-attributes (concat ido-current-directory a)))))))
(ido-to-end ;; move . files to end (again) (ido-to-end ;; move . files to end (again)
(delq nil (mapcar (cl-loop for x in ido-temp-list
(lambda (x) (and (char-equal (string-to-char x) ?.) x)) if (char-equal (string-to-char x) ?.)
ido-temp-list)))) collect x)))
(advice-add #'ido-sort-mtime :override #'+ido*sort-mtime) (advice-add #'ido-sort-mtime :override #'+ido*sort-mtime)
(add-hook! (ido-make-file-list ido-make-dir-list) #'+ido*sort-mtime) (add-hook! (ido-make-file-list ido-make-dir-list) #'+ido*sort-mtime)
(defun +ido|setup-home-keybind () (defun +ido|setup-home-keybind ()
"Go to $HOME with ~" "Go to $HOME with ~"
(define-key ido-file-completion-map (kbd "~") (define-key ido-file-completion-map (kbd "~")
(λ! (if (looking-back "/") (λ! (if (looking-back "/" (point-min))
(insert "~/") (insert "~/")
(call-interactively #'self-insert-command))))) (call-interactively #'self-insert-command)))))
(add-hook 'ido-setup-hook #'+ido|setup-home-keybind)) (add-hook 'ido-setup-hook #'+ido|setup-home-keybind))

View file

@ -1,5 +1,5 @@
;; -*- no-byte-compile: t; -*- ;; -*- no-byte-compile: t; -*-
;;; emacs/ido/packages.el ;;; completion/ido/packages.el
(package! flx-ido) (package! flx-ido)
(package! ido-ubiquitous) (package! ido-ubiquitous)

View file

@ -1,4 +1,4 @@
;;; completion/ivy/autoload/evil.el ;;; completion/ivy/autoload/evil.el -*- lexical-binding: t; -*-
;;;###autoload (autoload '+ivy:swiper "completion/ivy/autoload/evil" nil t) ;;;###autoload (autoload '+ivy:swiper "completion/ivy/autoload/evil" nil t)
(evil-define-command +ivy:swiper (&optional search) (evil-define-command +ivy:swiper (&optional search)
@ -19,7 +19,7 @@
(defvar +ivy--file-search-recursion-p t) (defvar +ivy--file-search-recursion-p t)
(defvar +ivy--file-search-all-files-p nil) (defvar +ivy--file-search-all-files-p nil)
(defun +ivy--file-search (engine beg end query &optional directory prompt) (defun +ivy--file-search (engine beg end query &optional directory)
(let* ((directory (or directory (doom-project-root))) (let* ((directory (or directory (doom-project-root)))
(recursion-p +ivy--file-search-recursion-p) (recursion-p +ivy--file-search-recursion-p)
(all-files-p +ivy--file-search-all-files-p) (all-files-p +ivy--file-search-all-files-p)

View file

@ -1,4 +1,4 @@
;;; completion/ivy/autoload/ivy.el ;;; completion/ivy/autoload/ivy.el -*- lexical-binding: t; -*-
;; Show more information in ivy-switch-buffer; and only display ;; Show more information in ivy-switch-buffer; and only display
;; workgroup-relevant buffers. ;; workgroup-relevant buffers.
@ -6,12 +6,14 @@
(let ((min-name 5) (let ((min-name 5)
(min-mode 5) (min-mode 5)
(proot (doom-project-root))) (proot (doom-project-root)))
(mapcar (cl-loop for buf in (or buffer-list (doom-buffer-list))
(lambda (b) (format (format "%%-%ds %%-%ds %%s" min-name min-mode) collect
(nth 0 b) (destructuring-bind (type mode path)
(nth 1 b) (+ivy--get-buffer-attrs buf proot)
(or (nth 2 b) ""))) (format (format "%%-%ds %%-%ds %%s" min-name min-mode)
(mapcar (lambda (b) type mode (or path ""))))))
(defun +ivy--get-buffer-attrs (b &optional project-root)
(with-current-buffer b (with-current-buffer b
(let ((buffer-name (buffer-name b)) (let ((buffer-name (buffer-name b))
(mode-name (symbol-name major-mode))) (mode-name (symbol-name major-mode)))
@ -23,7 +25,8 @@
(propertize buffer-name (propertize buffer-name
'face (cond ((string-match-p "^ ?\\*" buffer-name) 'face (cond ((string-match-p "^ ?\\*" buffer-name)
'font-lock-comment-face) 'font-lock-comment-face)
((not (string= proot (doom-project-root))) ((and project-root
(not (string= project-root (doom-project-root))))
'font-lock-keyword-face) 'font-lock-keyword-face)
(buffer-read-only (buffer-read-only
'error))) 'error)))
@ -32,7 +35,6 @@
(propertize mode-name 'face 'font-lock-constant-face) (propertize mode-name 'face 'font-lock-constant-face)
(when buffer-file-name (when buffer-file-name
(abbreviate-file-name (file-name-directory buffer-file-name))))))) (abbreviate-file-name (file-name-directory buffer-file-name)))))))
(or buffer-list (doom-buffer-list))))))
(defun +ivy--select-buffer-action (buffer) (defun +ivy--select-buffer-action (buffer)
(ivy--switch-buffer-action (ivy--switch-buffer-action
@ -66,54 +68,54 @@ limit to buffers in the current workspace."
:keymap ivy-switch-buffer-map :keymap ivy-switch-buffer-map
:caller '+ivy/switch-workspace-buffer)) :caller '+ivy/switch-workspace-buffer))
;; TODO refactor ivy task candidate functions (messy!)
(defun +ivy--tasks-candidates (tasks) (defun +ivy--tasks-candidates (tasks)
"Generate a list of task tags (specified by `+ivy-task-tags') for "Generate a list of task tags (specified by `+ivy-task-tags') for
`+ivy/tasks'." `+ivy/tasks'."
(let* ((max-type-width (seq-max (mapcar #'length (mapcar #'car +ivy-task-tags)))) (let* ((max-type-width
(max-desc-width (seq-max (mapcar #'length (mapcar #'cl-cdadr tasks)))) (cl-loop for task in +ivy-task-tags maximize (length (car task))))
(max-width (max 25 (min (- (frame-width) (+ max-type-width 1)) (max-desc-width
max-desc-width))) (cl-loop for task in tasks maximize (length (cl-cdadr task))))
(fmt (format "%%-%ds %%-%ds%%s%%s:%%s" max-type-width max-desc-width)) (max-width (max (- (frame-width) (1+ max-type-width) max-desc-width)
lines) 25)))
(dolist (alist tasks (nreverse lines)) (cl-loop
with fmt = (format "%%-%ds %%-%ds%%s%%s:%%s" max-type-width max-width)
for alist in tasks
collect
(let-alist alist (let-alist alist
(push (format fmt (format fmt
(propertize .type 'face (cdr (assoc .type +ivy-task-tags))) (propertize .type 'face (cdr (assoc .type +ivy-task-tags)))
(substring .desc 0 (min max-desc-width (length .desc))) (substring .desc 0 (min max-desc-width (length .desc)))
(propertize " | " 'face 'font-lock-comment-face) (propertize " | " 'face 'font-lock-comment-face)
(propertize (abbreviate-file-name .file) 'face 'font-lock-keyword-face) (propertize (abbreviate-file-name .file) 'face 'font-lock-keyword-face)
(propertize .line 'face 'font-lock-constant-face)) (propertize .line 'face 'font-lock-constant-face))))))
lines)))))
(defun +ivy--tasks (target) (defun +ivy--tasks (target)
(let (case-fold-search) (let* (case-fold-search
(delq (task-tags (mapcar #'car +ivy-task-tags))
nil (cmd
(mapcar (lambda (x) (format "%s -H -S --no-heading -- %s %s"
(save-match-data (or (when-let (bin (executable-find "rg"))
(when (string-match (concat "^\\([^:]+\\):\\([0-9]+\\):.+\\(" (concat bin " --line-number"))
(string-join (mapcar #'car +ivy-task-tags) "\\|") (when-let (bin (executable-find "ag"))
"\\):?\\s-*\\(.+\\)") (concat bin " --numbers"))
x) (error "ripgrep & the_silver_searcher are unavailable"))
`((type . ,(match-string 3 x))
(desc . ,(match-string 4 x))
(file . ,(match-string 1 x))
(line . ,(match-string 2 x))))))
(let ((command (or (let ((bin (executable-find "rg")))
(and bin (concat bin " --line-number")))
(let ((bin (executable-find "ag")))
(and bin (concat bin " --numbers")))
(error "Neither ripgrep or the_silver_searcher is available")))
(args (concat " -- "
(shell-quote-argument (shell-quote-argument
(concat "\\s(" (concat "\\s("
(string-join (mapcar #'car +ivy-task-tags) "|") (string-join task-tags "|")
")([\\s:]|\\([^)]+\\):?)"))))) ")([\\s:]|\\([^)]+\\):?)"))
(when-let (out (shell-command-to-string target)))
(format "%s -H -S --no-heading %s %s" (save-match-data
command args target))) (cl-loop with out = (shell-command-to-string cmd)
(split-string out "\n" t))))))) for x in (and out (split-string out "\n" t))
when (string-match
(concat "^\\([^:]+\\):\\([0-9]+\\):.+\\("
(string-join task-tags "\\|")
"\\):?\\s-*\\(.+\\)")
x)
collect `((type . ,(match-string 3 x))
(desc . ,(match-string 4 x))
(file . ,(match-string 1 x))
(line . ,(match-string 2 x)))))))
(defun +ivy--tasks-open-action (x) (defun +ivy--tasks-open-action (x)
"Jump to the file and line of the current task." "Jump to the file and line of the current task."
@ -180,8 +182,8 @@ counsel-rg)."
(defun +ivy/wgrep-occur () (defun +ivy/wgrep-occur ()
"Invoke the search+replace wgrep buffer on the current ag/rg search results." "Invoke the search+replace wgrep buffer on the current ag/rg search results."
(interactive) (interactive)
(if (not (window-minibuffer-p)) (unless (window-minibuffer-p)
(user-error "No completion session is active") (user-error "No completion session is active"))
(require 'wgrep) (require 'wgrep)
(let* ((caller (ivy-state-caller ivy-last)) (let* ((caller (ivy-state-caller ivy-last))
(occur-fn (plist-get ivy--occurs-list caller)) (occur-fn (plist-get ivy--occurs-list caller))
@ -200,7 +202,7 @@ counsel-rg)."
(ivy-exit-with-action (ivy-exit-with-action
`(lambda (_) `(lambda (_)
(pop-to-buffer ,buffer) (pop-to-buffer ,buffer)
(ivy-wgrep-change-to-wgrep-mode)))))) (ivy-wgrep-change-to-wgrep-mode)))))
;;;###autoload ;;;###autoload
(defun +ivy-yas-prompt (prompt choices &optional display-fn) (defun +ivy-yas-prompt (prompt choices &optional display-fn)

View file

@ -1,6 +1,7 @@
;;; completion/ivy/packages.el ;;; completion/ivy/config.el -*- lexical-binding: t; -*-
(defvar +ivy-task-tags '(("TODO" . warning) (defvar +ivy-task-tags
'(("TODO" . warning)
("FIXME" . error)) ("FIXME" . error))
"An alist of tags for `+ivy/tasks' to include in its search, whose CDR is the "An alist of tags for `+ivy/tasks' to include in its search, whose CDR is the
face to render it with.") face to render it with.")
@ -20,7 +21,8 @@ session)."
;; Packages ;; Packages
;; ;;
(def-package! ivy :demand t (def-package! ivy
:demand t
:config :config
(setq ivy-height 12 (setq ivy-height 12
ivy-do-completion-in-region nil ivy-do-completion-in-region nil
@ -38,7 +40,7 @@ session)."
(after! magit (setq magit-completing-read-function #'ivy-completing-read)) (after! magit (setq magit-completing-read-function #'ivy-completing-read))
(after! yasnippet (push #'+ivy-yas-prompt yas-prompt-functions)) (after! yasnippet (push #'+ivy-yas-prompt yas-prompt-functions))
(ivy-mode +1) (add-hook 'window-setup-hook #'ivy-mode)
(map! :map ivy-mode-map (map! :map ivy-mode-map
[remap describe-face] #'counsel-describe-face [remap describe-face] #'counsel-describe-face
@ -79,12 +81,16 @@ session)."
;; Configure `counsel-rg', `counsel-ag' & `counsel-pt' ;; Configure `counsel-rg', `counsel-ag' & `counsel-pt'
(set! :popup 'ivy-occur-grep-mode :size (+ 2 ivy-height) :regexp t :autokill t) (set! :popup 'ivy-occur-grep-mode :size (+ 2 ivy-height) :regexp t :autokill t)
(dolist (cmd '(counsel-ag counsel-rg counsel-pt)) (dolist (cmd '(counsel-ag counsel-rg counsel-pt))
(ivy-add-actions (ivy-add-actions
cmd cmd
'(("O" +ivy-git-grep-other-window-action "open in other window")))) '(("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
(advice-add #'counsel-ag-function :override #'+ivy*counsel-ag-function)) (advice-add #'counsel-ag-function :override #'+ivy*counsel-ag-function))

View file

@ -1,42 +0,0 @@
;;; feature/debug/autoload.el
;;;###autoload
(defun +debug/quit ()
(interactive)
(ignore-errors (call-interactively 'realgud:cmd-quit))
(doom/popup-close)
(evil-normal-state))
;;;###autoload (autoload '+debug:debug-toggle-breakpoint "feature/debug/autoload" nil t)
;;;###autoload (autoload '+debug:run "feature/debug/autoload" nil t)
(after! evil
(evil-define-command +debug:run (&optional path)
"Initiate debugger for current major mode"
(interactive "<f>")
(let ((default-directory (doom-project-root)))
(cond ((memq major-mode '(c-mode c++-mode))
(realgud:gdb (if path (concat "gdb " path))))
((memq major-mode '(ruby-mode enh-ruby-mode))
(doom:repl nil (format "run '%s'" (file-name-nondirectory (or path buffer-file-name)))))
((eq major-mode 'sh-mode)
(let ((shell sh-shell))
(when (string= shell "sh")
(setq shell "bash"))
(cond ((string= shell "bash")
(realgud:bashdb (if path (concat "bashdb " path))))
((string= shell "zsh")
(realgud:zshdb (if path (concat "zshdb " path))))
(t (user-error "No shell debugger for %s" shell)))))
;; TODO Add python debugging
((memq major-mode '(js-mode js2-mode js3-mode))
(realgud:trepanjs))
((eq major-mode 'haskell-mode)
(haskell-debug))
(t (user-error "No debugger for %s" major-mode)))))
(evil-define-command +debug:debug-toggle-breakpoint (&optional bang)
(interactive "<!>")
(call-interactively (if bang 'realgud:cmd-clear 'realgud:cmd-break))))

View file

@ -0,0 +1,9 @@
;;; feature/debug/autoload/debug.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +debug/quit ()
(interactive)
(ignore-errors (call-interactively 'realgud:cmd-quit))
(doom/popup-close)
(evil-normal-state))

View file

@ -0,0 +1,31 @@
;;; feature/debug/autoload/evil.el -*- lexical-binding: t; -*-
;;;###autoload (autoload '+debug:run "feature/debug/autoload/evil" nil t)
(evil-define-command +debug:run (&optional path)
"Initiate debugger for current major mode"
(interactive "<f>")
(let ((default-directory (doom-project-root)))
(cond ((memq major-mode '(c-mode c++-mode))
(realgud:gdb (if path (concat "gdb " path))))
((memq major-mode '(ruby-mode enh-ruby-mode))
(doom:repl nil (format "run '%s'" (file-name-nondirectory (or path buffer-file-name)))))
((eq major-mode 'sh-mode)
(let ((shell sh-shell))
(when (string= shell "sh")
(setq shell "bash"))
(cond ((string= shell "bash")
(realgud:bashdb (if path (concat "bashdb " path))))
((string= shell "zsh")
(realgud:zshdb (if path (concat "zshdb " path))))
(t (user-error "No shell debugger for %s" shell)))))
;; TODO Add python debugging
((memq major-mode '(js-mode js2-mode js3-mode))
(realgud:trepanjs))
((eq major-mode 'haskell-mode)
(haskell-debug))
(t (user-error "No debugger for %s" major-mode)))))
;;;###autoload (autoload '+debug:toggle-breakpoint "feature/debug/autoload/evil" nil t)
(evil-define-command +debug:toggle-breakpoint (&optional bang)
(interactive "<!>")
(call-interactively (if bang 'realgud:cmd-clear 'realgud:cmd-break)))

View file

@ -1,4 +1,4 @@
;;; feature/debug/config.el ;;; feature/debug/config.el -*- lexical-binding: t; -*-
(def-package! realgud (def-package! realgud
:commands (realgud:gdb realgud:trepanjs realgud:bashdb realgud:zshdb) :commands (realgud:gdb realgud:trepanjs realgud:bashdb realgud:zshdb)
@ -11,7 +11,7 @@
;; (def-tmp-excmd! doom:def-debug-on doom:def-debug-off ;; (def-tmp-excmd! doom:def-debug-on doom:def-debug-off
;; ("n[ext]" . realgud:cmd-next) ;; ("n[ext]" . realgud:cmd-next)
;; ("s[tep]" . realgud:cmd-step) ;; ("s[tep]" . realgud:cmd-step)
;; ("b[reak]" . doom:debug-toggle-breakpoint) ;; ("b[reak]" . +debug:toggle-breakpoint)
;; ("c[ontinue]" . realgud:cmd-continue)) ;; ("c[ontinue]" . realgud:cmd-continue))
;; (advice-add #'realgud-cmdbuf-init :after #'doom:def-debug-on) ;; (advice-add #'realgud-cmdbuf-init :after #'doom:def-debug-on)
;; (advice-add #'realgud:cmd-quit :after #'doom:def-debug-off) ;; (advice-add #'realgud:cmd-quit :after #'doom:def-debug-off)
@ -21,13 +21,10 @@
;; FIXME Causes realgud:cmd-* to focus popup on every invocation ;; FIXME Causes realgud:cmd-* to focus popup on every invocation
(defun +debug*realgud-run-process (defun +debug*realgud-run-process
(debugger-name script-filename cmd-args minibuffer-history &optional no-reset) (debugger-name script-filename cmd-args minibuffer-history &optional no-reset)
(let ((cmd-buf)) (let* ((cmd-buf (apply #'realgud-exec-shell debugger-name script-filename
(setq cmd-buf
(apply #'realgud-exec-shell debugger-name script-filename
(car cmd-args) no-reset (cdr cmd-args))) (car cmd-args) no-reset (cdr cmd-args)))
(let ((process (get-buffer-process cmd-buf))) (process (get-buffer-process cmd-buf)))
(if (and process (eq 'run (process-status process))) (cond ((and process (eq 'run (process-status process)))
(progn
(pop-to-buffer cmd-buf) (pop-to-buffer cmd-buf)
(define-key evil-emacs-state-local-map (kbd "ESC ESC") #'+debug/quit) (define-key evil-emacs-state-local-map (kbd "ESC ESC") #'+debug/quit)
(realgud:track-set-debugger debugger-name) (realgud:track-set-debugger debugger-name)
@ -41,6 +38,7 @@
(cmd-str (mapconcat #'identity cmd-args " "))) (cmd-str (mapconcat #'identity cmd-args " ")))
(set minibuffer-history (set minibuffer-history
(list-utils-uniq (cons cmd-str (eval minibuffer-history)))))))) (list-utils-uniq (cons cmd-str (eval minibuffer-history))))))))
(t
(if cmd-buf (switch-to-buffer cmd-buf)) (if cmd-buf (switch-to-buffer cmd-buf))
(message "Error running command: %s" (mapconcat #'identity cmd-args " ")))) (message "Error running command: %s" (mapconcat #'identity cmd-args " "))))
cmd-buf)) cmd-buf))

View file

@ -1,4 +1,4 @@
;;; feature/eval/autoload/build.el ;;; feature/eval/autoload/build.el -*- lexical-binding: t; -*-
(defvar-local +eval-last-builder nil (defvar-local +eval-last-builder nil
"The last builder run in the current buffer.") "The last builder run in the current buffer.")
@ -22,9 +22,7 @@ functions.")
:key 'cdr)) :key 'cdr))
(if (= (length builders) 1) (if (= (length builders) 1)
(car builders) (car builders)
(when-let (builder (completing-read "Build: " (when-let (builder (completing-read "Build: " (mapcar #'car builders) nil t))
(mapcar #'car builders)
nil t))
(assq (intern builder) builders))))) (assq (intern builder) builders)))))
;;;###autoload ;;;###autoload
@ -36,9 +34,8 @@ functions.")
(error "No builder for this buffer")))) (error "No builder for this buffer"))))
(unless builder (unless builder
(error "Builder not found in registered builders")) (error "Builder not found in registered builders"))
(let* ((name (car builder)) (let ((name (car builder))
(plist (cdr builder)) (fn (plist-get (cdr builder) :fn)))
(fn (plist-get plist :fn)))
(message "Running %s" name) (message "Running %s" name)
(if (or (functionp fn) (if (or (functionp fn)
(and (symbolp fn) (fboundp fn))) (and (symbolp fn) (fboundp fn)))

View file

@ -1,4 +1,4 @@
;;; feature/eval/autoload/eval.el ;;; feature/eval/autoload/eval.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun +eval/buffer () (defun +eval/buffer ()

View file

@ -1,4 +1,4 @@
;;; feature/eval/autoload/evil.el ;;; feature/eval/autoload/evil.el -*- lexical-binding: t; -*-
;;;###autoload (autoload '+eval:region "feature/eval/autoload/evil" nil t) ;;;###autoload (autoload '+eval:region "feature/eval/autoload/evil" nil t)
(evil-define-operator +eval:region (beg end) (evil-define-operator +eval:region (beg end)

View file

@ -1,11 +1,11 @@
;;; feature/eval/autoload/repl.el ;;; feature/eval/autoload/repl.el -*- lexical-binding: t; -*-
(defvar +eval-repl-buffer nil (defvar +eval-repl-buffer nil
"The buffer of the last open repl.") "The buffer of the last open repl.")
(defun +eval--ensure-in-repl-buffer (&optional command) (defun +eval--ensure-in-repl-buffer (&optional command)
(if (eq (current-buffer) +eval-repl-buffer) (or (eq (current-buffer) +eval-repl-buffer)
t (progn
(if (and +eval-repl-buffer (buffer-live-p +eval-repl-buffer)) (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) (select-window win)
@ -22,7 +22,7 @@
(cdr comint-last-prompt)) (cdr comint-last-prompt))
(cdr comint-last-prompt) (cdr comint-last-prompt)
(point-max))) (point-max)))
t))) t))))
;;;###autoload ;;;###autoload
(defun +eval/repl () (defun +eval/repl ()
@ -31,8 +31,8 @@ the cursor at the prompt."
(interactive) (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 (+eval--ensure-in-repl-buffer command)
(when (and (featurep 'evil) evil-mode) (when (bound-and-true-p evil-mode)
(call-interactively 'evil-append-line)) (call-interactively #'evil-append-line))
t))) t)))
;;;###autoload ;;;###autoload
@ -43,8 +43,8 @@ execute it immediately after."
(let ((selection (buffer-substring-no-properties beg end))) (let ((selection (buffer-substring-no-properties beg end)))
(unless (+eval--ensure-in-repl-buffer) (unless (+eval--ensure-in-repl-buffer)
(error "No REPL open")) (error "No REPL open"))
(when (and (featurep 'evil) evil-mode) (when (bound-and-true-p evil-mode)
(call-interactively 'evil-append-line)) (call-interactively #'evil-append-line))
(insert (string-trim selection)) (insert (string-trim selection))
(when auto-execute-p (when auto-execute-p
;; I don't use `comint-send-input' because different REPLs may have their ;; I don't use `comint-send-input' because different REPLs may have their

View file

@ -1,4 +1,4 @@
;;; feature/eval/config.el ;;; feature/eval/config.el -*- lexical-binding: t; -*-
;; ;;
;; Code building ;; Code building

View file

@ -1,4 +1,4 @@
;;; feature/evil/autoload/evil-mc.el ;;; feature/evil/autoload/evil-mc.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun +evil/mc-toggle-cursors () (defun +evil/mc-toggle-cursors ()
@ -21,9 +21,7 @@ cursors."
(interactive) (interactive)
(cond ((memq evil-this-type '(block line)) (cond ((memq evil-this-type '(block line))
(let ((col (evil-column)) (let ((col (evil-column))
(line-at-pt (line-number-at-pos)) (line-at-pt (line-number-at-pos)))
(beg evil-visual-beginning)
(end evil-visual-end))
;; Fix off-by-one error ;; Fix off-by-one error
(when (= evil-visual-direction 1) (when (= evil-visual-direction 1)
(cl-decf col) (cl-decf col)
@ -36,7 +34,7 @@ cursors."
(move-to-column col) (move-to-column col)
(when (= (current-column) col) (when (= (current-column) col)
(evil-mc-make-cursor-here)))) (evil-mc-make-cursor-here))))
beg evil-visual-beginning
(if (eq evil-this-type 'line) (1- evil-visual-end) evil-visual-end) (if (eq evil-this-type 'line) (1- evil-visual-end) evil-visual-end)
nil) nil)
(evil-exit-visual-state)))) (evil-exit-visual-state))))

View file

@ -1,4 +1,4 @@
;;; feature/evil/autoload/evil.el ;;; feature/evil/autoload/evil.el -*- lexical-binding: t; -*-
(eval-when-compile (require 'subr-x)) (eval-when-compile (require 'subr-x))
@ -36,16 +36,13 @@ flags. See http://vimdoc.sourceforge.net/htmldoc/cmdline.html#filename-modifiers
"\\([#%]\\)" "\\([#%]\\)"
"\\(\\(?::\\(?:[PphtreS~.]\\|g?s[^:\t\n ]+\\)\\)*\\)")) "\\(\\(?::\\(?:[PphtreS~.]\\|g?s[^:\t\n ]+\\)\\)*\\)"))
(matches (matches
(let ((all-strings ()) (cl-loop with i = 0
(i 0)) while (and (< i (length file-name))
(while (and (< i (length file-name))
(string-match regexp file-name i)) (string-match regexp file-name i))
(setq i (1+ (match-beginning 0))) do (setq i (1+ (match-beginning 0)))
(let (strings) and collect
(push (dotimes (i (/ (length (match-data)) 2) (nreverse strings)) (cl-loop for j to (/ (length (match-data)) 2)
(push (match-string i file-name) strings)) collect (match-string j file-name)))))
all-strings)))
(nreverse all-strings))))
(dolist (match matches) (dolist (match matches)
(let ((flags (split-string (car (cdr (cdr match))) ":" t)) (let ((flags (split-string (car (cdr (cdr match))) ":" t))
(path (and buffer-file-name (path (and buffer-file-name
@ -113,16 +110,18 @@ evil-window-move-* (e.g. `evil-window-move-far-left')"
(doom-popup-p that-window)) (doom-popup-p that-window))
(setq that-buffer nil that-window nil)) (setq that-buffer nil that-window nil))
(if (not (or that-window (one-window-p t))) (if (not (or that-window (one-window-p t)))
(funcall (case direction (funcall (pcase direction
('left 'evil-window-move-far-left) ('left #'evil-window-move-far-left)
('right 'evil-window-move-far-right) ('right #'evil-window-move-far-right)
('up 'evil-window-move-very-top) ('up #'evil-window-move-very-top)
('down 'evil-window-move-very-bottom))) ('down #'evil-window-move-very-bottom)))
(unless that-window (unless that-window
(setq that-window (setq that-window
(split-window this-window nil (cond ((eq direction 'up) 'above) (split-window this-window nil
((eq direction 'down) 'below) (pcase direction
(t direction)))) ('up 'above)
('down 'below)
(_ direction))))
(with-selected-window that-window (with-selected-window that-window
(switch-to-buffer doom-buffer)) (switch-to-buffer doom-buffer))
(setq that-buffer (window-buffer that-window))) (setq that-buffer (window-buffer that-window)))
@ -172,20 +171,22 @@ evil-window-move-* (e.g. `evil-window-move-far-left')"
;; --- custom arg handlers ---------------- ;; --- custom arg handlers ----------------
(defvar +evil--flag nil)
(defun +evil--ex-match-init (name &optional face update-hook) (defun +evil--ex-match-init (name &optional face update-hook)
(with-current-buffer evil-ex-current-buffer (with-current-buffer evil-ex-current-buffer
(cond (cond
((eq flag 'start) ((eq +evil--flag 'start)
(evil-ex-make-hl name (evil-ex-make-hl name
:face (or face 'evil-ex-substitute-matches) :face (or face 'evil-ex-substitute-matches)
:update-hook (or update-hook #'evil-ex-pattern-update-ex-info)) :update-hook (or update-hook #'evil-ex-pattern-update-ex-info))
(setq flag 'update)) (setq +evil--flag 'update))
((eq flag 'stop) ((eq +evil--flag 'stop)
(evil-ex-delete-hl name))))) (evil-ex-delete-hl name)))))
(defun +evil--ex-buffer-match (arg &optional hl-name flags beg end) (defun +evil--ex-buffer-match (arg &optional hl-name flags beg end)
(when (and (eq flag 'update) (when (and (eq +evil--flag 'update)
evil-ex-substitute-highlight-all evil-ex-substitute-highlight-all
(not (zerop (length arg)))) (not (zerop (length arg))))
(condition-case lossage (condition-case lossage
@ -209,21 +210,24 @@ evil-window-move-* (e.g. `evil-window-move-far-left')"
;;;###autoload ;;;###autoload
(defun +evil-ex-buffer-match (flag &optional arg) (defun +evil-ex-buffer-match (flag &optional arg)
(let ((hl-name 'evil-ex-buffer-match)) (let ((hl-name 'evil-ex-buffer-match)
(+evil--flag flag))
(with-selected-window (minibuffer-selected-window) (with-selected-window (minibuffer-selected-window)
(+evil--ex-match-init hl-name) (+evil--ex-match-init hl-name)
(+evil--ex-buffer-match arg hl-name (list (if evil-ex-substitute-global ?g)))))) (+evil--ex-buffer-match arg hl-name (list (if evil-ex-substitute-global ?g))))))
;;;###autoload ;;;###autoload
(defun +evil-ex-global-match (flag &optional arg) (defun +evil-ex-global-match (flag &optional arg)
(let ((hl-name 'evil-ex-global-match)) (let ((hl-name 'evil-ex-global-match)
(+evil--flag flag))
(with-selected-window (minibuffer-selected-window) (with-selected-window (minibuffer-selected-window)
(+evil--ex-match-init hl-name) (+evil--ex-match-init hl-name)
(+evil--ex-buffer-match arg hl-name nil (point-min) (point-max))))) (+evil--ex-buffer-match arg hl-name nil (point-min) (point-max)))))
;;;###autoload ;;;###autoload
(defun +evil-ex-global-delim-match (flag &optional arg) (defun +evil-ex-global-delim-match (flag &optional arg)
(let ((hl-name 'evil-ex-global-delim-match)) (let ((hl-name 'evil-ex-global-delim-match)
(+evil--flag flag))
(with-selected-window (minibuffer-selected-window) (with-selected-window (minibuffer-selected-window)
(+evil--ex-match-init hl-name) (+evil--ex-match-init hl-name)
(let ((result (car-safe (evil-delimited-arguments arg 2)))) (let ((result (car-safe (evil-delimited-arguments arg 2))))
@ -249,7 +253,7 @@ evil-window-move-* (e.g. `evil-window-move-far-left')"
"A wrapper around `evil-delete' for `wgrep' buffers that will invoke "A wrapper around `evil-delete' for `wgrep' buffers that will invoke
`wgrep-mark-deletion' on lines you try to delete." `wgrep-mark-deletion' on lines you try to delete."
(interactive "<R><x><y>") (interactive "<R><x><y>")
(condition-case ex (condition-case _ex
(evil-delete beg end type register yank-handler) (evil-delete beg end type register yank-handler)
('text-read-only ('text-read-only
(evil-apply-on-block (evil-apply-on-block

View file

@ -1,4 +1,4 @@
;;; feature/evil/autoload/files.el ;;; feature/evil/autoload/files.el -*- lexical-binding: t; -*-
(defun +evil--forget-file (old-path &optional new-path) (defun +evil--forget-file (old-path &optional new-path)
"Ensure `recentf', `projectile' and `save-place' forget OLD-PATH." "Ensure `recentf', `projectile' and `save-place' forget OLD-PATH."
@ -23,11 +23,9 @@ kills the buffer. If FORCE-P, force the deletion (don't ask for confirmation)."
(buf (current-buffer))) (buf (current-buffer)))
(cond ((not (file-exists-p fname)) (cond ((not (file-exists-p fname))
(error "File doesn't exist: %s" fname)) (error "File doesn't exist: %s" fname))
((not (or force-p (y-or-n-p (format "Really delete %s?" fbase)))) ((not (or force-p (y-or-n-p (format "Really delete %s?" fbase))))
(message "Aborted") (message "Aborted")
nil) nil)
(t (t
(unwind-protect (unwind-protect
(progn (delete-file fname) t) (progn (delete-file fname) t)
@ -38,8 +36,7 @@ kills the buffer. If FORCE-P, force the deletion (don't ask for confirmation)."
;; to real buffers (`doom-real-buffer-p') ;; to real buffers (`doom-real-buffer-p')
(doom-force-kill-buffer buf t) (doom-force-kill-buffer buf t)
(+evil--forget-file fname) (+evil--forget-file fname)
(message "Successfully deleted %s" short-path) (message "Successfully deleted %s" short-path))))))))
)))))))
(defun +evil--copy-file (old-path new-path &optional force-p) (defun +evil--copy-file (old-path new-path &optional force-p)
(let* ((new-path (expand-file-name new-path)) (let* ((new-path (expand-file-name new-path))

View file

@ -1,9 +1,9 @@
;;; feature/evil/autoload/folds.el ;;; feature/evil/autoload/folds.el -*- lexical-binding: t; -*-
;; It's frustrating how hideshow is a decent code folding implementation, but it ;; `hideshow' is a decent code folding implementation, but it won't let you
;; won't let you create custom folds. Meanwhile, evil-vimish-fold offers custom ;; create custom folds. `evil-vimish-fold' offers custom folds, but essentially
;; folds, but essentially ignores any other type of folding (indent or custom ;; ignores any other type of folding (indent or custom markers, which
;; markers, which hs-minor-mode gives you). ;; hs-minor-mode gives you).
;; ;;
;; So this is my effort to combine them. ;; So this is my effort to combine them.

View file

@ -1,4 +1,4 @@
;;; feature/evil/config.el ;;; feature/evil/config.el -*- lexical-binding: t; -*-
;; I'm a vimmer at heart. Its modal philosophy suits me better, and this module ;; I'm a vimmer at heart. Its modal philosophy suits me better, and this module
;; strives to make Emacs a much better vim than vim was. ;; strives to make Emacs a much better vim than vim was.
@ -41,7 +41,7 @@
shift-select-mode nil) shift-select-mode nil)
:config :config
(evil-mode +1) (add-hook 'emacs-startup-hook #'evil-mode)
(evil-select-search-module 'evil-search-module 'evil-search) (evil-select-search-module 'evil-search-module 'evil-search)
(set! :popup (set! :popup
@ -170,7 +170,7 @@ across windows."
(def-package! evil-easymotion (def-package! evil-easymotion
:defer 1 :after evil-snipe
:config :config
(defvar +evil--snipe-repeat-fn (defvar +evil--snipe-repeat-fn
(evilem-create #'evil-snipe-repeat (evilem-create #'evil-snipe-repeat
@ -185,7 +185,6 @@ across windows."
(setq evil-embrace-show-help-p nil) (setq evil-embrace-show-help-p nil)
(evil-embrace-enable-evil-surround-integration) (evil-embrace-enable-evil-surround-integration)
;; Defuns
(defun +evil--embrace-get-pair (char) (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 pair
@ -234,15 +233,15 @@ across windows."
(def-package! evil-escape (def-package! evil-escape
:demand t :commands evil-escape-mode
:init :init
(setq evil-escape-excluded-states '(normal visual multiedit emacs) (setq evil-escape-excluded-states '(normal visual multiedit emacs)
evil-escape-excluded-major-modes '(neotree-mode) evil-escape-excluded-major-modes '(neotree-mode)
evil-escape-key-sequence "jk" evil-escape-key-sequence "jk"
evil-escape-delay 0.25) evil-escape-delay 0.25)
(add-hook 'emacs-startup-hook #'evil-escape-mode)
:config :config
(evil-escape-mode +1)
(map! :irvo "C-g" #'evil-escape)) (map! :irvo "C-g" #'evil-escape))
@ -330,7 +329,7 @@ the new algorithm is confusing, like in python or ruby."
(?\] "[]})]") (?\] "[]})]")
(?\; "[;:]"))) (?\; "[;:]")))
:config :config
(evil-snipe-override-mode +1)) (add-hook 'emacs-startup-hook #'evil-snipe-override-mode))
(def-package! evil-surround (def-package! evil-surround

View file

@ -1,4 +1,4 @@
;;; feature/file-templates/config.el ;;; feature/file-templates/config.el -*- lexical-binding: t; -*-
(require! :feature snippets) (require! :feature snippets)
@ -31,12 +31,13 @@
(overlay-get yas--active-field-overlay 'yas--field))) (overlay-get yas--active-field-overlay 'yas--field)))
(evil-initialize-state 'insert)))) (evil-initialize-state 'insert))))
(defun +file-templates|add (regexp trigger mode &optional project-only-p) (defun +file-templates-add (args)
(destructuring-bind (regexp trigger mode &optional project-only-p) args
(define-auto-insert (define-auto-insert
regexp regexp
(vector `(lambda () (+file-templates--expand ,trigger ',mode ,project-only-p))))) (vector `(lambda () (+file-templates--expand ,trigger ',mode ,project-only-p))))))
(mapc (lambda (args) (apply #'+file-templates|add args)) (mapc #'+file-templates-add
;; General ;; General
'(("/\\.gitignore$" "__" gitignore-mode) '(("/\\.gitignore$" "__" gitignore-mode)
("/Dockerfile$" "__" dockerfile-mode) ("/Dockerfile$" "__" dockerfile-mode)

View file

@ -1,3 +1,3 @@
;;; `(file-relative-name buffer-file-name doom-modules-dir)` ;;; `(file-relative-name buffer-file-name doom-modules-dir)` -*- lexical-binding: t; -*-
$0 $0

View file

@ -1,4 +1,4 @@
;;; `(file-name-nondirectory buffer-file-name)`${1: --- ${2:description}} ;;; `(file-name-nondirectory buffer-file-name)`${1: --- ${2:description}} -*- lexical-binding: t; -*-
$0 $0

View file

@ -1,4 +1,4 @@
;;; feature/jump/autoload/evil.el ;;; feature/jump/autoload/evil.el -*- lexical-binding: t; -*-
;;;###autoload (autoload '+jump:online "feature/jump/autoload/evil" nil t) ;;;###autoload (autoload '+jump:online "feature/jump/autoload/evil" nil t)
(evil-define-command +jump:online (query &optional bang) (evil-define-command +jump:online (query &optional bang)
@ -6,11 +6,12 @@
reuse it on consecutive uses of this command. If BANG, always prompt for search reuse it on consecutive uses of this command. If BANG, always prompt for search
engine." engine."
(interactive "<a><!>") (interactive "<a><!>")
(setq query (or query (thing-at-point 'symbol t))) (let ((query (or query (thing-at-point 'symbol t))))
(unless query (unless query
(user-error "The search query is empty")) (user-error "The search query is empty"))
(let ((engine (or (and (not bang) (bound-and-true-p +jump--online-last)) (+jump/online
(or (and (not bang) (bound-and-true-p +jump--online-last))
(completing-read (format "Search on (%s): " query) (completing-read (format "Search on (%s): " query)
(mapcar #'car +jump-search-url-alist) (mapcar #'car +jump-search-url-alist)
nil t)))) nil t))
(+jump/online engine query))) query)))

View file

@ -1,4 +1,4 @@
;;; feature/jump/autoload.el ;;; feature/jump/autoload.el -*- lexical-binding: t; -*-
(defvar +jump--rg-installed-p (executable-find "rg")) (defvar +jump--rg-installed-p (executable-find "rg"))
(defvar +jump--ag-installed-p (executable-find "ag")) (defvar +jump--ag-installed-p (executable-find "ag"))
@ -42,12 +42,11 @@ Tries xref and falls back to `dumb-jump', then rg/ag, then
((and (featurep 'evil) ((and (featurep 'evil)
evil-mode evil-mode
(let ((bounds (bounds-of-thing-at-point 'symbol)) (destructuring-bind (beg end) (bounds-of-thing-at-point 'symbol)
(orig-pt (point)))
(evil-goto-definition) (evil-goto-definition)
(let ((pt (point))) (let ((pt (point)))
(not (and (>= pt (car bounds)) (not (and (>= pt beg)
(< pt (cdr bounds)))))))) (< pt end)))))))
(t (user-error "Couldn't find '%s'" sym))))) (t (user-error "Couldn't find '%s'" sym)))))
@ -58,9 +57,8 @@ Tries xref and falls back to `dumb-jump', then rg/ag, then
Tries `xref-find-references' and falls back to rg/ag." Tries `xref-find-references' and falls back to rg/ag."
(interactive) (interactive)
(let ((sym (thing-at-point 'symbol t))) (let ((sym (thing-at-point 'symbol t)))
(cond ((progn (cond ((ignore-errors (xref-find-references sym)
(ignore-errors (xref-find-references sym) t))
t)))
((and sym ((and sym
(featurep 'counsel) (featurep 'counsel)
@ -87,7 +85,7 @@ Interactively, you are prompted to choose a source from
(mapcar #'car +jump-search-url-alist) (mapcar #'car +jump-search-url-alist)
nil t)) nil t))
(thing-at-point 'symbol t))) (thing-at-point 'symbol t)))
(condition-case ex (condition-case _ex
(let ((url (cdr (assoc where +jump-search-url-alist)))) (let ((url (cdr (assoc where +jump-search-url-alist))))
(unless url (unless url
(error "'%s' is an invalid search engine" where)) (error "'%s' is an invalid search engine" where))

View file

@ -1,4 +1,4 @@
;;; feature/jump/config.el ;;; feature/jump/config.el -*- lexical-binding: t; -*-
;; "What am I looking at?" ;; "What am I looking at?"
;; ;;

View file

@ -1,4 +1,4 @@
;;; feature/snippets/autoload/evil.el ;;; feature/snippets/autoload/evil.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun +snippets/expand-on-region () (defun +snippets/expand-on-region ()

View file

@ -1,4 +1,4 @@
;;; feature/snippets/autoload/snippets.el ;;; feature/snippets/autoload/snippets.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun +snippets/goto-start-of-field () (defun +snippets/goto-start-of-field ()

View file

@ -1,4 +1,4 @@
;;; feature/snippets/config.el ;;; feature/snippets/config.el -*- lexical-binding: t; -*-
;; Snippets! I've thrown together a few hacks to make `yasnippet' and `evil' ;; Snippets! I've thrown together a few hacks to make `yasnippet' and `evil'
;; behave together. ;; behave together.

View file

@ -1,4 +1,4 @@
;;; feature/spellcheck/config.el ;;; feature/spellcheck/config.el -*- lexical-binding: t; -*-
(def-package! flyspell ; built-in (def-package! flyspell ; built-in
:commands flyspell-mode :commands flyspell-mode

View file

@ -1,4 +1,4 @@
;;; feature/syntax-checker/config.el ;;; feature/syntax-checker/config.el -*- lexical-binding: t; -*-
;; pkg-info doesn't get autoloaded when `flycheck-version' needs it, so we do ;; pkg-info doesn't get autoloaded when `flycheck-version' needs it, so we do
;; it ourselves: ;; it ourselves:

View file

@ -1,4 +1,4 @@
;;; feature/version-control/+git.el ;;; feature/version-control/+git.el -*- lexical-binding: t; -*-
(def-package! gitconfig-mode (def-package! gitconfig-mode
:mode "/\\.?git/?config$" :mode "/\\.?git/?config$"

View file

@ -1,4 +1,4 @@
;;; feature/version-control/autoload.el ;;; feature/version-control/autoload.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun +vcs-root () (defun +vcs-root ()
@ -15,8 +15,8 @@
"Open the website for the current version controlled file. Fallback to "Open the website for the current version controlled file. Fallback to
repository root." repository root."
(interactive) (interactive)
(let ((git-link-open-in-browser t)) (destructuring-bind (beg end) (if buffer-file-name (git-link--get-region))
(call-interactively 'git-link))) (git-link (git-link--select-remote) beg end)))
;;;###autoload ;;;###autoload
(defun +vcs/git-browse-issues () (defun +vcs/git-browse-issues ()

View file

@ -1,4 +1,4 @@
;;; feature/version-control/config.el ;;; feature/version-control/config.el -*- lexical-binding: t; -*-
(setq vc-make-backup-files nil) (setq vc-make-backup-files nil)

View file

@ -1,4 +1,4 @@
;;; feature/workspaces/autoload/evil.el ;;; feature/workspaces/autoload/evil.el -*- lexical-binding: t; -*-
;;;###autoload (autoload '+workspace:save-session "feature/workspaces/autoload/evil" nil t) ;;;###autoload (autoload '+workspace:save-session "feature/workspaces/autoload/evil" nil t)
(evil-define-command +workspace:save-session (&optional bang name) (evil-define-command +workspace:save-session (&optional bang name)

View file

@ -1,4 +1,4 @@
;;; feature/workspaces/autoload/workspaces.el ;;; feature/workspaces/autoload/workspaces.el -*- lexical-binding: t; -*-
(defvar +workspace-workspace-file "_workspaces" (defvar +workspace-workspace-file "_workspaces"
"The file basename in which to store single workspace perspectives.") "The file basename in which to store single workspace perspectives.")
@ -139,12 +139,11 @@ perspective or its hash table."
(persp-frame-switch name)) (persp-frame-switch name))
(defun +workspace--generate-id () (defun +workspace--generate-id ()
(let ((numbers (mapcar (lambda (it) (string-to-number (substring it 1))) (or (cl-loop for name in (+workspace-list)
(cl-remove-if-not (lambda (it) (string-match-p "^#[0-9]+$" it)) when (string-match-p "^#[0-9]+$" name)
(+workspace-list))))) maximize (string-to-number (substring name 1)) into max
(if numbers finally return (if max (1+ max)))
(1+ (car (sort numbers (lambda (it other) (> it other))))) 1))
1)))
(defun +workspace-protected-p (name) (defun +workspace-protected-p (name)
(or (equal name persp-nil-name) (or (equal name persp-nil-name)
@ -373,17 +372,16 @@ the workspace and move to the next."
(defun +workspace--tabline (&optional names) (defun +workspace--tabline (&optional names)
(let ((names (or names (+workspace-list))) (let ((names (or names (+workspace-list)))
(current-name (+workspace-current-name)) (current-name (+workspace-current-name)))
(i 0))
(mapconcat (mapconcat
#'identity #'identity
(mapcar (lambda (it) (cl-loop for name in names
(cl-incf i) for i to (length names)
(propertize (format " [%d] %s " i it) collect
'face (if (equal current-name it) (propertize (format " [%d] %s " i name)
'face (if (equal current-name name)
'+workspace-tab-selected-face '+workspace-tab-selected-face
'+workspace-tab-face))) '+workspace-tab-face)))
names)
" "))) " ")))
(defun +workspace--message-body (message &optional type) (defun +workspace--message-body (message &optional type)

View file

@ -1,4 +1,4 @@
;;; feature/workspaces/config.el ;;; feature/workspaces/config.el -*- lexical-binding: t; -*-
;; `persp-mode' gives me workspaces, a workspace-restricted `buffer-list', and ;; `persp-mode' gives me workspaces, a workspace-restricted `buffer-list', and
;; file-based session persistence. I had used workgroups2 before this, but ;; file-based session persistence. I had used workgroups2 before this, but
@ -24,7 +24,8 @@ renamed.")
;; Plugins ;; Plugins
;; ;;
(def-package! persp-mode :demand t (def-package! persp-mode
:demand t
:config :config
(setq persp-autokill-buffer-on-remove 'kill-weak (setq persp-autokill-buffer-on-remove 'kill-weak
persp-nil-name "nil" persp-nil-name "nil"
@ -44,35 +45,34 @@ renamed.")
(defun +workspaces|init (&rest _) (defun +workspaces|init (&rest _)
(unless persp-mode (unless persp-mode
(persp-mode +1)) (persp-mode +1)
;; The default perspective persp-mode makes (defined by `persp-nil-name') is ;; The default perspective persp-mode makes (defined by `persp-nil-name')
;; special and doesn't actually represent a real persp object, so buffers ;; is special and doesn't actually represent a real persp object, so
;; can't really be assigned to it, among other quirks. We create a *real* ;; buffers can't really be assigned to it, among other quirks. We create a
;; main workspace to fill this role. ;; *real* main workspace to fill this role.
(persp-add-new +workspaces-main) (persp-add-new +workspaces-main)
;; Switch to it if we aren't auto-loading the last session ;; Switch to it if we aren't auto-loading the last session
(when (or (= persp-auto-resume-time -1) (when (or (= persp-auto-resume-time -1)
(equal (safe-persp-name (get-current-persp)) persp-nil-name)) (equal (safe-persp-name (get-current-persp)) persp-nil-name))
(persp-frame-switch +workspaces-main))) (persp-frame-switch +workspaces-main))))
(add-hook! 'after-init-hook (add-hook 'emacs-startup-hook #'+workspaces|init)
(if (display-graphic-p) (add-hook 'after-make-frame-functions #'+workspaces|init)
(+workspaces|init)
(add-hook 'after-make-frame-functions #'+workspaces|init)))
(define-key persp-mode-map [remap delete-window] #'+workspace/close-window-or-workspace) (define-key persp-mode-map [remap delete-window] #'+workspace/close-window-or-workspace)
;; Spawn a perspective for each new frame ;; Spawn a perspective for each new frame
(setq persp-init-new-frame-behaviour-override nil (setq persp-init-new-frame-behaviour-override nil
persp-interactive-init-frame-behaviour-override persp-interactive-init-frame-behaviour-override
(lambda (frame &optional new-frame-p) (lambda (frame &optional _new-frame-p)
(select-frame frame) (select-frame frame)
(+workspace/new) (+workspace/new)
(set-frame-parameter frame 'assoc-persp (+workspace-current-name)))) (set-frame-parameter frame 'assoc-persp (+workspace-current-name))))
(defun +workspaces*delete-frame-and-persp (frame) (defun +workspaces*delete-frame-and-persp (frame)
"Delete workspace associated with current frame IF it has no real buffers." "Delete workspace associated with current frame IF it has no real buffers."
(when (and (string= (or (frame-parameter frame 'assoc-persp) "") (+workspace-current-name)) (when (and (string= (or (frame-parameter frame 'assoc-persp) "")
(+workspace-current-name))
(not (delq (doom-fallback-buffer) (doom-real-buffers-list)))) (not (delq (doom-fallback-buffer) (doom-real-buffers-list))))
(+workspace/delete persp-name))) (+workspace/delete persp-name)))
(add-hook 'delete-frame-functions #'+workspaces*delete-frame-and-persp) (add-hook 'delete-frame-functions #'+workspaces*delete-frame-and-persp)

View file

@ -1,4 +1,4 @@
;;; lang/assembly/config.el ;;; lang/assembly/config.el -*- lexical-binding: t; -*-
(def-package! mips-mode :mode "\\.mips$") (def-package! mips-mode :mode "\\.mips$")

View file

@ -1,4 +1,4 @@
;;; lang/cc/autoload.el ;;; lang/cc/autoload.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun +cc/autoclose->-maybe () (defun +cc/autoclose->-maybe ()

View file

@ -1,4 +1,4 @@
;;; lang/cc/config.el --- C, C++, and Objective-C ;;; lang/cc/config.el --- c, c++, and obj-c -*- lexical-binding: t; -*-
(def-package! cc-mode (def-package! cc-mode
:commands (c-mode c++-mode objc-mode java-mode) :commands (c-mode c++-mode objc-mode java-mode)
@ -67,7 +67,7 @@
(c-set-offset 'arglist-intro '+) (c-set-offset 'arglist-intro '+)
(c-set-offset 'arglist-close '0) (c-set-offset 'arglist-close '0)
(defun +cc--c-lineup-inclass (langelem) (defun +cc--c-lineup-inclass (_langelem)
(if (memq major-mode '(c-mode c++-mode)) (if (memq major-mode '(c-mode c++-mode))
(let ((inclass (assq 'inclass c-syntactic-context))) (let ((inclass (assq 'inclass c-syntactic-context)))
(save-excursion (save-excursion
@ -115,12 +115,15 @@
(def-package! irony (def-package! irony
:after cc-mode :after cc-mode
:commands irony-install-server :commands irony-install-server
:init :preface
(add-hook! 'c-mode-common-hook
(when (memq major-mode '(c-mode c++-mode objc-mode))
(irony-mode +1)))
:config
(setq irony-server-install-prefix (concat doom-etc-dir "irony-server/")) (setq irony-server-install-prefix (concat doom-etc-dir "irony-server/"))
:init
(defun +cc|init-irony-mode ()
(when (memq major-mode '(c-mode c++-mode objc-mode))
(when (file-directory-p irony-server-install-prefix)
(irony-mode +1))))
(add-hook 'c-mode-common-hook #'+cc|init-irony-mode)
:config
(add-hook! 'irony-mode-hook #'(irony-eldoc flycheck-mode)) (add-hook! 'irony-mode-hook #'(irony-eldoc flycheck-mode))
(add-hook! 'c++-mode-hook (add-hook! 'c++-mode-hook
(make-local-variable 'irony-additional-clang-options) (make-local-variable 'irony-additional-clang-options)

View file

@ -1,4 +1,4 @@
;;; lang/clojure/config.el ;;; lang/clojure/config.el -*- lexical-binding: t; -*-
(def-package! clojure-mode (def-package! clojure-mode
:mode "\\.clj$") :mode "\\.clj$")
@ -6,5 +6,4 @@
(def-package! cider (def-package! cider
:commands (cider-jack-in cider-mode) :commands (cider-jack-in cider-mode)
:config :config
(setq (setq nrepl-hide-special-buffers t))
nrepl-hide-special-buffers t))

View file

@ -1,4 +1,4 @@
;;; module-crystal.el ;;; lang/crystal/config.el -*- lexical-binding: t; -*-
(def-package! crystal-mode (def-package! crystal-mode
:mode "\\.cr$" :mode "\\.cr$"

View file

@ -1,4 +1,4 @@
;;; module-csharp.el ;;; lang/csharp/config.el -*- lexical-binding: t; -*-
(def-package! csharp-mode :mode "\\.cs$") (def-package! csharp-mode :mode "\\.cs$")

View file

@ -1,4 +1,4 @@
;;; module-data.el ;;; lang/data/config.el -*- lexical-binding: t; -*-
(push '("/sxhkdrc" . conf-mode) auto-mode-alist) (push '("/sxhkdrc" . conf-mode) auto-mode-alist)

View file

@ -1,2 +1,2 @@
;;; lang/elixir/autoload/elixir.el ;;; lang/elixir/autoload/elixir.el -*- lexical-binding: t; -*-

View file

@ -1,10 +1,9 @@
;;; lang/elixir/config.el ;;; lang/elixir/config.el -*- lexical-binding: t; -*-
(def-package! elixir-mode (def-package! elixir-mode
:mode ("\\.ex$") :mode "\\.ex$"
:init :init
(add-hook 'elixir-mode-hook #'turn-off-smartparens-mode) (add-hook! 'elixir-mode-hook #'(turn-off-smartparens-mode alchemist))
(add-hook 'elixir-mode-hook #'alchemist)
:config :config
(set! :company-backend 'elixir-mode '(alchemist-company company-yasnippet))) (set! :company-backend 'elixir-mode '(alchemist-company company-yasnippet)))

View file

@ -1,4 +1,4 @@
;;; lang/elm/config.el ;;; lang/elm/config.el -*- lexical-binding: t; -*-
(def-package! elm-mode (def-package! elm-mode
:mode "\\.elm$" :mode "\\.elm$"

View file

@ -1,4 +1,4 @@
;;; lang/emacs-lisp/autoload.el ;;; lang/emacs-lisp/autoload.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun +emacs-lisp/repl () (defun +emacs-lisp/repl ()
@ -20,8 +20,6 @@ to a pop up buffer."
(buf (get-buffer-create "*doom eval*")) (buf (get-buffer-create "*doom eval*"))
(inhibit-read-only t) (inhibit-read-only t)
lines) lines)
(unwind-protect
(progn
(with-current-buffer buf (with-current-buffer buf
(read-only-mode +1) (read-only-mode +1)
(erase-buffer) (erase-buffer)
@ -34,4 +32,4 @@ to a pop up buffer."
(if (> lines 1) (if (> lines 1)
(doom-popup-buffer buf) (doom-popup-buffer buf)
(message "%s" (buffer-substring (point-min) (point-max))) (message "%s" (buffer-substring (point-min) (point-max)))
(kill-buffer buf))))))) (kill-buffer buf)))))

View file

@ -1,10 +1,9 @@
;;; lang/emacs-lisp/config.el ;;; lang/emacs-lisp/config.el -*- lexical-binding: t; -*-
(def-package! elisp-mode ; built-in (def-package! elisp-mode ; built-in
:mode ("/Cask$" . emacs-lisp-mode) :mode ("/Cask$" . emacs-lisp-mode)
:init :init
(add-hook 'emacs-lisp-mode-hook #'+emacs-lisp|hook) (add-hook 'emacs-lisp-mode-hook #'+emacs-lisp|hook)
:config :config
(set! :repl 'emacs-lisp-mode #'+emacs-lisp/repl) (set! :repl 'emacs-lisp-mode #'+emacs-lisp/repl)
(set! :eval 'emacs-lisp-mode #'+emacs-lisp-eval) (set! :eval 'emacs-lisp-mode #'+emacs-lisp-eval)

View file

@ -1,4 +1,4 @@
;;; lang/go/autoload.el ;;; lang/go/autoload.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
;; TODO (defun +go/build ()) ;; TODO (defun +go/build ())

View file

@ -1,4 +1,4 @@
;;; lang/go/config.el ;;; lang/go/config.el -*- lexical-binding: t; -*-
(def-package! go-mode (def-package! go-mode
:mode "\\.go$" :mode "\\.go$"

View file

@ -1,4 +1,4 @@
;;; module-haskell.el ;;; lang/haskell/config.el -*- lexical-binding: t; -*-
(def-package! haskell-mode (def-package! haskell-mode
:mode "\\.hs$" :mode "\\.hs$"
@ -10,7 +10,6 @@
(load "haskell-mode-autoloads" nil t) (load "haskell-mode-autoloads" nil t)
(set! :repl 'haskell-mode #'switch-to-haskell) (set! :repl 'haskell-mode #'switch-to-haskell)
(push ".hi" completion-ignored-extensions) (push ".hi" completion-ignored-extensions)
(autoload 'switch-to-haskell "inf-haskell" nil t) (autoload 'switch-to-haskell "inf-haskell" nil t)

View file

@ -1,4 +1,4 @@
;;; lang/java/config.el ;;; lang/java/config.el -*- lexical-binding: t; -*-
;; yasnippet defuns ;; yasnippet defuns
;;;###autoload ;;;###autoload
@ -9,7 +9,7 @@
;;;###autoload ;;;###autoload
(defun +java-android-mode-in-tags (&rest tags) (defun +java-android-mode-in-tags (&rest tags)
(-contains? tags (android-mode-tag-name))) (cl-find (android-mode-tag-name) tags))
;;;###autoload ;;;###autoload
(defun +java-android-mode-tag-name () (defun +java-android-mode-tag-name ()

View file

@ -1,4 +1,4 @@
;;; lang/java/config.el ;;; lang/java/config.el -*- lexical-binding: t; -*-
(def-package! meghanada (def-package! meghanada
:commands meghanada-mode :commands meghanada-mode

View file

@ -1,4 +1,4 @@
;;; lang/javascript/+screeps.el ;;; lang/javascript/+screeps.el -*- lexical-binding: t; -*-
;; TODO Constants may be out-of-date ;; TODO Constants may be out-of-date
@ -171,8 +171,9 @@
:match "/screeps/.+$" :match "/screeps/.+$"
:modes (+javascript-npm-mode)) :modes (+javascript-npm-mode))
(add-hook! '+javascript-screeps-mode-hook (defun +javascript|init-screeps-mode ()
(when (eq major-mode 'js2-mode) (when (eq major-mode 'js2-mode)
(push 'javascript-jshint flycheck-disabled-checkers) (cl-pushnew 'javascript-jshint flycheck-disabled-checkers)
(setq js2-additional-externs (append '("_") screeps-objects screeps-constants)))) (setq js2-additional-externs (append '("_") screeps-objects screeps-constants))))
(add-hook '+javascript-screeps-mode-hook #'+javascript|init-screeps-mode)

View file

@ -1,4 +1,4 @@
;;; lang/javascript/autoload.el ;;; lang/javascript/autoload.el -*- lexical-binding: t; -*-
(defvar +javascript-npm-conf (make-hash-table :test 'equal)) (defvar +javascript-npm-conf (make-hash-table :test 'equal))
@ -17,13 +17,13 @@ ignore the cache."
;;;###autoload ;;;###autoload
(defun +javascript-npm-dep-p (packages &optional project-root refresh-p) (defun +javascript-npm-dep-p (packages &optional project-root refresh-p)
(when-let (data (and (bound-and-true-p +javascript-npm-mode) (when-let (data (and (bound-and-true-p +javascript-npm-mode)
(+javascript-npm-conf))) (+javascript-npm-conf project-root refresh-p)))
(let ((deps (append (cdr (assq 'dependencies data)) (let ((deps (append (cdr (assq 'dependencies data))
(cdr (assq 'devDependencies data))))) (cdr (assq 'devDependencies data)))))
(cond ((listp packages) (cond ((listp packages)
(funcall (if (eq (car packages) 'and) (funcall (if (eq (car packages) 'and)
'cl-every #'cl-every
'cl-some) #'cl-some)
(lambda (pkg) (assq pkg deps)) (lambda (pkg) (assq pkg deps))
(if (listp packages) packages (list packages)))) (if (listp packages) packages (list packages))))
((symbolp packages) ((symbolp packages)

View file

@ -1,4 +1,4 @@
;; lang/javascript/config.el ;;; lang/javascript/config.el -*- lexical-binding: t; -*-
(load! +screeps) (load! +screeps)
@ -17,12 +17,13 @@
(add-hook! 'js2-mode-hook (setq js-switch-indent-offset js-indent-level)) (add-hook! 'js2-mode-hook (setq js-switch-indent-offset js-indent-level))
;; Favor local eslint over global, if available ;; Favor local eslint over global, if available
(add-hook! 'flycheck-mode-hook (defun +javascript|init-flycheck-elint ()
(when (derived-mode-p 'js-mode 'js2-mode) (when (derived-mode-p 'js-mode 'js2-mode)
(when-let ((eslint (expand-file-name "node_modules/eslint/bin/eslint.js" (doom-project-root))) (when-let ((eslint (expand-file-name "node_modules/eslint/bin/eslint.js" (doom-project-root)))
(exists-p (file-exists-p eslint)) (exists-p (file-exists-p eslint))
(executable-p (file-executable-p eslint))) (executable-p (file-executable-p eslint)))
(setq-local flycheck-javascript-eslint-executable eslint)))) (setq-local flycheck-javascript-eslint-executable eslint))))
(add-hook 'flycheck-mode-hook #'+javascript|init-flycheck-elint)
(set! :repl 'js2-mode '+javascript/repl) (set! :repl 'js2-mode '+javascript/repl)
(set! :electric 'js2-mode :chars '(?\} ?\) ?.)) (set! :electric 'js2-mode :chars '(?\} ?\) ?.))

View file

@ -1,4 +1,4 @@
;;; lang/julia/autoload.el ;;; lang/julia/autoload.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun +julia/repl () (defun +julia/repl ()

View file

@ -1,4 +1,4 @@
;;; lang/julia/config.el ;;; lang/julia/config.el -*- lexical-binding: t; -*-
(use-package julia-mode (use-package julia-mode
:mode "\\.jl$" :mode "\\.jl$"

View file

@ -1,4 +1,4 @@
;;; lang/latex/config.el ;;; lang/latex/config.el -*- lexical-binding: t; -*-
(defvar +latex-bibtex-dir "~/work/writing/biblio/" (defvar +latex-bibtex-dir "~/work/writing/biblio/"
"Where bibtex files are kept.") "Where bibtex files are kept.")

View file

@ -1,9 +1,9 @@
;;; lang/lua/autoload.el ;;; lang/lua/autoload.el -*- lexical-binding: t; -*-
;;;###autoload ;;;###autoload
(defun +lua/repl () (defun +lua/repl ()
"Open Lua REPL."
(interactive) (interactive)
(lua-start-process "lua" "lua") (lua-start-process "lua" "lua")
(pop-to-buffer lua-process-buffer)) (pop-to-buffer lua-process-buffer))

View file

@ -1,4 +1,4 @@
;;; lang/lua/config.el --- lua + Love2D ;;; lang/lua/config.el --- lua + Love2D -*- lexical-binding: t; -*-
(def-package! lua-mode (def-package! lua-mode
:mode "\\.lua$" :mode "\\.lua$"

View file

@ -1,7 +1,7 @@
;;; lang/markdown/autoload.el ;;; lang/markdown/autoload.el -*- lexical-binding: t; -*-
;; Implement strike-through formatting ;; Implement strike-through formatting
(defvar +text--markdown-regex-del (defvar +markdown--regex-del
"\\(^\\|[^\\]\\)\\(\\(~\\{2\\}\\)\\([^ \n \\]\\|[^ \n ]\\(?:.\\|\n[^\n]\\)*?[^\\ ]\\)\\(\\3\\)\\)") "\\(^\\|[^\\]\\)\\(\\(~\\{2\\}\\)\\([^ \n \\]\\|[^ \n ]\\(?:.\\|\n[^\n]\\)*?[^\\ ]\\)\\(\\3\\)\\)")
;;;###autoload ;;;###autoload
@ -11,12 +11,13 @@
(let ((delim "~~")) (let ((delim "~~"))
(if (markdown-use-region-p) (if (markdown-use-region-p)
;; Active region ;; Active region
(let ((bounds (markdown-unwrap-things-in-region (destructuring-bind (beg end)
(markdown-unwrap-things-in-region
(region-beginning) (region-end) (region-beginning) (region-end)
+text--markdown-regex-del 2 4))) +markdown--regex-del 2 4)
(markdown-wrap-or-insert delim delim nil (car bounds) (cdr bounds))) (markdown-wrap-or-insert delim delim nil beg end))
;; Bold markup removal, bold word at point, or empty markup insertion ;; Bold markup removal, bold word at point, or empty markup insertion
(if (thing-at-point-looking-at +text--markdown-regex-del) (if (thing-at-point-looking-at +markdown--regex-del)
(markdown-unwrap-thing-at-point nil 2 4) (markdown-unwrap-thing-at-point nil 2 4)
(markdown-wrap-or-insert delim delim 'word nil nil))))) (markdown-wrap-or-insert delim delim 'word nil nil)))))

View file

@ -1,4 +1,4 @@
;;; lang/markdown/config.el ;;; lang/markdown/config.el -*- lexical-binding: t; -*-
(def-package! markdown-mode (def-package! markdown-mode
:mode ("\\.m\\(d\\|arkdown\\)$" "/README$" :mode ("\\.m\\(d\\|arkdown\\)$" "/README$"

View file

@ -1,4 +1,4 @@
;;; lang/php/autoload.el ;;; lang/php/autoload.el -*- lexical-binding: t; -*-
(defvar +php-composer-conf (make-hash-table :test 'equal)) (defvar +php-composer-conf (make-hash-table :test 'equal))

View file

@ -1,4 +1,4 @@
;;; lang/php/config.el ;;; lang/php/config.el -*- lexical-binding: t; -*-
;; (def-package! hack-mode ;; (def-package! hack-mode
;; :mode "\\.hh$" ;; :mode "\\.hh$"
@ -52,7 +52,8 @@
;; company will set up itself ;; company will set up itself
(advice-add #'php-extras-company-setup :override #'ignore) (advice-add #'php-extras-company-setup :override #'ignore)
:config :config
(setq php-extras-eldoc-functions-file (concat doom-etc-dir "php-extras-eldoc-functions")) (setq php-extras-eldoc-functions-file
(concat doom-etc-dir "php-extras-eldoc-functions"))
;; Make expensive php-extras generation async ;; Make expensive php-extras generation async
(unless (file-exists-p (concat php-extras-eldoc-functions-file ".el")) (unless (file-exists-p (concat php-extras-eldoc-functions-file ".el"))

View file

@ -1,25 +1,20 @@
;;; lang/purescript/config.el ;;; lang/purescript/config.el -*- lexical-binding: t; -*-
(def-package! purescript-mode (def-package! purescript-mode
:mode "\\.purs$" :mode "\\.purs$"
:config :config
(add-hook! 'purescript-mode-hook #'flycheck-mode) (add-hook! 'purescript-mode-hook
(add-hook! 'purescript-mode-hook #'company-mode) #'(flycheck-mode purescript-indentation-mode rainbow-delimiters-mode))
(add-hook! 'purescript-mode-hook #'purescript-indentation-mode)
(add-hook! 'purescript-mode-hook #'rainbow-delimiters-mode) (load "purescript-mode-autoloads" nil t))
(load "purescript-mode-autoloads" nil t)
)
;; (def-package! flycheck-purescript ;; (def-package! flycheck-purescript
;; :after purescript-mode ;; :after purescript-mode
;; :config ;; :config
;; (add-hook! 'flycheck-mode-hook #'flycheck-purescript-setup) ;; (add-hook 'flycheck-mode-hook #'flycheck-purescript-setup))
;; )
(def-package! psc-ide (def-package! psc-ide
:after purescript-mode :after purescript-mode
:config :config
(require 'psc-ide) (add-hook 'purescript-mode-hook #'psc-ide-mode))
(add-hook! 'purescript-mode-hook #'psc-ide-mode)
)

Some files were not shown because too many files have changed in this diff Show more