214 lines
9.9 KiB
EmacsLisp
214 lines
9.9 KiB
EmacsLisp
;;; 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-replace-filename-modifiers-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 ((origin-buffer (current-buffer))
|
|
case-fold-search)
|
|
(with-temp-buffer
|
|
(let ((buffer-file-name (buffer-file-name origin-buffer)))
|
|
(save-excursion (insert file-name))
|
|
(while (re-search-forward "\\(^\\|[^\\\\]\\)\\(\\([%#]\\)\\(:\\([PphtreS~.]\\|g?s\\)\\)*\\)" nil t)
|
|
(if (null buffer-file-name)
|
|
(replace-match (match-string 1) t t nil 2)
|
|
(let ((beg (match-beginning 2))
|
|
(end (match-end 3))
|
|
(path (pcase (match-string 3)
|
|
("%" (file-relative-name buffer-file-name default-directory))
|
|
("#" (and (other-buffer origin-buffer)
|
|
(buffer-file-name (other-buffer origin-buffer)))))))
|
|
(save-match-data
|
|
(goto-char beg)
|
|
(while (re-search-forward ":\\([PphtreS~.]\\|g?s\\)" (+ (point) 3) t)
|
|
(let* ((modifier (match-string 1))
|
|
(global (string-prefix-p "gs" modifier)))
|
|
(when global
|
|
(setq modifier (substring modifier 1)))
|
|
(setq end (match-end 1)
|
|
path
|
|
(pcase (and path (substring modifier 0 1))
|
|
(`nil "")
|
|
("p" (expand-file-name path))
|
|
("~" (concat "~/" (file-relative-name path "~")))
|
|
("." (file-relative-name path))
|
|
("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 (file-equal-p path 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 modifier 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)))))
|
|
;; strip trailing slash, if applicable
|
|
(or (string-empty-p path)
|
|
(not (equal (substring path -1) "/"))
|
|
(setq path (substring path 0 -1))))))
|
|
(replace-match path t t nil 2))))
|
|
(replace-regexp-in-string "\\\\\\([#%]\\)" "\\1" (buffer-string) 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 nil)
|
|
(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 (fn count)
|
|
(if (or (not +evil-want-o/O-to-continue-comments)
|
|
(not (eq this-command 'evil-open-below))
|
|
(evil-insert-state-p)
|
|
(evil-emacs-state-p))
|
|
(funcall fn count)
|
|
(letf! (defun evil-insert-newline-below () (+evil--insert-newline))
|
|
(let ((evil-auto-indent evil-auto-indent))
|
|
(funcall fn count)))))
|
|
|
|
;;;###autoload
|
|
(defun +evil--insert-newline-above-and-respect-comments-a (fn count)
|
|
(if (or (not +evil-want-o/O-to-continue-comments)
|
|
(not (eq this-command 'evil-open-above))
|
|
(evil-insert-state-p)
|
|
(evil-emacs-state-p))
|
|
(funcall fn count)
|
|
(letf! (defun evil-insert-newline-above () (+evil--insert-newline 'above))
|
|
(let ((evil-auto-indent evil-auto-indent))
|
|
(funcall 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 (autoload '+evil-join-a "editor/evil/autoload/advice" nil nil)
|
|
(defun +evil-join-a (fn beg end)
|
|
"Join the selected lines.
|
|
|
|
This advice improves on `evil-join' by removing comment delimiters when joining
|
|
commented lines, by using `fill-region-as-paragraph'.
|
|
|
|
From https://github.com/emacs-evil/evil/issues/606"
|
|
;; But revert to the default we're not in a comment, where
|
|
;; `fill-region-as-paragraph' is too greedy.
|
|
(if (not (doom-point-in-comment-p (min (max beg (1+ (point))) end)))
|
|
(funcall fn beg end)
|
|
(let* ((count (count-lines beg end))
|
|
(count (if (> count 1) (1- count) count))
|
|
(fixup-mark (make-marker)))
|
|
(unwind-protect
|
|
(dotimes (var count)
|
|
(if (and (bolp) (eolp))
|
|
(join-line 1)
|
|
(let* ((end (line-beginning-position 3))
|
|
(fill-column (1+ (- end beg))))
|
|
(set-marker fixup-mark (line-end-position))
|
|
(fill-region-as-paragraph beg end nil t)
|
|
(goto-char fixup-mark)
|
|
(fixup-whitespace))))
|
|
(set-marker fixup-mark nil)))))
|
|
|
|
;;;###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)))
|