From 68f7033322dcba3781dddb48465878e896a9f57b Mon Sep 17 00:00:00 2001 From: tam5 Date: Mon, 1 Apr 2019 15:06:59 -0400 Subject: optionally keep xml attributes --- evil-surround.el | 35 ++++++++++++++++++++++++++++++----- test/evil-surround-test.el | 10 ++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/evil-surround.el b/evil-surround.el index 91b6d1c..6eb3a11 100644 --- a/evil-surround.el +++ b/evil-surround.el @@ -88,13 +88,23 @@ Each item is of the form (OPERATOR . OPERATION)." (defvar evil-surround-read-tag-map (let ((map (copy-keymap minibuffer-local-map))) - (define-key map ">" 'exit-minibuffer) + (define-key map ">" (lambda () + (interactive) + (call-interactively 'self-insert-command) + (run-at-time nil nil + (lambda () + (when (active-minibuffer-window) + (select-window (active-minibuffer-window)) + (exit-minibuffer)))))) map) "Keymap used by `evil-surround-read-tag'.") (defvar evil-surround-record-repeat nil "Flag to indicate we're manually recording repeat info.") +(defvar evil-surround-last-deleted-left "" + "The previously deleted LEFT region.") + (defun evil-surround-read-from-minibuffer (&rest args) (when evil-surround-record-repeat (evil-repeat-keystrokes 'post)) @@ -124,13 +134,27 @@ Each item is of the form (OPERATOR . OPERATION)." (cons (format "%s(" (or fname "")) ")"))) +(defconst evil-surround-tag-name-re "\\([0-9a-z-]+\\)" + "Regexp matching an XML tag name.") + +(defun evil-surround-tag-p (string) + "Return t if `STRING' looks like a tag." + (string-match-p evil-surround-tag-name-re string)) + (defun evil-surround-read-tag () "Read a XML tag from the minibuffer." (let* ((input (evil-surround-read-from-minibuffer "<" "" evil-surround-read-tag-map)) - (match (string-match "\\([0-9a-z-]+\\)\\(.*?\\)[>]*$" input)) + (match (string-match (concat evil-surround-tag-name-re "\\(.*?\\)\\([>]*\\)$") input)) (tag (match-string 1 input)) - (rest (match-string 2 input))) - (cons (format "<%s%s>" (or tag "") (or rest "")) + (rest (match-string 2 input)) + (keep-attributes (not (string-match-p ">" input))) + (original-tag (when (evil-surround-tag-p evil-surround-last-deleted-left) + (substring evil-surround-last-deleted-left + (string-match (concat "<" evil-surround-tag-name-re) evil-surround-last-deleted-left) + (match-end 0)))) + (original-attributes (when (and keep-attributes original-tag) + (substring evil-surround-last-deleted-left (length original-tag))))) + (cons (format "<%s%s%s" (or tag "") (or rest "") (or original-attributes ">")) (format "" (or tag ""))))) (defun evil-surround-valid-char-p (char) @@ -217,7 +241,8 @@ between these overlays is what is deleted." (interactive (evil-surround-input-char)) (cond ((and outer inner) - (delete-region (overlay-start outer) (overlay-start inner)) + (setq evil-surround-last-deleted-left + (delete-and-extract-region (overlay-start outer) (overlay-start inner))) (delete-region (overlay-end inner) (overlay-end outer)) (goto-char (overlay-start outer))) (t diff --git a/test/evil-surround-test.el b/test/evil-surround-test.el index df71b11..c70f181 100644 --- a/test/evil-surround-test.el +++ b/test/evil-surround-test.el @@ -93,6 +93,16 @@ "tag1 tag2" ("W.") "tag1 tag2")) + (ert-info ("optionally keep xml attributes") + (evil-test-buffer + :visual-start nil + :visual-end nil + "
Bar
" + (turn-on-evil-surround-mode) + ("cstBar" + ("cst

") + "

Bar

")) (ert-info ("repeat surrounding") (evil-test-buffer "[o]ne two three" -- cgit v1.0