emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/jade-mode a8d77823a7 087/128: Merge pull request #40 from


From: ELPA Syncer
Subject: [nongnu] elpa/jade-mode a8d77823a7 087/128: Merge pull request #40 from tjefferson08/39_highlight_js
Date: Sat, 29 Jan 2022 08:24:49 -0500 (EST)

branch: elpa/jade-mode
commit a8d77823a766510b63de8d26b944010f5157245d
Merge: 4e7a20db49 a90b512c6e
Author: Travis Jefferson <tjefferson@signpost.com>
Commit: Travis Jefferson <tjefferson@signpost.com>

    Merge pull request #40 from tjefferson08/39_highlight_js
    
    39 highlight js
---
 example.jade |  10 ++++--
 jade-mode.el | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 101 insertions(+), 16 deletions(-)

diff --git a/example.jade b/example.jade
index ca47edd415..69f9376ecc 100644
--- a/example.jade
+++ b/example.jade
@@ -1,5 +1,5 @@
 !!!
-html(lang="en")
+html(lang="en", class = ['classOne', 'classTwo'].join(','))
   -// consult http://jade-lang.com for a full language reference
   head
     title My page
@@ -26,7 +26,13 @@ html(lang="en")
           span= 'another' + "quote example"
           span this one shouldn't higlight strings or... .other #things if else
           | this one shouldn't highlight strings, and the same goes for 
.keywords #ok ?
-        div#paren.content.example(style = 'float-left') Content .here #should 
be plain if for
+        div#paren.content.example(style = 'float: left;') Content .here 
#should be plain if for
+        div.examples#javascript
+          - var a = 1;
+          - var helperFunction = function (a) { return (a === 1 ? 'singular' : 
'plural'); };
+          span= locals.someArray.join(', ')
+          span= a.toString() + helperFunction(a)
+          span#id.class(style = 'margin-bottom: 0;')= 
"some_js_expression".split('_').join(' ')
       #footer
         #copywrite-text= locals
 
