Package: emacs;
Reported by: Simen Heggestøyl <simenheg <at> gmail.com>
Date: Sun, 29 Mar 2015 21:16:02 UTC
Severity: normal
Tags: patch
Found in version 25.0.50
Done: Simen Heggestøyl <simenheg <at> gmail.com>
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 20226 in the body.
You can then email your comments to 20226 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
View this report as an mbox folder, status mbox, maintainer mbox
bug-gnu-emacs <at> gnu.org
:bug#20226
; Package emacs
.
(Sun, 29 Mar 2015 21:16:02 GMT) Full text and rfc822 format available.Simen Heggestøyl <simenheg <at> gmail.com>
:bug-gnu-emacs <at> gnu.org
.
(Sun, 29 Mar 2015 21:16:02 GMT) Full text and rfc822 format available.Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Simen Heggestøyl <simenheg <at> gmail.com> To: bug-gnu-emacs <at> gnu.org Cc: rgm <at> gnu.org Subject: 25.0.50; [PATCH] Make (S)CSS mode require final newline Date: Sun, 29 Mar 2015 23:15:10 +0200
[Message part 1 (text/plain, inline)]
This patch makes CSS mode and its sister mode, SCSS mode, require final newlines. I was surprised to find that the modes didn't do this already. I think that final newlines play nicer with version control systems such as Git, in that adding new lines won't be interpreted as changes to the line that used to be last. Final newlines are also mandated by at least one SCSS linter [1]. By the way, maybe it would make sense for CSS mode to derive from `prog-mode' instead of `fundamental-mode'? With this patch, it is already setting `require-final-newline' and `parse-sexp-ignore-comments'. I can see that it used to derive from `prog-mode', but this was changed in 2007 by Glenn Morris. Glenn, can you remember the reason for this change? [1] https://github.com/causes/scss-lint From e960348b679ba5743743afc7a0fdd3f55b098358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simen=20Heggest=C3=B8yl?= <simenheg <at> gmail.com> Date: Sun, 29 Mar 2015 22:50:19 +0200 Subject: [PATCH] Make (S)CSS mode require final newline * textmodes/css-mode.el (css-mode): Require final newline. --- lisp/ChangeLog | 4 ++++ lisp/textmodes/css-mode.el | 1 + 2 files changed, 5 insertions(+) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index c8e84a3..babdbde 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,7 @@ +2015-03-29 Simen Heggestøyl <simenheg <at> gmail.com> + + * textmodes/css-mode.el (css-mode): Require final newline. + 2015-03-28 Jan Djärv <jan.h.d <at> swipnet.se> * emacs-lisp/package.el (package-refresh-contents): Fix spelling diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index 3e7612a..6004d84 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -372,6 +372,7 @@ pseudo-classes, and at-rules." ;;;###autoload (define-derived-mode css-mode fundamental-mode "CSS" "Major mode to edit Cascading Style Sheets." + (setq-local require-final-newline mode-require-final-newline) (setq-local font-lock-defaults css-font-lock-defaults) (setq-local comment-start "/*") (setq-local comment-start-skip "/\\*+[ \t]*") -- 2.1.4
[Message part 2 (text/html, inline)]
bug-gnu-emacs <at> gnu.org
:bug#20226
; Package emacs
.
(Mon, 30 Mar 2015 01:07:02 GMT) Full text and rfc822 format available.Message #8 received at 20226 <at> debbugs.gnu.org (full text, mbox):
From: Stefan Monnier <monnier <at> iro.umontreal.ca> To: Simen Heggestøyl <simenheg <at> gmail.com> Cc: 20226 <at> debbugs.gnu.org Subject: Re: bug#20226: 25.0.50; [PATCH] Make (S)CSS mode require final newline Date: Sun, 29 Mar 2015 21:06:01 -0400
> By the way, maybe it would make sense for CSS mode to derive from > `prog-mode' instead of `fundamental-mode'? That sounds right. > `parse-sexp-ignore-comments'. I can see that it used to derive from > `prog-mode', but this was changed in 2007 by Glenn Morris. Glenn, can > you remember the reason for this change? That's because when css-mode.el was added to Emacs, prog-mode didn't exist yet (it was only added to Emacs in 2010). Stefan
bug-gnu-emacs <at> gnu.org
:bug#20226
; Package emacs
.
(Mon, 30 Mar 2015 20:52:03 GMT) Full text and rfc822 format available.Message #11 received at 20226 <at> debbugs.gnu.org (full text, mbox):
From: Simen Heggestøyl <simenheg <at> gmail.com> To: Stefan Monnier <monnier <at> iro.umontreal.ca> Cc: 20226 <at> debbugs.gnu.org Subject: Re: bug#20226: 25.0.50; [PATCH] Make (S)CSS mode require final newline Date: Mon, 30 Mar 2015 22:50:52 +0200
[Message part 1 (text/plain, inline)]
On Mon, Mar 30, 2015 at 3:06 AM, Stefan Monnier <monnier <at> iro.umontreal.ca> wrote: >> By the way, maybe it would make sense for CSS mode to derive from >> `prog-mode' instead of `fundamental-mode'? > > That sounds right. Good! Then I propose the following two patches: From 6c340b625258e45f81ce10b2ede73e402190758f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simen=20Heggest=C3=B8yl?= <simenheg <at> gmail.com> Date: Mon, 30 Mar 2015 22:32:58 +0200 Subject: [PATCH 1/2] Derive `css-mode' from `prog-mode' * textmodes/css-mode.el (css-mode): Derive from `prog-mode'. --- lisp/ChangeLog | 4 ++++ lisp/textmodes/css-mode.el | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 649e884..f95139c 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,7 @@ +2015-03-30 Simen Heggestøyl <simenheg <at> gmail.com> + + * textmodes/css-mode.el (css-mode): Derive from `prog-mode'. + 2015-03-30 Alan Mackenzie <acm <at> muc.de> Correct calculation of CC Mode's font-lock region. diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index 3e7612a..7280080 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -370,14 +370,13 @@ pseudo-classes, and at-rules." (css--complete-at-rule))) ;;;###autoload -(define-derived-mode css-mode fundamental-mode "CSS" +(define-derived-mode css-mode prog-mode "CSS" "Major mode to edit Cascading Style Sheets." (setq-local font-lock-defaults css-font-lock-defaults) (setq-local comment-start "/*") (setq-local comment-start-skip "/\\*+[ \t]*") (setq-local comment-end "*/") (setq-local comment-end-skip "[ \t]*\\*+/") - (setq-local parse-sexp-ignore-comments t) (setq-local fill-paragraph-function 'css-fill-paragraph) (setq-local add-log-current-defun-function #'css-current-defun-name) (smie-setup css-smie-grammar #'css-smie-rules -- 2.1.4 From adad951e4b139c27accb00fa7a0f47c25594c9f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simen=20Heggest=C3=B8yl?= <simenheg <at> gmail.com> Date: Mon, 30 Mar 2015 22:38:10 +0200 Subject: [PATCH 2/2] Move `css-mode.el' from `textmodes' to `progmodes' --- lisp/ChangeLog | 2 + lisp/progmodes/css-mode.el | 508 +++++++++++++++++++++++++++++++++++++++++++++ lisp/textmodes/css-mode.el | 508 --------------------------------------------- 3 files changed, 510 insertions(+), 508 deletions(-) create mode 100644 lisp/progmodes/css-mode.el delete mode 100644 lisp/textmodes/css-mode.el diff --git a/lisp/ChangeLog b/lisp/ChangeLog index f95139c..00d618c 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,7 @@ 2015-03-30 Simen Heggestøyl <simenheg <at> gmail.com> + * textmodes/css-mode.el: Move file to the `progmodes' directory. + * textmodes/css-mode.el (css-mode): Derive from `prog-mode'. 2015-03-30 Alan Mackenzie <acm <at> muc.de> diff --git a/lisp/progmodes/css-mode.el b/lisp/progmodes/css-mode.el new file mode 100644 index 0000000..7280080 --- /dev/null +++ b/lisp/progmodes/css-mode.el @@ -0,0 +1,508 @@ +;;; css-mode.el --- Major mode to edit CSS files -*- lexical-binding: t -*- + +;; Copyright (C) 2006-2015 Free Software Foundation, Inc. + +;; Author: Stefan Monnier <monnier <at> iro.umontreal.ca> +;; Maintainer: Simen Heggestøyl <simenheg <at> gmail.com> +;; Keywords: hypermedia + +;; This file is part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs 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 GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Yet another CSS mode. + +;;; Todo: + +;; - electric ; and } +;; - filling code with auto-fill-mode +;; - attribute value completion +;; - fix font-lock errors with multi-line selectors + +;;; Code: + +(defgroup css nil + "Cascading Style Sheets (CSS) editing mode." + :group 'languages) + +(defconst css-pseudo-class-ids + '("active" "checked" "disabled" "empty" "enabled" "first" + "first-child" "first-of-type" "focus" "hover" "indeterminate" "lang" + "last-child" "last-of-type" "left" "link" "nth-child" + "nth-last-child" "nth-last-of-type" "nth-of-type" "only-child" + "only-of-type" "right" "root" "target" "visited") + "Identifiers for pseudo-classes.") + +(defconst css-pseudo-element-ids + '("after" "before" "first-letter" "first-line") + "Identifiers for pseudo-elements.") + +(defconst css-at-ids + '("charset" "font-face" "import" "media" "namespace" "page") + "Identifiers that appear in the form @foo.") + +(defconst css-descriptor-ids + '("ascent" "baseline" "bbox" "cap-height" "centerline" "definition-src" + "descent" "font-family" "font-size" "font-stretch" "font-style" + "font-variant" "font-weight" "mathline" "panose-1" "slope" "src" "stemh" + "stemv" "topline" "unicode-range" "units-per-em" "widths" "x-height") + "Identifiers for font descriptors.") + +(defconst css-media-ids + '("all" "aural" "bitmap" "continuous" "grid" "paged" "static" "tactile" + "visual") + "Identifiers for types of media.") + +(defconst css-property-ids + '(;; CSS 2.1 properties (http://www.w3.org/TR/CSS21/propidx.html). + ;; + ;; Properties duplicated by any of the CSS3 modules below have + ;; been removed. + "azimuth" "border-collapse" "border-spacing" "bottom" + "caption-side" "clear" "clip" "content" "counter-increment" + "counter-reset" "cue" "cue-after" "cue-before" "direction" "display" + "elevation" "empty-cells" "float" "height" "left" "line-height" + "list-style" "list-style-image" "list-style-position" + "list-style-type" "margin" "margin-bottom" "margin-left" + "margin-right" "margin-top" "max-height" "max-width" "min-height" + "min-width" "orphans" "overflow" "padding" "padding-bottom" + "padding-left" "padding-right" "padding-top" "page-break-after" + "page-break-before" "page-break-inside" "pause" "pause-after" + "pause-before" "pitch" "pitch-range" "play-during" "position" + "quotes" "richness" "right" "speak" "speak-header" "speak-numeral" + "speak-punctuation" "speech-rate" "stress" "table-layout" "top" + "unicode-bidi" "vertical-align" "visibility" "voice-family" "volume" + "widows" "width" "z-index" + + ;; CSS Animations + ;; (http://www.w3.org/TR/css3-animations/#property-index) + "animation" "animation-delay" "animation-direction" + "animation-duration" "animation-fill-mode" + "animation-iteration-count" "animation-name" + "animation-play-state" "animation-timing-function" + + ;; CSS Backgrounds and Borders Module Level 3 + ;; (http://www.w3.org/TR/css3-background/#property-index) + "background" "background-attachment" "background-clip" + "background-color" "background-image" "background-origin" + "background-position" "background-repeat" "background-size" + "border" "border-bottom" "border-bottom-color" + "border-bottom-left-radius" "border-bottom-right-radius" + "border-bottom-style" "border-bottom-width" "border-color" + "border-image" "border-image-outset" "border-image-repeat" + "border-image-slice" "border-image-source" "border-image-width" + "border-left" "border-left-color" "border-left-style" + "border-left-width" "border-radius" "border-right" + "border-right-color" "border-right-style" "border-right-width" + "border-style" "border-top" "border-top-color" + "border-top-left-radius" "border-top-right-radius" + "border-top-style" "border-top-width" "border-width" "box-shadow" + + ;; CSS Basic User Interface Module Level 3 (CSS3 UI) + ;; (http://www.w3.org/TR/css3-ui/#property-index) + "box-sizing" "caret-color" "cursor" "nav-down" "nav-left" + "nav-right" "nav-up" "outline" "outline-color" "outline-offset" + "outline-style" "outline-width" "resize" "text-overflow" + + ;; CSS Color Module Level 3 + ;; (http://www.w3.org/TR/css3-color/#property) + "color" "opacity" + + ;; CSS Flexible Box Layout Module Level 1 + ;; (http://www.w3.org/TR/css-flexbox-1/#property-index) + "align-content" "align-items" "align-self" "flex" "flex-basis" + "flex-direction" "flex-flow" "flex-grow" "flex-shrink" "flex-wrap" + "justify-content" "order" + + ;; CSS Fonts Module Level 3 + ;; (http://www.w3.org/TR/css3-fonts/#property-index) + "font" "font-family" "font-feature-settings" "font-kerning" + "font-language-override" "font-size" "font-size-adjust" + "font-stretch" "font-style" "font-synthesis" "font-variant" + "font-variant-alternates" "font-variant-caps" + "font-variant-east-asian" "font-variant-ligatures" + "font-variant-numeric" "font-variant-position" "font-weight" + + ;; CSS Text Decoration Module Level 3 + ;; (http://dev.w3.org/csswg/css-text-decor-3/#property-index) + "text-decoration" "text-decoration-color" "text-decoration-line" + "text-decoration-skip" "text-decoration-style" "text-emphasis" + "text-emphasis-color" "text-emphasis-position" "text-emphasis-style" + "text-shadow" "text-underline-position" + + ;; CSS Text Module Level 3 + ;; (http://www.w3.org/TR/css3-text/#property-index) + "hanging-punctuation" "hyphens" "letter-spacing" "line-break" + "overflow-wrap" "tab-size" "text-align" "text-align-last" + "text-indent" "text-justify" "text-transform" "white-space" + "word-break" "word-spacing" "word-wrap" + + ;; CSS Transforms Module Level 1 + ;; (http://www.w3.org/TR/css3-2d-transforms/#property-index) + "backface-visibility" "perspective" "perspective-origin" + "transform" "transform-origin" "transform-style" + + ;; CSS Transitions + ;; (http://www.w3.org/TR/css3-transitions/#property-index) + "transition" "transition-delay" "transition-duration" + "transition-property" "transition-timing-function" + + ;; Filter Effects Module Level 1 + ;; (http://www.w3.org/TR/filter-effects/#property-index) + "color-interpolation-filters" "filter" "flood-color" + "flood-opacity" "lighting-color") + "Identifiers for properties.") + +(defcustom css-electric-keys '(?\} ?\;) ;; '() + "Self inserting keys which should trigger re-indentation." + :version "22.2" + :type '(repeat character) + :options '((?\} ?\;)) + :group 'css) + +(defvar css-mode-syntax-table + (let ((st (make-syntax-table))) + ;; C-style comments. + (modify-syntax-entry ?/ ". 14" st) + (modify-syntax-entry ?* ". 23b" st) + ;; Strings. + (modify-syntax-entry ?\" "\"" st) + (modify-syntax-entry ?\' "\"" st) + ;; Blocks. + (modify-syntax-entry ?\{ "(}" st) + (modify-syntax-entry ?\} "){" st) + ;; Args in url(...) thingies and other "function calls". + (modify-syntax-entry ?\( "()" st) + (modify-syntax-entry ?\) ")(" st) + ;; To match attributes in selectors. + (modify-syntax-entry ?\[ "(]" st) + (modify-syntax-entry ?\] ")[" st) + ;; Special chars that sometimes come at the beginning of words. + (modify-syntax-entry ?@ "'" st) + ;; (modify-syntax-entry ?: "'" st) + (modify-syntax-entry ?# "'" st) + ;; Distinction between words and symbols. + (modify-syntax-entry ?- "_" st) + st)) + +(defconst css-escapes-re + "\\\\\\(?:[^\000-\037\177]\\|[0-9a-fA-F]+[ \n\t\r\f]?\\)") +(defconst css-nmchar-re (concat "\\(?:[-[:alnum:]]\\|" css-escapes-re "\\)")) +(defconst css-nmstart-re (concat "\\(?:[[:alpha:]]\\|" css-escapes-re "\\)")) +(defconst css-ident-re ;; (concat css-nmstart-re css-nmchar-re "*") + ;; Apparently, "at rules" names can start with a dash, e.g. @-moz-keyframes. + (concat css-nmchar-re "+")) +(defconst css-proprietary-nmstart-re ;; Vendor-specific properties. + (concat "[-_]" (regexp-opt '("ms" "moz" "o" "khtml" "webkit")) "-")) +(defconst css-name-re (concat css-nmchar-re "+")) + +(defconst scss--hash-re "#\\(?:{[$-_[:alnum:]]+}\\|[[:alnum:]]+\\)") + +(defface css-selector '((t :inherit font-lock-function-name-face)) + "Face to use for selectors." + :group 'css) +(defface css-property '((t :inherit font-lock-variable-name-face)) + "Face to use for properties." + :group 'css) +(defface css-proprietary-property '((t :inherit (css-property italic))) + "Face to use for vendor-specific properties.") + +(defun css--font-lock-keywords (&optional sassy) + `((,(concat "!\\s-*" + (regexp-opt (append (if sassy '("global")) + '("important")))) + (0 font-lock-builtin-face)) + ;; Atrules keywords. IDs not in css-at-ids are valid (ignored). + ;; In fact the regexp should probably be + ;; (,(concat "\\(@" css-ident-re "\\)\\([ \t\n][^;{]*\\)[;{]") + ;; (1 font-lock-builtin-face)) + ;; Since "An at-rule consists of everything up to and including the next + ;; semicolon (;) or the next block, whichever comes first." + (,(concat "@" css-ident-re) (0 font-lock-builtin-face)) + ;; Selectors. + ;; FIXME: attribute selectors don't work well because they may contain + ;; strings which have already been highlighted as f-l-string-face and + ;; thus prevent this highlighting from being applied (actually now that + ;; I use `keep' this should work better). But really the part of the + ;; selector between [...] should simply not be highlighted. + (,(concat + "^[ \t]*\\(" + (if (not sassy) + ;; We don't allow / as first char, so as not to + ;; take a comment as the beginning of a selector. + "[^@/:{} \t\n][^:{}]+" + ;; Same as for non-sassy except we do want to allow { and } + ;; chars in selectors in the case of #{$foo} + ;; variable interpolation! + (concat "\\(?:" scss--hash-re + "\\|[^@/:{} \t\n#]\\)" + "[^:{}#]*\\(?:" scss--hash-re "[^:{}#]*\\)*")) + ;; Even though pseudo-elements should be prefixed by ::, a + ;; single colon is accepted for backward compatibility. + "\\(?:\\(:" (regexp-opt (append css-pseudo-class-ids + css-pseudo-element-ids) t) + "\\|\\::" (regexp-opt css-pseudo-element-ids t) "\\)" + "\\(?:([^\)]+)\\)?" + (if (not sassy) + "[^:{}\n]*" + (concat "[^:{}\n#]*\\(?:" scss--hash-re "[^:{}\n#]*\\)*")) + "\\)*" + "\\)\\(?:\n[ \t]*\\)*{") + (1 'css-selector keep)) + ;; In the above rule, we allow the open-brace to be on some subsequent + ;; line. This will only work if we properly mark the intervening text + ;; as being part of a multiline element (and even then, this only + ;; ensures proper refontification, but not proper discovery). + ("^[ \t]*{" (0 (save-excursion + (goto-char (match-beginning 0)) + (skip-chars-backward " \n\t") + (put-text-property (point) (match-end 0) + 'font-lock-multiline t) + ;; No face. + nil))) + ;; Properties. Again, we don't limit ourselves to css-property-ids. + (,(concat "\\(?:[{;]\\|^\\)[ \t]*\\(" + "\\(?:\\(" css-proprietary-nmstart-re "\\)\\|" + css-nmstart-re "\\)" css-nmchar-re "*" + "\\)\\s-*:") + (1 (if (match-end 2) 'css-proprietary-property 'css-property))))) + +(defvar css-font-lock-keywords (css--font-lock-keywords)) + +(defvar css-font-lock-defaults + '(css-font-lock-keywords nil t)) + +(defcustom css-indent-offset 4 + "Basic size of one indentation step." + :version "22.2" + :type 'integer) + +(require 'smie) + +(defconst css-smie-grammar + (smie-prec2->grammar + (smie-precs->prec2 '((assoc ";") (assoc ",") (left ":"))))) + +(defun css-smie--forward-token () + (cond + ((and (eq (char-before) ?\}) + (scss-smie--not-interpolation-p) + ;; FIXME: If the next char is not whitespace, what should we do? + (or (memq (char-after) '(?\s ?\t ?\n)) + (looking-at comment-start-skip))) + (if (memq (char-after) '(?\s ?\t ?\n)) + (forward-char 1) (forward-comment 1)) + ";") + ((progn (forward-comment (point-max)) + (looking-at "[;,:]")) + (forward-char 1) (match-string 0)) + (t (smie-default-forward-token)))) + +(defun css-smie--backward-token () + (let ((pos (point))) + (forward-comment (- (point))) + (cond + ;; FIXME: If the next char is not whitespace, what should we do? + ((and (eq (char-before) ?\}) (scss-smie--not-interpolation-p) + (> pos (point))) ";") + ((memq (char-before) '(?\; ?\, ?\:)) + (forward-char -1) (string (char-after))) + (t (smie-default-backward-token))))) + +(defun css-smie-rules (kind token) + (pcase (cons kind token) + (`(:elem . basic) css-indent-offset) + (`(:elem . arg) 0) + (`(:list-intro . ,(or `";" `"")) t) ;"" stands for BOB (bug#15467). + (`(:before . ,(or "{" "(")) + (if (smie-rule-hanging-p) (smie-rule-parent 0))))) + +;;; Completion + +(defun css--complete-property () + "Complete property at point." + (save-excursion + (let ((pos (point))) + (skip-chars-backward "-[:alnum:]") + (let ((start (point))) + (skip-chars-backward " \t\r\n") + (when (memq (char-before) '(?\{ ?\;)) + (list start pos css-property-ids)))))) + +(defun css--complete-pseudo-element-or-class () + "Complete pseudo-element or pseudo-class at point." + (save-excursion + (let ((pos (point))) + (skip-chars-backward "-[:alnum:]") + (when (eq (char-before) ?\:) + (list (point) pos + (if (eq (char-before (- (point) 1)) ?\:) + css-pseudo-element-ids + css-pseudo-class-ids)))))) + +(defun css--complete-at-rule () + "Complete at-rule (statement beginning with `@') at point." + (save-excursion + (let ((pos (point))) + (skip-chars-backward "-[:alnum:]") + (when (eq (char-before) ?\@) + (list (point) pos css-at-ids))))) + +(defun css-completion-at-point () + "Complete current symbol at point. +Currently supports completion of CSS properties, pseudo-elements, +pseudo-classes, and at-rules." + (or (css--complete-property) + (css--complete-pseudo-element-or-class) + (css--complete-at-rule))) + +;;;###autoload +(define-derived-mode css-mode prog-mode "CSS" + "Major mode to edit Cascading Style Sheets." + (setq-local font-lock-defaults css-font-lock-defaults) + (setq-local comment-start "/*") + (setq-local comment-start-skip "/\\*+[ \t]*") + (setq-local comment-end "*/") + (setq-local comment-end-skip "[ \t]*\\*+/") + (setq-local fill-paragraph-function 'css-fill-paragraph) + (setq-local add-log-current-defun-function #'css-current-defun-name) + (smie-setup css-smie-grammar #'css-smie-rules + :forward-token #'css-smie--forward-token + :backward-token #'css-smie--backward-token) + (setq-local electric-indent-chars + (append css-electric-keys electric-indent-chars)) + (add-hook 'completion-at-point-functions + #'css-completion-at-point nil 'local)) + +(defvar comment-continue) + +(defun css-fill-paragraph (&optional justify) + (save-excursion + (let ((ppss (syntax-ppss)) + (eol (line-end-position))) + (cond + ((and (nth 4 ppss) + (save-excursion + (goto-char (nth 8 ppss)) + (forward-comment 1) + (prog1 (not (bolp)) + (setq eol (point))))) + ;; Filling inside a comment whose comment-end marker is not \n. + ;; This code is meant to be generic, so that it works not only for + ;; css-mode but for all modes. + (save-restriction + (narrow-to-region (nth 8 ppss) eol) + (comment-normalize-vars) ;Will define comment-continue. + (let ((fill-paragraph-function nil) + (paragraph-separate + (if (and comment-continue + (string-match "[^ \t]" comment-continue)) + (concat "\\(?:[ \t]*" (regexp-quote comment-continue) + "\\)?\\(?:" paragraph-separate "\\)") + paragraph-separate)) + (paragraph-start + (if (and comment-continue + (string-match "[^ \t]" comment-continue)) + (concat "\\(?:[ \t]*" (regexp-quote comment-continue) + "\\)?\\(?:" paragraph-start "\\)") + paragraph-start))) + (fill-paragraph justify) + ;; Don't try filling again. + t))) + + ((and (null (nth 8 ppss)) + (or (nth 1 ppss) + (and (ignore-errors + (down-list 1) + (when (<= (point) eol) + (setq ppss (syntax-ppss))))))) + (goto-char (nth 1 ppss)) + (let ((end (save-excursion + (ignore-errors (forward-sexp 1) (copy-marker (point) t))))) + (when end + (while (re-search-forward "[{;}]" end t) + (cond + ;; This is a false positive inside a string or comment. + ((nth 8 (syntax-ppss)) nil) + ;; This is a false positive when encountering an + ;; interpolated variable (bug#19751). + ((eq (char-before (- (point) 1)) ?#) nil) + ((eq (char-before) ?\}) + (save-excursion + (forward-char -1) + (skip-chars-backward " \t") + (when (and (not (bolp)) + (scss-smie--not-interpolation-p)) + (newline)))) + (t + (while + (progn + (setq eol (line-end-position)) + (and (forward-comment 1) + (> (point) eol) + ;; A multi-line comment should be on its own line. + (save-excursion (forward-comment -1) + (when (< (point) eol) + (newline) + t))))) + (if (< (point) eol) (newline))))) + (goto-char (nth 1 ppss)) + (indent-region (line-beginning-position 2) end) + ;; Don't use the default filling code. + t))))))) + +(defun css-current-defun-name () + "Return the name of the CSS section at point, or nil." + (save-excursion + (let ((max (max (point-min) (- (point) 1600)))) ; approx 20 lines back + (when (search-backward "{" max t) + (skip-chars-backward " \t\r\n") + (beginning-of-line) + (if (looking-at "^[ \t]*\\([^{\r\n]*[^ {\t\r\n]\\)") + (match-string-no-properties 1)))))) + +;;; SCSS mode + +(defvar scss-mode-syntax-table + (let ((st (make-syntax-table css-mode-syntax-table))) + (modify-syntax-entry ?/ ". 124" st) + (modify-syntax-entry ?\n ">" st) + st)) + +(defvar scss-font-lock-keywords + (append `((,(concat "$" css-ident-re) (0 font-lock-variable-name-face))) + (css--font-lock-keywords 'sassy) + `((,(concat "@mixin[ \t]+\\(" css-ident-re "\\)[ \t]*(") + (1 font-lock-function-name-face))))) + +(defun scss-smie--not-interpolation-p () + (save-excursion + (forward-char -1) + (or (zerop (skip-chars-backward "-[:alnum:]")) + (not (looking-back "#{\\$" (- (point) 3)))))) + +;;;###autoload (add-to-list 'auto-mode-alist '("\\.scss\\'" . scss-mode)) +;;;###autoload +(define-derived-mode scss-mode css-mode "SCSS" + "Major mode to edit \"Sassy CSS\" files." + (setq-local comment-start "// ") + (setq-local comment-end "") + (setq-local comment-start-skip "/[*/]+[ \t]*") + (setq-local comment-end-skip "[ \t]*\\(?:\n\\|\\*+/\\)") + (setq-local font-lock-defaults '(scss-font-lock-keywords nil t))) + +(provide 'css-mode) +;;; css-mode.el ends here diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el deleted file mode 100644 index 7280080..0000000 --- a/lisp/textmodes/css-mode.el +++ /dev/null @@ -1,508 +0,0 @@ -;;; css-mode.el --- Major mode to edit CSS files -*- lexical-binding: t -*- - -;; Copyright (C) 2006-2015 Free Software Foundation, Inc. - -;; Author: Stefan Monnier <monnier <at> iro.umontreal.ca> -;; Maintainer: Simen Heggestøyl <simenheg <at> gmail.com> -;; Keywords: hypermedia - -;; This file is part of GNU Emacs. - -;; GNU Emacs 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. - -;; GNU Emacs 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 GNU Emacs. If not, see <http://www.gnu.org/licenses/>. - -;;; Commentary: - -;; Yet another CSS mode. - -;;; Todo: - -;; - electric ; and } -;; - filling code with auto-fill-mode -;; - attribute value completion -;; - fix font-lock errors with multi-line selectors - -;;; Code: - -(defgroup css nil - "Cascading Style Sheets (CSS) editing mode." - :group 'languages) - -(defconst css-pseudo-class-ids - '("active" "checked" "disabled" "empty" "enabled" "first" - "first-child" "first-of-type" "focus" "hover" "indeterminate" "lang" - "last-child" "last-of-type" "left" "link" "nth-child" - "nth-last-child" "nth-last-of-type" "nth-of-type" "only-child" - "only-of-type" "right" "root" "target" "visited") - "Identifiers for pseudo-classes.") - -(defconst css-pseudo-element-ids - '("after" "before" "first-letter" "first-line") - "Identifiers for pseudo-elements.") - -(defconst css-at-ids - '("charset" "font-face" "import" "media" "namespace" "page") - "Identifiers that appear in the form @foo.") - -(defconst css-descriptor-ids - '("ascent" "baseline" "bbox" "cap-height" "centerline" "definition-src" - "descent" "font-family" "font-size" "font-stretch" "font-style" - "font-variant" "font-weight" "mathline" "panose-1" "slope" "src" "stemh" - "stemv" "topline" "unicode-range" "units-per-em" "widths" "x-height") - "Identifiers for font descriptors.") - -(defconst css-media-ids - '("all" "aural" "bitmap" "continuous" "grid" "paged" "static" "tactile" - "visual") - "Identifiers for types of media.") - -(defconst css-property-ids - '(;; CSS 2.1 properties (http://www.w3.org/TR/CSS21/propidx.html). - ;; - ;; Properties duplicated by any of the CSS3 modules below have - ;; been removed. - "azimuth" "border-collapse" "border-spacing" "bottom" - "caption-side" "clear" "clip" "content" "counter-increment" - "counter-reset" "cue" "cue-after" "cue-before" "direction" "display" - "elevation" "empty-cells" "float" "height" "left" "line-height" - "list-style" "list-style-image" "list-style-position" - "list-style-type" "margin" "margin-bottom" "margin-left" - "margin-right" "margin-top" "max-height" "max-width" "min-height" - "min-width" "orphans" "overflow" "padding" "padding-bottom" - "padding-left" "padding-right" "padding-top" "page-break-after" - "page-break-before" "page-break-inside" "pause" "pause-after" - "pause-before" "pitch" "pitch-range" "play-during" "position" - "quotes" "richness" "right" "speak" "speak-header" "speak-numeral" - "speak-punctuation" "speech-rate" "stress" "table-layout" "top" - "unicode-bidi" "vertical-align" "visibility" "voice-family" "volume" - "widows" "width" "z-index" - - ;; CSS Animations - ;; (http://www.w3.org/TR/css3-animations/#property-index) - "animation" "animation-delay" "animation-direction" - "animation-duration" "animation-fill-mode" - "animation-iteration-count" "animation-name" - "animation-play-state" "animation-timing-function" - - ;; CSS Backgrounds and Borders Module Level 3 - ;; (http://www.w3.org/TR/css3-background/#property-index) - "background" "background-attachment" "background-clip" - "background-color" "background-image" "background-origin" - "background-position" "background-repeat" "background-size" - "border" "border-bottom" "border-bottom-color" - "border-bottom-left-radius" "border-bottom-right-radius" - "border-bottom-style" "border-bottom-width" "border-color" - "border-image" "border-image-outset" "border-image-repeat" - "border-image-slice" "border-image-source" "border-image-width" - "border-left" "border-left-color" "border-left-style" - "border-left-width" "border-radius" "border-right" - "border-right-color" "border-right-style" "border-right-width" - "border-style" "border-top" "border-top-color" - "border-top-left-radius" "border-top-right-radius" - "border-top-style" "border-top-width" "border-width" "box-shadow" - - ;; CSS Basic User Interface Module Level 3 (CSS3 UI) - ;; (http://www.w3.org/TR/css3-ui/#property-index) - "box-sizing" "caret-color" "cursor" "nav-down" "nav-left" - "nav-right" "nav-up" "outline" "outline-color" "outline-offset" - "outline-style" "outline-width" "resize" "text-overflow" - - ;; CSS Color Module Level 3 - ;; (http://www.w3.org/TR/css3-color/#property) - "color" "opacity" - - ;; CSS Flexible Box Layout Module Level 1 - ;; (http://www.w3.org/TR/css-flexbox-1/#property-index) - "align-content" "align-items" "align-self" "flex" "flex-basis" - "flex-direction" "flex-flow" "flex-grow" "flex-shrink" "flex-wrap" - "justify-content" "order" - - ;; CSS Fonts Module Level 3 - ;; (http://www.w3.org/TR/css3-fonts/#property-index) - "font" "font-family" "font-feature-settings" "font-kerning" - "font-language-override" "font-size" "font-size-adjust" - "font-stretch" "font-style" "font-synthesis" "font-variant" - "font-variant-alternates" "font-variant-caps" - "font-variant-east-asian" "font-variant-ligatures" - "font-variant-numeric" "font-variant-position" "font-weight" - - ;; CSS Text Decoration Module Level 3 - ;; (http://dev.w3.org/csswg/css-text-decor-3/#property-index) - "text-decoration" "text-decoration-color" "text-decoration-line" - "text-decoration-skip" "text-decoration-style" "text-emphasis" - "text-emphasis-color" "text-emphasis-position" "text-emphasis-style" - "text-shadow" "text-underline-position" - - ;; CSS Text Module Level 3 - ;; (http://www.w3.org/TR/css3-text/#property-index) - "hanging-punctuation" "hyphens" "letter-spacing" "line-break" - "overflow-wrap" "tab-size" "text-align" "text-align-last" - "text-indent" "text-justify" "text-transform" "white-space" - "word-break" "word-spacing" "word-wrap" - - ;; CSS Transforms Module Level 1 - ;; (http://www.w3.org/TR/css3-2d-transforms/#property-index) - "backface-visibility" "perspective" "perspective-origin" - "transform" "transform-origin" "transform-style" - - ;; CSS Transitions - ;; (http://www.w3.org/TR/css3-transitions/#property-index) - "transition" "transition-delay" "transition-duration" - "transition-property" "transition-timing-function" - - ;; Filter Effects Module Level 1 - ;; (http://www.w3.org/TR/filter-effects/#property-index) - "color-interpolation-filters" "filter" "flood-color" - "flood-opacity" "lighting-color") - "Identifiers for properties.") - -(defcustom css-electric-keys '(?\} ?\;) ;; '() - "Self inserting keys which should trigger re-indentation." - :version "22.2" - :type '(repeat character) - :options '((?\} ?\;)) - :group 'css) - -(defvar css-mode-syntax-table - (let ((st (make-syntax-table))) - ;; C-style comments. - (modify-syntax-entry ?/ ". 14" st) - (modify-syntax-entry ?* ". 23b" st) - ;; Strings. - (modify-syntax-entry ?\" "\"" st) - (modify-syntax-entry ?\' "\"" st) - ;; Blocks. - (modify-syntax-entry ?\{ "(}" st) - (modify-syntax-entry ?\} "){" st) - ;; Args in url(...) thingies and other "function calls". - (modify-syntax-entry ?\( "()" st) - (modify-syntax-entry ?\) ")(" st) - ;; To match attributes in selectors. - (modify-syntax-entry ?\[ "(]" st) - (modify-syntax-entry ?\] ")[" st) - ;; Special chars that sometimes come at the beginning of words. - (modify-syntax-entry ?@ "'" st) - ;; (modify-syntax-entry ?: "'" st) - (modify-syntax-entry ?# "'" st) - ;; Distinction between words and symbols. - (modify-syntax-entry ?- "_" st) - st)) - -(defconst css-escapes-re - "\\\\\\(?:[^\000-\037\177]\\|[0-9a-fA-F]+[ \n\t\r\f]?\\)") -(defconst css-nmchar-re (concat "\\(?:[-[:alnum:]]\\|" css-escapes-re "\\)")) -(defconst css-nmstart-re (concat "\\(?:[[:alpha:]]\\|" css-escapes-re "\\)")) -(defconst css-ident-re ;; (concat css-nmstart-re css-nmchar-re "*") - ;; Apparently, "at rules" names can start with a dash, e.g. @-moz-keyframes. - (concat css-nmchar-re "+")) -(defconst css-proprietary-nmstart-re ;; Vendor-specific properties. - (concat "[-_]" (regexp-opt '("ms" "moz" "o" "khtml" "webkit")) "-")) -(defconst css-name-re (concat css-nmchar-re "+")) - -(defconst scss--hash-re "#\\(?:{[$-_[:alnum:]]+}\\|[[:alnum:]]+\\)") - -(defface css-selector '((t :inherit font-lock-function-name-face)) - "Face to use for selectors." - :group 'css) -(defface css-property '((t :inherit font-lock-variable-name-face)) - "Face to use for properties." - :group 'css) -(defface css-proprietary-property '((t :inherit (css-property italic))) - "Face to use for vendor-specific properties.") - -(defun css--font-lock-keywords (&optional sassy) - `((,(concat "!\\s-*" - (regexp-opt (append (if sassy '("global")) - '("important")))) - (0 font-lock-builtin-face)) - ;; Atrules keywords. IDs not in css-at-ids are valid (ignored). - ;; In fact the regexp should probably be - ;; (,(concat "\\(@" css-ident-re "\\)\\([ \t\n][^;{]*\\)[;{]") - ;; (1 font-lock-builtin-face)) - ;; Since "An at-rule consists of everything up to and including the next - ;; semicolon (;) or the next block, whichever comes first." - (,(concat "@" css-ident-re) (0 font-lock-builtin-face)) - ;; Selectors. - ;; FIXME: attribute selectors don't work well because they may contain - ;; strings which have already been highlighted as f-l-string-face and - ;; thus prevent this highlighting from being applied (actually now that - ;; I use `keep' this should work better). But really the part of the - ;; selector between [...] should simply not be highlighted. - (,(concat - "^[ \t]*\\(" - (if (not sassy) - ;; We don't allow / as first char, so as not to - ;; take a comment as the beginning of a selector. - "[^@/:{} \t\n][^:{}]+" - ;; Same as for non-sassy except we do want to allow { and } - ;; chars in selectors in the case of #{$foo} - ;; variable interpolation! - (concat "\\(?:" scss--hash-re - "\\|[^@/:{} \t\n#]\\)" - "[^:{}#]*\\(?:" scss--hash-re "[^:{}#]*\\)*")) - ;; Even though pseudo-elements should be prefixed by ::, a - ;; single colon is accepted for backward compatibility. - "\\(?:\\(:" (regexp-opt (append css-pseudo-class-ids - css-pseudo-element-ids) t) - "\\|\\::" (regexp-opt css-pseudo-element-ids t) "\\)" - "\\(?:([^\)]+)\\)?" - (if (not sassy) - "[^:{}\n]*" - (concat "[^:{}\n#]*\\(?:" scss--hash-re "[^:{}\n#]*\\)*")) - "\\)*" - "\\)\\(?:\n[ \t]*\\)*{") - (1 'css-selector keep)) - ;; In the above rule, we allow the open-brace to be on some subsequent - ;; line. This will only work if we properly mark the intervening text - ;; as being part of a multiline element (and even then, this only - ;; ensures proper refontification, but not proper discovery). - ("^[ \t]*{" (0 (save-excursion - (goto-char (match-beginning 0)) - (skip-chars-backward " \n\t") - (put-text-property (point) (match-end 0) - 'font-lock-multiline t) - ;; No face. - nil))) - ;; Properties. Again, we don't limit ourselves to css-property-ids. - (,(concat "\\(?:[{;]\\|^\\)[ \t]*\\(" - "\\(?:\\(" css-proprietary-nmstart-re "\\)\\|" - css-nmstart-re "\\)" css-nmchar-re "*" - "\\)\\s-*:") - (1 (if (match-end 2) 'css-proprietary-property 'css-property))))) - -(defvar css-font-lock-keywords (css--font-lock-keywords)) - -(defvar css-font-lock-defaults - '(css-font-lock-keywords nil t)) - -(defcustom css-indent-offset 4 - "Basic size of one indentation step." - :version "22.2" - :type 'integer) - -(require 'smie) - -(defconst css-smie-grammar - (smie-prec2->grammar - (smie-precs->prec2 '((assoc ";") (assoc ",") (left ":"))))) - -(defun css-smie--forward-token () - (cond - ((and (eq (char-before) ?\}) - (scss-smie--not-interpolation-p) - ;; FIXME: If the next char is not whitespace, what should we do? - (or (memq (char-after) '(?\s ?\t ?\n)) - (looking-at comment-start-skip))) - (if (memq (char-after) '(?\s ?\t ?\n)) - (forward-char 1) (forward-comment 1)) - ";") - ((progn (forward-comment (point-max)) - (looking-at "[;,:]")) - (forward-char 1) (match-string 0)) - (t (smie-default-forward-token)))) - -(defun css-smie--backward-token () - (let ((pos (point))) - (forward-comment (- (point))) - (cond - ;; FIXME: If the next char is not whitespace, what should we do? - ((and (eq (char-before) ?\}) (scss-smie--not-interpolation-p) - (> pos (point))) ";") - ((memq (char-before) '(?\; ?\, ?\:)) - (forward-char -1) (string (char-after))) - (t (smie-default-backward-token))))) - -(defun css-smie-rules (kind token) - (pcase (cons kind token) - (`(:elem . basic) css-indent-offset) - (`(:elem . arg) 0) - (`(:list-intro . ,(or `";" `"")) t) ;"" stands for BOB (bug#15467). - (`(:before . ,(or "{" "(")) - (if (smie-rule-hanging-p) (smie-rule-parent 0))))) - -;;; Completion - -(defun css--complete-property () - "Complete property at point." - (save-excursion - (let ((pos (point))) - (skip-chars-backward "-[:alnum:]") - (let ((start (point))) - (skip-chars-backward " \t\r\n") - (when (memq (char-before) '(?\{ ?\;)) - (list start pos css-property-ids)))))) - -(defun css--complete-pseudo-element-or-class () - "Complete pseudo-element or pseudo-class at point." - (save-excursion - (let ((pos (point))) - (skip-chars-backward "-[:alnum:]") - (when (eq (char-before) ?\:) - (list (point) pos - (if (eq (char-before (- (point) 1)) ?\:) - css-pseudo-element-ids - css-pseudo-class-ids)))))) - -(defun css--complete-at-rule () - "Complete at-rule (statement beginning with `@') at point." - (save-excursion - (let ((pos (point))) - (skip-chars-backward "-[:alnum:]") - (when (eq (char-before) ?\@) - (list (point) pos css-at-ids))))) - -(defun css-completion-at-point () - "Complete current symbol at point. -Currently supports completion of CSS properties, pseudo-elements, -pseudo-classes, and at-rules." - (or (css--complete-property) - (css--complete-pseudo-element-or-class) - (css--complete-at-rule))) - -;;;###autoload -(define-derived-mode css-mode prog-mode "CSS" - "Major mode to edit Cascading Style Sheets." - (setq-local font-lock-defaults css-font-lock-defaults) - (setq-local comment-start "/*") - (setq-local comment-start-skip "/\\*+[ \t]*") - (setq-local comment-end "*/") - (setq-local comment-end-skip "[ \t]*\\*+/") - (setq-local fill-paragraph-function 'css-fill-paragraph) - (setq-local add-log-current-defun-function #'css-current-defun-name) - (smie-setup css-smie-grammar #'css-smie-rules - :forward-token #'css-smie--forward-token - :backward-token #'css-smie--backward-token) - (setq-local electric-indent-chars - (append css-electric-keys electric-indent-chars)) - (add-hook 'completion-at-point-functions - #'css-completion-at-point nil 'local)) - -(defvar comment-continue) - -(defun css-fill-paragraph (&optional justify) - (save-excursion - (let ((ppss (syntax-ppss)) - (eol (line-end-position))) - (cond - ((and (nth 4 ppss) - (save-excursion - (goto-char (nth 8 ppss)) - (forward-comment 1) - (prog1 (not (bolp)) - (setq eol (point))))) - ;; Filling inside a comment whose comment-end marker is not \n. - ;; This code is meant to be generic, so that it works not only for - ;; css-mode but for all modes. - (save-restriction - (narrow-to-region (nth 8 ppss) eol) - (comment-normalize-vars) ;Will define comment-continue. - (let ((fill-paragraph-function nil) - (paragraph-separate - (if (and comment-continue - (string-match "[^ \t]" comment-continue)) - (concat "\\(?:[ \t]*" (regexp-quote comment-continue) - "\\)?\\(?:" paragraph-separate "\\)") - paragraph-separate)) - (paragraph-start - (if (and comment-continue - (string-match "[^ \t]" comment-continue)) - (concat "\\(?:[ \t]*" (regexp-quote comment-continue) - "\\)?\\(?:" paragraph-start "\\)") - paragraph-start))) - (fill-paragraph justify) - ;; Don't try filling again. - t))) - - ((and (null (nth 8 ppss)) - (or (nth 1 ppss) - (and (ignore-errors - (down-list 1) - (when (<= (point) eol) - (setq ppss (syntax-ppss))))))) - (goto-char (nth 1 ppss)) - (let ((end (save-excursion - (ignore-errors (forward-sexp 1) (copy-marker (point) t))))) - (when end - (while (re-search-forward "[{;}]" end t) - (cond - ;; This is a false positive inside a string or comment. - ((nth 8 (syntax-ppss)) nil) - ;; This is a false positive when encountering an - ;; interpolated variable (bug#19751). - ((eq (char-before (- (point) 1)) ?#) nil) - ((eq (char-before) ?\}) - (save-excursion - (forward-char -1) - (skip-chars-backward " \t") - (when (and (not (bolp)) - (scss-smie--not-interpolation-p)) - (newline)))) - (t - (while - (progn - (setq eol (line-end-position)) - (and (forward-comment 1) - (> (point) eol) - ;; A multi-line comment should be on its own line. - (save-excursion (forward-comment -1) - (when (< (point) eol) - (newline) - t))))) - (if (< (point) eol) (newline))))) - (goto-char (nth 1 ppss)) - (indent-region (line-beginning-position 2) end) - ;; Don't use the default filling code. - t))))))) - -(defun css-current-defun-name () - "Return the name of the CSS section at point, or nil." - (save-excursion - (let ((max (max (point-min) (- (point) 1600)))) ; approx 20 lines back - (when (search-backward "{" max t) - (skip-chars-backward " \t\r\n") - (beginning-of-line) - (if (looking-at "^[ \t]*\\([^{\r\n]*[^ {\t\r\n]\\)") - (match-string-no-properties 1)))))) - -;;; SCSS mode - -(defvar scss-mode-syntax-table - (let ((st (make-syntax-table css-mode-syntax-table))) - (modify-syntax-entry ?/ ". 124" st) - (modify-syntax-entry ?\n ">" st) - st)) - -(defvar scss-font-lock-keywords - (append `((,(concat "$" css-ident-re) (0 font-lock-variable-name-face))) - (css--font-lock-keywords 'sassy) - `((,(concat "@mixin[ \t]+\\(" css-ident-re "\\)[ \t]*(") - (1 font-lock-function-name-face))))) - -(defun scss-smie--not-interpolation-p () - (save-excursion - (forward-char -1) - (or (zerop (skip-chars-backward "-[:alnum:]")) - (not (looking-back "#{\\$" (- (point) 3)))))) - -;;;###autoload (add-to-list 'auto-mode-alist '("\\.scss\\'" . scss-mode)) -;;;###autoload -(define-derived-mode scss-mode css-mode "SCSS" - "Major mode to edit \"Sassy CSS\" files." - (setq-local comment-start "// ") - (setq-local comment-end "") - (setq-local comment-start-skip "/[*/]+[ \t]*") - (setq-local comment-end-skip "[ \t]*\\(?:\n\\|\\*+/\\)") - (setq-local font-lock-defaults '(scss-font-lock-keywords nil t))) - -(provide 'css-mode) -;;; css-mode.el ends here -- 2.1.4
[Message part 2 (text/html, inline)]
bug-gnu-emacs <at> gnu.org
:bug#20226
; Package emacs
.
(Mon, 30 Mar 2015 22:05:02 GMT) Full text and rfc822 format available.Message #14 received at 20226 <at> debbugs.gnu.org (full text, mbox):
From: Stefan Monnier <monnier <at> iro.umontreal.ca> To: Simen Heggestøyl <simenheg <at> gmail.com> Cc: 20226 <at> debbugs.gnu.org Subject: Re: bug#20226: 25.0.50; [PATCH] Make (S)CSS mode require final newline Date: Mon, 30 Mar 2015 18:03:53 -0400
> Good! Then I propose the following two patches: The first looks good. I think the second is kind of pointless. Stefan
Simen Heggestøyl <simenheg <at> gmail.com>
:Simen Heggestøyl <simenheg <at> gmail.com>
:Message #19 received at 20226-done <at> debbugs.gnu.org (full text, mbox):
From: Simen Heggestøyl <simenheg <at> gmail.com> To: Stefan Monnier <monnier <at> iro.umontreal.ca> Cc: 20226-done <at> debbugs.gnu.org Subject: Re: bug#20226: 25.0.50; [PATCH] Make (S)CSS mode require final newline Date: Tue, 31 Mar 2015 20:05:02 +0200
[Message part 1 (text/plain, inline)]
On Tue, Mar 31, 2015 at 12:03 AM, Stefan Monnier <monnier <at> iro.umontreal.ca> wrote: >> Good! Then I propose the following two patches: > > The first looks good. I think the second is kind of pointless. > > > Stefan I would find it more logical for `css-mode.el' to reside in `progmodes' together with the other progmodes, but it's not important. I've installed the first patch!
[Message part 2 (text/html, inline)]
bug-gnu-emacs <at> gnu.org
:bug#20226
; Package emacs
.
(Tue, 31 Mar 2015 21:13:01 GMT) Full text and rfc822 format available.Message #22 received at 20226-done <at> debbugs.gnu.org (full text, mbox):
From: Stefan Monnier <monnier <at> iro.umontreal.ca> To: Simen Heggestøyl <simenheg <at> gmail.com> Cc: 20226-done <at> debbugs.gnu.org Subject: Re: bug#20226: 25.0.50; [PATCH] Make (S)CSS mode require final newline Date: Tue, 31 Mar 2015 17:12:15 -0400
> I would find it more logical for `css-mode.el' to reside in `progmodes' > together with the other progmodes, There's some logic to it, but: > but it's not important. That's the main point. Moving files just because it's marginally more logical is just making history-digging harder for very little benefit. [ The textmodes directory has many such "borderline" cases. E.g. tex-mode.el can just as well be considered a programming mode. ] > I've installed the first patch! Thanks, Stefan
Debbugs Internal Request <help-debbugs <at> gnu.org>
to internal_control <at> debbugs.gnu.org
.
(Wed, 29 Apr 2015 11:24:05 GMT) Full text and rfc822 format available.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.