177 lines
6.3 KiB
EmacsLisp
177 lines
6.3 KiB
EmacsLisp
;;;
|
|
;;; rhtml-fonts.el - font-lock-based fontification support for `rhtml-mode'
|
|
;;;
|
|
|
|
;; This file is not 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 2, 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; see the file COPYING. If not, write to the
|
|
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
;; Boston, MA 02110-1301, USA.
|
|
|
|
|
|
;; 2007 MAR 22 - Rewrote to work with jit-lock-mode, cleanup
|
|
;; 2007 MAR 28 - PST: changed to GPL license from MPL (using font-lock code)
|
|
|
|
|
|
(defvar rhtml-in-erb-keywords
|
|
'(;("\\([A-Z][0-9a-zA-Z_]*\\)" . (1 font-lock-type-face prepend))
|
|
("[^_]\\<\\(alias\\|and\\|begin\\|break\\|case\\|catch\\|class\\|def\\|do\\|elsif\\|else\\|fail\\|ensure\\|for\\|end\\|if\\|in\\|module\\|next\\|not\\|or\\|raise\\|redo\\|rescue\\|retry\\|return\\|then\\|throw\\|super\\|unless\\|undef\\|until\\|when\\|while\\|yield\\|render\\)\\>[^_]" .
|
|
(1 font-lock-keyword-face prepend))
|
|
("\\(@[0-9a-zA-Z_]*\\)" . (1 font-lock-variable-name-face prepend))
|
|
("\\(:[0-9a-zA-Z_]*\\)" . (1 font-lock-constant-face prepend))))
|
|
|
|
(defvar rhtml-font-lock-syntactic-keywords
|
|
'(("\\(<\\)!--" (1 "< b"))
|
|
("--[ \t\n]*\\(>\\)" (1 "> b"))
|
|
("\\(<\\)%" (1 "<"))
|
|
("%\\(>\\)" (1 ">"))
|
|
"Override `sgml-mode' syntactic keywords to support ERb tags."))
|
|
|
|
(defun rhtml-activate-fontification ()
|
|
"Activate font-lock fontification support for the current buffer."
|
|
;; PST: note `jit-lock-mode' seems to play okay with
|
|
;; `font-lock-mode' (but I'm still fighting with `font-lock-mode')
|
|
|
|
(font-lock-mode t)
|
|
(jit-lock-mode t)
|
|
|
|
;; PST -- ERb regions are treated syntactically as comments but have
|
|
;; their `face' text property cleared and are overwritten.
|
|
(set (make-local-variable 'font-lock-syntactic-keywords)
|
|
'rhtml-font-lock-syntactic-keywords)
|
|
|
|
(add-hook 'jit-lock-functions 'rhtml-fontify-region t t))
|
|
|
|
(defun rhtml-fontify-buffer ()
|
|
(interactive)
|
|
(jit-lock-refontify))
|
|
|
|
(defun rhtml-fontify-erb-block (type begin end)
|
|
(let ((delim-face (cdr (assoc type erb-type-to-delim-face)))
|
|
(body-face (cdr (assoc type erb-type-to-face)))
|
|
(open-start begin)
|
|
(open-end (+ begin (if (eq type 'exec) 2 3)))
|
|
(close-start (- end 2))
|
|
(close-end end))
|
|
;; apply edging and base
|
|
(font-lock-append-text-property open-start open-end 'face delim-face)
|
|
(when body-face
|
|
(font-lock-append-text-property open-end close-start 'face body-face))
|
|
(font-lock-append-text-property close-start close-end 'face delim-face)
|
|
;; apply normal ERb fontification
|
|
(when (not (eq type 'comment))
|
|
(let ((font-lock-keywords rhtml-in-erb-keywords)
|
|
(case-fold-search nil))
|
|
(font-lock-fontify-keywords-region open-end close-start)))))
|
|
|
|
(defun rhtml-font-unfontify-region (beg end)
|
|
"Taken from ``font-lock.el''. Similar to
|
|
`font-lock-default-unfontify-region' but does not clear syntactical
|
|
information. This is useful to keep syntactical state without the
|
|
colorization."
|
|
(remove-list-of-text-properties
|
|
beg end (append
|
|
font-lock-extra-managed-props
|
|
'(face font-lock-multiline))))
|
|
|
|
(defun rhtml-fontify-region (begin end)
|
|
;; PST -- hack to greedily grab more ERb tags to update (ensures
|
|
;; that the current ERb tag is updated entirely)
|
|
(save-excursion
|
|
(goto-char begin)
|
|
(search-backward rhtml-erb-open-delim nil t)
|
|
(setq begin (point))
|
|
(goto-char end)
|
|
(search-forward rhtml-erb-close-delim nil t)
|
|
(setq end (point)))
|
|
;; fontify ERb tags -- fontification has already been applied by
|
|
;; font-lock-mode for sgml-mode so we need to clear faces (but not
|
|
;; syntactical information)
|
|
(mapc (lambda (i)
|
|
(rhtml-font-unfontify-region (nth 1 i) (nth 2 i))
|
|
(apply 'rhtml-fontify-erb-block i))
|
|
(rhtml-erb-regions begin end)))
|
|
|
|
|
|
;; ERB faces - each type of ERB tag has it's own face properties
|
|
|
|
(defface erb-face
|
|
'((((class color) (min-colors 88) (background dark))
|
|
:background "#383838")
|
|
(((class color) (min-colors 88) (background light))
|
|
;; :background "azure")
|
|
:background "snow2")
|
|
(((class color) (min-colors 16) (background dark))
|
|
:background "blue3")
|
|
(((class color) (min-colors 16) (background light))
|
|
:background "azure")
|
|
(((class color) (min-colors 8))
|
|
:background "blue")
|
|
(((type tty) (class mono))
|
|
:inverse-video t)
|
|
(t :background "gray"))
|
|
"Default inherited face for ERB tag body"
|
|
:group 'rhtml-faces)
|
|
|
|
(defface erb-delim-face
|
|
'((t (:inherit font-lock-preprocessor-face :bold t :italic t)))
|
|
"Default inherited face for ERB tag delimeters"
|
|
:group 'rhtml-faces)
|
|
|
|
(defface erb-exec-face
|
|
`((t (:inherit erb-face)))
|
|
"Basic face for Ruby embedded into HTML"
|
|
:group 'rhtml-faces)
|
|
|
|
(defface erb-exec-delim-face
|
|
`((t (:inherit erb-delim-face :weight bold)))
|
|
"Basic face for Ruby embedded into HTML"
|
|
:group 'rhtml-faces)
|
|
|
|
(defface erb-out-face
|
|
`((t (:inherit erb-face)))
|
|
"Basic face for Ruby embedded into HTML"
|
|
:group 'rhtml-faces)
|
|
|
|
(defface erb-out-delim-face
|
|
`((((background dark)) :foreground "#aaffff" :background "#383838")
|
|
(t (:inherit erb-delim-face :weight bold :foreground "darkred")))
|
|
"Basic face for Ruby embedded into HTML"
|
|
:group 'rhtml-faces)
|
|
|
|
(defface erb-comment-face
|
|
`((((background dark)) :foreground "lightgreen")
|
|
(t (:inherit erb-face :weight bold :foreground "darkgreen")))
|
|
"Basic face for Ruby embedded into HTML"
|
|
:group 'rhtml-faces)
|
|
|
|
(defface erb-comment-delim-face
|
|
`((((background dark)) :foreground "lightgreen")
|
|
(t (:inherit erb-delim-face :weight bold :foreground "darkgreen")))
|
|
"Basic face for Ruby embedded into HTML"
|
|
:group 'rhtml-faces)
|
|
|
|
|
|
(defvar erb-type-to-face
|
|
'((exec . erb-exec-face)
|
|
(out . erb-out-face)
|
|
(comment . erb-comment-face)))
|
|
|
|
(defvar erb-type-to-delim-face
|
|
'((exec . erb-exec-delim-face)
|
|
(out . erb-out-delim-face)
|
|
(comment . erb-comment-delim-face)))
|
|
|
|
;;
|
|
(provide 'rhtml-fonts) |