Moving to Doom Emacs!

This commit is contained in:
Derek Taylor
2019-12-16 20:21:19 -06:00
parent d9f2f456f1
commit d4b4c33550
683 changed files with 51877 additions and 100 deletions

View File

@@ -0,0 +1,66 @@
;;; lang/web/+css.el -*- lexical-binding: t; -*-
;; An improved newline+continue comment function
(setq-hook! css-mode
comment-indent-function #'+css/comment-indent-new-line)
(after! (:any css-mode sass-mode)
(set-docsets! '(css-mode scss-mode sass-mode)
"CSS" "HTML" "Bourbon" "Compass"
["Sass" (memq major-mode '(scss-mode sass-mode))]))
(after! projectile
(pushnew! projectile-other-file-alist
'("css" "scss" "sass" "less" "styl")
'("scss" "css")
'("sass" "css")
'("less" "css")
'("styl" "css")))
;;
;;; Major modes
(add-hook! '(css-mode-hook sass-mode-hook stylus-mode-hook)
#'rainbow-mode)
;; built-in, and contains both css-mode & scss-mode
(after! css-mode
;; css-mode hooks apply to scss and less-css modes
(add-hook 'css-mode-hook #'rainbow-delimiters-mode)
(map! :localleader
:map scss-mode-map
"b" #'+css/scss-build
:map (css-mode-map scss-mode-map less-css-mode-map)
"rb" #'+css/toggle-inline-or-block)
(use-package! counsel-css
:when (featurep! :completion ivy)
:commands counsel-css
:hook (css-mode . counsel-css-imenu-setup)
:init
(map! :map (css-mode-map scss-mode-map less-css-mode-map)
:localleader ";" #'counsel-css))
(use-package! helm-css-scss
:when (featurep! :completion helm)
:defer t
:init
(map! :map (css-mode-map scss-mode-map less-css-mode-map)
:localleader ";" #'helm-css-scss)
:config
(setq helm-css-scss-split-direction #'split-window-vertically
helm-css-scss-split-with-multiple-windows t)))
(after! sass-mode
(set-company-backend! 'sass-mode 'company-css)
(map! :map sass-mode-map :localleader "b" #'+css/sass-build))
;;
;;; Tools
(when (featurep! +lsp)
(add-hook! '(css-mode-hook sass-mode-hook less-css-mode-hook)
#'lsp!))

View File

@@ -0,0 +1,127 @@
;;; lang/web/+html.el -*- lexical-binding: t; -*-
(use-package! web-mode
:mode "\\.\\(?:as\\(?:[cp]x\\)\\|blade\\.php\\|erb\\|hbs\\|j\\(?:inja\\|sp\\)\\|mustache\\|p?html?\\|svelte\\|t\\(?:pl\\.php\\|sx\\|wig\\)\\|vue\\)\\'"
:mode "wp-content/themes/.+/.+\\.php\\'"
:mode "templates/.+\\.php\\'"
:config
(set-docsets! 'web-mode "HTML" "CSS" "Twig" "WordPress")
;; tidy is already defined by the format-all package. We redefine it to add
;; more sensible arguments to the tidy command.
(set-formatter! 'html-tidy
'("tidy" "-q" "-indent"
"--tidy-mark" "no"
"--drop-empty-elements" "no"
"--show-body-only" "auto" ; don't inject html/body tags
("--indent-spaces" "%d" tab-width)
("--indent-with-tabs" "%s" (if indent-tabs-mode "yes" "no"))
("-xml" (memq major-mode '(nxml-mode xml-mode))))
:ok-statuses '(0 1))
(setq web-mode-enable-html-entities-fontification t
web-mode-auto-close-style 1)
(after! smartparens
(defun +web-is-auto-close-style-3 (_id action _context)
(and (eq action 'insert)
(eq web-mode-auto-close-style 3)))
(sp-local-pair 'web-mode "<" ">" :unless '(:add +web-is-auto-close-style-3))
;; let smartparens handle these
(setq web-mode-enable-auto-quoting nil
web-mode-enable-auto-pairing t)
;; 1. Remove web-mode auto pairs whose end pair starts with a latter
;; (truncated autopairs like <?p and hp ?>). Smartparens handles these
;; better.
;; 2. Strips out extra closing pairs to prevent redundant characters
;; inserted by smartparens.
(dolist (alist web-mode-engines-auto-pairs)
(setcdr alist
(cl-loop for pair in (cdr alist)
unless (string-match-p "^[a-z-]" (cdr pair))
collect (cons (car pair)
(string-trim-right (cdr pair)
"\\(?:>\\|]\\|}\\)+\\'")))))
(delq! nil web-mode-engines-auto-pairs))
(map! :map web-mode-map
(:localleader
:desc "Rehighlight buffer" "h" #'web-mode-buffer-highlight
:desc "Indent buffer" "i" #'web-mode-buffer-indent
(:prefix ("a" . "attribute")
"b" #'web-mode-attribute-beginning
"e" #'web-mode-attribute-end
"i" #'web-mode-attribute-insert
"n" #'web-mode-attribute-next
"s" #'web-mode-attribute-select
"k" #'web-mode-attribute-kill
"p" #'web-mode-attribute-previous
"p" #'web-mode-attribute-transpose)
(:prefix ("b" . "block")
"b" #'web-mode-block-beginning
"c" #'web-mode-block-close
"e" #'web-mode-block-end
"k" #'web-mode-block-kill
"n" #'web-mode-block-next
"p" #'web-mode-block-previous
"s" #'web-mode-block-select)
(:prefix ("d" . "dom")
"a" #'web-mode-dom-apostrophes-replace
"d" #'web-mode-dom-errors-show
"e" #'web-mode-dom-entities-encode
"n" #'web-mode-dom-normalize
"q" #'web-mode-dom-quotes-replace
"t" #'web-mode-dom-traverse
"x" #'web-mode-dom-xpath)
(:prefix ("e" . "element")
"/" #'web-mode-element-close
"a" #'web-mode-element-content-select
"b" #'web-mode-element-beginning
"c" #'web-mode-element-clone
"d" #'web-mode-element-child
"e" #'web-mode-element-end
"f" #'web-mode-element-children-fold-or-unfold
"i" #'web-mode-element-insert
"k" #'web-mode-element-kill
"m" #'web-mode-element-mute-blanks
"n" #'web-mode-element-next
"p" #'web-mode-element-previous
"r" #'web-mode-element-rename
"s" #'web-mode-element-select
"t" #'web-mode-element-transpose
"u" #'web-mode-element-parent
"v" #'web-mode-element-vanish
"w" #'web-mode-element-wrap)
(:prefix ("t" . "tag")
"a" #'web-mode-tag-attributes-sort
"b" #'web-mode-tag-beginning
"e" #'web-mode-tag-end
"m" #'web-mode-tag-match
"n" #'web-mode-tag-next
"p" #'web-mode-tag-previous
"s" #'web-mode-tag-select))
:g "M-/" #'web-mode-comment-or-uncomment
:i "SPC" #'self-insert-command
:n "za" #'web-mode-fold-or-unfold
:nv "]a" #'web-mode-attribute-next
:nv "[a" #'web-mode-attribute-previous
:nv "]t" #'web-mode-tag-next
:nv "[t" #'web-mode-tag-previous
:nv "]T" #'web-mode-element-child
:nv "[T" #'web-mode-element-parent))
;;
(after! pug-mode
(set-company-backend! 'pug-mode 'company-web-jade))
(after! web-mode
(set-company-backend! 'web-mode 'company-css 'company-web-html))
(after! slim-mode
(set-company-backend! 'slim-mode 'company-web-slim))
(when (featurep! +lsp)
(add-hook! '(html-mode-hook web-mode-hook) #'lsp!))

View File

@@ -0,0 +1,82 @@
;;; lang/web/autoload/css.el -*- lexical-binding: t; -*-
;; ;;;###autoload
;; TODO (defun +css/scss-build ())
;; ;;;###autoload
;; TODO (defun +css/sass-build ())
(defun +css--toggle-inline-or-block (beg end)
(skip-chars-forward " \t")
(let ((orig (point-marker)))
(goto-char beg)
(if (= (line-number-at-pos beg) (line-number-at-pos end))
(progn
(forward-char)
(insert "\n")
(while (re-search-forward ";\\s-+" end t)
(replace-match ";\n" nil t))
(indent-region beg end))
(save-excursion
(while (re-search-forward "\n+" end t)
(replace-match " " nil t)))
(while (re-search-forward "\\([{;]\\) +" end t)
(replace-match (concat (match-string 1) " ") nil t)))
(if orig (goto-char orig))
(skip-chars-forward " \t")))
;;;###autoload
(defun +css/toggle-inline-or-block ()
"Toggles between a bracketed block and inline block."
(interactive)
(let ((inhibit-modification-hooks t))
(cl-destructuring-bind (&key beg end op cl &allow-other-keys)
(save-excursion
(when (and (eq (char-after) ?\{)
(not (eq (char-before) ?\{)))
(forward-char))
(sp-get-sexp))
(when (or (not (and beg end op cl))
(string-empty-p op) (string-empty-p cl))
(user-error "No block found %s" (list beg end op cl)))
(unless (string= op "{")
(user-error "Incorrect block found"))
(+css--toggle-inline-or-block beg end))))
;;;###autoload
(defun +css/comment-indent-new-line (&optional _)
"Continues the comment in an indented new line.
Meant for `comment-line-break-function' in `css-mode' and `scss-mode'."
(interactive)
(when (sp-point-in-comment)
(let ((at-end (looking-at-p ".+\\*/"))
type pre-indent post-indent)
(save-excursion
(let ((bol (line-beginning-position))
(eol (line-end-position)))
(if (not comment-use-syntax)
(progn
(goto-char bol)
(when (re-search-forward comment-start-skip eol t)
(goto-char (or (match-end 1) (match-beginning 0)))))
(goto-char (comment-beginning))))
(save-match-data
(looking-at "\\(//\\|/?\\*\\)")
(setq type (match-string 0)
pre-indent (- (match-beginning 0) (line-beginning-position))
post-indent
(progn
(goto-char (match-end 0))
(max 1 (skip-chars-forward " " (line-end-position)))))
(if (eolp) (setq post-indent 1))))
(insert "\n"
(make-string pre-indent 32)
(if (string= "/*" type)
" *"
type)
(make-string post-indent 32))
(when at-end
(save-excursion
(insert "\n" (make-string pre-indent 32))
(delete-char -1))))))

View File

@@ -0,0 +1,21 @@
;;; lang/html/autoload/evil.el -*- lexical-binding: t; -*-
;;;###if (featurep! :editor evil)
;;;###autoload (autoload '+web:encode-html-entities "lang/web/autoload/evil" nil t)
(evil-define-operator +web:encode-html-entities (beg end &optional input)
"Encodes HTML entities in INPUT or the selected region."
(interactive "<r><a>")
(cond (input
(insert (+web-encode-entities input)))
((and beg end)
(+web/encode-entities-region beg end))))
;;;###autoload (autoload '+web:decode-html-entities "lang/web/autoload/evil" nil t)
(evil-define-operator +web:decode-html-entities (beg end &optional input)
"Decodes HTML entities in INPUT or the selected region."
(interactive "<r><a>")
(cond (input
(insert (+web-decode-entities input)))
((and beg end)
(+web/decode-entities-region beg end))))

View File

@@ -0,0 +1,130 @@
;;; lang/web/autoload/html.el -*- lexical-binding: t; -*-
(defvar +web-entities-list
[["&amp;" "&"] ["&nbsp;" " "] ["&ensp;" ""] ["&emsp;" ""] ["&thinsp;" ""]
["&rlm;" ""] ["&lrm;" ""] ["&zwj;" ""] ["&zwnj;" ""]
["&iexcl;" "¡"] ["&cent;" "¢"] ["&pound;" "£"] ["&curren;" "¤"] ["&yen;" "¥"]
["&brvbar;" "¦"] ["&sect;" "§"] ["&uml;" "¨"] ["&copy;" "©"] ["&ordf;" "ª"]
["&laquo;" "«"] ["&not;" "¬"] ["&shy;" "­"] ["&reg;" "®"] ["&macr;" "¯"]
["&deg;" "°"] ["&plusmn;" "±"] ["&sup2;" "²"] ["&sup3;" "³"] ["&acute;" "´"]
["&micro;" "µ"] ["&para;" ""] ["&middot;" "·"] ["&cedil;" "¸"] ["&sup1;" "¹"]
["&ordm;" "º"] ["&raquo;" "»"] ["&frac14;" "¼"] ["&frac12;" "½"]
["&frac34;" "¾"] ["&iquest;" "¿"] ["&Agrave;" "À"] ["&Aacute;" "Á"]
["&Acirc;" "Â"] ["&Atilde;" "Ã"] ["&Auml;" "Ä"] ["&Aring;" "Å"] ["&AElig;" "Æ"]
["&Ccedil;" "Ç"] ["&Egrave;" "È"] ["&Eacute;" "É"] ["&Ecirc;" "Ê"]
["&Euml;" "Ë"] ["&Igrave;" "Ì"] ["&Iacute;" "Í"] ["&Icirc;" "Î"] ["&Iuml;" "Ï"]
["&ETH;" "Ð"] ["&Ntilde;" "Ñ"] ["&Ograve;" "Ò"] ["&Oacute;" "Ó"]
["&Ocirc;" "Ô"] ["&Otilde;" "Õ"] ["&Ouml;" "Ö"] ["&times;" "×"] ["&Oslash;" "Ø"]
["&Ugrave;" "Ù"] ["&Uacute;" "Ú"] ["&Ucirc;" "Û"] ["&Uuml;" "Ü"]
["&Yacute;" "Ý"] ["&THORN;" "Þ"] ["&szlig;" "ß"] ["&agrave;" "à"] ["&aacute;" "á"]
["&acirc;" "â"] ["&atilde;" "ã"] ["&auml;" "ä"] ["&aring;" "å"]
["&aelig;" "æ"] ["&ccedil;" "ç"] ["&egrave;" "è"] ["&eacute;" "é"] ["&ecirc;" "ê"]
["&euml;" "ë"] ["&igrave;" "ì"] ["&iacute;" "í"] ["&icirc;" "î"]
["&iuml;" "ï"] ["&eth;" "ð"] ["&ntilde;" "ñ"] ["&ograve;" "ò"] ["&oacute;" "ó"]
["&ocirc;" "ô"] ["&otilde;" "õ"] ["&ouml;" "ö"] ["&divide;" "÷"] ["&oslash;" "ø"]
["&ugrave;" "ù"] ["&uacute;" "ú"] ["&ucirc;" "û"] ["&uuml;" "ü"] ["&yacute;" "ý"]
["&thorn;" "þ"] ["&yuml;" "ÿ"] ["&fnof;" "ƒ"] ["&Alpha;" "Α"] ["&Beta;" "Β"]
["&Gamma;" "Γ"] ["&Delta;" "Δ"] ["&Epsilon;" "Ε"] ["&Zeta;" "Ζ"] ["&Eta;" "Η"]
["&Theta;" "Θ"] ["&Iota;" "Ι"] ["&Kappa;" "Κ"] ["&Lambda;" "Λ"] ["&Mu;" "Μ"]
["&Nu;" "Ν"] ["&Xi;" "Ξ"] ["&Omicron;" "Ο"] ["&Pi;" "Π"] ["&Rho;" "Ρ"]
["&Sigma;" "Σ"] ["&Tau;" "Τ"] ["&Upsilon;" "Υ"] ["&Phi;" "Φ"] ["&Chi;" "Χ"]
["&Psi;" "Ψ"] ["&Omega;" "Ω"] ["&alpha;" "α"] ["&beta;" "β"] ["&gamma;" "γ"]
["&delta;" "δ"] ["&epsilon;" "ε"] ["&zeta;" "ζ"] ["&eta;" "η"] ["&theta;" "θ"]
["&iota;" "ι"] ["&kappa;" "κ"] ["&lambda;" "λ"] ["&mu;" "μ"] ["&nu;" "ν"]
["&xi;" "ξ"] ["&omicron;" "ο"] ["&pi;" "π"] ["&rho;" "ρ"] ["&sigmaf;" "ς"]
["&sigma;" "σ"] ["&tau;" "τ"] ["&upsilon;" "υ"] ["&phi;" "φ"] ["&chi;" "χ"]
["&psi;" "ψ"] ["&omega;" "ω"] ["&thetasym;" "ϑ"] ["&upsih;" "ϒ"] ["&piv;" "ϖ"]
["&bull;" ""] ["&hellip;" ""] ["&prime;" ""] ["&Prime;" ""] ["&oline;" ""]
["&frasl;" ""] ["&weierp;" ""] ["&image;" ""] ["&real;" ""] ["&trade;" ""]
["&alefsym;" ""] ["&larr;" ""] ["&uarr;" ""] ["&rarr;" ""] ["&darr;" ""]
["&harr;" ""] ["&crarr;" ""] ["&lArr;" ""] ["&uArr;" ""] ["&rArr;" ""]
["&dArr;" ""] ["&hArr;" ""] ["&forall;" ""] ["&part;" ""] ["&exist;" ""]
["&empty;" ""] ["&nabla;" ""] ["&isin;" ""] ["&notin;" ""] ["&ni;" ""]
["&prod;" ""] ["&sum;" ""] ["&minus;" ""] ["&lowast;" ""] ["&radic;" ""]
["&prop;" ""] ["&infin;" ""] ["&ang;" ""] ["&and;" ""] ["&or;" ""]
["&cap;" ""] ["&cup;" ""] ["&int;" ""] ["&there4;" ""] ["&sim;" ""]
["&cong;" ""] ["&asymp;" ""] ["&ne;" ""] ["&equiv;" ""] ["&le;" ""]
["&ge;" ""] ["&sub;" ""] ["&sup;" ""] ["&nsub;" ""] ["&sube;" ""]
["&supe;" ""] ["&oplus;" ""] ["&otimes;" ""] ["&perp;" ""] ["&sdot;" ""]
["&lceil;" ""] ["&rceil;" ""] ["&lfloor;" ""] ["&rfloor;" ""] ["&lang;" ""]
["&rang;" ""] ["&loz;" ""] ["&spades;" ""] ["&clubs;" ""]
["&hearts;" ""] ["&diams;" ""] ["&quot;" "\""] ["&OElig;" "Œ"] ["&oelig;" "œ"]
["&Scaron;" "Š"] ["&scaron;" "š"] ["&Yuml;" "Ÿ"] ["&circ;" "ˆ"]
["&tilde;" "˜"] ["&ndash;" ""] ["&mdash;" ""] ["&lsquo;" ""] ["&rsquo;" ""]
["&sbquo;" ""] ["&ldquo;" ""] ["&rdquo;" ""] ["&bdquo;" ""]
["&dagger;" ""] ["&Dagger;" ""] ["&permil;" ""] ["&lsaquo;" ""] ["&rsaquo;" ""]
["&euro;" ""]]
"A list of sequence string pairs, representing an html entity and its decoded
character.")
(defun +web--entities-string (text &optional decode-p)
"HTML encode/decode TEXT. Based on Xah's replace HTML named entities function
@ http://ergoemacs.org/emacs/elisp_replace_html_entities_command.html"
(interactive "<!><r>")
(mapc (lambda (rep)
(let ((from (elt rep (if decode-p 0 1)))
(to (elt rep (if decode-p 1 0)))
case-fold-search)
(when (and (not (equal from " "))
(string-match-p (regexp-quote from) text))
(setq text (replace-regexp-in-string (regexp-quote from) to text t t)))))
+web-entities-list)
text)
(defun +web--entities-region (beg end &optional decode-p)
"HTML encode/decode the selected region. Based on Xah's replace HTML named entities
function @ http://ergoemacs.org/emacs/elisp_replace_html_entities_command.html"
(save-restriction
(narrow-to-region beg end)
(mapc (lambda (rep)
(let ((from (elt rep (if decode-p 0 1)))
(to (elt rep (if decode-p 1 0)))
case-fold-search)
(unless (equal from " ")
(goto-char (point-min))
(while (search-forward from nil t)
(replace-match to 'FIXEDCASE 'LITERAL)))))
+web-entities-list)))
;;;###autoload
(defun +web-encode-entities (text)
"TODO"
(+web--entities-string text nil))
;;;###autoload
(defun +web-decode-entities (text)
"TODO"
(+web--entities-string text t))
;;
;;; Commands
;;;###autoload
(defun +web/encode-entities-region (beg end)
"Encode HTML entities in region."
(interactive "r")
(+web--entities-region beg end))
;;;###autoload
(defun +web/decode-entities-region (beg end)
"Decode HTML entities in region."
(interactive "r")
(+web--entities-region beg end t))
;;;###autoload
(defun +web/indent-or-yas-or-emmet-expand ()
"Do-what-I-mean on TAB.
Invokes `indent-for-tab-command' if at or before text bol, `yas-expand' if on a
snippet, or `emmet-expand-yas'/`emmet-expand-line', depending on whether
`yas-minor-mode' is enabled or not."
(interactive)
(call-interactively
(cond ((<= (current-column) (current-indentation))
#'indent-for-tab-command)
((bound-and-true-p yas-minor-mode)
(if (yas--templates-for-key-at-point)
#'yas-expand
#'emmet-expand-yas))
(#'emmet-expand-line))))

View File

@@ -0,0 +1,47 @@
;;; lang/web/config.el -*- lexical-binding: t; -*-
(load! "+html")
(load! "+css")
(use-package! emmet-mode
:preface (defvar emmet-mode-keymap (make-sparse-keymap))
:hook (css-mode web-mode html-mode haml-mode nxml-mode rjsx-mode reason-mode)
:config
(when (require 'yasnippet nil t)
(add-hook 'emmet-mode-hook #'yas-minor-mode-on))
(setq emmet-move-cursor-between-quotes t)
(setq-hook! 'rjsx-mode-hook emmet-expand-jsx-className? t)
(map! :map emmet-mode-keymap
:v [tab] #'emmet-wrap-with-markup
:i [tab] #'+web/indent-or-yas-or-emmet-expand
:i "M-E" #'emmet-expand-line))
;;
;;; Framework-based minor-modes
(def-project-mode! +web-jekyll-mode
:modes '(web-mode js-mode coffee-mode css-mode haml-mode pug-mode)
:files (and (or "_config.yml" "_config.toml")
(or "_layouts/" "_posts/"))
:on-enter
(when (eq major-mode 'web-mode)
(web-mode-set-engine "django")))
(def-project-mode! +web-wordpress-mode
:modes '(php-mode web-mode css-mode haml-mode pug-mode)
:files (or "wp-config.php" "wp-config-sample.php"))
(when (featurep! :lang javascript)
(def-project-mode! +web-angularjs-mode
:modes '(+javascript-npm-mode)
:when (+javascript-npm-dep-p 'angular))
(def-project-mode! +web-react-mode
:modes '(+javascript-npm-mode)
:when (+javascript-npm-dep-p 'react))
(def-project-mode! +web-phaser-mode
:modes '(+javascript-npm-mode)
:when (+javascript-npm-dep-p '(or phaser phaser-ce))))

View File

@@ -0,0 +1,12 @@
;;; lang/web/doctor.el -*- lexical-binding: t; -*-
(assert! (or (not (featurep! +lsp))
(featurep! :tools lsp))
"This module requires (:tools lsp)")
(unless (executable-find "js-beautify")
(warn! "Couldn't find js-beautify. Code formatting in JS/CSS/HTML modes will not work."))
(unless (executable-find "stylelint")
(warn! "Couldn't find stylelint. Linting for CSS modes will not work."))

View File

@@ -0,0 +1,24 @@
;; -*- no-byte-compile: t; -*-
;;; lang/web/packages.el
;; +html.el
(package! emmet-mode)
(package! haml-mode)
(package! pug-mode)
(package! slim-mode)
(when (package! web-mode)
(when (featurep! :completion company)
(package! company-web)))
;; +css.el
(package! css-mode :built-in t)
(package! less-css-mode :built-in t)
(package! sass-mode)
(package! stylus-mode)
(package! sws-mode)
(package! rainbow-mode)
(when (featurep! :completion ivy)
(package! counsel-css))
(when (featurep! :completion helm)
(package! helm-css-scss))

View File

@@ -0,0 +1,92 @@
;; -*- no-byte-compile: t; -*-
;;; lang/web/test/test-autoload-web.el
(describe "lang/web"
(describe "+html"
(before-all (load! "../autoload/html.el"))
(describe "encode entities"
(it "encodes strings with html entities"
(expect (+web-encode-entities "H€llø wørld")
:to-equal "H&euro;ll&oslash; w&oslash;rld"))
(it "does nothing when html entities are absent"
(expect (+web-encode-entities "Hello world")
:to-equal "Hello world")))
(describe "decode entities"
(it "decodes strings with html entities"
(expect (+web-decode-entities "H&euro;ll&oslash; w&oslash;rld")
:to-equal "H€llø wørld"))
(it "does nothing when html entities are absent"
(expect (+web-decode-entities "Hello world")
:to-equal "Hello world"))))
(describe "+css"
:var (css-indent-offset)
(before-all
(load! "../autoload/css.el")
(require 'smartparens)
(smartparens-mode +1))
(after-all
(smartparens-mode -1)
(unload-feature 'smartparens t))
(before-each
(setq css-indent-offset 2)
(set-buffer (get-buffer-create "css"))
(delay-mode-hooks (css-mode)))
(after-each
(kill-buffer (get-buffer "css")))
(describe "toggle-inline-or-block"
(after-each
(quiet! (+css/toggle-inline-or-block))
(expect (string-trim (buffer-string)) :to-equal
(string-join
'("body {"
" color: red;"
" font-size: 2em;"
"}")
"\n")))
(describe "css-mode"
(it "converts inline statements into multiline blocks"
(insert!! "body { color: red{0}; font-size: 2em; }"))
(it "works when cursor is on closing brace"
(insert!! "body { color: red; font-size: 2em; {0}}"))
(it "works when cursor is on opening brace"
(insert!! "body {{0} color: red; font-size: 2em; }"))
(it "works when cursor is on same line"
(insert!! "{0}body { color: red; font-size: 2em; }"))))
(describe "comment-indent-new-line"
(before-each
(delay-mode-hooks (scss-mode)))
(it "continues commented lines on newline"
(insert!! "// test{0}\n"
"body { color: red; font-size: 2em; }")
(+css/comment-indent-new-line)
(expect (string-trim (buffer-string)) :to-equal
(string-join
'("// test"
"// "
"body { color: red; font-size: 2em; }")
"\n"))
(expect (eolp))
(expect (line-number-at-pos) :to-be 2))
(it "preserves indentation within continued comments"
(insert!! "// test{0}\n"
"body { color: red; font-size: 2em; }")
(+css/comment-indent-new-line)
(expect (string-trim (buffer-string)) :to-equal
(string-join
'("// test"
"// "
"body { color: red; font-size: 2em; }")
"\n"))
(expect (eolp))
(expect (line-number-at-pos) :to-be 2)))))
;;