;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Emmet minor mode (defgroup emmet nil "Customization group for emmet-mode." :group 'convenience) (defun emmet-expr-on-line () "Extract a emmet expression and the corresponding bounds for the current line." (let* ((end (point)) (start (emmet-find-left-bound)) (line (buffer-substring-no-properties start end)) (expr (emmet-regex "\\([ \t]*\\)\\([^\n]+\\)" line 2))) (if (first expr) (list (first expr) start end)))) (defun emmet-find-left-bound () "Find the left bound of an emmet expr" (save-excursion (save-match-data (let ((char (char-before)) (in-style-attr (looking-back "style=[\"'][^\"']*" nil)) (syn-tab (make-syntax-table))) (modify-syntax-entry ?\\ "\\") (while char (cond ((and in-style-attr (member char '(?\" ?\'))) (setq char nil)) ((member char '(?\} ?\] ?\))) (with-syntax-table syn-tab (backward-sexp) (setq char (char-before)))) ((eq char ?\>) (if (looking-back "<[^>]+>" (line-beginning-position)) (setq char nil) (progn (backward-char) (setq char (char-before))))) ((not (string-match-p "[[:space:]\n;]" (string char))) (backward-char) (setq char (char-before))) (t (setq char nil)))) (point))))) (defcustom emmet-indentation 4 "Number of spaces used for indentation." :type '(number :tag "Spaces") :group 'emmet) (defcustom emmet-indent-after-insert t "Indent region after insert?" :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) (defcustom emmet-self-closing-tag-style "/" "Self-closing tags style. This determines how Emmet expands self-closing tags. E.g., FOO is a self-closing tag. When expanding \"FOO\": When \" /\", the expansion is \"\". When \"/\", the expansion is \"\". When \"\", the expansion is \"\". Default value is \"/\". NOTE: only \" /\", \"/\" and \"\" are valid." :type '(choice (const :tag " />" " /") (const :tag "/>" "/") (const :tag ">" "")) :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) (defvar emmet-use-sass-syntax nil "When true, uses Sass syntax for CSS abbreviations expanding, e. g. without semicolons") (make-variable-buffer-local 'emmet-use-sass-syntax) (defvar emmet-css-major-modes '(css-mode scss-mode sass-mode less-mode less-css-mode) "Major modes that use emmet for CSS, rather than HTML.") (defvar emmet-fallback-filter '("html") "Fallback filter for `emmet-default-filter', if none is found.") (defvar emmet-file-filter nil "File local filter used by `emmet-default-filter'.") (make-variable-buffer-local 'emmet-file-filter) (defun emmet-transform (input) (if (or (emmet-detect-style-tag-and-attr) emmet-use-css-transform) (emmet-css-transform input) (emmet-html-transform input))) (defun emmet-detect-style-tag-and-attr () (let* ((style-attr-end "[^=][\"']") (style-attr-begin "style=[\"']") (style-tag-end "") (style-tag-begin "