From 18554ca5b52ecb283273f72a70eb518a8c274919 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 7 Sep 2018 22:02:41 -0400 Subject: [PATCH] feature/evil: extract advice functions Into its own autoloads file, for better organization. --- modules/feature/evil/autoload/advice.el | 179 ++++++++++++++++++++++++ modules/feature/evil/autoload/evil.el | 155 ++------------------ modules/feature/evil/config.el | 57 +------- 3 files changed, 195 insertions(+), 196 deletions(-) create mode 100644 modules/feature/evil/autoload/advice.el diff --git a/modules/feature/evil/autoload/advice.el b/modules/feature/evil/autoload/advice.el new file mode 100644 index 000000000..8f9a97158 --- /dev/null +++ b/modules/feature/evil/autoload/advice.el @@ -0,0 +1,179 @@ +;;; feature/evil/autoload/advice.el -*- lexical-binding: t; -*- + +;;;###autoload +(defun +evil*insert-newline-below-and-respect-comments (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 () + (let ((pos (save-excursion (beginning-of-line-text) (point)))) + (evil-narrow-to-field + (evil-move-end-of-line) + (require 'smartparens) + (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))) + (t + (insert (if use-hard-newlines hard-newline "\n")) + (back-to-indentation)))))))) + (let ((evil-auto-indent evil-auto-indent)) + (funcall orig-fn count))))) + +;;;###autoload +(defun +evil*insert-newline-above-and-respect-comments (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 () + (let ((pos (save-excursion (beginning-of-line-text) (point)))) + (evil-narrow-to-field + (require 'smartparens) + (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) + (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))))))) + (let ((evil-auto-indent evil-auto-indent)) + (funcall orig-fn count))))) + +;;;###autoload +(defun +evil*static-reindent (orig-fn &rest args) + "Don't move cursor on indent." + (save-excursion (apply orig-fn args))) + +;;;###autoload +(defun +evil*resolve-vim-path (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 ((default-directory (file-name-directory (expand-file-name path)))) + (abbreviate-file-name (doom-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))) + +;;;###autoload (autoload '+evil*window-split "feature/evil/autoload/advice" nil t) +(evil-define-command +evil*window-split (&optional count file) + "Same as `evil-window-split', but focuses (and recenters) the new split." + :repeat nil + (interactive "P") + (split-window (selected-window) count + (if evil-split-window-below 'above 'below)) + (call-interactively + (if evil-split-window-below + #'evil-window-up + #'evil-window-down)) + (recenter) + (when (and (not count) evil-auto-balance-windows) + (balance-windows (window-parent))) + (if file (evil-edit file))) + +;;;###autoload (autoload '+evil*window-vsplit "feature/evil/autoload/advice" nil t) +(evil-define-command +evil*window-vsplit (&optional count file) + "Same as `evil-window-vsplit', but focuses (and recenters) the new split." + :repeat nil + (interactive "P") + (split-window (selected-window) count + (if evil-vsplit-window-right 'left 'right)) + (call-interactively + (if evil-vsplit-window-right + #'evil-window-left + #'evil-window-right)) + (recenter) + (when (and (not count) evil-auto-balance-windows) + (balance-windows (window-parent))) + (if file (evil-edit file))) + +;;;###autoload +(defun +evil*escape (&rest _) + "Call `doom/escape' if `evil-force-normal-state' is called interactively." + (when (called-interactively-p 'any) + (call-interactively #'doom/escape))) diff --git a/modules/feature/evil/autoload/evil.el b/modules/feature/evil/autoload/evil.el index f15c13b11..8893d5a94 100644 --- a/modules/feature/evil/autoload/evil.el +++ b/modules/feature/evil/autoload/evil.el @@ -100,6 +100,21 @@ evil-window-move-* (e.g. `evil-window-move-far-left')" ;;;###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 prefix) + (which-key-reload-key-sequence + (vconcat (when evil-this-operator + (where-is-internal evil-this-operator + evil-normal-state-map + t)) + prefix)))) + ;; ;; Evil commands/operators @@ -243,143 +258,3 @@ the first match on each line)." (goto-char beg) (call-interactively #'wgrep-mark-deletion)) beg (1- end) nil)))) - - -;; -;; Advice -;; - -;;;###autoload -(defun +evil*static-reindent (orig-fn &rest args) - "Don't move cursor on indent." - (save-excursion (apply orig-fn args))) - -;;;###autoload -(defun +evil*resolve-vim-path (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 ((default-directory (file-name-directory (expand-file-name path)))) - (abbreviate-file-name (doom-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))) - -;;;###autoload (autoload '+evil*window-split "feature/evil/autoload/evil" nil t) -(evil-define-command +evil*window-split (&optional count file) - "Same as `evil-window-split', but focuses (and recenters) the new split." - :repeat nil - (interactive "P") - (split-window (selected-window) count - (if evil-split-window-below 'above 'below)) - (call-interactively - (if evil-split-window-below - #'evil-window-up - #'evil-window-down)) - (recenter) - (when (and (not count) evil-auto-balance-windows) - (balance-windows (window-parent))) - (if file (evil-edit file))) - -;;;###autoload (autoload '+evil*window-vsplit "feature/evil/autoload/evil" nil t) -(evil-define-command +evil*window-vsplit (&optional count file) - "Same as `evil-window-vsplit', but focuses (and recenters) the new split." - :repeat nil - (interactive "P") - (split-window (selected-window) count - (if evil-vsplit-window-right 'left 'right)) - (call-interactively - (if evil-vsplit-window-right - #'evil-window-left - #'evil-window-right)) - (recenter) - (when (and (not count) evil-auto-balance-windows) - (balance-windows (window-parent))) - (if file (evil-edit file))) - -;;;###autoload -(defun +evil*escape (&rest _) - "Call `doom/escape' if `evil-force-normal-state' is called interactively." - (when (called-interactively-p 'any) - (call-interactively #'doom/escape))) - -;;;###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 prefix) - (which-key-reload-key-sequence - (vconcat (when evil-this-operator - (where-is-internal evil-this-operator - evil-normal-state-map - t)) - prefix)))) diff --git a/modules/feature/evil/config.el b/modules/feature/evil/config.el index 4ea48d95e..6d804abd2 100644 --- a/modules/feature/evil/config.el +++ b/modules/feature/evil/config.el @@ -137,63 +137,8 @@ line with a linewise comment.") (funcall orig-fn char))) (advice-add #'evil-global-marker-p :around #'+evil*make-numbered-markers-global) - ;; Make o/O continue comments - (defun +evil*insert-newline-above-and-respect-comments (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 () - (let ((pos (save-excursion (beginning-of-line-text) (point)))) - (evil-narrow-to-field - (require 'smartparens) - (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) - (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))))))) - (let ((evil-auto-indent evil-auto-indent)) - (funcall orig-fn count))))) + ;; Make o/O continue comments (see `+evil-want-o/O-to-continue-comments') (advice-add #'evil-open-above :around #'+evil*insert-newline-above-and-respect-comments) - - (defun +evil*insert-newline-below-and-respect-comments (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 () - (let ((pos (save-excursion (beginning-of-line-text) (point)))) - (evil-narrow-to-field - (evil-move-end-of-line) - (require 'smartparens) - (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))) - (t - (insert (if use-hard-newlines hard-newline "\n")) - (back-to-indentation)))))))) - (let ((evil-auto-indent evil-auto-indent)) - (funcall orig-fn count))))) (advice-add #'evil-open-below :around #'+evil*insert-newline-below-and-respect-comments) ;; --- custom interactive codes -----------