diff --git a/jade-mode.el b/jade-mode.el
index 1639fc74ff..b43b2ddb0c 100644
--- a/jade-mode.el
+++ b/jade-mode.el
@@ -4,6 +4,7 @@
 ;;; Author: Brian M. Carlson and other contributors
 ;;; inspired by http://xahlee.org/emacs/elisp_syntax_coloring.html
 (require 'font-lock)
+(require 'js)
 
 (defun jade-debug (string &rest args)
   "Prints a debug message"
@@ -75,12 +76,11 @@
 (defvar jade-single-quote-string-re "[']\\(\\\\.\\|[^'\n]\\)*[']"
   "Regexp used to match a single-quoted string literal")
 
+(defvar jade-tag-declaration-char-re "[-a-zA-Z0-9_.#]"
+  "Regexp used to match a character in a tag declaration")
+
 (defvar jade-font-lock-keywords
   `(
-    ;; highlight string literals everywhere (except where we later
-    ;; remove all font lock faces)
-    (,(concat jade-single-quote-string-re "\\|" jade-double-quote-string-re) . 
font-lock-string-face)
-
     (,"!!!\\|doctype\\( ?[A-Za-z0-9\-\_]*\\)?" 0 font-lock-comment-face) ;; 
doctype
     (,jade-keywords . font-lock-keyword-face) ;; keywords
     (,"#\\(\\w\\|_\\|-\\)*" . font-lock-variable-name-face) ;; id
@@ -115,12 +115,72 @@
               "\\("
               "|"
               ".*"
-              "\\)") 1 nil t)))
+              "\\)") 1 nil t)
+
+    ;; we abuse font-lock a bit here; these functions inject js-mode
+    ;; highlighting under the guise of matching text for more standard
+    ;; font-lock face application (like we do with regexps above)
+    (jade-highlight-js-in-parens 1 font-lock-preprocessor-face)
+    (jade-highlight-js-after-tag 1 font-lock-preprocessor-face)))
+
+(defun jade-highlight-js-in-parens (limit)
+  "Search for a tag declaration (up to LIMIT) which contains a paren
+block, then highlight the region between the parentheses as
+javascript."
+  (when (re-search-forward (concat "^\\s-*" jade-tag-declaration-char-re "+" 
"(") limit t)
+    (forward-char -1)
+    (let ((start (point))
+          (end (progn
+                 (forward-sexp)
+                 (1- (point)))))
+      (jade-fontify-region-as-js start end)
+      (forward-char -1)
+
+      ;; return some empty match data to appease the font-lock gods
+      (looking-at "\\(\\)"))))
+
+(defun jade-highlight-js-after-tag (limit)
+  "Search for a valid js block, then highlight its contents with js-mode 
syntax highlighting"
+  (when (re-search-forward "^[ \t]*" limit t)
+    (when (not (eolp))
+
+      ;; before parsing/skipping ahead, check the first char; if it's
+      ;; - (not a comment starter!) or =, then we know it's a JS block
+      (if (or (looking-at "-[^/]") (looking-at "="))
+          (jade-fontify-region-as-js (point) (point-at-eol))
+
+        ;; no luck with the first char, so parse to the end of the tag
+        ;; (including optional paren block) and check for '='
+        (jade-goto-end-of-tag)
+        (if (and (looking-at "=") (not (eolp)))
+            (jade-fontify-region-as-js (point) (point-at-eol)))))
+
+    ;; return some empty match data to appease the font-lock gods
+    (looking-at "\\(\\)")))
+
+(defun jade-goto-end-of-tag ()
+  "Skip ahead over whitespace, tag characters (defined in
+`jade-tag-declaration-char-re'), and paren blocks (using
+`forward-sexp') to put point at the end of a full tag declaration (but
+before its content). Use when point is inside or to the left of a tag
+declaration"
+  (interactive)
+
+  ;; skip indentation characters
+  (while (looking-at "[ \t]")
+    (forward-char 1))
+
+  (while (looking-at jade-tag-declaration-char-re)
+    (forward-char 1))
+  (if (looking-at "(")
+      (forward-sexp 1)))
+
 
-;; syntax table
 (defvar jade-syntax-table
-  (let ((syn-table (make-syntax-table)))
-    syn-table)
+  (let ((table (make-syntax-table)))
+    (modify-syntax-entry ?\" "\"" table)
+    (modify-syntax-entry ?\' "\"" table)
+    table)
   "Syntax table for `jade-mode'.")
 
 (defun jade-region-for-sexp ()
@@ -176,7 +236,6 @@ additional call will reset indentation to column 0."
   "Indent active region according to indentation of region's first
 line relative to its parent. Keep region active after command
 terminates (to facilitate subsequent indentations of the same region)"
-
   (interactive "r")
   (save-excursion
 
@@ -221,8 +280,7 @@ terminates (to facilitate subsequent indentations of the 
same region)"
          (line-end-position)))
 
     ;; when no region is active
-    (jade-unindent-line)
-    ))
+    (jade-unindent-line)))
 
 (defun jade-unindent-line ()
   "Unindent line under point by `jade-tab-width'.
@@ -235,7 +293,6 @@ Calling when `current-indentation' is 0 will have no 
effect."
 (defun jade-unindent-region (start end)
   "Unindent active region by `jade-tab-width'.
 Follows indentation behavior of `indent-rigidly'."
-
   (interactive "r")
   (let (deactivate-mark)
     (indent-rigidly start end (- jade-tab-width))))
@@ -256,8 +313,30 @@ Follows indentation behavior of `indent-rigidly'."
   "Insert newline and indent to parent's indentation level."
   (interactive)
   (newline)
-  (indent-line-to (max (jade-previous-line-indentation) 0))
-  )
+  (indent-line-to (max (jade-previous-line-indentation) 0)))
+
+(defun jade-fontify-region-as-js (beg end)
+  "Fontify a region between BEG and END using js-mode fontification.
+Inspired by (read: stolen from) from `haml-mode'. Note the clever use
+of `narrow-to-region' by the author of `haml-mode' to keep syntactic
+highlighting (maybe other things too?) from looking beyond the
+region defined by BEG and END."
+  (save-excursion
+    (save-match-data
+      (let ((font-lock-keywords js--font-lock-keywords-3)
+            (font-lock-syntax-table js-mode-syntax-table)
+            (font-lock-syntactic-keywords nil)
+            (syntax-propertize-function nil)
+            (font-lock-multiline 'undecided)
+            (font-lock-dont-widen t)
+            font-lock-keywords-only
+            font-lock-extend-region-functions
+            font-lock-keywords-case-fold-search)
+        (when (and (fboundp 'js--update-quick-match-re) (null 
js--quick-match-re-func))
+          (js--update-quick-match-re))
+        (save-restriction
+          (narrow-to-region beg end)
+          (font-lock-fontify-region beg end))))))
 
 (defvar jade-mode-map (make-sparse-keymap))
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]