;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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 "