Moving to Doom Emacs!

This commit is contained in:
Derek Taylor
2019-12-16 20:21:19 -06:00
parent d9f2f456f1
commit d4b4c33550
683 changed files with 51877 additions and 100 deletions

View File

@@ -0,0 +1,198 @@
;;; editor/evil/autoload/advice.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +evil-escape-a (&rest _)
"Call `doom/escape' if `evil-force-normal-state' is called interactively."
(when (called-interactively-p 'any)
(call-interactively #'doom/escape)))
;;;###autoload
(defun +evil-resolve-vim-path-a (file-name)
"Take a path and resolve any vim-like filename modifiers in it. This adds
support for most vim file modifiers, as well as:
%:P Resolves to `doom-project-root'.
See http://vimdoc.sourceforge.net/htmldoc/cmdline.html#filename-modifiers for
more information on modifiers."
(let* (case-fold-search
(regexp (concat "\\(?:^\\|[^\\\\]\\)"
"\\([#%]\\)"
"\\(\\(?::\\(?:[PphtreS~.]\\|g?s[^:\t\n ]+\\)\\)*\\)"))
(matches
(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
(pcase (car (cdr match))
("%" (file-relative-name buffer-file-name))
("#" (save-excursion (other-window 1) (file-relative-name buffer-file-name))))))
flag global)
(if (not path)
(setq path "")
(while flags
(setq flag (pop flags))
(when (string-suffix-p "\\" flag)
(setq flag (concat flag (pop flags))))
(when (string-prefix-p "gs" flag)
(setq global t
flag (substring flag 1)))
(setq path
(or (pcase (substring flag 0 1)
("p" (expand-file-name path))
("~" (concat "~/" (file-relative-name path "~")))
("." (file-relative-name path default-directory))
("t" (file-name-nondirectory (directory-file-name path)))
("r" (file-name-sans-extension path))
("e" (file-name-extension path))
("S" (shell-quote-argument path))
("h"
(let ((parent (file-name-directory (expand-file-name path))))
(unless (equal (file-truename path)
(file-truename parent))
(if (file-name-absolute-p path)
(directory-file-name parent)
(file-relative-name parent)))))
("s"
(if (featurep 'evil)
(when-let (args (evil-delimited-arguments (substring flag 1) 2))
(let ((pattern (evil-transform-vim-style-regexp (car args)))
(replace (cadr args)))
(replace-regexp-in-string
(if global pattern (concat "\\(" pattern "\\).*\\'"))
(evil-transform-vim-style-regexp replace) path t t
(unless global 1))))
path))
("P"
(let ((project-root (doom-project-root (file-name-directory (expand-file-name path)))))
(unless project-root
(user-error "Not in a project"))
(abbreviate-file-name project-root)))
(_ path))
"")))
;; strip trailing slash, if applicable
(when (and (not (string= path "")) (equal (substring path -1) "/"))
(setq path (substring path 0 -1))))
(setq file-name
(replace-regexp-in-string
(format "\\(?:^\\|[^\\\\]\\)\\(%s\\)"
(regexp-quote (string-trim-left (car match))))
path file-name t t 1))))
(replace-regexp-in-string regexp "\\1" file-name t)))
(defun +evil--insert-newline (&optional above _noextranewline)
(let ((pos (save-excursion (beginning-of-line-text) (point)))
comment-auto-fill-only-comments)
(require 'smartparens)
(evil-narrow-to-field
(if above
(if (save-excursion (nth 4 (sp--syntax-ppss pos)))
(evil-save-goal-column
(setq evil-auto-indent nil)
(goto-char pos)
(let ((ws (abs (skip-chars-backward " \t"))))
;; FIXME oh god why
(save-excursion
(if comment-line-break-function
(funcall comment-line-break-function nil)
(comment-indent-new-line))
(when (and (derived-mode-p 'c-mode 'c++-mode 'objc-mode 'java-mode 'js2-mode)
(eq (char-after) ?/))
(insert "*"))
(insert
(make-string (max 0 (+ ws (skip-chars-backward " \t")))
32)))
(insert (make-string (max 1 ws) 32))))
(evil-move-beginning-of-line)
(insert (if use-hard-newlines hard-newline "\n"))
(forward-line -1)
(back-to-indentation))
(evil-move-end-of-line)
(cond ((sp-point-in-comment pos)
(setq evil-auto-indent nil)
(if comment-line-break-function
(funcall comment-line-break-function)
(comment-indent-new-line)))
;; TODO Find a better way to do this
((and (eq major-mode 'haskell-mode)
(fboundp 'haskell-indentation-newline-and-indent))
(setq evil-auto-indent nil)
(haskell-indentation-newline-and-indent))
(t
(insert (if use-hard-newlines hard-newline "\n"))
(back-to-indentation)))))))
;;;###autoload
(defun +evil--insert-newline-below-and-respect-comments-a (orig-fn count)
(if (or (not +evil-want-o/O-to-continue-comments)
(not (eq this-command 'evil-open-below))
(evil-insert-state-p))
(funcall orig-fn count)
(cl-letf (((symbol-function 'evil-insert-newline-below)
(lambda () (+evil--insert-newline))))
(let ((evil-auto-indent evil-auto-indent))
(funcall orig-fn count)))))
;;;###autoload
(defun +evil--insert-newline-above-and-respect-comments-a (orig-fn count)
(if (or (not +evil-want-o/O-to-continue-comments)
(not (eq this-command 'evil-open-above))
(evil-insert-state-p))
(funcall orig-fn count)
(cl-letf (((symbol-function 'evil-insert-newline-above)
(lambda () (+evil--insert-newline 'above))))
(let ((evil-auto-indent evil-auto-indent))
(funcall orig-fn count)))))
;;;###autoload (autoload '+evil-window-split-a "editor/evil/autoload/advice" nil t)
(evil-define-command +evil-window-split-a (&optional count file)
"Same as `evil-window-split', but correctly updates the window history."
:repeat nil
(interactive "P<f>")
;; HACK This ping-ponging between the destination and source windows is to
;; update the window focus history, so that, if you close either split
;; afterwards you won't be sent to some random window.
(let ((doom-inhibit-switch-window-hooks t)
(origwin (selected-window)))
(select-window (split-window origwin count 'below))
(unless evil-split-window-below
(select-window origwin))
(run-hooks 'doom-switch-window-hook))
(recenter)
(when (and (not count) evil-auto-balance-windows)
(balance-windows (window-parent)))
(if file (evil-edit file)))
;;;###autoload (autoload '+evil-window-vsplit-a "editor/evil/autoload/advice" nil t)
(evil-define-command +evil-window-vsplit-a (&optional count file)
"Same as `evil-window-split', but correctly updates the window history."
:repeat nil
(interactive "P<f>")
;; HACK This ping-ponging between the destination and source windows is to
;; update the window focus history, so that, if you close either split
;; afterwards you won't be sent to some random window.
(let ((doom-inhibit-switch-window-hooks t)
(origwin (selected-window)))
(select-window (split-window origwin count 'right))
(unless evil-vsplit-window-right
(select-window origwin))
(run-hooks 'doom-switch-window-hook))
(run-hooks)
(recenter)
(when (and (not count) evil-auto-balance-windows)
(balance-windows (window-parent)))
(if file (evil-edit file)))
;;;###autoload
(defun +evil--fix-dabbrev-in-minibuffer-h ()
"Make `try-expand-dabbrev' from `hippie-expand' work in minibuffer. See
`he-dabbrev-beg', so we need to redefine syntax for '/'."
(set-syntax-table (let* ((table (make-syntax-table)))
(modify-syntax-entry ?/ "." table)
table)))

View File

@@ -0,0 +1,39 @@
;;; editor/evil/autoload/embrace.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +evil--embrace-get-pair (char)
(if-let* ((pair (cdr-safe (assoc (string-to-char char) evil-surround-pairs-alist))))
pair
(if-let* ((pair (assoc-default char embrace--pairs-list)))
(if-let* ((real-pair (and (functionp (embrace-pair-struct-read-function pair))
(funcall (embrace-pair-struct-read-function pair)))))
real-pair
(cons (embrace-pair-struct-left pair) (embrace-pair-struct-right pair)))
(cons char char))))
;;;###autoload
(defun +evil--embrace-escaped ()
"Backslash-escaped surround character support for embrace."
(let ((char (read-char "\\")))
(if (eq char 27)
(cons "" "")
(let ((pair (+evil--embrace-get-pair (string char)))
(text (if (sp-point-in-string) "\\\\%s" "\\%s")))
(cons (format text (car pair))
(format text (cdr pair)))))))
;;;###autoload
(defun +evil--embrace-latex ()
"LaTeX command support for embrace."
(cons (format "\\%s{" (read-string "\\")) "}"))
;;;###autoload
(defun +evil--embrace-elisp-fn ()
"Elisp function support for embrace."
(cons (format "(%s " (or (read-string "(") "")) ")"))
;;;###autoload
(defun +evil--embrace-angle-brackets ()
"Type/generic angle brackets."
(cons (format "%s<" (or (read-string "") ""))
">"))

View File

@@ -0,0 +1,180 @@
;; editor/evil/autoload/evil.el -*- lexical-binding: t; -*-
;;;###autodef
(defun set-evil-initial-state! (modes state)
"Set the initialize STATE of MODES using `evil-set-initial-state'."
(declare (indent defun))
(after! evil
(if (listp modes)
(dolist (mode (doom-enlist modes))
(evil-set-initial-state mode state))
(evil-set-initial-state modes state))))
;;
;;; Interactive commands
;;;###autoload
(defun +evil/visual-indent ()
"vnoremap < <gv"
(interactive)
(evil-shift-right (region-beginning) (region-end))
(evil-normal-state)
(evil-visual-restore))
;;;###autoload
(defun +evil/visual-dedent ()
"vnoremap > >gv"
(interactive)
(evil-shift-left (region-beginning) (region-end))
(evil-normal-state)
(evil-visual-restore))
;;;###autoload
(defun +evil/paste-preserve-register ()
"Call `evil-paste-after' without overwriting the clipboard (by writing to the
0 register instead). This allows you to paste the same text again afterwards."
(interactive)
(let ((evil-this-register ?0))
(call-interactively #'evil-paste-after)))
(defun +evil--window-swap (direction)
"Move current window to the next window in DIRECTION.
If there are no windows there and there is only one window, split in that
direction and place this window there. If there are no windows and this isn't
the only window, use evil-window-move-* (e.g. `evil-window-move-far-left')."
(when (window-dedicated-p)
(user-error "Cannot swap a dedicated window"))
(let* ((this-window (selected-window))
(this-buffer (current-buffer))
(that-window (windmove-find-other-window direction nil this-window))
(that-buffer (window-buffer that-window)))
(when (or (minibufferp that-buffer)
(window-dedicated-p this-window))
(setq that-buffer nil that-window nil))
(if (not (or that-window (one-window-p t)))
(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
(pcase direction
('up 'above)
('down 'below)
(_ direction))))
(with-selected-window that-window
(switch-to-buffer (doom-fallback-buffer)))
(setq that-buffer (window-buffer that-window)))
(with-selected-window this-window
(switch-to-buffer that-buffer))
(with-selected-window that-window
(switch-to-buffer this-buffer))
(select-window that-window))))
;;;###autoload
(defun +evil/window-move-left () "See `+evil--window-swap'" (interactive) (+evil--window-swap 'left))
;;;###autoload
(defun +evil/window-move-right () "See `+evil--window-swap'" (interactive) (+evil--window-swap 'right))
;;;###autoload
(defun +evil/window-move-up () "See `+evil--window-swap'" (interactive) (+evil--window-swap 'up))
;;;###autoload
(defun +evil/window-move-down () "See `+evil--window-swap'" (interactive) (+evil--window-swap 'down))
;;;###autoload
(defun +evil/easymotion ()
"Invoke and lazy-load `evil-easymotion' without compromising which-key
integration."
(interactive)
(let ((prefix (this-command-keys)))
(evil-define-key* 'motion 'global prefix nil)
(evilem-default-keybindings (key-description prefix))
(setq prefix-arg current-prefix-arg
unread-command-events
(mapcar (lambda (e) (cons t e))
(vconcat (when evil-this-operator
(where-is-internal evil-this-operator
evil-normal-state-map
t))
prefix)))))
;;;###autoload (autoload '+evil:apply-macro "editor/evil/autoload/evil" nil t)
(evil-define-operator +evil:apply-macro (beg end)
"Apply macro to each line."
:move-point nil
(interactive "<r>")
(let ((register (or evil-this-register (read-char)))
macro)
(cond ((or (and (eq register ?@) (eq evil-last-register ?:))
(eq register ?:))
(setq macro (lambda () (evil-ex-repeat nil))
evil-last-register ?:))
((eq register ?@)
(unless evil-last-register
(user-error "No previously executed keyboard macro."))
(setq macro (evil-get-register evil-last-register t)))
((setq macro (evil-get-register register t)
evil-last-register register)))
(unless macro
(user-error "No macro recorded in %c register" register))
(evil-change-state 'normal)
(evil-with-single-undo
(let ((lines (count-lines beg end)))
(message "Applied macro in %c register %d times" register lines)
(apply-macro-to-region-lines beg end macro)
(message "Applied macro in %c register %d times...DONE" register lines)))))
;;;###autoload (autoload '+evil:retab "editor/evil/autoload/evil" nil t)
(evil-define-operator +evil:retab (&optional beg end)
"Wrapper around `doom/retab'."
:motion nil :move-point nil :type line
(interactive "<r>")
(doom/retab beg end))
;;;###autoload (autoload '+evil:narrow-buffer "editor/evil/autoload/evil" nil t)
(evil-define-operator +evil:narrow-buffer (beg end &optional bang)
"Narrow the buffer to region between BEG and END.
Widens narrowed buffers first. If BANG, use indirect buffer clones instead."
:move-point nil
(interactive "<r><!>")
(if (not bang)
(if (buffer-narrowed-p)
(widen)
(narrow-to-region beg end))
(when (buffer-narrowed-p)
(doom/widen-indirectly-narrowed-buffer t))
(doom/narrow-buffer-indirectly beg end)))
;;;###autoload (autoload '+evil:yank-unindented "editor/evil/autoload/evil" nil t)
(evil-define-operator +evil:yank-unindented (beg end _type _register _yank-handler)
"Saves the (reindented) characters in motion into the kill-ring."
:move-point nil
:repeat nil
(interactive "<R><x><y>")
(let ((indent (save-excursion (goto-char beg) (current-indentation)))
(text (buffer-substring beg end)))
(with-temp-buffer
(insert text)
(indent-rigidly (point-min) (point-max) (- indent))
(evil-yank (point-min) (point-max)))))
;;
;;; wgrep
;;;###autoload (autoload '+evil-delete "editor/evil/autoload/evil" nil t)
(evil-define-operator +evil-delete (beg end type register yank-handler)
"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
(evil-delete beg end type register yank-handler)
('text-read-only
(evil-apply-on-block
(lambda (beg _)
(goto-char beg)
(call-interactively #'wgrep-mark-deletion))
beg (1- end) nil))))

View File

@@ -0,0 +1,190 @@
;;; editor/evil/autoload/ex.el -*- lexical-binding: t; -*-
(defvar +evil--flag nil)
(defun +evil--ex-match-init (name &optional face update-hook)
(with-current-buffer evil-ex-current-buffer
(cond
((eq +evil--flag 'start)
(evil-ex-make-hl name
:face (or face 'evil-ex-lazy-highlight)
:update-hook (or update-hook #'evil-ex-pattern-update-ex-info))
(setq +evil--flag 'update))
((eq +evil--flag 'stop)
(evil-ex-delete-hl name)))))
(defun +evil--ex-buffer-match (arg &optional hl-name flags beg end)
(when (and (eq +evil--flag 'update)
evil-ex-substitute-highlight-all
(not (zerop (length arg))))
(condition-case lossage
(let* ((pattern (evil-ex-make-substitute-pattern
arg
(or flags (list))))
(range (or (evil-copy-range evil-ex-range)
(evil-range (or beg (line-beginning-position))
(or end (line-end-position))
'line
:expanded t))))
(evil-expand-range range)
(evil-ex-hl-set-region hl-name
(max (evil-range-beginning range) (window-start))
(min (evil-range-end range) (window-end)))
(evil-ex-hl-change hl-name pattern))
(end-of-file
(evil-ex-pattern-update-ex-info nil "incomplete replacement"))
(user-error
(evil-ex-pattern-update-ex-info nil (format "?%s" lossage))))))
;;;###autoload
(defun +evil-ex-regexp-match (flag &optional arg invert)
(let ((hl-name 'evil-ex-buffer-match)
(+evil--flag flag))
(with-selected-window (minibuffer-selected-window)
(+evil--ex-match-init hl-name)
(cl-destructuring-bind (&optional arg flags)
(evil-delimited-arguments arg 2)
(let ((evil-ex-substitute-global
(if invert
(not evil-ex-substitute-global)
evil-ex-substitute-global)))
(+evil--ex-buffer-match
arg hl-name (string-to-list flags)))))))
;;
;;; Ex Commands
;;;###autoload (autoload '+evil:align "editor/evil/autoload/ex" nil t)
(evil-define-command +evil:align (beg end pattern &optional flags)
"Ex interface to `align-regexp'.
PATTERN is a vim-style regexp. FLAGS is an optional string of characters.
Supports the following flags:
g Repeat alignment on all matches in each line"
(interactive "<r><//>")
(align-regexp
beg end
(concat "\\(\\s-*\\)" (evil-transform-vim-style-regexp pattern))
1 1 (memq ?g flags)))
;;;###autoload (autoload '+evil:align-right "editor/evil/autoload/ex" nil t)
(evil-define-command +evil:align-right (beg end pattern &optional flags)
"Ex interface to `align-regexp' that right-aligns matches.
PATTERN is a vim-style regexp. FLAGS is an optional string of characters.
Supports the following flags:
g Repeat alignment on all matches in each line"
(interactive "<r><//>")
(align-regexp
beg end
(concat "\\(" (evil-transform-vim-style-regexp pattern) "\\)")
-1 1 (memq ?g flags)))
;; ;;;###autoload (autoload '+evil:sort "editor/evil/autoload/ex" nil nil)
;; (evil-define-command +evil:sort (beg end &optional pattern flags reverse)
;; (interactive "<r><//><!>"))
;;;###autoload (autoload '+evil:open-scratch-buffer "editor/evil/autoload/ex" nil t)
(evil-define-operator +evil:open-scratch-buffer (bang)
(interactive "<!>")
(doom/open-scratch-buffer bang))
;;;###autoload (autoload '+evil:pwd "editor/evil/autoload/ex" nil t)
(evil-define-command +evil:pwd (bang)
"Display the current working directory. If BANG, copy it to your clipboard."
(interactive "<!>")
(if (not bang)
(pwd)
(kill-new default-directory)
(message "Copied to clipboard")))
;;;###autoload (autoload '+evil:make "editor/evil/autoload/ex" nil t)
(evil-define-command +evil:make (arguments &optional bang)
"Run make with ARGUMENTS.
If BANG is non-nil, open compilation output in a comint buffer.
If BANG, then run ARGUMENTS as a full command. This command understands vim file
modifiers (like %:p:h). See `+evil-resolve-vim-path-a' for details."
(interactive "<sh><!>")
(+evil:compile (format "make %s"
(evil-ex-replace-special-filenames
arguments))
bang))
;;;###autoload (autoload '+evil:compile "editor/evil/autoload/ex" nil t)
(evil-define-command +evil:compile (arguments &optional bang)
"Run `compile-command' with ARGUMENTS.
If BANG is non-nil, open compilation output in a comint buffer.
This command understands vim file modifiers (like %:p:h). See
`+evil-resolve-vim-path-a' for details."
(interactive "<sh><!>")
(compile (evil-ex-replace-special-filenames
(format "%s %s"
(eval compile-command)
arguments))
bang))
;;;###autoload (autoload '+evil:reverse-lines "editor/evil/autoload/ex" nil t)
(evil-define-command +evil:reverse-lines (beg end)
"Reverse lines between BEG and END."
(interactive "<r>")
(reverse-region beg end))
;;;###autoload (autoload '+evil:cd "editor/evil/autoload/ex" nil t)
(evil-define-command +evil:cd (&optional path)
"Change `default-directory' with `cd'."
(interactive "<f>")
(let ((path (or path "~")))
(cd path)
(message "Changed directory to '%s'" (abbreviate-file-name (expand-file-name path)))))
;;;###autoload (autoload '+evil:kill-all-buffers "editor/evil/autoload/ex" nil t)
(evil-define-command +evil:kill-all-buffers (&optional bang)
"Kill all buffers. If BANG, kill current session too."
(interactive "<!>")
(if (and bang (fboundp '+workspace/kill-session))
(+workspace/kill-session)
(call-interactively #'doom/kill-all-buffers)))
;;;###autoload (autoload '+evil:kill-matching-buffers "editor/evil/autoload/ex" nil t)
(evil-define-command +evil:kill-matching-buffers (&optional bang pattern)
"Kill all buffers matching PATTERN regexp. If BANG, only match project
buffers."
(interactive "<a>")
(doom/kill-matching-buffers
pattern (if bang (doom-project-buffer-list))))
;;;###autoload (autoload '+evil:help "editor/evil/autoload/ex" nil t)
(evil-define-command +evil:help (&optional bang query)
"Look up documentation for QUERY.
If QUERY is in the format of an ex command, it will map it to the underlying
function and open its documentation with `helpful-function'. Otherwise, it will
search for it with `apropos'.
If QUERY is empty, this runs the equivalent of 'M-x apropos'. If BANG is
non-nil, a search is preformed against Doom's manual (with `doom/help-search')."
(interactive "<!><a>")
(if bang
(doom/help-search query)
(save-match-data
(cond ((or (null query) (string-empty-p (string-trim query)))
(call-interactively
(or (command-remapping #'apropos)
#'apropos)))
((string-match "^ *:\\([^ ]+\\)$" query)
(helpful-function
(evil-ex-completed-binding (match-string 1 query))))
((message "Searching for %S, this may take a while..." query)
(apropos query t))))))
;;;###autoload (autoload '+evil:read "editor/evil/autoload/ex" nil t)
(evil-define-command +evil:read (count file)
"Alternative version of `evil-read' that replaces filename modifiers in FILE."
(interactive "P<fsh>")
(evil-read count (evil-ex-replace-special-filenames file)))

View File

@@ -0,0 +1,33 @@
;;; editor/evil/autoload/files.el -*- lexical-binding: t; -*-
;;;###autoload (autoload '+evil:delete-this-file "editor/evil/autoload/files" nil t)
(evil-define-command +evil:delete-this-file (&optional filename force-p)
"Delete FILENAME (defaults to the file associated with current buffer) and
kills the buffer. If FORCE-P, force the deletion (don't ask for confirmation)."
:repeat nil
(interactive "<f><!>")
(doom/delete-this-file (or filename (file-truename buffer-file-name))
force-p))
;;;###autoload (autoload '+evil:move-this-file "editor/evil/autoload/files" nil t)
(evil-define-command +evil:move-this-file (new-path &optional force-p)
"Move current buffer's file to NEW-PATH. Replaces %, # and other vim-esque
filename modifiers (see `+evil*ex-replace-special-filenames'). If FORCE-P,
overwrite the destination file if it exists, without confirmation."
:repeat nil
(interactive "<f><!>")
(when (or (not new-path) (string-empty-p new-path))
(user-error "No new path was specified"))
(doom/move-this-file new-path force-p))
;;;###autoload (autoload '+evil:copy-this-file "editor/evil/autoload/files" nil nil)
(evil-define-command +evil:copy-this-file (new-path &optional force-p)
"Copy current buffer's file to NEW-PATH. Replaces %, # and other vim-esque
filename modifiers (see `+evil*ex-replace-special-filenames'). If FORCE-P,
overwrite the destination file if it exists, without confirmation."
:repeat nil
(interactive "<f><!>")
(when (or (not new-path) (string-empty-p new-path))
(user-error "No new path was specified"))
(doom/copy-this-file new-path force-p))

View File

@@ -0,0 +1,13 @@
;;; editor/evil/autoload/textobjects.el -*- lexical-binding: t; -*-
;;;###autoload (autoload '+evil:whole-buffer-txtobj "editor/evil/autoload/textobjects" nil nil)
(evil-define-text-object +evil:whole-buffer-txtobj (count &optional _beg _end type)
"Text object to select the whole buffer."
(evil-range (point-min) (point-max) type))
;;;###autoload (autoload '+evil:defun-txtobj "editor/evil/autoload/textobjects" nil nil)
(evil-define-text-object +evil:defun-txtobj (count &optional _beg _end type)
"Text object to select the whole buffer."
(cl-destructuring-bind (beg . end)
(bounds-of-thing-at-point 'defun)
(evil-range beg end type)))

View File

@@ -0,0 +1,200 @@
;;; editor/evil/autoload/unimpaired.el -*- lexical-binding: t; -*-
;; These are ported from vim-unimpaired https://github.com/tpope/vim-unimpaired
;; and bound in the :config default module (in +evil-bindings.el).
;;
;;; Next/Previous commands
;;;###autoload
(defun +evil/next-beginning-of-method (count)
"Jump to the beginning of the COUNT-th method/function after point."
(interactive "p")
(beginning-of-defun (- count)))
;;;###autoload
(defun +evil/previous-beginning-of-method (count)
"Jump to the beginning of the COUNT-th method/function before point."
(interactive "p")
(beginning-of-defun count))
;;;###autoload
(defalias #'+evil/next-end-of-method #'end-of-defun
"Jump to the end of the COUNT-th method/function after point.")
;;;###autoload
(defun +evil/previous-end-of-method (count)
"Jump to the end of the COUNT-th method/function before point."
(interactive "p")
(end-of-defun (- count)))
;;;###autoload
(defun +evil/next-preproc-directive (count)
"Jump to the COUNT-th preprocessor directive after point.
By default, this only recognizes C preproc directives. To change this see
`+evil-preprocessor-regexp'."
(interactive "p")
;; TODO More generalized search, to support directives in other languages?
(if (re-search-forward +evil-preprocessor-regexp nil t count)
(goto-char (match-beginning 0))
(user-error "No preprocessor directives %s point"
(if (> count 0) "after" "before"))))
;;;###autoload
(defun +evil/previous-preproc-directive (count)
"Jump to the COUNT-th preprocessor directive before point.
See `+evil/next-preproc-directive' for details."
(interactive "p")
(+evil/next-preproc-statement (- count)))
;;;###autoload
(defun +evil/next-comment (count)
"Jump to the beginning of the COUNT-th commented region after point."
(interactive "p")
(let ((orig-pt (point)))
(require 'newcomment)
(dotimes (_ (abs count))
(cond ((> count 0)
(while (and (not (eobp)) (sp-point-in-comment))
(forward-line 1))
(unless (comment-search-forward (point-max) 'noerror)
(goto-char orig-pt)
(user-error "No comment after point")))
(t
(while (and (not (bobp)) (sp-point-in-comment))
(forward-line -1))
(unless (comment-search-backward nil 'noerror)
(goto-char orig-pt)
(user-error "No comment before point")))))))
;;;###autoload
(defun +evil/previous-comment (count)
"Jump to the beginning of the COUNT-th commented region before point."
(interactive "p")
(+evil/next-comment (- count)))
;;; ] SPC / [ SPC
;;;###autoload
(defun +evil/insert-newline-below (count)
"Insert COUNT blank line(s) below current line. Does not change modes."
(interactive "p")
(dotimes (_ count)
(save-excursion (evil-insert-newline-below))))
;;;###autoload
(defun +evil/insert-newline-above (count)
"Insert COUNT blank line(s) above current line. Does not change modes."
(interactive "p")
(dotimes (_ count)
(save-excursion (evil-insert-newline-above))))
;;; ]t / [t
;;;###autoload
(defun +evil/next-frame (count)
"Focus next frame."
(interactive "p")
(dotimes (_ (abs count))
(let ((frame (if (> count 0) (next-frame) (previous-frame))))
(if (eq frame (selected-frame))
(user-error "No other frame")
(select-frame-set-input-focus frame)))))
;;;###autoload
(defun +evil/previous-frame (count)
"Focus previous frame."
(interactive "p")
(+evil/next-frame (- count)))
;;; ]f / [f
(defun +evil--next-file (n)
(unless buffer-file-name
(user-error "Must be called from a file-visiting buffer"))
(let* ((directory (file-name-directory buffer-file-name))
(filename (file-name-nondirectory buffer-file-name))
(files (doom-glob (file-name-directory buffer-file-name) "[!.]*"))
(index (cl-position filename files :test #'file-equal-p)))
(when (null index)
(user-error "Couldn't find this file in current directory"))
(let ((index (+ index n)))
(cond ((>= index (length files))
(user-error "No files after this one"))
((< index 0)
(user-error "No files before this one"))
((expand-file-name (nth index files) directory))))))
;;;###autoload
(defun +evil/next-file (count)
"Open file following this one, alphabetically, in the same directory."
(interactive "p")
(find-file (+evil--next-file count)))
;;;###autoload
(defun +evil/previous-file (count)
"Open file preceding this one, alphabetically, in the same directory."
(interactive "p")
(find-file (+evil--next-file (- count))))
;;
;;; Encoding/Decoding
;; NOTE For ]x / [x see :lang web
;; - `+web:encode-html-entities'
;; - `+web:decode-html-entities'
(defun +evil--encode (beg end fn)
(save-excursion
(goto-char beg)
(let* ((end (if (eq evil-this-type 'line) (1- end) end))
(text (buffer-substring-no-properties beg end)))
(delete-region beg end)
(insert (funcall fn text)))))
;;; ]u / [u
;;;###autoload (autoload '+evil:url-encode "editor/evil/autoload/unimpaired" nil t)
(evil-define-operator +evil:url-encode (_count &optional beg end)
"TODO"
(interactive "<c><r>")
(+evil--encode beg end #'url-encode-url))
;;;###autoload (autoload '+evil:url-decode "editor/evil/autoload/unimpaired" nil t)
(evil-define-operator +evil:url-decode (_count &optional beg end)
"TODO"
(interactive "<c><r>")
(+evil--encode beg end #'url-unhex-string))
;;; ]y / [y
;;;###autoload (autoload '+evil:c-string-encode "editor/evil/autoload/unimpaired" nil t)
(evil-define-operator +evil:c-string-encode (_count &optional beg end)
"TODO"
(interactive "<c><r>")
(+evil--encode
beg end
(lambda (text)
(replace-regexp-in-string "[\"\\]" (lambda (ch) (concat "\\" ch)) text))))
;;;###autoload (autoload '+evil:c-string-decode "editor/evil/autoload/unimpaired" nil t)
(evil-define-operator +evil:c-string-decode (_count &optional beg end)
"TODO"
(interactive "<c><r>")
(+evil--encode
beg end
(lambda (text)
(replace-regexp-in-string "\\\\[\"\\]" (lambda (str) (substring str 1)) text))))
;;
;;; Standalone
;;; gp
;;;###autoload
(defun +evil/reselect-paste ()
"Return to visual mode and reselect the last pasted region."
(interactive)
(cl-destructuring-bind (_ _ _ beg end &optional _)
evil-last-paste
(evil-visual-make-selection
(save-excursion (goto-char beg) (point-marker))
end)))