From 1a64b7dfece4357df0b0d96929225057951fe781 Mon Sep 17 00:00:00 2001 From: Dave Mayo Date: Mon, 5 Sep 2016 23:53:01 -0400 Subject: Added multi-line * wrap functionality as per #81 This is a proof-of-concept - it needs to do the token-replacement jazz the original version did, because right now this will fail if the content of the txt/lines includes unmatched braces in various configurations. I think the overall plan is sound: split expression into leading and terminal components, render the text as a list (either a one-element list of all text or a multiline list, depending on trailing *), and create a terminal phrase consisting of "terminal-element{TOKEN}" joined on "+" To do: render list into a-list of '((hash-of-txt . txt), ...), mapconcat the hash replacement instead of the text, then run replace over result. Write tests. Also, tests appear to be broken on master, at least on my machine. --- emmet-mode.el | 23 +++++++++++++++-------- src/mode-def.el | 23 +++++++++++++++-------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/emmet-mode.el b/emmet-mode.el index 5c2bdee..2e03c94 100644 --- a/emmet-mode.el +++ b/emmet-mode.el @@ -172,7 +172,7 @@ and leaving the point in place." "Find the left bound of an emmet expr" (save-excursion (save-match-data (let ((char (char-before)) - (in-style-attr (looking-back "style=[\"'][^\"']*")) + (in-style-attr (looking-back "style=[\"'][^\"']*" nil)) (syn-tab (make-syntax-table))) (modify-syntax-entry ?\\ "\\") (while char @@ -627,12 +627,20 @@ accept it or skip it." (defun emmet-wrap-with-markup (wrap-with) "Wrap region with markup." (interactive "sExpression to wrap with: ") - (let* ((to-wrap (buffer-substring-no-properties (region-beginning) (region-end))) - (expr (concat wrap-with ">{!EMMET-TO-WRAP-REPLACEMENT!}")) - (markup (replace-regexp-in-string - "!EMMET-TO-WRAP-REPLACEMENT!" to-wrap - (emmet-transform expr) - t t))) + (let* ((multi (string-match "\\*$" wrap-with)) + (txt (buffer-substring-no-properties (region-beginning) (region-end))) + (to-wrap (if multi + (split-string txt "\n") + (list txt))) + (initial-elements (replace-regexp-in-string "\\(.*>\\)?[^>*]+\\*?$" "\\1" wrap-with)) + (terminal-element (replace-regexp-in-string "\\(.*>\\)?\\([^>*]+\\)\\*?$" "\\2" wrap-with)) + (expr (concat + initial-elements + (mapconcat (lambda (el) (concat terminal-element "{" el "}")) to-wrap "+"))) + + (markup (emmet-transform expr)) + (debug-shit (message "initial-elements: %s\nterminal-element: %s\n expr: %s\n markup: %s" initial-elements terminal-element expr markup)) + ) (when markup (delete-region (region-beginning) (region-end)) (insert markup) @@ -656,7 +664,6 @@ accept it or skip it." (error "First edit point reached."))) (provide 'emmet-mode) - ;; src/snippets.el ;; This file is generated from conf/snippets.json ;; Don't edit. diff --git a/src/mode-def.el b/src/mode-def.el index 104ace2..1b4358e 100644 --- a/src/mode-def.el +++ b/src/mode-def.el @@ -19,7 +19,7 @@ "Find the left bound of an emmet expr" (save-excursion (save-match-data (let ((char (char-before)) - (in-style-attr (looking-back "style=[\"'][^\"']*")) + (in-style-attr (looking-back "style=[\"'][^\"']*" nil)) (syn-tab (make-syntax-table))) (modify-syntax-entry ?\\ "\\") (while char @@ -474,12 +474,20 @@ accept it or skip it." (defun emmet-wrap-with-markup (wrap-with) "Wrap region with markup." (interactive "sExpression to wrap with: ") - (let* ((to-wrap (buffer-substring-no-properties (region-beginning) (region-end))) - (expr (concat wrap-with ">{!EMMET-TO-WRAP-REPLACEMENT!}")) - (markup (replace-regexp-in-string - "!EMMET-TO-WRAP-REPLACEMENT!" to-wrap - (emmet-transform expr) - t t))) + (let* ((multi (string-match "\\*$" wrap-with)) + (txt (buffer-substring-no-properties (region-beginning) (region-end))) + (to-wrap (if multi + (split-string txt "\n") + (list txt))) + (initial-elements (replace-regexp-in-string "\\(.*>\\)?[^>*]+\\*?$" "\\1" wrap-with)) + (terminal-element (replace-regexp-in-string "\\(.*>\\)?\\([^>*]+\\)\\*?$" "\\2" wrap-with)) + (expr (concat + initial-elements + (mapconcat (lambda (el) (concat terminal-element "{" el "}")) to-wrap "+"))) + + (markup (emmet-transform expr)) + (debug-shit (message "initial-elements: %s\nterminal-element: %s\n expr: %s\n markup: %s" initial-elements terminal-element expr markup)) + ) (when markup (delete-region (region-beginning) (region-end)) (insert markup) @@ -503,4 +511,3 @@ accept it or skip it." (error "First edit point reached."))) (provide 'emmet-mode) - -- cgit v1.2.3 From ae7d5a2588ea5f8a48eda1c9d190ff06073e555b Mon Sep 17 00:00:00 2001 From: Dave Mayo Date: Tue, 6 Sep 2016 00:47:44 -0400 Subject: Implement token-replacement in new wrap * function It itched at me, so I cleaned it up and rewrote to make it do the token replacement. Would be more performant to do the sha1 once, but realistically, it's not going to be meaningfully slow for the use-case. This is essentially complete, but needs tests - I'll add them as soon as I can get testing working on my computer. --- emmet-mode.el | 39 +++++++++++++++++++++++---------------- src/mode-def.el | 39 +++++++++++++++++++++++---------------- 2 files changed, 46 insertions(+), 32 deletions(-) diff --git a/emmet-mode.el b/emmet-mode.el index 2e03c94..92542f4 100644 --- a/emmet-mode.el +++ b/emmet-mode.el @@ -632,24 +632,31 @@ accept it or skip it." (to-wrap (if multi (split-string txt "\n") (list txt))) - (initial-elements (replace-regexp-in-string "\\(.*>\\)?[^>*]+\\*?$" "\\1" wrap-with)) - (terminal-element (replace-regexp-in-string "\\(.*>\\)?\\([^>*]+\\)\\*?$" "\\2" wrap-with)) + (initial-elements (replace-regexp-in-string "\\(.*>\\)?[^>*]+\\*?$" "\\1" wrap-with t)) + (terminal-element (replace-regexp-in-string "\\(.*>\\)?\\([^>*]+\\)\\*?$" "\\2" wrap-with t)) (expr (concat initial-elements - (mapconcat (lambda (el) (concat terminal-element "{" el "}")) to-wrap "+"))) - - (markup (emmet-transform expr)) - (debug-shit (message "initial-elements: %s\nterminal-element: %s\n expr: %s\n markup: %s" initial-elements terminal-element expr markup)) - ) - (when markup - (delete-region (region-beginning) (region-end)) - (insert markup) - (indent-region (region-beginning) (region-end)) - (let ((end (region-end))) - (goto-char (region-beginning)) - (unless (ignore-errors (progn (emmet-next-edit-point 1) t)) - (goto-char end))) - ))) + (mapconcat (lambda (el) (concat terminal-element "{!!!" (secure-hash 'sha1 el) "!!!}")) + to-wrap + "+"))) + (markup + (reduce + (lambda (result text) + (replace-regexp-in-string + (concat "!!!" (secure-hash 'sha1 text) "!!!") + text + result t t)) + to-wrap + :initial-value (emmet-transform expr)))) + (when markup + (delete-region (region-beginning) (region-end)) + (insert markup) + (indent-region (region-beginning) (region-end)) + (let ((end (region-end))) + (goto-char (region-beginning)) + (unless (ignore-errors (progn (emmet-next-edit-point 1) t)) + (goto-char end))) + ))) ;;;###autoload (defun emmet-next-edit-point (count) diff --git a/src/mode-def.el b/src/mode-def.el index 1b4358e..0f3a522 100644 --- a/src/mode-def.el +++ b/src/mode-def.el @@ -479,24 +479,31 @@ accept it or skip it." (to-wrap (if multi (split-string txt "\n") (list txt))) - (initial-elements (replace-regexp-in-string "\\(.*>\\)?[^>*]+\\*?$" "\\1" wrap-with)) - (terminal-element (replace-regexp-in-string "\\(.*>\\)?\\([^>*]+\\)\\*?$" "\\2" wrap-with)) + (initial-elements (replace-regexp-in-string "\\(.*>\\)?[^>*]+\\*?$" "\\1" wrap-with t)) + (terminal-element (replace-regexp-in-string "\\(.*>\\)?\\([^>*]+\\)\\*?$" "\\2" wrap-with t)) (expr (concat initial-elements - (mapconcat (lambda (el) (concat terminal-element "{" el "}")) to-wrap "+"))) - - (markup (emmet-transform expr)) - (debug-shit (message "initial-elements: %s\nterminal-element: %s\n expr: %s\n markup: %s" initial-elements terminal-element expr markup)) - ) - (when markup - (delete-region (region-beginning) (region-end)) - (insert markup) - (indent-region (region-beginning) (region-end)) - (let ((end (region-end))) - (goto-char (region-beginning)) - (unless (ignore-errors (progn (emmet-next-edit-point 1) t)) - (goto-char end))) - ))) + (mapconcat (lambda (el) (concat terminal-element "{!!!" (secure-hash 'sha1 el) "!!!}")) + to-wrap + "+"))) + (markup + (reduce + (lambda (result text) + (replace-regexp-in-string + (concat "!!!" (secure-hash 'sha1 text) "!!!") + text + result t t)) + to-wrap + :initial-value (emmet-transform expr)))) + (when markup + (delete-region (region-beginning) (region-end)) + (insert markup) + (indent-region (region-beginning) (region-end)) + (let ((end (region-end))) + (goto-char (region-beginning)) + (unless (ignore-errors (progn (emmet-next-edit-point 1) t)) + (goto-char end))) + ))) ;;;###autoload (defun emmet-next-edit-point (count) -- cgit v1.2.3 From 039526bd8e41ced107892cf13c89ca7b43749260 Mon Sep 17 00:00:00 2001 From: Dave Mayo Date: Tue, 6 Sep 2016 01:27:25 -0400 Subject: Fix regression in regular multiplier handling Previous commit borked regular multplied markup, this one doesn't. Also, tests were there! --- emmet-mode.el | 7 ++++--- src/mode-def.el | 7 ++++--- src/test.el | 5 +++++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/emmet-mode.el b/emmet-mode.el index 92542f4..5f0a204 100644 --- a/emmet-mode.el +++ b/emmet-mode.el @@ -632,11 +632,12 @@ accept it or skip it." (to-wrap (if multi (split-string txt "\n") (list txt))) - (initial-elements (replace-regexp-in-string "\\(.*>\\)?[^>*]+\\*?$" "\\1" wrap-with t)) - (terminal-element (replace-regexp-in-string "\\(.*>\\)?\\([^>*]+\\)\\*?$" "\\2" wrap-with t)) + (initial-elements (replace-regexp-in-string "\\(.*\\(\\+\\|>\\)\\)?[^>*]+\\*?[[:digit:]]*$" "\\1" wrap-with t)) + (terminal-element (replace-regexp-in-string "\\(.*>\\)?\\([^>*]+\\)\\(\\*[[:digit:]]+$\\)?\\*?$" "\\2" wrap-with t)) + (multiplier-expr (replace-regexp-in-string "\\(.*>\\)?\\([^>*]+\\)\\(\\*[[:digit:]]+$\\)?\\*?$" "\\3" wrap-with t)) (expr (concat initial-elements - (mapconcat (lambda (el) (concat terminal-element "{!!!" (secure-hash 'sha1 el) "!!!}")) + (mapconcat (lambda (el) (concat terminal-element "{!!!" (secure-hash 'sha1 el) "!!!}" multiplier-expr)) to-wrap "+"))) (markup diff --git a/src/mode-def.el b/src/mode-def.el index 0f3a522..c0e3e2c 100644 --- a/src/mode-def.el +++ b/src/mode-def.el @@ -479,11 +479,12 @@ accept it or skip it." (to-wrap (if multi (split-string txt "\n") (list txt))) - (initial-elements (replace-regexp-in-string "\\(.*>\\)?[^>*]+\\*?$" "\\1" wrap-with t)) - (terminal-element (replace-regexp-in-string "\\(.*>\\)?\\([^>*]+\\)\\*?$" "\\2" wrap-with t)) + (initial-elements (replace-regexp-in-string "\\(.*\\(\\+\\|>\\)\\)?[^>*]+\\*?[[:digit:]]*$" "\\1" wrap-with t)) + (terminal-element (replace-regexp-in-string "\\(.*>\\)?\\([^>*]+\\)\\(\\*[[:digit:]]+$\\)?\\*?$" "\\2" wrap-with t)) + (multiplier-expr (replace-regexp-in-string "\\(.*>\\)?\\([^>*]+\\)\\(\\*[[:digit:]]+$\\)?\\*?$" "\\3" wrap-with t)) (expr (concat initial-elements - (mapconcat (lambda (el) (concat terminal-element "{!!!" (secure-hash 'sha1 el) "!!!}")) + (mapconcat (lambda (el) (concat terminal-element "{!!!" (secure-hash 'sha1 el) "!!!}" multiplier-expr)) to-wrap "+"))) (markup diff --git a/src/test.el b/src/test.el index 05f7a24..913daca 100644 --- a/src/test.el +++ b/src/test.el @@ -655,6 +655,11 @@ #'emmet-wrap-with-markup-test '((("div>ul>li" "I am some\nmultiline\n text") . "
\n
    \n
  • I am some\n multiline\n text
  • \n
\n
"))) +(emmet-run-test-case "Wrap with per-line markup (trailing *)" + #'emmet-wrap-with-markup-test + '((("div>ul>li*" "I am some\nmultiline\n text") . + "
\n
    \n
  • I am some
  • \n
  • multiline
  • \n
  • text
  • \n
\n
"))) + ;; Regression test for #54 (broken emmet-find-left-bound behavior ;; after tag with attributes) (defun emmet-regression-54-test (lis) -- cgit v1.2.3