diff options
author | flyingleafe <flyingleafe@gmail.com> | 2014-10-01 22:37:41 +0400 |
---|---|---|
committer | flyingleafe <flyingleafe@gmail.com> | 2014-10-01 22:37:41 +0400 |
commit | 264e63ea70c69fd18b33f13e1837f12b36bcf8a7 (patch) | |
tree | 61b9a3ee20ca97dde29944b9f62030258599afa2 | |
parent | c76f9e62501c240ed8bb9af46f59d2ce4b975b89 (diff) | |
download | emmet-mode-264e63ea70c69fd18b33f13e1837f12b36bcf8a7.tar.lz emmet-mode-264e63ea70c69fd18b33f13e1837f12b36bcf8a7.tar.xz emmet-mode-264e63ea70c69fd18b33f13e1837f12b36bcf8a7.zip |
Fixed stack overflow error while checking for style tag and attr
-rw-r--r-- | emmet-mode.el | 41 | ||||
-rw-r--r-- | src/init.el | 8 | ||||
-rw-r--r-- | src/mode-def.el | 33 |
3 files changed, 66 insertions, 16 deletions
diff --git a/emmet-mode.el b/emmet-mode.el index 8a9d5fb..89a870e 100644 --- a/emmet-mode.el +++ b/emmet-mode.el @@ -130,6 +130,14 @@ ,then-form) ,@else-forms))) +(defmacro emmet-find (direction regexp &optional limit-of-search repeat-count) + "Regexp-search in given direction, returning the position (or nil) +and leaving the point in place." + `(save-excursion + (if (,(intern (concat "re-search-" direction)) + ,regexp ,limit-of-search t ,repeat-count) + (match-beginning 0)))) + (defun emmet-regex (regexp string refs) "Return a list of (`ref') matches for a `regex' on a `string' or nil." (if (string-match (concat "^" regexp "\\([^\n]*\\)$") string) @@ -3536,6 +3544,12 @@ tbl)) :type 'boolean :group 'emmet) +(defcustom emmet-use-style-tag-and-attr-detection t + "When true, enables detection of style tags and attributes in HTML +to provide proper CSS abbreviations completion." + :type 'boolean + :group 'emmet) + (defvar emmet-use-css-transform nil "When true, transform Emmet snippets into CSS, instead of the usual HTML.") (make-variable-buffer-local 'emmet-use-css-transform) @@ -3545,6 +3559,7 @@ tbl)) e. g. without semicolons") (make-variable-buffer-local 'emmet-use-sass-syntax) + (defvar emmet-css-major-modes '(css-mode scss-mode @@ -3570,14 +3585,24 @@ e. g. without semicolons") new-pos)))))) (defun emmet-detect-style-tag-and-attr () - (let* ((qt "[\"']") - (not-qt "[^\"']") - (everything "\\(.\\|\n\\)*")) - (or - (and (looking-at (format "%s*%s" not-qt qt)) - (looking-back (format "style=%s%s*" qt not-qt))) ; style attr - (and (looking-at (format "%s</style>" everything)) - (looking-back (format "<style>%s" everything)))))) ; style tag + (let* ((style-attr-end "[^=][\"']") + (style-attr-begin "style=[\"']") + (style-tag-end "</style>") + (style-tag-begin "<style>")) + (and emmet-use-style-tag-and-attr-detection + (or + (emmet-check-if-between style-attr-begin style-attr-end) ; style attr + (emmet-check-if-between style-tag-begin style-tag-end))))) ; style tag + +(defun emmet-check-if-between (begin end) + (let ((begin-back (emmet-find "backward" begin)) + (end-back (emmet-find "backward" end)) + (begin-front (emmet-find "forward" begin)) + (end-front (emmet-find "forward" end))) + (and begin-back end-front + (or (not end-back) (> begin-back end-back)) + (or (not begin-front) (< end-front begin-front))))) + ;;;###autoload (defun emmet-expand-line (arg) diff --git a/src/init.el b/src/init.el index 8e1d7f9..c6095f1 100644 --- a/src/init.el +++ b/src/init.el @@ -65,6 +65,14 @@ ,then-form) ,@else-forms))) +(defmacro emmet-find (direction regexp &optional limit-of-search repeat-count) + "Regexp-search in given direction, returning the position (or nil) +and leaving the point in place." + `(save-excursion + (if (,(intern (concat "re-search-" direction)) + ,regexp ,limit-of-search t ,repeat-count) + (match-beginning 0)))) + (defun emmet-regex (regexp string refs) "Return a list of (`ref') matches for a `regex' on a `string' or nil." (if (string-match (concat "^" regexp "\\([^\n]*\\)$") string) diff --git a/src/mode-def.el b/src/mode-def.el index e0a22b9..533e98c 100644 --- a/src/mode-def.el +++ b/src/mode-def.el @@ -47,6 +47,12 @@ :type 'boolean :group 'emmet) +(defcustom emmet-use-style-tag-and-attr-detection t + "When true, enables detection of style tags and attributes in HTML +to provide proper CSS abbreviations completion." + :type 'boolean + :group 'emmet) + (defvar emmet-use-css-transform nil "When true, transform Emmet snippets into CSS, instead of the usual HTML.") (make-variable-buffer-local 'emmet-use-css-transform) @@ -56,6 +62,7 @@ e. g. without semicolons") (make-variable-buffer-local 'emmet-use-sass-syntax) + (defvar emmet-css-major-modes '(css-mode scss-mode @@ -81,14 +88,24 @@ e. g. without semicolons") new-pos)))))) (defun emmet-detect-style-tag-and-attr () - (let* ((qt "[\"']") - (not-qt "[^\"']") - (everything "\\(.\\|\n\\)*")) - (or - (and (looking-at (format "%s*%s" not-qt qt)) - (looking-back (format "style=%s%s*" qt not-qt))) ; style attr - (and (looking-at (format "%s</style>" everything)) - (looking-back (format "<style>%s" everything)))))) ; style tag + (let* ((style-attr-end "[^=][\"']") + (style-attr-begin "style=[\"']") + (style-tag-end "</style>") + (style-tag-begin "<style>")) + (and emmet-use-style-tag-and-attr-detection + (or + (emmet-check-if-between style-attr-begin style-attr-end) ; style attr + (emmet-check-if-between style-tag-begin style-tag-end))))) ; style tag + +(defun emmet-check-if-between (begin end) + (let ((begin-back (emmet-find "backward" begin)) + (end-back (emmet-find "backward" end)) + (begin-front (emmet-find "forward" begin)) + (end-front (emmet-find "forward" end))) + (and begin-back end-front + (or (not end-back) (> begin-back end-back)) + (or (not begin-front) (< end-front begin-front))))) + ;;;###autoload (defun emmet-expand-line (arg) |