mirror of
https://github.com/doomemacs/doomemacs
synced 2025-08-13 13:13:35 -05:00
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:
@@ -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))))
|
||||
|
9
modules/feature/debug/autoload/debug.el
Normal file
9
modules/feature/debug/autoload/debug.el
Normal 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))
|
||||
|
31
modules/feature/debug/autoload/evil.el
Normal file
31
modules/feature/debug/autoload/evil.el
Normal 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)))
|
@@ -1,4 +1,4 @@
|
||||
;;; feature/debug/config.el
|
||||
;;; feature/debug/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! realgud
|
||||
:commands (realgud:gdb realgud:trepanjs realgud:bashdb realgud:zshdb)
|
||||
@@ -11,7 +11,7 @@
|
||||
;; (def-tmp-excmd! doom:def-debug-on doom:def-debug-off
|
||||
;; ("n[ext]" . realgud:cmd-next)
|
||||
;; ("s[tep]" . realgud:cmd-step)
|
||||
;; ("b[reak]" . doom:debug-toggle-breakpoint)
|
||||
;; ("b[reak]" . +debug:toggle-breakpoint)
|
||||
;; ("c[ontinue]" . realgud:cmd-continue))
|
||||
;; (advice-add #'realgud-cmdbuf-init :after #'doom:def-debug-on)
|
||||
;; (advice-add #'realgud:cmd-quit :after #'doom:def-debug-off)
|
||||
@@ -21,28 +21,26 @@
|
||||
;; FIXME Causes realgud:cmd-* to focus popup on every invocation
|
||||
(defun +debug*realgud-run-process
|
||||
(debugger-name script-filename cmd-args minibuffer-history &optional no-reset)
|
||||
(let ((cmd-buf))
|
||||
(setq cmd-buf
|
||||
(apply #'realgud-exec-shell debugger-name script-filename
|
||||
(car cmd-args) no-reset (cdr cmd-args)))
|
||||
(let ((process (get-buffer-process cmd-buf)))
|
||||
(if (and process (eq 'run (process-status process)))
|
||||
(progn
|
||||
(pop-to-buffer cmd-buf)
|
||||
(define-key evil-emacs-state-local-map (kbd "ESC ESC") #'+debug/quit)
|
||||
(realgud:track-set-debugger debugger-name)
|
||||
(realgud-cmdbuf-info-in-debugger?= 't)
|
||||
(realgud-cmdbuf-info-cmd-args= cmd-args)
|
||||
(when cmd-buf
|
||||
(switch-to-buffer cmd-buf)
|
||||
(when realgud-cmdbuf-info
|
||||
(let* ((info realgud-cmdbuf-info)
|
||||
(cmd-args (realgud-cmdbuf-info-cmd-args info))
|
||||
(cmd-str (mapconcat #'identity cmd-args " ")))
|
||||
(set minibuffer-history
|
||||
(list-utils-uniq (cons cmd-str (eval minibuffer-history))))))))
|
||||
(if cmd-buf (switch-to-buffer cmd-buf))
|
||||
(message "Error running command: %s" (mapconcat #'identity cmd-args " "))))
|
||||
(let* ((cmd-buf (apply #'realgud-exec-shell debugger-name script-filename
|
||||
(car cmd-args) no-reset (cdr cmd-args)))
|
||||
(process (get-buffer-process cmd-buf)))
|
||||
(cond ((and process (eq 'run (process-status process)))
|
||||
(pop-to-buffer cmd-buf)
|
||||
(define-key evil-emacs-state-local-map (kbd "ESC ESC") #'+debug/quit)
|
||||
(realgud:track-set-debugger debugger-name)
|
||||
(realgud-cmdbuf-info-in-debugger?= 't)
|
||||
(realgud-cmdbuf-info-cmd-args= cmd-args)
|
||||
(when cmd-buf
|
||||
(switch-to-buffer cmd-buf)
|
||||
(when realgud-cmdbuf-info
|
||||
(let* ((info realgud-cmdbuf-info)
|
||||
(cmd-args (realgud-cmdbuf-info-cmd-args info))
|
||||
(cmd-str (mapconcat #'identity cmd-args " ")))
|
||||
(set minibuffer-history
|
||||
(list-utils-uniq (cons cmd-str (eval minibuffer-history))))))))
|
||||
(t
|
||||
(if cmd-buf (switch-to-buffer cmd-buf))
|
||||
(message "Error running command: %s" (mapconcat #'identity cmd-args " "))))
|
||||
cmd-buf))
|
||||
(advice-add #'realgud:run-process :override #'+debug*realgud-run-process))
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
;;; feature/eval/autoload/build.el
|
||||
;;; feature/eval/autoload/build.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar-local +eval-last-builder nil
|
||||
"The last builder run in the current buffer.")
|
||||
@@ -22,9 +22,7 @@ functions.")
|
||||
:key 'cdr))
|
||||
(if (= (length builders) 1)
|
||||
(car builders)
|
||||
(when-let (builder (completing-read "Build: "
|
||||
(mapcar #'car builders)
|
||||
nil t))
|
||||
(when-let (builder (completing-read "Build: " (mapcar #'car builders) nil t))
|
||||
(assq (intern builder) builders)))))
|
||||
|
||||
;;;###autoload
|
||||
@@ -36,9 +34,8 @@ functions.")
|
||||
(error "No builder for this buffer"))))
|
||||
(unless builder
|
||||
(error "Builder not found in registered builders"))
|
||||
(let* ((name (car builder))
|
||||
(plist (cdr builder))
|
||||
(fn (plist-get plist :fn)))
|
||||
(let ((name (car builder))
|
||||
(fn (plist-get (cdr builder) :fn)))
|
||||
(message "Running %s" name)
|
||||
(if (or (functionp fn)
|
||||
(and (symbolp fn) (fboundp fn)))
|
||||
|
@@ -1,4 +1,4 @@
|
||||
;;; feature/eval/autoload/eval.el
|
||||
;;; feature/eval/autoload/eval.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +eval/buffer ()
|
||||
|
@@ -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)
|
||||
(evil-define-operator +eval:region (beg end)
|
||||
|
@@ -1,28 +1,28 @@
|
||||
;;; feature/eval/autoload/repl.el
|
||||
;;; feature/eval/autoload/repl.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +eval-repl-buffer nil
|
||||
"The buffer of the last open repl.")
|
||||
|
||||
(defun +eval--ensure-in-repl-buffer (&optional command)
|
||||
(if (eq (current-buffer) +eval-repl-buffer)
|
||||
t
|
||||
(if (and +eval-repl-buffer (buffer-live-p +eval-repl-buffer))
|
||||
(if-let (win (get-buffer-window +eval-repl-buffer))
|
||||
(select-window win)
|
||||
(doom-popup-buffer +eval-repl-buffer))
|
||||
(when command
|
||||
(let ((repl-buffer (save-window-excursion (call-interactively command))))
|
||||
(unless (bufferp repl-buffer)
|
||||
(error "REPL command didn't return a buffer"))
|
||||
(with-current-buffer repl-buffer (+eval-repl-mode +1))
|
||||
(setq +eval-repl-buffer repl-buffer)
|
||||
(select-window (doom-popup-buffer repl-buffer)))))
|
||||
(when (eq (current-buffer) +eval-repl-buffer)
|
||||
(goto-char (if (and (derived-mode-p 'comint-mode)
|
||||
(cdr comint-last-prompt))
|
||||
(cdr comint-last-prompt)
|
||||
(point-max)))
|
||||
t)))
|
||||
(or (eq (current-buffer) +eval-repl-buffer)
|
||||
(progn
|
||||
(if (and +eval-repl-buffer (buffer-live-p +eval-repl-buffer))
|
||||
(if-let (win (get-buffer-window +eval-repl-buffer))
|
||||
(select-window win)
|
||||
(doom-popup-buffer +eval-repl-buffer))
|
||||
(when command
|
||||
(let ((repl-buffer (save-window-excursion (call-interactively command))))
|
||||
(unless (bufferp repl-buffer)
|
||||
(error "REPL command didn't return a buffer"))
|
||||
(with-current-buffer repl-buffer (+eval-repl-mode +1))
|
||||
(setq +eval-repl-buffer repl-buffer)
|
||||
(select-window (doom-popup-buffer repl-buffer)))))
|
||||
(when (eq (current-buffer) +eval-repl-buffer)
|
||||
(goto-char (if (and (derived-mode-p 'comint-mode)
|
||||
(cdr comint-last-prompt))
|
||||
(cdr comint-last-prompt)
|
||||
(point-max)))
|
||||
t))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +eval/repl ()
|
||||
@@ -31,8 +31,8 @@ the cursor at the prompt."
|
||||
(interactive)
|
||||
(when-let (command (cdr (assq major-mode +eval-repls)))
|
||||
(when (+eval--ensure-in-repl-buffer command)
|
||||
(when (and (featurep 'evil) evil-mode)
|
||||
(call-interactively 'evil-append-line))
|
||||
(when (bound-and-true-p evil-mode)
|
||||
(call-interactively #'evil-append-line))
|
||||
t)))
|
||||
|
||||
;;;###autoload
|
||||
@@ -43,8 +43,8 @@ execute it immediately after."
|
||||
(let ((selection (buffer-substring-no-properties beg end)))
|
||||
(unless (+eval--ensure-in-repl-buffer)
|
||||
(error "No REPL open"))
|
||||
(when (and (featurep 'evil) evil-mode)
|
||||
(call-interactively 'evil-append-line))
|
||||
(when (bound-and-true-p evil-mode)
|
||||
(call-interactively #'evil-append-line))
|
||||
(insert (string-trim selection))
|
||||
(when auto-execute-p
|
||||
;; I don't use `comint-send-input' because different REPLs may have their
|
||||
|
@@ -1,4 +1,4 @@
|
||||
;;; feature/eval/config.el
|
||||
;;; feature/eval/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;
|
||||
;; Code building
|
||||
|
@@ -1,4 +1,4 @@
|
||||
;;; feature/evil/autoload/evil-mc.el
|
||||
;;; feature/evil/autoload/evil-mc.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil/mc-toggle-cursors ()
|
||||
@@ -21,9 +21,7 @@ cursors."
|
||||
(interactive)
|
||||
(cond ((memq evil-this-type '(block line))
|
||||
(let ((col (evil-column))
|
||||
(line-at-pt (line-number-at-pos))
|
||||
(beg evil-visual-beginning)
|
||||
(end evil-visual-end))
|
||||
(line-at-pt (line-number-at-pos)))
|
||||
;; Fix off-by-one error
|
||||
(when (= evil-visual-direction 1)
|
||||
(cl-decf col)
|
||||
@@ -36,7 +34,7 @@ cursors."
|
||||
(move-to-column col)
|
||||
(when (= (current-column) col)
|
||||
(evil-mc-make-cursor-here))))
|
||||
beg
|
||||
evil-visual-beginning
|
||||
(if (eq evil-this-type 'line) (1- evil-visual-end) evil-visual-end)
|
||||
nil)
|
||||
(evil-exit-visual-state))))
|
||||
|
@@ -1,4 +1,4 @@
|
||||
;;; feature/evil/autoload/evil.el
|
||||
;;; feature/evil/autoload/evil.el -*- lexical-binding: t; -*-
|
||||
|
||||
(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 ]+\\)\\)*\\)"))
|
||||
(matches
|
||||
(let ((all-strings ())
|
||||
(i 0))
|
||||
(while (and (< i (length file-name))
|
||||
(string-match regexp file-name i))
|
||||
(setq i (1+ (match-beginning 0)))
|
||||
(let (strings)
|
||||
(push (dotimes (i (/ (length (match-data)) 2) (nreverse strings))
|
||||
(push (match-string i file-name) strings))
|
||||
all-strings)))
|
||||
(nreverse all-strings))))
|
||||
(cl-loop with i = 0
|
||||
while (and (< i (length file-name))
|
||||
(string-match regexp file-name i))
|
||||
do (setq i (1+ (match-beginning 0)))
|
||||
and collect
|
||||
(cl-loop for j to (/ (length (match-data)) 2)
|
||||
collect (match-string j file-name)))))
|
||||
(dolist (match matches)
|
||||
(let ((flags (split-string (car (cdr (cdr match))) ":" t))
|
||||
(path (and buffer-file-name
|
||||
@@ -113,16 +110,18 @@ evil-window-move-* (e.g. `evil-window-move-far-left')"
|
||||
(doom-popup-p that-window))
|
||||
(setq that-buffer nil that-window nil))
|
||||
(if (not (or that-window (one-window-p t)))
|
||||
(funcall (case direction
|
||||
('left 'evil-window-move-far-left)
|
||||
('right 'evil-window-move-far-right)
|
||||
('up 'evil-window-move-very-top)
|
||||
('down 'evil-window-move-very-bottom)))
|
||||
(funcall (pcase direction
|
||||
('left #'evil-window-move-far-left)
|
||||
('right #'evil-window-move-far-right)
|
||||
('up #'evil-window-move-very-top)
|
||||
('down #'evil-window-move-very-bottom)))
|
||||
(unless that-window
|
||||
(setq that-window
|
||||
(split-window this-window nil (cond ((eq direction 'up) 'above)
|
||||
((eq direction 'down) 'below)
|
||||
(t direction))))
|
||||
(split-window this-window nil
|
||||
(pcase direction
|
||||
('up 'above)
|
||||
('down 'below)
|
||||
(_ direction))))
|
||||
(with-selected-window that-window
|
||||
(switch-to-buffer doom-buffer))
|
||||
(setq that-buffer (window-buffer that-window)))
|
||||
@@ -172,20 +171,22 @@ evil-window-move-* (e.g. `evil-window-move-far-left')"
|
||||
|
||||
;; --- custom arg handlers ----------------
|
||||
|
||||
(defvar +evil--flag nil)
|
||||
|
||||
(defun +evil--ex-match-init (name &optional face update-hook)
|
||||
(with-current-buffer evil-ex-current-buffer
|
||||
(cond
|
||||
((eq flag 'start)
|
||||
((eq +evil--flag 'start)
|
||||
(evil-ex-make-hl name
|
||||
:face (or face 'evil-ex-substitute-matches)
|
||||
: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)))))
|
||||
|
||||
(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
|
||||
(not (zerop (length arg))))
|
||||
(condition-case lossage
|
||||
@@ -209,21 +210,24 @@ evil-window-move-* (e.g. `evil-window-move-far-left')"
|
||||
|
||||
;;;###autoload
|
||||
(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)
|
||||
(+evil--ex-match-init hl-name)
|
||||
(+evil--ex-buffer-match arg hl-name (list (if evil-ex-substitute-global ?g))))))
|
||||
|
||||
;;;###autoload
|
||||
(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)
|
||||
(+evil--ex-match-init hl-name)
|
||||
(+evil--ex-buffer-match arg hl-name nil (point-min) (point-max)))))
|
||||
|
||||
;;;###autoload
|
||||
(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)
|
||||
(+evil--ex-match-init hl-name)
|
||||
(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
|
||||
`wgrep-mark-deletion' on lines you try to delete."
|
||||
(interactive "<R><x><y>")
|
||||
(condition-case ex
|
||||
(condition-case _ex
|
||||
(evil-delete beg end type register yank-handler)
|
||||
('text-read-only
|
||||
(evil-apply-on-block
|
||||
|
@@ -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)
|
||||
"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)))
|
||||
(cond ((not (file-exists-p fname))
|
||||
(error "File doesn't exist: %s" fname))
|
||||
|
||||
((not (or force-p (y-or-n-p (format "Really delete %s?" fbase))))
|
||||
(message "Aborted")
|
||||
nil)
|
||||
|
||||
(t
|
||||
(unwind-protect
|
||||
(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')
|
||||
(doom-force-kill-buffer buf t)
|
||||
(+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)
|
||||
(let* ((new-path (expand-file-name new-path))
|
||||
|
@@ -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
|
||||
;; won't let you create custom folds. Meanwhile, evil-vimish-fold offers custom
|
||||
;; folds, but essentially ignores any other type of folding (indent or custom
|
||||
;; markers, which hs-minor-mode gives you).
|
||||
;; `hideshow' is a decent code folding implementation, but it won't let you
|
||||
;; create custom folds. `evil-vimish-fold' offers custom folds, but essentially
|
||||
;; ignores any other type of folding (indent or custom markers, which
|
||||
;; hs-minor-mode gives you).
|
||||
;;
|
||||
;; So this is my effort to combine them.
|
||||
|
||||
|
@@ -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
|
||||
;; strives to make Emacs a much better vim than vim was.
|
||||
@@ -41,7 +41,7 @@
|
||||
shift-select-mode nil)
|
||||
|
||||
:config
|
||||
(evil-mode +1)
|
||||
(add-hook 'emacs-startup-hook #'evil-mode)
|
||||
(evil-select-search-module 'evil-search-module 'evil-search)
|
||||
|
||||
(set! :popup
|
||||
@@ -170,7 +170,7 @@ across windows."
|
||||
|
||||
|
||||
(def-package! evil-easymotion
|
||||
:defer 1
|
||||
:after evil-snipe
|
||||
:config
|
||||
(defvar +evil--snipe-repeat-fn
|
||||
(evilem-create #'evil-snipe-repeat
|
||||
@@ -185,7 +185,6 @@ across windows."
|
||||
(setq evil-embrace-show-help-p nil)
|
||||
(evil-embrace-enable-evil-surround-integration)
|
||||
|
||||
;; Defuns
|
||||
(defun +evil--embrace-get-pair (char)
|
||||
(if-let (pair (cdr-safe (assoc (string-to-char char) evil-surround-pairs-alist)))
|
||||
pair
|
||||
@@ -234,15 +233,15 @@ across windows."
|
||||
|
||||
|
||||
(def-package! evil-escape
|
||||
:demand t
|
||||
:commands evil-escape-mode
|
||||
:init
|
||||
(setq evil-escape-excluded-states '(normal visual multiedit emacs)
|
||||
evil-escape-excluded-major-modes '(neotree-mode)
|
||||
evil-escape-key-sequence "jk"
|
||||
evil-escape-delay 0.25)
|
||||
|
||||
(add-hook 'emacs-startup-hook #'evil-escape-mode)
|
||||
:config
|
||||
(evil-escape-mode +1)
|
||||
(map! :irvo "C-g" #'evil-escape))
|
||||
|
||||
|
||||
@@ -330,7 +329,7 @@ the new algorithm is confusing, like in python or ruby."
|
||||
(?\] "[]})]")
|
||||
(?\; "[;:]")))
|
||||
:config
|
||||
(evil-snipe-override-mode +1))
|
||||
(add-hook 'emacs-startup-hook #'evil-snipe-override-mode))
|
||||
|
||||
|
||||
(def-package! evil-surround
|
||||
|
@@ -1,4 +1,4 @@
|
||||
;;; feature/file-templates/config.el
|
||||
;;; feature/file-templates/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(require! :feature snippets)
|
||||
|
||||
@@ -31,12 +31,13 @@
|
||||
(overlay-get yas--active-field-overlay 'yas--field)))
|
||||
(evil-initialize-state 'insert))))
|
||||
|
||||
(defun +file-templates|add (regexp trigger mode &optional project-only-p)
|
||||
(define-auto-insert
|
||||
regexp
|
||||
(vector `(lambda () (+file-templates--expand ,trigger ',mode ,project-only-p)))))
|
||||
(defun +file-templates-add (args)
|
||||
(destructuring-bind (regexp trigger mode &optional project-only-p) args
|
||||
(define-auto-insert
|
||||
regexp
|
||||
(vector `(lambda () (+file-templates--expand ,trigger ',mode ,project-only-p))))))
|
||||
|
||||
(mapc (lambda (args) (apply #'+file-templates|add args))
|
||||
(mapc #'+file-templates-add
|
||||
;; General
|
||||
'(("/\\.gitignore$" "__" gitignore-mode)
|
||||
("/Dockerfile$" "__" dockerfile-mode)
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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)
|
||||
(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
|
||||
engine."
|
||||
(interactive "<a><!>")
|
||||
(setq query (or query (thing-at-point 'symbol t)))
|
||||
(unless query
|
||||
(user-error "The search query is empty"))
|
||||
(let ((engine (or (and (not bang) (bound-and-true-p +jump--online-last))
|
||||
(completing-read (format "Search on (%s): " query)
|
||||
(mapcar #'car +jump-search-url-alist)
|
||||
nil t))))
|
||||
(+jump/online engine query)))
|
||||
(let ((query (or query (thing-at-point 'symbol t))))
|
||||
(unless query
|
||||
(user-error "The search query is empty"))
|
||||
(+jump/online
|
||||
(or (and (not bang) (bound-and-true-p +jump--online-last))
|
||||
(completing-read (format "Search on (%s): " query)
|
||||
(mapcar #'car +jump-search-url-alist)
|
||||
nil t))
|
||||
query)))
|
||||
|
@@ -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--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)
|
||||
evil-mode
|
||||
(let ((bounds (bounds-of-thing-at-point 'symbol))
|
||||
(orig-pt (point)))
|
||||
(destructuring-bind (beg end) (bounds-of-thing-at-point 'symbol)
|
||||
(evil-goto-definition)
|
||||
(let ((pt (point)))
|
||||
(not (and (>= pt (car bounds))
|
||||
(< pt (cdr bounds))))))))
|
||||
(not (and (>= pt beg)
|
||||
(< pt end)))))))
|
||||
|
||||
(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."
|
||||
(interactive)
|
||||
(let ((sym (thing-at-point 'symbol t)))
|
||||
(cond ((progn
|
||||
(ignore-errors (xref-find-references sym)
|
||||
t)))
|
||||
(cond ((ignore-errors (xref-find-references sym)
|
||||
t))
|
||||
|
||||
((and sym
|
||||
(featurep 'counsel)
|
||||
@@ -87,7 +85,7 @@ Interactively, you are prompted to choose a source from
|
||||
(mapcar #'car +jump-search-url-alist)
|
||||
nil t))
|
||||
(thing-at-point 'symbol t)))
|
||||
(condition-case ex
|
||||
(condition-case _ex
|
||||
(let ((url (cdr (assoc where +jump-search-url-alist))))
|
||||
(unless url
|
||||
(error "'%s' is an invalid search engine" where))
|
||||
|
@@ -1,4 +1,4 @@
|
||||
;;; feature/jump/config.el
|
||||
;;; feature/jump/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; "What am I looking at?"
|
||||
;;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
;;; feature/snippets/autoload/evil.el
|
||||
;;; feature/snippets/autoload/evil.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +snippets/expand-on-region ()
|
||||
|
@@ -1,4 +1,4 @@
|
||||
;;; feature/snippets/autoload/snippets.el
|
||||
;;; feature/snippets/autoload/snippets.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +snippets/goto-start-of-field ()
|
||||
|
@@ -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'
|
||||
;; behave together.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
;;; feature/spellcheck/config.el
|
||||
;;; feature/spellcheck/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! flyspell ; built-in
|
||||
:commands flyspell-mode
|
||||
|
@@ -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
|
||||
;; it ourselves:
|
||||
|
@@ -1,4 +1,4 @@
|
||||
;;; feature/version-control/+git.el
|
||||
;;; feature/version-control/+git.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! gitconfig-mode
|
||||
:mode "/\\.?git/?config$"
|
||||
|
@@ -1,4 +1,4 @@
|
||||
;;; feature/version-control/autoload.el
|
||||
;;; feature/version-control/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +vcs-root ()
|
||||
@@ -15,8 +15,8 @@
|
||||
"Open the website for the current version controlled file. Fallback to
|
||||
repository root."
|
||||
(interactive)
|
||||
(let ((git-link-open-in-browser t))
|
||||
(call-interactively 'git-link)))
|
||||
(destructuring-bind (beg end) (if buffer-file-name (git-link--get-region))
|
||||
(git-link (git-link--select-remote) beg end)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +vcs/git-browse-issues ()
|
||||
|
@@ -1,4 +1,4 @@
|
||||
;;; feature/version-control/config.el
|
||||
;;; feature/version-control/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(setq vc-make-backup-files nil)
|
||||
|
||||
|
@@ -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)
|
||||
(evil-define-command +workspace:save-session (&optional bang name)
|
||||
|
@@ -1,4 +1,4 @@
|
||||
;;; feature/workspaces/autoload/workspaces.el
|
||||
;;; feature/workspaces/autoload/workspaces.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +workspace-workspace-file "_workspaces"
|
||||
"The file basename in which to store single workspace perspectives.")
|
||||
@@ -139,12 +139,11 @@ perspective or its hash table."
|
||||
(persp-frame-switch name))
|
||||
|
||||
(defun +workspace--generate-id ()
|
||||
(let ((numbers (mapcar (lambda (it) (string-to-number (substring it 1)))
|
||||
(cl-remove-if-not (lambda (it) (string-match-p "^#[0-9]+$" it))
|
||||
(+workspace-list)))))
|
||||
(if numbers
|
||||
(1+ (car (sort numbers (lambda (it other) (> it other)))))
|
||||
1)))
|
||||
(or (cl-loop for name in (+workspace-list)
|
||||
when (string-match-p "^#[0-9]+$" name)
|
||||
maximize (string-to-number (substring name 1)) into max
|
||||
finally return (if max (1+ max)))
|
||||
1))
|
||||
|
||||
(defun +workspace-protected-p (name)
|
||||
(or (equal name persp-nil-name)
|
||||
@@ -373,17 +372,16 @@ the workspace and move to the next."
|
||||
|
||||
(defun +workspace--tabline (&optional names)
|
||||
(let ((names (or names (+workspace-list)))
|
||||
(current-name (+workspace-current-name))
|
||||
(i 0))
|
||||
(current-name (+workspace-current-name)))
|
||||
(mapconcat
|
||||
#'identity
|
||||
(mapcar (lambda (it)
|
||||
(cl-incf i)
|
||||
(propertize (format " [%d] %s " i it)
|
||||
'face (if (equal current-name it)
|
||||
'+workspace-tab-selected-face
|
||||
'+workspace-tab-face)))
|
||||
names)
|
||||
(cl-loop for name in names
|
||||
for i to (length names)
|
||||
collect
|
||||
(propertize (format " [%d] %s " i name)
|
||||
'face (if (equal current-name name)
|
||||
'+workspace-tab-selected-face
|
||||
'+workspace-tab-face)))
|
||||
" ")))
|
||||
|
||||
(defun +workspace--message-body (message &optional type)
|
||||
|
@@ -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
|
||||
;; file-based session persistence. I had used workgroups2 before this, but
|
||||
@@ -24,7 +24,8 @@ renamed.")
|
||||
;; Plugins
|
||||
;;
|
||||
|
||||
(def-package! persp-mode :demand t
|
||||
(def-package! persp-mode
|
||||
:demand t
|
||||
:config
|
||||
(setq persp-autokill-buffer-on-remove 'kill-weak
|
||||
persp-nil-name "nil"
|
||||
@@ -44,35 +45,34 @@ renamed.")
|
||||
|
||||
(defun +workspaces|init (&rest _)
|
||||
(unless persp-mode
|
||||
(persp-mode +1))
|
||||
;; The default perspective persp-mode makes (defined by `persp-nil-name') is
|
||||
;; special and doesn't actually represent a real persp object, so buffers
|
||||
;; can't really be assigned to it, among other quirks. We create a *real*
|
||||
;; main workspace to fill this role.
|
||||
(persp-add-new +workspaces-main)
|
||||
;; Switch to it if we aren't auto-loading the last session
|
||||
(when (or (= persp-auto-resume-time -1)
|
||||
(equal (safe-persp-name (get-current-persp)) persp-nil-name))
|
||||
(persp-frame-switch +workspaces-main)))
|
||||
(persp-mode +1)
|
||||
;; The default perspective persp-mode makes (defined by `persp-nil-name')
|
||||
;; is special and doesn't actually represent a real persp object, so
|
||||
;; buffers can't really be assigned to it, among other quirks. We create a
|
||||
;; *real* main workspace to fill this role.
|
||||
(persp-add-new +workspaces-main)
|
||||
;; Switch to it if we aren't auto-loading the last session
|
||||
(when (or (= persp-auto-resume-time -1)
|
||||
(equal (safe-persp-name (get-current-persp)) persp-nil-name))
|
||||
(persp-frame-switch +workspaces-main))))
|
||||
|
||||
(add-hook! 'after-init-hook
|
||||
(if (display-graphic-p)
|
||||
(+workspaces|init)
|
||||
(add-hook 'after-make-frame-functions #'+workspaces|init)))
|
||||
(add-hook 'emacs-startup-hook #'+workspaces|init)
|
||||
(add-hook 'after-make-frame-functions #'+workspaces|init)
|
||||
|
||||
(define-key persp-mode-map [remap delete-window] #'+workspace/close-window-or-workspace)
|
||||
|
||||
;; Spawn a perspective for each new frame
|
||||
(setq persp-init-new-frame-behaviour-override nil
|
||||
persp-interactive-init-frame-behaviour-override
|
||||
(lambda (frame &optional new-frame-p)
|
||||
(lambda (frame &optional _new-frame-p)
|
||||
(select-frame frame)
|
||||
(+workspace/new)
|
||||
(set-frame-parameter frame 'assoc-persp (+workspace-current-name))))
|
||||
|
||||
(defun +workspaces*delete-frame-and-persp (frame)
|
||||
"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))))
|
||||
(+workspace/delete persp-name)))
|
||||
(add-hook 'delete-frame-functions #'+workspaces*delete-frame-and-persp)
|
||||
|
Reference in New Issue
Block a user