aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2013-08-29 17:00:18 -0400
committerStefan Monnier2013-08-29 17:00:18 -0400
commit112798c18dbbb095a34ace257767ae6f57643468 (patch)
tree99d4759444b3609f43954776f38da1cec29b357f
parent40f7e0e853bf21003fdffeac35e47616f393055d (diff)
downloademacs-112798c18dbbb095a34ace257767ae6f57643468.tar.gz
emacs-112798c18dbbb095a34ace257767ae6f57643468.zip
* lisp/textmodes/css-mode.el: Use SMIE.
(css-smie-grammar): New var. (css-smie--forward-token, css-smie--backward-token) (css-smie-rules): New functions. (css-mode): Use them. (css-navigation-syntax-table): Remove var. (css-backward-sexp, css-forward-sexp, css-indent-calculate-virtual) (css-indent-calculate, css-indent-line): Remove functions.
-rw-r--r--lisp/ChangeLog27
-rw-r--r--lisp/textmodes/css-mode.el172
2 files changed, 72 insertions, 127 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 4d0859097d2..a2028d5623b 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,32 @@
12013-08-29 Stefan Monnier <monnier@iro.umontreal.ca> 12013-08-29 Stefan Monnier <monnier@iro.umontreal.ca>
2 2
3 * textmodes/css-mode.el: Use SMIE.
4 (css-smie-grammar): New var.
5 (css-smie--forward-token, css-smie--backward-token)
6 (css-smie-rules): New functions.
7 (css-mode): Use them.
8 (css-navigation-syntax-table): Remove var.
9 (css-backward-sexp, css-forward-sexp, css-indent-calculate-virtual)
10 (css-indent-calculate, css-indent-line): Remove functions.
11
12 Misc changes to reduce use of `(lambda...); and other cleanups.
13 * cus-edit.el: Use lexical-binding.
14 (customize-push-and-save, customize-apropos)
15 (custom-buffer-create-internal): Use closures.
16 * progmodes/bat-mode.el (bat-mode-syntax-table): "..." are strings.
17 * progmodes/ada-xref.el: Use setq.
18 * net/tramp.el (with-tramp-progress-reporter): Avoid setq.
19 * dframe.el: Use lexical-binding.
20 (dframe-frame-mode): Fix calling convention for hooks. Use a closure.
21 * speedbar.el (speedbar-frame-mode): Adjust call accordingly.
22 * descr-text.el: Use lexical-binding.
23 (describe-text-widget, describe-text-sexp, describe-property-list):
24 Use closures.
25 * comint.el (comint-history-isearch-push-state): Use a closure.
26 * calculator.el: Use lexical-binding.
27 (calculator-number-to-string): Make it work with lexical-binding.
28 (calculator-funcall): Same and use cl-letf.
29
3 * emacs-lisp/lisp.el (lisp--company-doc-buffer) 30 * emacs-lisp/lisp.el (lisp--company-doc-buffer)
4 (lisp--company-doc-string, lisp--company-location): New functions. 31 (lisp--company-doc-string, lisp--company-location): New functions.
5 (lisp-completion-at-point): Use them to improve Company support. 32 (lisp-completion-at-point): Use them to improve Company support.
diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el
index cb19c018839..9c32604b4f4 100644
--- a/lisp/textmodes/css-mode.el
+++ b/lisp/textmodes/css-mode.el
@@ -263,6 +263,48 @@
263(defvar css-font-lock-defaults 263(defvar css-font-lock-defaults
264 '(css-font-lock-keywords nil t)) 264 '(css-font-lock-keywords nil t))
265 265
266(defcustom css-indent-offset 4
267 "Basic size of one indentation step."
268 :version "22.2"
269 :type 'integer)
270
271(require 'smie)
272
273(defconst css-smie-grammar
274 (smie-prec2->grammar
275 (smie-precs->prec2 '((assoc ";") (assoc ",") (left ":")))))
276
277(defun css-smie--forward-token ()
278 (cond
279 ((and (eq (char-before) ?\})
280 ;; FIXME: If the next char is not whitespace, what should we do?
281 (or (memq (char-after) '(?\s ?\t ?\n))
282 (looking-at comment-start-skip)))
283 (if (memq (char-after) '(?\s ?\t ?\n))
284 (forward-char 1) (forward-comment 1))
285 ";")
286 ((progn (forward-comment (point-max))
287 (looking-at "[;,:]"))
288 (forward-char 1) (match-string 0))
289 (t (smie-default-forward-token))))
290
291(defun css-smie--backward-token ()
292 (let ((pos (point)))
293 (forward-comment (- (point)))
294 (cond
295 ;; FIXME: If the next char is not whitespace, what should we do?
296 ((and (eq (char-before) ?\}) (> pos (point))) ";")
297 ((memq (char-before) '(?\; ?\, ?\:))
298 (forward-char -1) (string (char-after)))
299 (t (smie-default-backward-token)))))
300
301(defun css-smie-rules (kind token)
302 (pcase (cons kind token)
303 (`(:elem . basic) css-indent-offset)
304 (`(:elem . arg) 0)
305 (`(:before . "{") (if (smie-rule-hanging-p)
306 (smie-rule-parent 0)))))
307
266;;;###autoload 308;;;###autoload
267(define-derived-mode css-mode fundamental-mode "CSS" 309(define-derived-mode css-mode fundamental-mode "CSS"
268 "Major mode to edit Cascading Style Sheets." 310 "Major mode to edit Cascading Style Sheets."
@@ -271,11 +313,13 @@
271 (setq-local comment-start-skip "/\\*+[ \t]*") 313 (setq-local comment-start-skip "/\\*+[ \t]*")
272 (setq-local comment-end "*/") 314 (setq-local comment-end "*/")
273 (setq-local comment-end-skip "[ \t]*\\*+/") 315 (setq-local comment-end-skip "[ \t]*\\*+/")
274 (setq-local forward-sexp-function 'css-forward-sexp)
275 (setq-local parse-sexp-ignore-comments t) 316 (setq-local parse-sexp-ignore-comments t)
276 (setq-local indent-line-function 'css-indent-line) 317 (setq-local indent-line-function 'css-indent-line)
277 (setq-local fill-paragraph-function 'css-fill-paragraph) 318 (setq-local fill-paragraph-function 'css-fill-paragraph)
278 (setq-local add-log-current-defun-function #'css-current-defun-name) 319 (setq-local add-log-current-defun-function #'css-current-defun-name)
320 (smie-setup css-smie-grammar #'css-smie-rules
321 :forward-token #'css-smie--forward-token
322 :backward-token #'css-smie--backward-token)
279 (when css-electric-keys 323 (when css-electric-keys
280 (let ((fc (make-char-table 'auto-fill-chars))) 324 (let ((fc (make-char-table 'auto-fill-chars)))
281 (set-char-table-parent fc auto-fill-chars) 325 (set-char-table-parent fc auto-fill-chars)
@@ -355,132 +399,6 @@
355 ;; Don't use the default filling code. 399 ;; Don't use the default filling code.
356 t))))))) 400 t)))))))
357 401
358;;; Navigation and indentation.
359
360(defconst css-navigation-syntax-table
361 (let ((st (make-syntax-table css-mode-syntax-table)))
362 (map-char-table (lambda (c v)
363 ;; Turn punctuation (code = 1) into symbol (code = 1).
364 (if (eq (car-safe v) 1)
365 (set-char-table-range st c (cons 3 (cdr v)))))
366 st)
367 st))
368
369(defun css-backward-sexp (n)
370 (let ((forward-sexp-function nil))
371 (if (< n 0) (css-forward-sexp (- n))
372 (while (> n 0)
373 (setq n (1- n))
374 (forward-comment (- (point-max)))
375 (if (not (eq (char-before) ?\;))
376 (backward-sexp 1)
377 (while (progn (backward-sexp 1)
378 (save-excursion
379 (forward-comment (- (point-max)))
380 ;; FIXME: We should also skip punctuation.
381 (not (or (bobp) (memq (char-before) '(?\; ?\{))))))))))))
382
383(defun css-forward-sexp (n)
384 (let ((forward-sexp-function nil))
385 (if (< n 0) (css-backward-sexp (- n))
386 (while (> n 0)
387 (setq n (1- n))
388 (forward-comment (point-max))
389 (if (not (eq (char-after) ?\;))
390 (forward-sexp 1)
391 (while (progn (forward-sexp 1)
392 (save-excursion
393 (forward-comment (point-max))
394 ;; FIXME: We should also skip punctuation.
395 (not (memq (char-after) '(?\; ?\})))))))))))
396
397(defun css-indent-calculate-virtual ()
398 (if (or (save-excursion (skip-chars-backward " \t") (bolp))
399 (if (looking-at "\\s(")
400 (save-excursion
401 (forward-char 1) (skip-chars-forward " \t")
402 (not (or (eolp) (looking-at comment-start-skip))))))
403 (current-column)
404 (css-indent-calculate)))
405
406(defcustom css-indent-offset 4
407 "Basic size of one indentation step."
408 :version "22.2"
409 :type 'integer
410 :group 'css)
411
412(defun css-indent-calculate ()
413 (let ((ppss (syntax-ppss))
414 pos)
415 (with-syntax-table css-navigation-syntax-table
416 (save-excursion
417 (cond
418 ;; Inside a string.
419 ((nth 3 ppss) 'noindent)
420 ;; Inside a comment.
421 ((nth 4 ppss)
422 (setq pos (point))
423 (forward-line -1)
424 (skip-chars-forward " \t")
425 (if (>= (nth 8 ppss) (point))
426 (progn
427 (goto-char (nth 8 ppss))
428 (if (eq (char-after pos) ?*)
429 (forward-char 1)
430 (if (not (looking-at comment-start-skip))
431 (error "Internal css-mode error")
432 (goto-char (match-end 0))))
433 (current-column))
434 (if (and (eq (char-after pos) ?*) (eq (char-after) ?*))
435 (current-column)
436 ;; 'noindent
437 (current-column)
438 )))
439 ;; In normal code.
440 (t
441 (or
442 (when (looking-at "\\s)")
443 (forward-char 1)
444 (backward-sexp 1)
445 (css-indent-calculate-virtual))
446 (when (looking-at comment-start-skip)
447 (forward-comment (point-max))
448 (css-indent-calculate))
449 (when (save-excursion (forward-comment (- (point-max)))
450 (setq pos (point))
451 (eq (char-syntax (preceding-char)) ?\())
452 (goto-char (1- pos))
453 (if (not (looking-at "\\s([ \t]*"))
454 (error "Internal css-mode error")
455 (if (or (memq (char-after (match-end 0)) '(?\n nil))
456 (save-excursion (goto-char (match-end 0))
457 (looking-at comment-start-skip)))
458 (+ (css-indent-calculate-virtual) css-indent-offset)
459 (progn (goto-char (match-end 0)) (current-column)))))
460 (progn
461 (css-backward-sexp 1)
462 (if (looking-at "\\s(")
463 (css-indent-calculate)
464 (css-indent-calculate-virtual))))))))))
465
466
467(defun css-indent-line ()
468 "Indent current line according to CSS indentation rules."
469 (interactive)
470 (let* ((savep (point))
471 (forward-sexp-function nil)
472 (indent (condition-case nil
473 (save-excursion
474 (forward-line 0)
475 (skip-chars-forward " \t")
476 (if (>= (point) savep) (setq savep nil))
477 (css-indent-calculate))
478 (error nil))))
479 (if (not (numberp indent)) 'noindent
480 (if savep
481 (save-excursion (indent-line-to indent))
482 (indent-line-to indent)))))
483
484(defun css-current-defun-name () 402(defun css-current-defun-name ()
485 "Return the name of the CSS section at point, or nil." 403 "Return the name of the CSS section at point, or nil."
486 (save-excursion 404 (save-excursion