# HG changeset patch # User Augie Fackler # Date 1244755814 18000 # Node ID 16b57e1fc23dd944bc8580fbc6990a5b8f5536c7 # Parent 398b9c3a3a0bc7b88b82efaaf24edc52a8d438c4 Add django-html-mode. diff --git a/.elisp/django-html-mode.el b/.elisp/django-html-mode.el new file mode 100644 --- /dev/null +++ b/.elisp/django-html-mode.el @@ -0,0 +1,155 @@ +;; This django-html-mode is mainly derived from html mode +(require 'sgml-mode) + +(defvar django-html-mode-hook nil) + +(defvar django-html-mode-map + (let ((django-html-mode-map (make-keymap))) + (define-key django-html-mode-map "\C-j" 'newline-and-indent) + django-html-mode-map) + "Keymap for Django major mode") + +;; if : if, if not, if A or B, if not A or B, if not A and B +;; for : for a in alist reversed + ;; forloop.counter The current iteration of the loop (1-indexed) + ;; forloop.counter0 The current iteration of the loop (0-indexed) + ;; forloop.revcounter The number of iterations from the end of the loop (1-indexed) + ;; forloop.revcounter0 The number of iterations from the end of the loop (0-indexed) + ;; forloop.first True if this is the first time through the loop + ;; forloop.last True if this is the last time through the loop + ;; forloop.parentloop For nested loops, this is the loop "above" the current one + +;; ifequal : ifequal A B +;; comment : {% This is comment %} +;; filter : {{ name | lower }} + +;; keyword-end : if, for, ifequal, block, ifnotequal, spaceless +;; keyword-3 : regroup +;; keyword-2 : for, ifequal +;; keyword-1 : if, block, extends, include, ifchanged, load, now, ssi, withratio +;; keyword-0 : else, spaceless + +;; start and end keyword for block/comment/variable +(defconst django-html-open-block "{%") +(defconst django-html-close-block "%}") +(defconst django-html-open-comment "{#") +(defconst django-html-close-comment "#}") +(defconst django-html-open-variable "{{") +(defconst django-html-close-variable "}}") + +(defconst django-html-font-lock-keywords-1 + (append + ;; html-mode keyword + sgml-font-lock-keywords-1) + + "First level keyword highlighting") + +(defconst django-html-font-lock-keywords-2 + (append + django-html-font-lock-keywords-1 + sgml-font-lock-keywords-2)) + +(defconst django-html-font-lock-keywords-3 + (append + django-html-font-lock-keywords-1 + django-html-font-lock-keywords-2 + + `(;; comment + (,(rx (eval django-html-open-comment) + (1+ space) + (0+ (not (any "#"))) + (1+ space) + (eval django-html-close-comment)) + . font-lock-comment-face) + + ;; variable font lock + (,(rx (eval django-html-open-variable) + (1+ space) + (group (0+ (not (any "}")))) + (1+ space) + (eval django-html-close-variable)) + (1 font-lock-variable-name-face)) + + ;; start, end keyword font lock + (,(rx (group (or (eval django-html-open-block) + (eval django-html-close-block) + (eval django-html-open-comment) + (eval django-html-close-comment) + (eval django-html-open-variable) + (eval django-html-close-variable)))) + (1 font-lock-builtin-face)) + + ;; end prefix keyword font lock + (,(rx (eval django-html-open-block) + (1+ space) + (group (and "end" + ;; end prefix keywords + (or "if" "for" "ifequal" "block" "ifnotequal" "spaceless" "filter"))) + (1+ space) + (eval django-html-close-block)) + (1 font-lock-keyword-face)) + + ;; more words after keyword + (,(rx (eval django-html-open-block) + (1+ space) + (group (or "extends" "for" "cycle" "filter" "if not" "else" + "firstof" "debug" "if" "ifchanged" "ifequal" "ifnotequal" + "include" "load" "now" "regroup" "spaceless" "ssi" + "templatetag" "widthratio" "block")) + + ;; TODO: is there a more beautiful way? + (0+ (not (any "}"))) + + (1+ space) + (eval django-html-close-block)) + (1 font-lock-keyword-face)) + + ;; TODO: if specific cases for supporting "or", "not", and "and" + + ;; for sepcific cases for supporting in + (,(rx (eval django-html-open-block) + (1+ space) + "for" + (1+ space) + + (group (1+ (or word ?_ ?.))) + + (1+ space) + (group "in") + (1+ space) + + (group (1+ (or word ?_ ?.))) + + (group (? (1+ space) "reverse")) + + (1+ space) + (eval django-html-close-block)) + (1 font-lock-variable-name-face) (2 font-lock-keyword-face) + (3 font-lock-variable-name-face) (4 font-lock-keyword-face))))) + +(defvar django-html-font-lock-keywords + django-html-font-lock-keywords-1) + +(defvar django-html-mode-syntax-table + (let ((django-html-mode-syntax-table (make-syntax-table))) + django-html-mode-syntax-table) + "Syntax table for django-html-mode") + +;;;###autoload +(define-derived-mode django-html-mode html-mode "django-html" + "Major mode for editing django html files(.djhtml)" + :group 'django-html + + ;; it mainly from sgml-mode font lock setting + (set (make-local-variable 'font-lock-defaults) + '((django-html-font-lock-keywords + django-html-font-lock-keywords-1 + django-html-font-lock-keywords-2 + django-html-font-lock-keywords-3) + nil t nil nil + (font-lock-syntactic-keywords + . sgml-font-lock-syntactic-keywords)))) + +(add-to-list 'auto-mode-alist '("\\.djhtml$'" . django-html-mode)) + +(provide 'django-html-mode) diff --git a/.elisp/settings/40.modes.el b/.elisp/settings/40.modes.el --- a/.elisp/settings/40.modes.el +++ b/.elisp/settings/40.modes.el @@ -29,6 +29,10 @@ point." (af-tab-fix) (local-set-key "\C-m" 'newline-and-indent))) +(require 'django-html-mode) +;; I think I probably just always want it in django mode for now +(add-to-list 'auto-mode-alist '("\\.html$'" . django-html-mode)) + (defun af-python-mode-hook () ; highlight tabs in Python (make-variable-buffer-local 'font-lock-mode-hook)