unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* css-mode
@ 2006-01-13 17:27 Stefan Monnier
  2006-01-13 20:33 ` css-mode Edward O'Connor
  2006-01-14 16:14 ` css-mode Richard M. Stallman
  0 siblings, 2 replies; 16+ messages in thread
From: Stefan Monnier @ 2006-01-13 17:27 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 251 bytes --]


I wish Emacs came builtin with a mode to edit CSS style files.
There are several floating around the net and I have my own (see below).

I don't really care which one is installed, but I just hope one of them
makes it into Emacs-22.


        Stefan

[-- Attachment #2: css-mode.el --]
[-- Type: application/emacs-lisp, Size: 11461 bytes --]

[-- Attachment #3: Type: text/plain, Size: 142 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: css-mode
  2006-01-13 17:27 css-mode Stefan Monnier
@ 2006-01-13 20:33 ` Edward O'Connor
  2006-01-13 22:16   ` css-mode Stefan Monnier
  2006-01-14 16:14 ` css-mode Richard M. Stallman
  1 sibling, 1 reply; 16+ messages in thread
From: Edward O'Connor @ 2006-01-13 20:33 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 569 bytes --]

> I wish Emacs came builtin with a mode to edit CSS style files.

Indeed!

> There are several floating around the net and I have my own (see
> below).

I had two issues trying to use your css-mode.el:

1. looks like the `css-nmchar-re' and `css-nmstart-re' definitions are
   messed up (patch attached).

2. `prog-mode' in not defined in my Emacs. Where does it come from?

> I don't really care which one is installed, but I just hope one of
> them makes it into Emacs-22.

Seconded.

-- 
Edward O'Connor
hober0@gmail.com

Ense petit placidam sub libertate quietem.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: fix defconsts in css-mode.el --]
[-- Type: text/x-patch, Size: 637 bytes --]

--- css-mode.el.orig	2006-01-13 12:30:22.000000000 -0800
+++ css-mode.el	2006-01-13 12:25:00.000000000 -0800
@@ -132,8 +132,8 @@
 
 (defconst css-escapes-re
   "\\\\\\(?:[^\000-\037\177]\\|[0-9a-fA-F]+[ \n\t\r\f]?\\)")
-(defconst css-nmchar-re "\\(?:[-[:alnum:]]\\|" css-escapes-re "\\)")
-(defconst css-nmstart-re "\\(?:[[:alpha:]]\\|" css-escapes-re "\\)")
+(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 "*"))
 (defconst css-name-re (concat css-nmchar-re "+"))
 

[-- Attachment #3: Type: text/plain, Size: 142 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: css-mode
  2006-01-13 20:33 ` css-mode Edward O'Connor
@ 2006-01-13 22:16   ` Stefan Monnier
  0 siblings, 0 replies; 16+ messages in thread
From: Stefan Monnier @ 2006-01-13 22:16 UTC (permalink / raw)
  Cc: emacs-devel

> I had two issues trying to use your css-mode.el:
> 1. looks like the `css-nmchar-re' and `css-nmstart-re' definitions are
>    messed up (patch attached).

Duh, yes, that's why I get for doing edits just before sending.

> 2. `prog-mode' in not defined in my Emacs. Where does it come from?

You can use nil instead.  It's a parent mode that I'm using, similar to
text-mode, except it's only useful as a parent mode.


        Stefan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: css-mode
  2006-01-13 17:27 css-mode Stefan Monnier
  2006-01-13 20:33 ` css-mode Edward O'Connor
@ 2006-01-14 16:14 ` Richard M. Stallman
  2006-01-15  1:09   ` css-mode Kenichi Handa
  1 sibling, 1 reply; 16+ messages in thread
From: Richard M. Stallman @ 2006-01-14 16:14 UTC (permalink / raw)
  Cc: emacs-devel

Installing such a mode is pretty harmless, so you can
install one if you wish.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: css-mode
  2006-01-14 16:14 ` css-mode Richard M. Stallman
@ 2006-01-15  1:09   ` Kenichi Handa
  2006-01-15 13:34     ` css-mode Alex Schroeder
  0 siblings, 1 reply; 16+ messages in thread
From: Kenichi Handa @ 2006-01-15  1:09 UTC (permalink / raw)
  Cc: monnier, emacs-devel

In article <E1Exo2i-0007uK-7h@fencepost.gnu.org>, "Richard M. Stallman" <rms@gnu.org> writes:

> Installing such a mode is pretty harmless, so you can
> install one if you wish.

But, if it has a bug or a questionable behavior, we will be
drawn into a discussion, and that consumes our time.

---
Kenichi Handa
handa@m17n.org

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: css-mode
  2006-01-15  1:09   ` css-mode Kenichi Handa
@ 2006-01-15 13:34     ` Alex Schroeder
  2006-01-17 11:39       ` css-mode Karl Chen
  2006-01-21  2:55       ` css-mode Stefan Monnier
  0 siblings, 2 replies; 16+ messages in thread
From: Alex Schroeder @ 2006-01-15 13:34 UTC (permalink / raw)


The one I'm using is the following.  The feature I was most interested
in was the correct indentation of nested statements, eg.

@media print {
    div.content {
        font-size: 16pt;
    }
}               

And I wanted M-q to do the right thing.  I currently don't fill
comments correctly, and highlighting for non-trivial selectors doesn't
always work.

I agree with Handa, though: This will cause more discussion.

Alex.

;;; css-mode.el --- A minimal CSS mode.
;; Copyright 2002  Lawrence Mitchell
;; Copyright 2005  Alex Schroeder

;; 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 2 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, write to the Free
;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
;; MA 02111-1307 USA

;;; Commentary:

;; A (very) minimal CSS mode.  Does indentation, some font-locking and
;; nothing more.

;;; Code:

(eval-when-compile
  (defvar comment-quote-nested))

(defvar css-mode-map nil
  "Keymap for `css-mode'.")

(defvar css-mode-indent-depth 4
  "*Depth of indentation.")

(defvar css-mode-font-lock-keywords-1
  (eval-when-compile
    (let ((keywords (regexp-opt
                     '("a" "abbr" "acronym" "address" "applet" "area" "b"
                       "base" "basefont" "bdo" "big" "blockquote" "body" "br"
                       "button" "caption" "center" "cite" "code" "col"
                       "colgroup" "dd" "del" "dfn" "dir" "div" "dl" "dt" "em"
                       "fieldset" "font" "form" "frame" "frameset" "h1" "h2"
                       "h3" "h4" "h5" "h6" "head" "hr" "html" "i" "iframe"
                       "img" "input" "ins" "isindex" "kbd" "label" "legend"
                       "li" "link" "map" "menu" "meta" "noframes" "noscript"
                       "object" "ol" "optgroup" "option" "p" "param" "pre" "q"
                       "s" "samp" "script" "select" "small" "span" "strike"
                       "strong" "style" "sub" "sup" "table" "tbody" "td"
                       "textarea" "tfoot" "th" "thead" "title" "tr" "tt" "u"
                       "ul" "var"))))
      (list
       (list
        (concat "\\b\\(" keywords "\\)[]{. \t]")
        1 'font-lock-keyword-face))))
  "Normal level higlighting for `css-mode'.")

(defvar css-mode-font-lock-keywords-2
  (append css-mode-font-lock-keywords-1
          (eval-when-compile
            (let ((keywords (regexp-opt
                             '("azimuth" "background" "background-attachment" "background-color"
                               "background-image" "background-position" "background-repeat"
                               "border" "border-collapse" "border-color" "border-spacing"
                               "border-style" "border-top" "border-right" "border-bottom"
                               "border-left" "border-top-color" "border-right-color"
                               "border-bottom-color" "border-left-color" "border-top-style"
                               "border-right-style" "border-bottom-style" "border-left-style"
                               "border-top-width" "border-right-width" "border-bottom-width"
                               "border-left-width" "border-width" "bottom" "caption-side"
                               "clear" "clip" "color" "content" "counter-increment"
                               "counter-reset" "cue" "cue-after" "cue-before" "cursor"
                               "direction" "display" "elevation" "empty-cells" "float" "font"
                               "font-family" "font-size" "font-size-adjust" "font-stretch"
                               "font-style" "font-variant" "font-weight" "height" "left"
                               "letter-spacing" "line-height" "list-style" "list-style-image"
                               "list-style-position" "list-style-type" "margin" "margin-top"
                               "margin-right" "margin-bottom" "margin-left" "marker-offset"
                               "marks" "max-height" "max-width" "min-height" "min-width"
                               "orphans" "outline" "outline-color" "outline-style"
                               "outline-width" "overflow" "padding" "padding-top"
                               "padding-right" "padding-bottom" "padding-left" "page"
                               "page-break-after" "page-break-before" "page-break-inside"
                               "pause" "pause-after" "pause-before" "pitch" "pitch-range"
                               "play-during" "position" "quotes" "richness" "right" "size"
                               "speak" "speak-header" "speak-numeral" "speak-punctuation"
                               "speech-rate" "stress" "table-layout" "text-align"
                               "text-decoration" "text-indent" "text-shadow" "text-transform"
                               "top" "unicode-bidi" "vertical-align" "visibility" "voice-family"
                               "volume" "white-space" "widows" "width" "word-spacing"
                               "z-index"))))
              (list
               (list
                (concat "\\<\\("
                        keywords
                        "\\)\\>[ \t]*:")
                1 'font-lock-type-face)))))
  "Gaudy level highlighting for `css-mode'.")

;; this is too excessive.
;; (defvar css-mode-font-lock-keywords-3
;;   (append css-mode-font-lock-keywords-2
;;           (eval-when-compile
;;             (list
;;              (list
;;               ":[ \t]*\\(.*\\);"
;;               1 'font-lock-variable-name-face)
;;              (list
;;               ":[ \t]*\\(rgb\\)([ \t]*[0-9]+[ \t]*,[ \t]*[0-9]+[ \t]*,[ \t]*[0-9]+[ \t]*)"
;;               1 'font-lock-function-name-face 'prepend))))
;;   "Incredibly over-the-top highlighting for `css-mode'.")
              
(defvar css-mode-font-lock-keywords css-mode-font-lock-keywords-1
  "Default expressions to highlight in `css-mode'.")

(defvar css-mode-syntax-table nil
  "Syntax table for `css-mode'.")

(defun css-mode ()
  "Major mode for editing Cascading StyleSheets."
  (interactive)
  (kill-all-local-variables)
  (setq major-mode 'css-mode
        mode-name "CSS")
  (use-local-map css-mode-map)
  ;; set up syntax table.
  (if css-mode-syntax-table
      ()
    (setq css-mode-syntax-table
          (let ((table (make-syntax-table)))
            ;; comment characters.
            (modify-syntax-entry ?/  ". 14" table)
            (modify-syntax-entry ?*  ". 23"   table)
            table)))
  (set-syntax-table css-mode-syntax-table)
  (make-local-variable 'comment-start)
  (setq comment-start "/* ")
  (make-local-variable 'comment-end)
  (setq comment-end " */")
  (make-local-variable 'comment-multi-line)
  (setq comment-multi-line t)
  (make-local-variable 'comment-quote-nested)
  (setq comment-quote-nested t)
  (make-local-variable 'comment-start-skip)
  (setq comment-start-skip "/\\*+ *")
  (make-local-variable 'comment-style)
  (setq comment-style 'extra-line)
  (make-local-variable 'fill-paragraph-function)
  (setq fill-paragraph-function 'css-fill)
  ;; (make-local-variable 'comment-indent-function)
  ;; (setq comment-indent-function 'css-mode-indent-comment)
  (setq indent-line-function 'css-mode-indent-line)
  (setq font-lock-defaults '((css-mode-font-lock-keywords
                              css-mode-font-lock-keywords-1
                              css-mode-font-lock-keywords-2))))

;; set up keymap
(if css-mode-map
    ()
  (setq css-mode-map (make-sparse-keymap))
  (define-key css-mode-map (kbd "RET") 'css-mode-newline-and-indent)
  (define-key css-mode-map [(tab)] 'css-mode-indent-line)
  (define-key css-mode-map [(})] 'css-mode-electric-insert-close-brace))

(defun css-mode-calc-indent-level ()
  "Calculate the indent level for the current line."
  ;; This counts indentation level based on parenthesis (the first
  ;; value in the list returned by parse-partial-sexp).  It then
  ;; corrects as follows: If we're on a line with a closing
  ;; parenthesis, outdent.  If we're inside a comment, indent by
  ;; three, unless the line starts with the closing comment sequence.
  (let* ((indent-data (parse-partial-sexp (point-min)
					  (line-beginning-position)))
	 (indent (car indent-data))
	 (in-comment (nth 4 indent-data))
	 close-block
	 close-comment
	 pos)
    (save-excursion
      (back-to-indentation)
      (setq close-block (looking-at "}")
	    close-comment (looking-at "\\*/")))
    (when close-block
      (setq indent (1- indent)))
    (setq pos (* indent css-mode-indent-depth))
    (if (and in-comment (not close-comment))
	(+ 3 pos)
      pos)))
      
(defun css-mode-indent-line (&optional indent)
  "Indent the current line.

If optional INDENT is non-nil, use that instead of calculating the
indent level."
  (interactive)
  (let ((indent (or indent (css-mode-calc-indent-level)))
	pos)
    (save-excursion
      (back-to-indentation)
      (delete-region (point-at-bol) (point))
      (indent-to indent)
      (setq pos (point)))
    (when (> pos (point))
      (goto-char pos)))); move only forward after indenting

(defun css-mode-newline-and-indent ()
  "Insert a newline and indent."
  (interactive)
  (newline)
  (css-mode-indent-line))

(defun css-mode-electric-insert-close-brace ()
  "Insert a closing brace }."
  (interactive)
  (insert "}")
  (css-mode-indent-line)
  (forward-char))

(defun css-fill (&rest ignore)
  "Lay out CSS expressions."
  (interactive)
  (condition-case data
      (progn
	(backward-up-list 1)
	(forward-char 1)
	(newline-and-indent)
	(catch 'done
	  (let ((start (point)))
	    (while (re-search-forward "\n\\|;")
	      (let* ((data (save-excursion
			     (parse-partial-sexp start (point))))
		     (depth (nth 0 data))
		     (in-string (nth 3 data))
		     (in-comment (nth 4 data)))
		(when (< depth 0)
		  (throw 'done t))
		(when (and (= depth 0)
			   (not (or in-string in-comment)))
		  (if (string= (match-string 0) "\n")
		      (replace-match "")
		    (newline-and-indent))))))))
    (scan-error
     (search-forward "{"))))

(provide 'css-mode)

;;; css-mode.el ends here

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: css-mode
  2006-01-15 13:34     ` css-mode Alex Schroeder
@ 2006-01-17 11:39       ` Karl Chen
  2006-01-18  9:20         ` including javascript/ecmascript mode (was: css-mode) Mathias Dahl
  2006-01-21  2:55       ` css-mode Stefan Monnier
  1 sibling, 1 reply; 16+ messages in thread
From: Karl Chen @ 2006-01-17 11:39 UTC (permalink / raw)



Here is the one I've been using.

I don't care whose version is initially used; I'm sure each has
features to be merged.  It just goes to show that emacs
desperately needs to distribute a CSS mode since everyone has
their own.




;;; css-mode.el

;; css-mode.el             -*- Emacs-Lisp -*-

;; Mode for editing Cascading Style Sheets

;; Created:    <Sat Feb 12 13:51:49 EST 2000>
;; Time-stamp: <2002-11-25 10:21:39 foof>
;; Author:     Alex Shinn <foof@synthcode.com>
;; Version:    0.3
;; Keywords:   html, style sheets, languages

;; Copyright (C) 2005 Karl Chen <quarl@quarl.org>

;; Copyright (C) 2000-2002 Alex Shinn

;; 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 2 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, write to the Free
;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
;; MA 02111-1307 USA

;;; Commentary:
;;
;; This file provides a major mode for editing level 1 and 2 Cascading
;; Style Sheets.  It offers syntax highlighting, indentation, and
;; auto-completion of various CSS elements.
;;
;; To use it, put the following in your .emacs:
;;
;; (autoload 'css-mode "css-mode" "Mode for editing CSS files" t)
;;
;; You may also want something like:
;;
;; (setq auto-mode-alist
;;       (append '(("\\.css$" . css-mode))
;;               auto-mode-alist))
;;

;;; ChangeLog:
;;
;; 2002/11/25 (version 0.3):
;;   * changed to use indent-to to obey tab preference (Vasily Korytov)

;; 2005-11-21 Karl Chen
;;   * Major cleanup


(defgroup css nil
  "Customizations for editing Cascading Style Sheets"
  :group 'languages)

(defcustom css-electric-semi-behavior nil
  "If non-nil semicolons are electric in css mode"
  :group 'css
  :type  'boolean)

(defcustom css-electric-brace-behavior nil
  "If non-nil braces are electric in css mode"
  :group 'css
  :type  'boolean)

(defcustom css-indent-offset 4
  "Number of spaces to indent lines in CSS mode"
  :group 'css
  :type  'integer)

(defcustom css-tab-mode 'auto
  "Behavior of tab in CSS mode"
  :group 'css
  :type  '(choice (const :tag "Always insert" insert)
                  (const :tag "Always indent" indent)
                  (const :tag "Always complete" complete)
                  (const :tag "Auto" auto) ))

(defun css--list-to-table (input)
  (let ((table (make-vector 5 0)))
    (mapcar (lambda (x) (intern x table))
            input)
    table))

(defvar css-at-rule-keywords
  '("import" "media" "page" "font-face" "charset")
  "Keywords for CSS at rules" )

(defvar css-at-rule-table (css--list-to-table css-at-rule-keywords)
  "Table for CSS at rules")

(defvar css-element-keywords
  '("A" "ADDRESS" "B" "BLOCKQUOTE" "BODY" "BR" "CITE"
    "CODE" "DIR" "DIV" "DD" "DL" "DT" "EM" "FORM" "H1"
    "H2" "H3" "H4" "H5" "H6" "HR" "I" "IMG" "KBD" "LI"
    "MENU" "OL" "P" "PRE" "SAMP" "SPAN" "STRONG" "TABLE"
    "TR" "TH" "TD" "TT" "UL" "VAR" )
  "Common CSS elements" )

(defvar css-element-table (css--list-to-table css-element-keywords)
  "Table for CSS elements")


(defvar css-property-keywords
  '("azimuth" "background" "background-attachment" "background-color"
    "background-image" "background-position" "background-repeat" "border"
    "border-collapse" "border-color" "border-spacing" "border-style"
    "border-top" "border-right" "border-bottom" "border-left"
    "border-top-color" "border-right-color" "border-bottom-color"
    "border-left-color" "border-top-style" "border-right-style"
    "border-bottom-style" "border-left-style" "border-top-width"
    "border-right-width" "border-bottom-width" "border-left-width"
    "border-width" "bottom" "caption-side" "clear" "clip" "color"
    "content" "counter-increment" "counter-reset" "cue" "cue-after"
    "cue-before" "cursor" "direction" "display" "elevation" "empty-cells"
    "float" "font" "font-family" "font-size" "font-size-adjust"
    "font-stretch" "font-style" "font-variant" "font-weight" "height"
    "left" "letter-spacing" "line-height" "list-style" "list-style-image"
    "list-style-position" "list-style-type" "margin" "margin-top"
    "margin-right" "margin-bottom" "margin-left" "marker-offset" "marks"
    "max-height" "max-width" "min-height" "min-width" "orphans" "outline"
    "outline-color" "outline-style" "outline-width" "overflow" "padding"
    "padding-top" "padding-right" "padding-bottom" "padding-left" "page"
    "page-break-after" "page-break-before" "page-break-inside" "pause"
    "pause-after" "pause-before" "pitch" "pitch-range" "play-during"
    "position" "quotes" "richness" "right" "size" "speak" "speak-header"
    "speak-numeral" "speak-punctuation" "speech-rate" "stress"
    "table-layout" "text-align" "text-decoration" "text-indent"
    "text-shadow" "text-transform" "top" "unicode-bidi" "vertical-align"
    "visibility" "voice-family" "volume" "white-space" "widows" "width"
    "word-spacing" "z-index")
  "CSS properties")

(defvar css-property-table (css--list-to-table css-property-keywords)
  "Table for CSS properties")

(defconst css-font-lock-keywords
  (purecopy
   (let* ((css-keywords  "\\(url\\|![ \t]*important\\)")
          (css-ident     "[a-zA-Z][a-zA-Z0-9-]*")
          (css-at-rule   (concat "\\(@"
                                 (regexp-opt css-at-rule-keywords t)
                                 "\\)"))
          (css-element-s (concat "^\\(" css-ident "\\)"))
          (css-element (concat "\\(?:[,+>][ \t]*\\)\\(" css-ident "\\)"))
          (css-class  (concat css-element "?\\.\\(" css-ident "\\)"))
          (css-pseudo (concat ":\\(" css-ident "\\)"))
          (css-attr (concat "\\[\\(" css-ident "\\)\\]"))
          (css-id (concat "#\\(" css-ident "\\)"))
          (css-declaration (concat "[ \t][ \t]*\\(\\<" css-ident "\\>\\):")) )
     (list
      (list css-keywords    1 'font-lock-keyword-face)
      (list css-at-rule     1 'font-lock-keyword-face)
      (list css-element-s   1 'font-lock-function-name-face)
      (list css-element     1 'font-lock-function-name-face)
      (list css-class       2 'font-lock-type-face)
      (list css-pseudo      1 'font-lock-constant-face)
      (list css-attr        1 'font-lock-variable-name-face)
      (list css-id          1 'font-lock-string-face)
      (list css-declaration 1 'font-lock-variable-name-face) )))
  "Expressions for highlighting in css-mode.")

(defvar css-mode-syntax-table
  (let ((table (make-syntax-table)))
    (modify-syntax-entry ?+  "."    table)
    (modify-syntax-entry ?=  "."    table)
    (modify-syntax-entry ?<  "."    table)
    (modify-syntax-entry ?>  "."    table)
    (modify-syntax-entry ?-  "w"    table)
    (modify-syntax-entry ?/  "w"    table)
    (modify-syntax-entry ?.  "w"    table)
    (modify-syntax-entry ?\' "\""   table)
    ;; (modify-syntax-entry ?/  ". 1456" table) ; XEmacs(?)
    (modify-syntax-entry ?/  ". 124b" table) ; GNU Emacs
    (modify-syntax-entry ?*  ". 23"   table)
    (modify-syntax-entry ?\n "> b"  table)
    ;; Give CR the same syntax as newline, for selective-display
    (modify-syntax-entry ?\^m "> b" table)
    table)

  "Syntax table used in `css-mode' buffers.")

(defvar css-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map ";"        'css-electric-semicolon)
    (define-key map "{"        'css-electric-brace)
    (define-key map "}"        'css-electric-brace)
    (define-key map "\t"       'css-tab-function)
    (define-key map "\C-c\C-c" 'css-comment-region)
    (define-key map "\C-c\C-a" 'css-complete-at-keyword)
    (define-key map "\C-c\C-e" 'css-complete-element)
    (define-key map "\C-c\C-p" 'css-complete-property)
    map)
  "Keymap used in `css-mode' buffers.")

;;; Utility functions

(defun css-in-comment-p ()
  "Returns non-nil if point is within a comment."
  (save-excursion
    (let ((here (point)))
      (and (search-backward "/*" nil t)
           (not (search-forward "*/" here t))))))

(defun css-complete-symbol (&optional table predicate prettify)
  (let* ((end (point))
	 (beg (save-excursion
		(skip-syntax-backward "w")
		(point)))
	 (pattern (buffer-substring beg end))
	 (table (or table obarray))
	 (completion (try-completion pattern table predicate)))
    (cond ((eq completion t))
	  ((null completion)
	   (error "Can't find completion for \"%s\"" pattern))
	  ((not (string-equal pattern completion))
	   (delete-region beg end)
	   (insert completion))
	  (t
	   (message "Making completion list...")
	   (let ((list (all-completions pattern table predicate)))
	     (if prettify
		 (setq list (funcall prettify list)))
	     (with-output-to-temp-buffer "*Help*"
	       (display-completion-list list)))
	   (message "Making completion list...%s" "done")))))

(defsubst css--backup-to-nonempty-line ()
  (while (and (= 0 (forward-line -1))
              (or (looking-at "^[ \t]*$")
                  (css-in-comment-p) ))
    ;; Jump to a non comment/white-space line
    ))

(defun css--indent-depth ()
  (let ((depth 0))
    (save-excursion
      (css--backup-to-nonempty-line)
      (cond ((looking-at "\\([ \t]*\\)\\([^ \t].*\\)?{[ \t]*$")
             (setq depth (+ (- (match-end 1) (match-beginning 1))
                            css-indent-offset )))
            ((looking-at "\\([ \t]*\\)[^ \t]")
             (setq depth (- (match-end 1) (match-beginning 1))) )
            (t (setq depth 0))))

    (save-excursion
      (beginning-of-line)
      (if (looking-at "[ \t]*}")
          (setq depth (- depth css-indent-offset))))

    depth))

(defun indent-line-to-excursion (column)
  (setq column (max column 0))
  (if (> (current-column) (current-indentation))
      (save-excursion (indent-line-to column))
    (indent-line-to column)))

(defun css-indent-line ()
  "Indent the current line"
  (unless (or (css-in-comment-p)
              (looking-at "[ \t]*/\\*"))
    (indent-line-to-excursion (css--indent-depth))))

;;; Commands

(defun css-electric-semicolon (arg)
  "Insert a semi-colon, and possibly indent line.
If numeric argument is not given, or is 1, auto-indent according to
`css-electric-semi-behavior'.  If arg is 0, do not auto-indent, if
arg is 2 always auto-indent, and if arg is anything else invert the
usual behavior."
  (interactive "P")
  ;; insert a semicolon
  (self-insert-command 1)
  ;; maybe do electric behavior
  (or (css-in-comment-p)
      (and (eq arg 1)
           css-electric-semi-behavior
           (css-indent-line) )
      (and (eq arg 2)
           (css-indent-line) )
      (eq arg 0)
      (or (not css-electric-semi-behavior)
          (css-indent-line) )))


(defun css-electric-brace (arg)
  "Insert a brace, and possibly indent line.
If numeric argument is not given, or is 1, auto-indent according to
`css-electric-brace-behavior'.  If arg is 0, do not auto-indent, if
arg is 2 always auto-indent, and if arg is anything else invert the
usual behavior."
  (interactive "P")
  ;; insert a brace
  (self-insert-command 1)
  ;; maybe do electric behavior
  (or (css-in-comment-p)
      (and (eq arg 1)
           css-electric-brace-behavior
           (css-indent-line) )
      (and (eq arg 2)
           (css-indent-line) )
      (eq arg 0)
      (or (not css-electric-brace-behavior)
          (css-indent-line) )))

(defun css-complete-at-keyword ()
  "Complete the standard element at point"
  (interactive)
  (let ((completion-ignore-case t))
    (css-complete-symbol css-at-rule-table) ))

(defun css-complete-element ()
  "Complete the standard element at point"
  (interactive)
  (let ((completion-ignore-case t))
    (css-complete-symbol css-element-table) ))

(defun css-complete-property ()
  "Complete the standard element at point"
  (interactive)
  (let ((completion-ignore-case t))
    (css-complete-symbol css-property-table) ))


(defun css-tab-function (&optional arg)
  "Function to call when tab is pressed in CSS mode.

With a prefix arg, insert a literal tab.  Otherwise behavior depends
on the value of `css-tab-mode'.  If it's 'insert, insert a literal
tab.  If it's 'indent, indent the current line, and if it's 'complete,
try to complete the expression before point.  A value of 'auto means
to inspect the current line, and indent if point is at the beginning
or end of the line, but complete if it's at a word.

There are three possible completions to perform:
`css-complete-at-keyword' if the point is after an '@',
`css-complete-property' if point is inside a block, and
`css-complete-element' otherwise."
  (interactive "P")
  (let* ((end (point))
         (start (prog2
                    (beginning-of-line)
                    (point)
                  (goto-char end) ))
         (prefix (buffer-substring start end)) )
    (cond ((or arg (eq css-tab-mode 'insert))
           (insert "\t"))
          ((eq css-tab-mode 'indent)
           (css-indent-line))
          ((and (not (eq css-tab-mode 'complete))
                (or (string-match "^[ \t]*[{}]?[ \t]*$" prefix)
                    (string-match "^.*;[ \t]*" prefix) ))
           ;; indent at the beginning or end of a line
           (css-indent-line))
          ((string-match "^.*@[a-zA-Z0-9-]*$" prefix)
           (css-complete-at-keyword))
          ((string-match "^\\([ \t]+.*\\|.*\{[ \t]*[a-zA-Z]+\\)$" prefix)
           ;; complete properties on non-starting lines
           (css-complete-property))
          ;; otherwise try an element
          (t (css-complete-element)) )))


;;;###autoload
(define-derived-mode css-mode fundamental-mode "CSS"
  "Major mode for editing CSS files"

  ;; local variables
  (make-local-variable 'parse-sexp-ignore-comments)
  (make-local-variable 'comment-start-skip)
  (make-local-variable 'comment-start)
  (make-local-variable 'comment-end)
  (make-local-variable 'block-comment-start)
  (make-local-variable 'block-comment-end)
  (make-local-variable 'block-comment-left)
  ;; (make-local-variable 'block-comment-right)
  ;; (make-local-variable 'block-comment-top-right)
  ;; (make-local-variable 'block-comment-bot-left)
  ;; (make-local-variable 'block-comment-char)
  (make-local-variable 'paragraph-start)
  (make-local-variable 'paragraph-separate)
  (make-local-variable 'paragraph-ignore-fill-prefix)
  (make-local-variable 'font-lock-defaults)
  (setq font-lock-defaults '(css-font-lock-keywords))
  ;; now set their values
  (setq parse-sexp-ignore-comments t
	comment-start-skip "/\\*+ *\\|// *"
	comment-start "/\\*"
	comment-end   "\\*/")
  (setq block-comment-start     "/*"
        block-comment-end       "*/"
        ;; block-comment-left      " * "
        ;; block-comment-right     " *"
        ;; block-comment-top-right ""
        ;; block-comment-bot-left  " "
        ;; block-comment-char      ?*
        )
  (setq indent-line-function   'css-indent-line
        indent-region-function 'css-indent-region
	paragraph-ignore-fill-prefix t
	paragraph-start (concat "\\|$" page-delimiter)
	paragraph-separate paragraph-start)
  ;; (run-hooks 'css-mode-hook)
  )


(provide 'css-mode)

;;; css-mode.el ends here.


-- 
Karl 2006-01-17 03:38

^ permalink raw reply	[flat|nested] 16+ messages in thread

* including javascript/ecmascript mode (was: css-mode)
  2006-01-17 11:39       ` css-mode Karl Chen
@ 2006-01-18  9:20         ` Mathias Dahl
  2006-01-18 12:35           ` including javascript/ecmascript mode Lennart Borgman
                             ` (4 more replies)
  0 siblings, 5 replies; 16+ messages in thread
From: Mathias Dahl @ 2006-01-18  9:20 UTC (permalink / raw)


Karl Chen <quarl@NOSPAM.quarl.org> writes:

> I don't care whose version is initially used; I'm sure each has
> features to be merged.  It just goes to show that emacs
> desperately needs to distribute a CSS mode since everyone has
> their own.

When speaking about modes, how about adding a *real* (not the one in
generic-x) ecmascript/javascript-mode too?  Coding javascript is not
likely to be less common in the near future.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: including javascript/ecmascript mode
  2006-01-18  9:20         ` including javascript/ecmascript mode (was: css-mode) Mathias Dahl
@ 2006-01-18 12:35           ` Lennart Borgman
  2006-01-18 15:43           ` Stefan Monnier
                             ` (3 subsequent siblings)
  4 siblings, 0 replies; 16+ messages in thread
From: Lennart Borgman @ 2006-01-18 12:35 UTC (permalink / raw)
  Cc: emacs-devel

Mathias Dahl wrote:
> When speaking about modes, how about adding a *real* (not the one in
> generic-x) ecmascript/javascript-mode too?  Coding javascript is not
> likely to be less common in the near future.
>   
I vote for this too.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: including javascript/ecmascript mode
  2006-01-18  9:20         ` including javascript/ecmascript mode (was: css-mode) Mathias Dahl
  2006-01-18 12:35           ` including javascript/ecmascript mode Lennart Borgman
@ 2006-01-18 15:43           ` Stefan Monnier
  2006-01-18 17:05           ` Edward O'Connor
                             ` (2 subsequent siblings)
  4 siblings, 0 replies; 16+ messages in thread
From: Stefan Monnier @ 2006-01-18 15:43 UTC (permalink / raw)
  Cc: emacs-devel

>> I don't care whose version is initially used; I'm sure each has
>> features to be merged.  It just goes to show that emacs
>> desperately needs to distribute a CSS mode since everyone has
>> their own.

> When speaking about modes, how about adding a *real* (not the one in
> generic-x) ecmascript/javascript-mode too?  Coding javascript is not
> likely to be less common in the near future.

Agreed.


        Stefan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: including javascript/ecmascript mode
  2006-01-18  9:20         ` including javascript/ecmascript mode (was: css-mode) Mathias Dahl
  2006-01-18 12:35           ` including javascript/ecmascript mode Lennart Borgman
  2006-01-18 15:43           ` Stefan Monnier
@ 2006-01-18 17:05           ` Edward O'Connor
  2006-01-25 23:52             ` Karl Chen
  2006-01-22  0:44           ` Juri Linkov
  2006-01-22  0:51           ` Desktop fails reading unknown mode (was: including javascript/ecmascript mode) Juri Linkov
  4 siblings, 1 reply; 16+ messages in thread
From: Edward O'Connor @ 2006-01-18 17:05 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 784 bytes --]

Mathias Dahl wrote:

> When speaking about modes, how about adding a *real* (not the one in
> generic-x) ecmascript/javascript-mode too? Coding javascript is not
> likely to be less common in the near future.

Including a Javascript mode would be really awesome.

FWIW, I compared the various existing Javascript modes not too long ago:

                http://emacsen.org/2005/09/26-javascript

I concluded that Karl Landström's javascript.el is the nicest one out
there. You can download it from his website here:

     http://web.comhem.se/~u83406637/javascript-mode/javascript.el

I've also attached it for convenience.

Hopefully he's already filed (or is willing to file) Emacs papers! :)


Ted

-- 
Edward O'Connor
hober0@gmail.com

Ense petit placidam sub libertate quietem.


[-- Attachment #2: Karl Landström's javascript.el --]
[-- Type: application/emacs-lisp, Size: 11034 bytes --]

[-- Attachment #3: Type: text/plain, Size: 142 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: css-mode
  2006-01-15 13:34     ` css-mode Alex Schroeder
  2006-01-17 11:39       ` css-mode Karl Chen
@ 2006-01-21  2:55       ` Stefan Monnier
  1 sibling, 0 replies; 16+ messages in thread
From: Stefan Monnier @ 2006-01-21  2:55 UTC (permalink / raw)
  Cc: emacs-devel

> And I wanted M-q to do the right thing.  I currently don't fill
> comments correctly, and highlighting for non-trivial selectors doesn't
> always work.

M-q was a good idea, so I added a similar feature to mine.


        Stefan


;;; css-mode.el --- Major mode to edit CSS files

;; Copyright (C) 2006  Free Software Foundation, Inc.

;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
;; Keywords: hypermedia

;; This file 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 2, or (at your option)
;; any later version.

;; This file 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; see the file COPYING.  If not, write to
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.

;;; Commentary:

;; Yet another CSS mode.

;;; Todo:

;; - electric ; and }
;; - filling code with auto-fill-mode
;; - completion
;; - fix font-lock errors with multi-line selectors

;;; Code:

(defun css-extract-keyword-list (res)
  (with-temp-buffer
    (url-insert-file-contents "http://www.w3.org/TR/REC-CSS2/css2.txt")
    (goto-char (point-max))
    (search-backward "Appendix H. Index")
    (forward-line)
    (delete-region (point-min) (point))
    (let ((result nil)
          keys)
      (dolist (re res)
        (goto-char (point-min))
        (setq keys nil)
        (while (re-search-forward (cdr re) nil t)
          (push (match-string 1) keys))
        (push (cons (car re) (sort keys 'string-lessp)) result))
      (nreverse result))))

;; Extraction was done with:
;; (css-extract-keyword-list
;;  '((pseudo . "^ +\\* :\\([^ \n,]+\\)")
;;    (at . "^ +\\* @\\([^ \n,]+\\)")
;;    (descriptor . "^ +\\* '\\([^ '\n]+\\)' (descriptor)")
;;    (media . "^ +\\* '\\([^ '\n]+\\)' media group")
;;    (property . "^ +\\* '\\([^ '\n]+\\)',")))

(defconst css-pseudo-ids
  '("active" "after" "before" "first" "first-child" "first-letter" "first-line"
    "focus" "hover" "lang" "left" "link" "right" "visited")
  "Identifiers for pseudo-elements and pseudo-classes.")

(defconst css-at-ids
  '("charset" "font-face" "import" "media" "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
  '("azimuth" "background" "background-attachment" "background-color"
    "background-image" "background-position" "background-repeat" "block"
    "border" "border-bottom" "border-bottom-color" "border-bottom-style"
    "border-bottom-width" "border-collapse" "border-color" "border-left"
    "border-left-color" "border-left-style" "border-left-width" "border-right"
    "border-right-color" "border-right-style" "border-right-width"
    "border-spacing" "border-style" "border-top" "border-top-color"
    "border-top-style" "border-top-width" "border-width" "bottom"
    "caption-side" "clear" "clip" "color" "compact" "content"
    "counter-increment" "counter-reset" "cue" "cue-after" "cue-before"
    "cursor" "dashed" "direction" "display" "dotted" "double" "elevation"
    "empty-cells" "float" "font" "font-family" "font-size" "font-size-adjust"
    "font-stretch" "font-style" "font-variant" "font-weight" "groove" "height"
    "hidden" "inline" "inline-table" "inset" "left" "letter-spacing"
    "line-height" "list-item" "list-style" "list-style-image"
    "list-style-position" "list-style-type" "margin" "margin-bottom"
    "margin-left" "margin-right" "margin-top" "marker-offset" "marks"
    "max-height" "max-width" "min-height" "min-width" "orphans" "outline"
    "outline-color" "outline-style" "outline-width" "outset" "overflow"
    "padding" "padding-bottom" "padding-left" "padding-right" "padding-top"
    "page" "page-break-after" "page-break-before" "page-break-inside" "pause"
    "pause-after" "pause-before" "pitch" "pitch-range" "play-during" "position"
    "quotes" "richness" "ridge" "right" "run-in" "size" "solid" "speak"
    "speak-header" "speak-numeral" "speak-punctuation" "speech-rate" "stress"
    "table" "table-caption" "table-cell" "table-column" "table-column-group"
    "table-footer-group" "table-header-group" "table-layout" "table-row"
    "table-row-group" "text-align" "text-decoration" "text-indent"
    "text-shadow" "text-transform" "top" "unicode-bidi" "vertical-align"
    "visibility" "voice-family" "volume" "white-space" "widows" "width"
    "word-spacing" "z-index")
  "Identifiers for properties.")

(defcustom css-electrick-keys '(?\} ?\;) ;; '()
  "Self inserting keys which should trigger re-indentation."
  :type '(repeat character)
  :options '((?\} ?\;)))

(defvar css-mode-syntax-table
  (let ((st (make-syntax-table)))
    ;; C-style comments.
    (modify-syntax-entry ?/ ". 14" st)
    (modify-syntax-entry ?* ". 23" 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 "*"))
(defconst css-name-re (concat css-nmchar-re "+"))

(defface css-selector '((t :inherit font-lock-function-name-face))
  "Face to use for selectors.")
(defface css-property '((t :inherit font-lock-variable-name-face))
  "Face to use for properties.")

(defvar css-font-lock-keywords
  `(("!\\s-*important" . font-lock-builtin-face)
    ;; Atrules keywords.  IDs not in css-at-ids are valid (ignored).
    (,(concat "@" css-ident-re) . font-lock-builtin-face)
    ;; Selectors.
    (,(concat "^\\([ \t]*[^:{\n]+\\(?::" (regexp-opt css-pseudo-ids t)
              "\\(([^)]+)\\)?[^:{\n]+\\)*\\){") (1 'css-selector))
    ;; Properties.  Again, we don't limit ourselves to css-property-ids.
    (,(concat "\\(?:[{;]\\|^\\)[ \t]*\\(" css-ident-re "\\)\\s-*:")
     (1 'css-property))))

(defvar css-font-lock-defaults
  '(css-font-lock-keywords nil t))

(unless (fboundp 'prog-mode) (defalias 'prog-mode 'fundamental-mode))

;;;###autoload (add-to-list 'auto-mode-alist '("\\.css\\'" . css-mode))
;;;###autoload
(define-derived-mode css-mode prog-mode "CSS"
  "Major mode to edit Cascading Style Sheets."
  (set (make-local-variable 'font-lock-defaults) css-font-lock-defaults)
  (set (make-local-variable 'comment-start) "/*")
  (set (make-local-variable 'comment-start-skip) "/\\*+[ \t]*")
  (set (make-local-variable 'comment-end) "*/")
  (set (make-local-variable 'comment-end-skip) "[ \t]*\\*+/")
  (set (make-local-variable 'forward-sexp-function) 'css-forward-sexp)
  (set (make-local-variable 'indent-line-function) 'css-indent-line)
  (set (make-local-variable 'fill-paragraph-function)
       'css-fill-paragraph)
  (when css-electrick-keys
    (let ((fc (make-char-table 'auto-fill-chars)))
      (set-char-table-parent fc auto-fill-chars)
      (dolist (c css-electrick-keys)
        (aset fc c 'indent-according-to-mode))
      (set (make-local-variable 'auto-fill-chars) fc))))

(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)
          (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)
               ((eq (char-before) ?\})
                (save-excursion
                  (forward-char -1)
                  (skip-chars-backward " \t")
                  (unless (bolp) (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)))))))

;;; Navigation and indentation.

(defconst css-navigation-syntax-table
  (let ((st (make-syntax-table css-mode-syntax-table)))
    (map-char-table (lambda (c v)
                      ;; Turn punctuation (code = 1) into symbol (code = 1).
                      (if (eq (car-safe v) 1)
                          (aset st c (cons 3 (cdr v)))))
                    st)
    st))

(defun css-backward-sexp (n)
  (let ((forward-sexp-function nil))
    (if (< n 0) (css-forward-sexp (- n))
      (while (> n 0)
        (setq n (1- n))
        (forward-comment (- (point-max)))
        (if (not (eq (char-before) ?\;))
            (backward-sexp 1)
          (while (progn (backward-sexp 1)
                        (save-excursion
                          (forward-comment (- (point-max)))
                          ;; FIXME: We should also skip punctuation.
                          (not (memq (char-before) '(?\; ?\{)))))))))))

(defun css-forward-sexp (n)
  (let ((forward-sexp-function nil))
    (if (< n 0) (css-backward-sexp (- n))
      (while (> n 0)
        (setq n (1- n))
        (forward-comment (point-max))
        (if (not (eq (char-after) ?\;))
            (forward-sexp 1)
          (while (progn (forward-sexp 1)
                        (save-excursion
                          (forward-comment (point-max))
                          ;; FIXME: We should also skip punctuation.
                          (not (memq (char-after) '(?\; ?\})))))))))))

(defun css-indent-calculate-virtual ()
  (if (or (save-excursion (skip-chars-backward " \t") (bolp))
          (if (looking-at "\\s(")
              (save-excursion
                (forward-char 1) (skip-chars-forward " \t") (not (eolp)))))
      (current-column)
    (css-indent-calculate)))

(defcustom css-indent-offset 4
  "Basic size of one indentation step."
  :type 'integer)

(defun css-indent-calculate ()
  (let ((ppss (syntax-ppss))
        pos)
    (with-syntax-table css-navigation-syntax-table
      (save-excursion
        (cond
         ;; Inside a string.
         ((nth 3 ppss) 'noindent)
         ;; Inside a comment.
         ((nth 4 ppss)
          (setq pos (point))
          (forward-line -1)
          (skip-chars-forward " \t")
          (if (>= (nth 8 ppss) (point))
              (progn
                (goto-char (nth 8 ppss))
                (if (eq (char-after pos) ?*)
                    (forward-char 1)
                  (if (not (looking-at comment-start-skip))
                      (error "Internal css-mode error")
                    (goto-char (match-end 0))))
                (current-column))
            (if (and (eq (char-after pos) ?*) (eq (char-after) ?*))
                (current-column)
              ;; 'noindent
              (current-column)
              )))
         ;; In normal code.
         (t
          (or
           (when (looking-at "\\s)")
             (forward-char 1)
             (backward-sexp 1)
             (css-indent-calculate-virtual))
           (when (looking-at comment-start-skip)
             (forward-comment (point-max))
             (css-indent-calculate))
           (when (save-excursion (forward-comment (- (point-max)))
                                 (setq pos (point))
                                 (eq (char-syntax (preceding-char)) ?\())
             (goto-char (1- pos))
             (if (not (looking-at "\\s([ \t]*"))
                 (error "Internal css-mode error")
               (if (memq (char-after (match-end 0)) '(?\n nil))
                   (+ (css-indent-calculate-virtual) css-indent-offset)
                 (progn (goto-char (match-end 0)) (current-column)))))
           (progn
             (css-backward-sexp 1)
             (if (looking-at "\\s(")
                 (css-indent-calculate)
               (css-indent-calculate-virtual))))))))))
     

(defun css-indent-line ()
  "Indent current line according to CSS indentation rules."
  (interactive)
  (let* ((savep (point))
         (forward-sexp-function nil)
	 (indent (condition-case nil
		     (save-excursion
		       (forward-line 0)
		       (skip-chars-forward " \t")
		       (if (>= (point) savep) (setq savep nil))
		       (css-indent-calculate))
		   (error nil))))
    (if (not (numberp indent)) 'noindent
      (if savep
          (save-excursion (indent-line-to indent))
        (indent-line-to indent)))))

(provide 'css-mode)
;; arch-tag: b4d8b8e2-b130-4e74-b3aa-cd8f1ab659d0
;;; css-mode.el ends here

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: including javascript/ecmascript mode
  2006-01-18  9:20         ` including javascript/ecmascript mode (was: css-mode) Mathias Dahl
                             ` (2 preceding siblings ...)
  2006-01-18 17:05           ` Edward O'Connor
@ 2006-01-22  0:44           ` Juri Linkov
  2006-01-22  0:51           ` Desktop fails reading unknown mode (was: including javascript/ecmascript mode) Juri Linkov
  4 siblings, 0 replies; 16+ messages in thread
From: Juri Linkov @ 2006-01-22  0:44 UTC (permalink / raw)
  Cc: emacs-devel

>> I don't care whose version is initially used; I'm sure each has
>> features to be merged.  It just goes to show that emacs
>> desperately needs to distribute a CSS mode since everyone has
>> their own.
>
> When speaking about modes, how about adding a *real* (not the one in
> generic-x) ecmascript/javascript-mode too?  Coding javascript is not
> likely to be less common in the near future.

Since CC mode already supports java-mode, wouldn't it be better to base
javascript-mode and css-mode on the feature-rich CC mode package?

-- 
Juri Linkov
http://www.jurta.org/emacs/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Desktop fails reading unknown mode (was: including javascript/ecmascript mode)
  2006-01-18  9:20         ` including javascript/ecmascript mode (was: css-mode) Mathias Dahl
                             ` (3 preceding siblings ...)
  2006-01-22  0:44           ` Juri Linkov
@ 2006-01-22  0:51           ` Juri Linkov
  2006-01-22 17:44             ` Richard M. Stallman
  4 siblings, 1 reply; 16+ messages in thread
From: Juri Linkov @ 2006-01-22  0:51 UTC (permalink / raw)
  Cc: emacs-devel

After trying out one javascript mode, desktop.el saved its major mode to
the desktop file and failed to restore the whole desktop because one mode
is not in the load path.

I propose to handle this situation more graciously and allow restoring the
desktop even if the Lisp file of one mode can't be obtained.  With the
following patch, desktop.el sets javascript-generic-mode instead of
failing on unavailable javascript-mode.  To me this is an acceptable solution.

Index: lisp/desktop.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/desktop.el,v
retrieving revision 1.96
diff -c -r1.96 desktop.el
*** lisp/desktop.el	14 Dec 2005 07:44:44 -0000	1.96
--- lisp/desktop.el	22 Jan 2006 00:47:41 -0000
***************
*** 966,972 ****
  (defun desktop-load-file (function)
    "Load the file where auto loaded FUNCTION is defined."
    (when function
!     (let ((fcell (symbol-function function)))
        (when (and (listp fcell)
                   (eq 'autoload (car fcell)))
          (load (cadr fcell))))))
--- 966,972 ----
  (defun desktop-load-file (function)
    "Load the file where auto loaded FUNCTION is defined."
    (when function
!     (let ((fcell (and (fboundp function) (symbol-function function))))
        (when (and (listp fcell)
                   (eq 'autoload (car fcell)))
          (load (cadr fcell))))))

-- 
Juri Linkov
http://www.jurta.org/emacs/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Desktop fails reading unknown mode (was: including javascript/ecmascript mode)
  2006-01-22  0:51           ` Desktop fails reading unknown mode (was: including javascript/ecmascript mode) Juri Linkov
@ 2006-01-22 17:44             ` Richard M. Stallman
  0 siblings, 0 replies; 16+ messages in thread
From: Richard M. Stallman @ 2006-01-22 17:44 UTC (permalink / raw)
  Cc: emacs-devel, brakjoller

Please install that patch.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: including javascript/ecmascript mode
  2006-01-18 17:05           ` Edward O'Connor
@ 2006-01-25 23:52             ` Karl Chen
  0 siblings, 0 replies; 16+ messages in thread
From: Karl Chen @ 2006-01-25 23:52 UTC (permalink / raw)


>>>>> On 2006-01-18 09:05 PST, Edward O'Connor writes:

    Ted> I concluded that Karl Landström's javascript.el is the
    Ted> nicest one out there. 

    Ted> Hopefully he's already filed (or is willing to file)
    Ted> Emacs papers! :)

Any news on this?  I would love a Javascript mode distributed with
Emacs as well.  Has anybody contacted him about assigning
copyright?

How hard would it be to add ECMA/Javascript support to cc-mode?
(I've used Java mode directly on js files, which is close enough
in terms of syntax other than a few things like regular
expressions.)

-- 
Karl 2006-01-25 15:50

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2006-01-25 23:52 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-01-13 17:27 css-mode Stefan Monnier
2006-01-13 20:33 ` css-mode Edward O'Connor
2006-01-13 22:16   ` css-mode Stefan Monnier
2006-01-14 16:14 ` css-mode Richard M. Stallman
2006-01-15  1:09   ` css-mode Kenichi Handa
2006-01-15 13:34     ` css-mode Alex Schroeder
2006-01-17 11:39       ` css-mode Karl Chen
2006-01-18  9:20         ` including javascript/ecmascript mode (was: css-mode) Mathias Dahl
2006-01-18 12:35           ` including javascript/ecmascript mode Lennart Borgman
2006-01-18 15:43           ` Stefan Monnier
2006-01-18 17:05           ` Edward O'Connor
2006-01-25 23:52             ` Karl Chen
2006-01-22  0:44           ` Juri Linkov
2006-01-22  0:51           ` Desktop fails reading unknown mode (was: including javascript/ecmascript mode) Juri Linkov
2006-01-22 17:44             ` Richard M. Stallman
2006-01-21  2:55       ` css-mode Stefan Monnier

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).