Tom Willemse
8af6f8d160
Loading ‘yasnippet’ shouldn't automatically load my package configuration. If my package configuration hasn't been loaded it shouldn't try to include my snippets.
172 lines
5.6 KiB
EmacsLisp
172 lines
5.6 KiB
EmacsLisp
;;; oni-css.el --- CSS configuration -*- lexical-binding: t; -*-
|
||
|
||
;; Copyright (C) 2019 Tom Willemse
|
||
|
||
;; Author: Tom Willemse <tom@ryuslash.org>
|
||
;; Keywords: local
|
||
;; Version: 2021.1201.134221
|
||
;; Package-Requires: (oni-company oni-hydra rainbow-mode oni-yasnippet)
|
||
|
||
;; This program is free software; you can redistribute it and/or modify
|
||
;; it under the terms of the GNU General Public License as published by
|
||
;; the Free Software Foundation, either version 3 of the License, or
|
||
;; (at your option) any later version.
|
||
|
||
;; This program is distributed in the hope that it will be useful,
|
||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
;; GNU General Public License for more details.
|
||
|
||
;; You should have received a copy of the GNU General Public License
|
||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
|
||
;;; Commentary:
|
||
|
||
;; Configuration for `css-mode' and `scss-mode'.
|
||
|
||
;;; Code:
|
||
|
||
(require 'align)
|
||
(require 'css-mode)
|
||
(require 'hydra)
|
||
(require 'yasnippet)
|
||
|
||
(eval-when-compile
|
||
(require 'compile)
|
||
(require 'grep))
|
||
|
||
(defconst oni-css-root
|
||
(file-name-directory
|
||
(or load-file-name
|
||
(buffer-file-name)))
|
||
"The directory where ‘oni-css’ was loaded from.")
|
||
|
||
(defconst oni-css-snippets-dir
|
||
(expand-file-name "snippets" oni-css-root)
|
||
"The directory where ‘oni-css’ stores its snippets.")
|
||
|
||
(defun oni-css-property-important-p ()
|
||
"Return whether or not the current property is important."
|
||
(save-excursion
|
||
(beginning-of-line)
|
||
(re-search-forward "!important" (line-end-position) :noerror)))
|
||
|
||
(defun oni-css-add-important ()
|
||
"Add an important flag to the property on the current line."
|
||
(interactive)
|
||
(unless (oni-css-property-important-p)
|
||
(save-excursion
|
||
(end-of-line)
|
||
(when (re-search-backward ";" (line-beginning-position) :noerror)
|
||
(insert " !important")))))
|
||
|
||
(defun oni-css-snippets-initialize ()
|
||
"Initialize the snippets for ‘oni-css’."
|
||
(when (boundp 'yas-snippet-dirs)
|
||
(add-to-list 'yas-snippet-dirs oni-css-snippets-dir t))
|
||
(yas-load-directory oni-css-snippets-dir))
|
||
|
||
(defun oni-css-remove-important ()
|
||
"Remove the important flag from the property on the current line."
|
||
(interactive)
|
||
(when (oni-css-property-important-p)
|
||
(save-excursion
|
||
(end-of-line)
|
||
(when (re-search-backward " !important" (line-beginning-position) :noerror)
|
||
(replace-match "")))))
|
||
|
||
(defun oni-css-mode-init--toggle-important ()
|
||
"Toggle the important flag on the property on the current line."
|
||
(interactive)
|
||
(if (oni-css-property-important-p)
|
||
(oni-css-remove-important)
|
||
(oni-css-add-important)))
|
||
|
||
(defun oni-css--auto-fill-mode ()
|
||
"Enable ‘auto-fill-mode’ only for comments."
|
||
(setq-local comment-auto-fill-only-comments t)
|
||
(auto-fill-mode))
|
||
|
||
(defhydra css-mode-hydra (:color blue)
|
||
("!" oni-css-mode-init--toggle-important))
|
||
|
||
(setq css-indent-offset 2)
|
||
|
||
(add-hook 'css-mode-hook 'company-mode)
|
||
(add-hook 'css-mode-hook 'display-fill-column-indicator-mode)
|
||
(add-hook 'css-mode-hook 'electric-indent-local-mode)
|
||
(add-hook 'css-mode-hook 'electric-pair-local-mode)
|
||
(add-hook 'css-mode-hook 'oni-css--auto-fill-mode)
|
||
(add-hook 'css-mode-hook 'rainbow-mode)
|
||
|
||
(with-eval-after-load 'compile
|
||
(let ((scss-error-regexp
|
||
(rx (and bol
|
||
(zero-or-more space) "on line "
|
||
(group (one-or-more digit)) " of "
|
||
(group (one-or-more (or word punct (syntax symbol))))
|
||
eol))))
|
||
|
||
(add-to-list 'compilation-error-regexp-alist
|
||
(list scss-error-regexp 2 1 nil 2 2))))
|
||
|
||
(define-key css-mode-map (kbd "C-c m") #'css-mode-hydra/body)
|
||
|
||
;; Align CSS files like so:
|
||
|
||
;; body { color: #ffffff; }
|
||
;; .some-class { background-color: #ffffff; }
|
||
;; #some-id { width: 200px; }
|
||
|
||
;; .some-more-class {
|
||
;; color: #ffffff;
|
||
;; background-color: #ffffff;
|
||
;; width: 200px;
|
||
;; }
|
||
|
||
;; Keep these in order. They are each added to the _front_ of the
|
||
;; list and are applied in order. Changing their order will change
|
||
;; the results.
|
||
(add-to-list 'align-rules-list
|
||
`(css-closing-brace
|
||
(regexp . ,(rx (group (0+ whitespace)) "}" eol))
|
||
(group . (1))
|
||
(modes . '(scss-mode css-mode))))
|
||
|
||
(add-to-list 'align-rules-list
|
||
`(css-colons
|
||
(regexp . ,(rx bol
|
||
(0+ whitespace)
|
||
(1+ (any (?a . ?z) ?- ?$))
|
||
":"
|
||
(group (0+ whitespace))
|
||
(0+ nonl)
|
||
";"
|
||
eol))
|
||
(group . (1))
|
||
(modes . '(scss-mode css-mode))
|
||
(repeat . t)))
|
||
|
||
(add-to-list 'align-rules-list
|
||
`(css-opening-brace
|
||
(regexp . ,(rx bol
|
||
(0+ whitespace)
|
||
(0+ (any ?# ?. ?, ?\s ?& ?: ?-
|
||
(?a . ?z) (?A . ?Z) (?0 . ?9)))
|
||
(any (?a . ?z) (?A . ?Z) (?0 . ?9))
|
||
(group (0+ whitespace))
|
||
"{"
|
||
(0+ nonl)))
|
||
(group . (1))
|
||
(modes . '(scss-mode css-mode))))
|
||
|
||
;;;###autoload
|
||
(with-eval-after-load 'grep
|
||
(add-to-list 'grep-files-aliases '("css" . "*.css *.less *.sass *.scss")))
|
||
|
||
(with-eval-after-load 'css-mode
|
||
(with-eval-after-load 'yasnippet
|
||
(oni-css-snippets-initialize)))
|
||
|
||
(provide 'oni-css)
|
||
;;; oni-css.el ends here
|