emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] trunk r114899: * lisp/progmodes/ruby-mode.el Use `syntax-p


From: Dmitry Gutov
Subject: [Emacs-diffs] trunk r114899: * lisp/progmodes/ruby-mode.el Use `syntax-propertize-function'
Date: Sat, 02 Nov 2013 01:10:13 +0000
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 114899
revision-id: address@hidden
parent: address@hidden
committer: Dmitry Gutov <address@hidden>
branch nick: trunk
timestamp: Sat 2013-11-02 05:10:10 +0400
message:
  * lisp/progmodes/ruby-mode.el Use `syntax-propertize-function'
  unconditionally.  Remove now unnecessary forward declarations.
  Remove XEmacs-specific setup.
  (ruby-here-doc-end-re, ruby-here-doc-beg-match)
  (ruby-font-lock-syntactic-keywords)
  (ruby-comment-beg-syntax, ruby-in-here-doc-p)
  (ruby-here-doc-find-end, ruby-here-doc-beg-syntax)
  (ruby-here-doc-end-syntax): Remove.
  (ruby-mode): Don't check whether `syntax-propertize-rules' is
  defined as function.
modified:
  lisp/ChangeLog                 changelog-20091113204419-o5vbwnq5f7feedwu-1432
  lisp/progmodes/ruby-mode.el    
rubymode.el-20091113204419-o5vbwnq5f7feedwu-8804
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2013-11-02 00:17:54 +0000
+++ b/lisp/ChangeLog    2013-11-02 01:10:10 +0000
@@ -1,3 +1,16 @@
+2013-11-02  Dmitry Gutov  <address@hidden>
+
+       * progmodes/ruby-mode.el Use `syntax-propertize-function'
+       unconditionally.  Remove now unnecessary forward declarations.
+       Remove XEmacs-specific setup.
+       (ruby-here-doc-end-re, ruby-here-doc-beg-match)
+       (ruby-font-lock-syntactic-keywords)
+       (ruby-comment-beg-syntax, ruby-in-here-doc-p)
+       (ruby-here-doc-find-end, ruby-here-doc-beg-syntax)
+       (ruby-here-doc-end-syntax): Remove.
+       (ruby-mode): Don't check whether `syntax-propertize-rules' is
+       defined as function.
+
 2013-11-02  Bozhidar Batsov  <address@hidden>
 
        * progmodes/ruby-mode.el (ruby-mode-variables, ruby-mode): Use 
`setq-local'.

=== modified file 'lisp/progmodes/ruby-mode.el'
--- a/lisp/progmodes/ruby-mode.el       2013-11-02 00:17:54 +0000
+++ b/lisp/progmodes/ruby-mode.el       2013-11-02 01:10:10 +0000
@@ -1515,349 +1515,182 @@
               (ruby-do-end-to-brace beg end)))
       (goto-char start))))
 
-(declare-function ruby-syntax-propertize-heredoc "ruby-mode" (limit))
-(declare-function ruby-syntax-enclosing-percent-literal "ruby-mode" (limit))
-(declare-function ruby-syntax-propertize-percent-literal "ruby-mode" (limit))
-;; Unusual code layout confuses the byte-compiler.
-(declare-function ruby-syntax-propertize-expansion "ruby-mode" ())
-(declare-function ruby-syntax-expansion-allowed-p "ruby-mode" (parse-state))
-(declare-function ruby-syntax-propertize-function "ruby-mode" (start end))
-
-(if (eval-when-compile (fboundp #'syntax-propertize-rules))
-    ;; New code that works independently from font-lock.
-    (progn
-      (eval-and-compile
-        (defconst ruby-percent-literal-beg-re
-          "\\(%\\)[qQrswWxIi]?\\([[:punct:]]\\)"
-          "Regexp to match the beginning of percent literal.")
-
-        (defconst ruby-syntax-methods-before-regexp
-          '("gsub" "gsub!" "sub" "sub!" "scan" "split" "split!" "index" "match"
-            "assert_match" "Given" "Then" "When")
-          "Methods that can take regexp as the first argument.
+(eval-and-compile
+  (defconst ruby-percent-literal-beg-re
+    "\\(%\\)[qQrswWxIi]?\\([[:punct:]]\\)"
+    "Regexp to match the beginning of percent literal.")
+
+  (defconst ruby-syntax-methods-before-regexp
+    '("gsub" "gsub!" "sub" "sub!" "scan" "split" "split!" "index" "match"
+      "assert_match" "Given" "Then" "When")
+    "Methods that can take regexp as the first argument.
 It will be properly highlighted even when the call omits parens.")
 
-        (defvar ruby-syntax-before-regexp-re
-          (concat
-           ;; Special tokens that can't be followed by a division operator.
-           "\\(^\\|[[=(,~;<>]"
-           ;; Distinguish ternary operator tokens.
-           ;; FIXME: They don't really have to be separated with spaces.
-           "\\|[?:] "
-           ;; Control flow keywords and operators following bol or whitespace.
-           "\\|\\(?:^\\|\\s \\)"
-           (regexp-opt '("if" "elsif" "unless" "while" "until" "when" "and"
-                         "or" "not" "&&" "||"))
-           ;; Method name from the list.
-           "\\|\\_<"
-           (regexp-opt ruby-syntax-methods-before-regexp)
-           "\\)\\s *")
-          "Regexp to match text that can be followed by a regular 
expression."))
-
-      (defun ruby-syntax-propertize-function (start end)
-        "Syntactic keywords for Ruby mode.  See `syntax-propertize-function'."
-        (let (case-fold-search)
-          (goto-char start)
-          (remove-text-properties start end '(ruby-expansion-match-data))
-          (ruby-syntax-propertize-heredoc end)
-          (ruby-syntax-enclosing-percent-literal end)
-          (funcall
-           (syntax-propertize-rules
-            ;; $' $" $` .... are variables.
-            ;; ?' ?" ?` are character literals (one-char strings in 1.9+).
-            ("\\([?$]\\)[#\"'`]"
-             (1 (unless (save-excursion
-                          ;; Not within a string.
-                          (nth 3 (syntax-ppss (match-beginning 0))))
-                  (string-to-syntax "\\"))))
-            ;; Regular expressions.  Start with matching unescaped slash.
-            ("\\(?:\\=\\|[^\\]\\)\\(?:\\\\\\\\\\)*\\(/\\)"
-             (1 (let ((state (save-excursion (syntax-ppss (match-beginning 
1)))))
-                  (when (or
-                         ;; Beginning of a regexp.
-                         (and (null (nth 8 state))
-                              (save-excursion
-                                (forward-char -1)
-                                (looking-back ruby-syntax-before-regexp-re
-                                              (point-at-bol))))
-                         ;; End of regexp.  We don't match the whole
-                         ;; regexp at once because it can have
-                         ;; string interpolation inside, or span
-                         ;; several lines.
-                         (eq ?/ (nth 3 state)))
-                    (string-to-syntax "\"/")))))
-            ;; Expression expansions in strings.  We're handling them
-            ;; here, so that the regexp rule never matches inside them.
-            (ruby-expression-expansion-re
-             (0 (ignore (ruby-syntax-propertize-expansion))))
-            ("^=en\\(d\\)\\_>" (1 "!"))
-            ("^\\(=\\)begin\\_>" (1 "!"))
-            ;; Handle here documents.
-            ((concat ruby-here-doc-beg-re ".*\\(\n\\)")
-             (7 (unless (or (nth 8 (save-excursion
-                                     (syntax-ppss (match-beginning 0))))
-                            (ruby-singleton-class-p (match-beginning 0)))
-                  (put-text-property (match-beginning 7) (match-end 7)
-                                     'syntax-table (string-to-syntax "\""))
-                  (ruby-syntax-propertize-heredoc end))))
-            ;; Handle percent literals: %w(), %q{}, etc.
-            ((concat "\\(?:^\\|[[ \t\n<+(,=]\\)" ruby-percent-literal-beg-re)
-             (1 (prog1 "|" (ruby-syntax-propertize-percent-literal end)))))
-           (point) end)))
-
-      (defun ruby-syntax-propertize-heredoc (limit)
-        (let ((ppss (syntax-ppss))
-              (res '()))
-          (when (eq ?\n (nth 3 ppss))
-            (save-excursion
-              (goto-char (nth 8 ppss))
-              (beginning-of-line)
-              (while (re-search-forward ruby-here-doc-beg-re
-                                        (line-end-position) t)
-                (unless (ruby-singleton-class-p (match-beginning 0))
-                  (push (concat (ruby-here-doc-end-match) "\n") res))))
-            (save-excursion
-              ;; With multiple openers on the same line, we don't know in which
-              ;; part `start' is, so we have to go back to the beginning.
-              (when (cdr res)
-                (goto-char (nth 8 ppss))
-                (setq res (nreverse res)))
-              (while (and res (re-search-forward (pop res) limit 'move))
-                (if (null res)
-                    (put-text-property (1- (point)) (point)
-                                       'syntax-table (string-to-syntax "\""))))
-              ;; End up at bol following the heredoc openers.
-              ;; Propertize expression expansions from this point forward.
-              ))))
-
-      (defun ruby-syntax-enclosing-percent-literal (limit)
-        (let ((state (syntax-ppss))
-              (start (point)))
-          ;; When already inside percent literal, re-propertize it.
-          (when (eq t (nth 3 state))
-            (goto-char (nth 8 state))
-            (when (looking-at ruby-percent-literal-beg-re)
-              (ruby-syntax-propertize-percent-literal limit))
-            (when (< (point) start) (goto-char start)))))
-
-      (defun ruby-syntax-propertize-percent-literal (limit)
-        (goto-char (match-beginning 2))
-        ;; Not inside a simple string or comment.
-        (when (eq t (nth 3 (syntax-ppss)))
-          (let* ((op (char-after))
-                 (ops (char-to-string op))
-                 (cl (or (cdr (aref (syntax-table) op))
-                         (cdr (assoc op '((?< . ?>))))))
-                 parse-sexp-lookup-properties)
-            (save-excursion
-              (condition-case nil
-                  (progn
-                    (if cl              ; Paired delimiters.
-                        ;; Delimiter pairs of the same kind can be nested
-                        ;; inside the literal, as long as they are balanced.
-                        ;; Create syntax table that ignores other characters.
-                        (with-syntax-table (make-char-table 'syntax-table nil)
-                          (modify-syntax-entry op (concat "(" (char-to-string 
cl)))
-                          (modify-syntax-entry cl (concat ")" ops))
-                          (modify-syntax-entry ?\\ "\\")
-                          (save-restriction
-                            (narrow-to-region (point) limit)
-                            (forward-list))) ; skip to the paired character
-                      ;; Single character delimiter.
-                      (re-search-forward (concat "[^\\]\\(?:\\\\\\\\\\)*"
-                                                 (regexp-quote ops)) limit 
nil))
-                    ;; Found the closing delimiter.
-                    (put-text-property (1- (point)) (point) 'syntax-table
-                                       (string-to-syntax "|")))
-                ;; Unclosed literal, do nothing.
-                ((scan-error search-failed)))))))
-
-      (defun ruby-syntax-propertize-expansion ()
-        ;; Save the match data to a text property, for font-locking later.
-        ;; Set the syntax of all double quotes and backticks to punctuation.
-        (let* ((beg (match-beginning 2))
-               (end (match-end 2))
-               (state (and beg (save-excursion (syntax-ppss beg)))))
-          (when (ruby-syntax-expansion-allowed-p state)
-            (put-text-property beg (1+ beg) 'ruby-expansion-match-data
-                               (match-data))
-            (goto-char beg)
-            (while (re-search-forward "[\"`]" end 'move)
-              (put-text-property (match-beginning 0) (match-end 0)
-                                 'syntax-table (string-to-syntax "."))))))
-
-      (defun ruby-syntax-expansion-allowed-p (parse-state)
-        "Return non-nil if expression expansion is allowed."
-        (let ((term (nth 3 parse-state)))
-          (cond
-           ((memq term '(?\" ?` ?\n ?/)))
-           ((eq term t)
-            (save-match-data
-              (save-excursion
-                (goto-char (nth 8 parse-state))
-                (looking-at "%\\(?:[QWrxI]\\|\\W\\)")))))))
-
-      (defun ruby-syntax-propertize-expansions (start end)
-        (save-excursion
-          (goto-char start)
-          (while (re-search-forward ruby-expression-expansion-re end 'move)
-            (ruby-syntax-propertize-expansion))))
-      )
-
-  ;; For Emacsen where syntax-propertize-rules is not (yet) available,
-  ;; fallback on the old font-lock-syntactic-keywords stuff.
-
-  (defconst ruby-here-doc-end-re
-    "^\\([ \t]+\\)?\\(.*\\)\\(\n\\)"
-    "Regexp to match the end of heredocs.
-
-This will actually match any line with one or more characters.
-It's useful in that it divides up the match string so that
-`ruby-here-doc-beg-match' can search for the beginning of the heredoc.")
-
-  (defun ruby-here-doc-beg-match ()
-    "Return a regexp to find the beginning of a heredoc.
-
-This should only be called after matching against `ruby-here-doc-end-re'."
-    (let ((contents (concat
-                     (regexp-quote (concat (match-string 2) (match-string 3)))
-                     (if (string= (match-string 3) "_") "\\B" "\\b"))))
-      (concat "<<"
-              (let ((match (match-string 1)))
-                (if (and match (> (length match) 0))
-                    (concat "\\(?:-\\([\"']?\\)\\|\\([\"']\\)"
-                            (match-string 1) "\\)"
-                            contents "\\(\\1\\|\\2\\)")
-                  (concat "-?\\([\"']\\|\\)" contents "\\1"))))))
-
-  (defconst ruby-font-lock-syntactic-keywords
-    `(
-    ;; the last $', $", $` in the respective string is not variable
-    ;; the last ?', ?", ?` in the respective string is not ascii code
-    ("\\(^\\|[\[ 
\t\n<+\(,=]\\)\\(['\"`]\\)\\(\\\\.\\|\\2\\|[^'\"`\n\\\\]\\)*?\\\\?[?$]\\(\\2\\)"
-     (2 (7 . nil))
-     (4 (7 . nil)))
-    ;; $' $" $` .... are variables
-    ;; ?' ?" ?` are ascii codes
-    ("\\(^\\|[^\\\\]\\)\\(\\\\\\\\\\)*[?$]\\([#\"'`]\\)" 3 (1 . nil))
-    ;; regexps
-    ("\\(^\\|[[=(,~?:;<>]\\|\\(^\\|\\s 
\\)\\(if\\|elsif\\|unless\\|while\\|until\\|when\\|and\\|or\\|&&\\|||\\)\\|g?sub!?\\|scan\\|split!?\\)\\s
 *\\(/\\)[^/\n\\\\]*\\(\\\\.[^/\n\\\\]*\\)*\\(/\\)"
-     (4 (7 . ?/))
-     (6 (7 . ?/)))
-    ("^=en\\(d\\)\\_>" 1 "!")
-    ;; Percent literal.
-    ("\\(^\\|[[ \t\n<+(,=]\\)\\(%[xrqQwW]?\\([^<[{(a-zA-Z0-9 
\n]\\)[^\n\\\\]*\\(\\\\.[^\n\\\\]*\\)*\\(\\3\\)\\)"
-     (3 "\"")
-     (5 "\""))
-    ("^\\(=\\)begin\\_>" 1 (ruby-comment-beg-syntax))
-    ;; Currently, the following case is highlighted incorrectly:
-    ;;
-    ;;   <<FOO
-    ;;   FOO
-    ;;   <<BAR
-    ;;   <<BAZ
-    ;;   BAZ
-    ;;   BAR
-    ;;
-    ;; This is because all here-doc beginnings are highlighted before any 
endings,
-    ;; so although <<BAR is properly marked as a beginning, when we get to 
<<BAZ
-    ;; it thinks <<BAR is part of a string so it's marked as well.
-    ;;
-    ;; This may be fixable by modifying ruby-in-here-doc-p to use
-    ;; ruby-in-non-here-doc-string-p rather than syntax-ppss-context,
-    ;; but I don't want to try that until we've got unit tests set up
-    ;; to make sure I don't break anything else.
-    (,(concat ruby-here-doc-beg-re ".*\\(\n\\)")
-     ,(+ 1 (regexp-opt-depth ruby-here-doc-beg-re))
-     (ruby-here-doc-beg-syntax))
-    (,ruby-here-doc-end-re 3 (ruby-here-doc-end-syntax)))
-  "Syntactic keywords for Ruby mode.  See `font-lock-syntactic-keywords'.")
-
-  (defun ruby-comment-beg-syntax ()
-  "Return the syntax cell for a the first character of a =begin.
-See the definition of `ruby-font-lock-syntactic-keywords'.
-
-This returns a comment-delimiter cell as long as the =begin
-isn't in a string or another comment."
-    (when (not (nth 3 (syntax-ppss)))
-      (string-to-syntax "!")))
-
-  (defun ruby-in-here-doc-p ()
-    "Return whether or not the point is in a heredoc."
-    (save-excursion
-      (let ((old-point (point)) (case-fold-search nil))
+  (defvar ruby-syntax-before-regexp-re
+    (concat
+     ;; Special tokens that can't be followed by a division operator.
+     "\\(^\\|[[=(,~;<>]"
+     ;; Distinguish ternary operator tokens.
+     ;; FIXME: They don't really have to be separated with spaces.
+     "\\|[?:] "
+     ;; Control flow keywords and operators following bol or whitespace.
+     "\\|\\(?:^\\|\\s \\)"
+     (regexp-opt '("if" "elsif" "unless" "while" "until" "when" "and"
+                   "or" "not" "&&" "||"))
+     ;; Method name from the list.
+     "\\|\\_<"
+     (regexp-opt ruby-syntax-methods-before-regexp)
+     "\\)\\s *")
+    "Regexp to match text that can be followed by a regular expression."))
+
+(defun ruby-syntax-propertize-function (start end)
+  "Syntactic keywords for Ruby mode.  See `syntax-propertize-function'."
+  (let (case-fold-search)
+    (goto-char start)
+    (remove-text-properties start end '(ruby-expansion-match-data))
+    (ruby-syntax-propertize-heredoc end)
+    (ruby-syntax-enclosing-percent-literal end)
+    (funcall
+     (syntax-propertize-rules
+      ;; $' $" $` .... are variables.
+      ;; ?' ?" ?` are character literals (one-char strings in 1.9+).
+      ("\\([?$]\\)[#\"'`]"
+       (1 (unless (save-excursion
+                    ;; Not within a string.
+                    (nth 3 (syntax-ppss (match-beginning 0))))
+            (string-to-syntax "\\"))))
+      ;; Regular expressions.  Start with matching unescaped slash.
+      ("\\(?:\\=\\|[^\\]\\)\\(?:\\\\\\\\\\)*\\(/\\)"
+       (1 (let ((state (save-excursion (syntax-ppss (match-beginning 1)))))
+            (when (or
+                   ;; Beginning of a regexp.
+                   (and (null (nth 8 state))
+                        (save-excursion
+                          (forward-char -1)
+                          (looking-back ruby-syntax-before-regexp-re
+                                        (point-at-bol))))
+                   ;; End of regexp.  We don't match the whole
+                   ;; regexp at once because it can have
+                   ;; string interpolation inside, or span
+                   ;; several lines.
+                   (eq ?/ (nth 3 state)))
+              (string-to-syntax "\"/")))))
+      ;; Expression expansions in strings.  We're handling them
+      ;; here, so that the regexp rule never matches inside them.
+      (ruby-expression-expansion-re
+       (0 (ignore (ruby-syntax-propertize-expansion))))
+      ("^=en\\(d\\)\\_>" (1 "!"))
+      ("^\\(=\\)begin\\_>" (1 "!"))
+      ;; Handle here documents.
+      ((concat ruby-here-doc-beg-re ".*\\(\n\\)")
+       (7 (unless (or (nth 8 (save-excursion
+                               (syntax-ppss (match-beginning 0))))
+                      (ruby-singleton-class-p (match-beginning 0)))
+            (put-text-property (match-beginning 7) (match-end 7)
+                               'syntax-table (string-to-syntax "\""))
+            (ruby-syntax-propertize-heredoc end))))
+      ;; Handle percent literals: %w(), %q{}, etc.
+      ((concat "\\(?:^\\|[[ \t\n<+(,=]\\)" ruby-percent-literal-beg-re)
+       (1 (prog1 "|" (ruby-syntax-propertize-percent-literal end)))))
+     (point) end)))
+
+(defun ruby-syntax-propertize-heredoc (limit)
+  (let ((ppss (syntax-ppss))
+        (res '()))
+    (when (eq ?\n (nth 3 ppss))
+      (save-excursion
+        (goto-char (nth 8 ppss))
         (beginning-of-line)
-        (catch 'found-beg
-          (while (and (re-search-backward ruby-here-doc-beg-re nil t)
-                      (not (ruby-singleton-class-p)))
-            (if (not (or (ruby-in-ppss-context-p 'anything)
-                         (ruby-here-doc-find-end old-point)))
-                (throw 'found-beg t)))))))
-
-  (defun ruby-here-doc-find-end (&optional limit)
-    "Expects the point to be on a line with one or more heredoc openers.
-Returns the buffer position at which all heredocs on the line
-are terminated, or nil if they aren't terminated before the
-buffer position `limit' or the end of the buffer."
-    (save-excursion
-      (beginning-of-line)
-      (catch 'done
-        (let ((eol (point-at-eol))
-              (case-fold-search nil)
-              ;; Fake match data such that (match-end 0) is at eol
-              (end-match-data (progn (looking-at ".*$") (match-data)))
-              beg-match-data end-re)
-          (while (re-search-forward ruby-here-doc-beg-re eol t)
-            (setq beg-match-data (match-data))
-            (setq end-re (ruby-here-doc-end-match))
-
-            (set-match-data end-match-data)
-            (goto-char (match-end 0))
-            (unless (re-search-forward end-re limit t) (throw 'done nil))
-            (setq end-match-data (match-data))
-
-            (set-match-data beg-match-data)
-            (goto-char (match-end 0)))
-          (set-match-data end-match-data)
-          (goto-char (match-end 0))
-          (point)))))
-
-  (defun ruby-here-doc-beg-syntax ()
-    "Return the syntax cell for a line that may begin a heredoc.
-See the definition of `ruby-font-lock-syntactic-keywords'.
-
-This sets the syntax cell for the newline ending the line
-containing the heredoc beginning so that cases where multiple
-heredocs are started on one line are handled correctly."
-    (save-excursion
-      (goto-char (match-beginning 0))
-      (unless (or (ruby-in-ppss-context-p 'non-heredoc)
-                  (ruby-in-here-doc-p))
-        (string-to-syntax "\""))))
-
-  (defun ruby-here-doc-end-syntax ()
-    "Return the syntax cell for a line that may end a heredoc.
-See the definition of `ruby-font-lock-syntactic-keywords'."
-    (let ((pss (syntax-ppss)) (case-fold-search nil))
-      ;; If we aren't in a string, we definitely aren't ending a heredoc,
-      ;; so we can just give up.
-      ;; This means we aren't doing a full-document search
-      ;; every time we enter a character.
-      (when (ruby-in-ppss-context-p 'heredoc pss)
+        (while (re-search-forward ruby-here-doc-beg-re
+                                  (line-end-position) t)
+          (unless (ruby-singleton-class-p (match-beginning 0))
+            (push (concat (ruby-here-doc-end-match) "\n") res))))
+      (save-excursion
+        ;; With multiple openers on the same line, we don't know in which
+        ;; part `start' is, so we have to go back to the beginning.
+        (when (cdr res)
+          (goto-char (nth 8 ppss))
+          (setq res (nreverse res)))
+        (while (and res (re-search-forward (pop res) limit 'move))
+          (if (null res)
+              (put-text-property (1- (point)) (point)
+                                 'syntax-table (string-to-syntax "\""))))
+        ;; End up at bol following the heredoc openers.
+        ;; Propertize expression expansions from this point forward.
+        ))))
+
+(defun ruby-syntax-enclosing-percent-literal (limit)
+  (let ((state (syntax-ppss))
+        (start (point)))
+    ;; When already inside percent literal, re-propertize it.
+    (when (eq t (nth 3 state))
+      (goto-char (nth 8 state))
+      (when (looking-at ruby-percent-literal-beg-re)
+        (ruby-syntax-propertize-percent-literal limit))
+      (when (< (point) start) (goto-char start)))))
+
+(defun ruby-syntax-propertize-percent-literal (limit)
+  (goto-char (match-beginning 2))
+  ;; Not inside a simple string or comment.
+  (when (eq t (nth 3 (syntax-ppss)))
+    (let* ((op (char-after))
+           (ops (char-to-string op))
+           (cl (or (cdr (aref (syntax-table) op))
+                   (cdr (assoc op '((?< . ?>))))))
+           parse-sexp-lookup-properties)
+      (save-excursion
+        (condition-case nil
+            (progn
+              (if cl              ; Paired delimiters.
+                  ;; Delimiter pairs of the same kind can be nested
+                  ;; inside the literal, as long as they are balanced.
+                  ;; Create syntax table that ignores other characters.
+                  (with-syntax-table (make-char-table 'syntax-table nil)
+                    (modify-syntax-entry op (concat "(" (char-to-string cl)))
+                    (modify-syntax-entry cl (concat ")" ops))
+                    (modify-syntax-entry ?\\ "\\")
+                    (save-restriction
+                      (narrow-to-region (point) limit)
+                      (forward-list))) ; skip to the paired character
+                ;; Single character delimiter.
+                (re-search-forward (concat "[^\\]\\(?:\\\\\\\\\\)*"
+                                           (regexp-quote ops)) limit nil))
+              ;; Found the closing delimiter.
+              (put-text-property (1- (point)) (point) 'syntax-table
+                                 (string-to-syntax "|")))
+          ;; Unclosed literal, do nothing.
+          ((scan-error search-failed)))))))
+
+(defun ruby-syntax-propertize-expansion ()
+  ;; Save the match data to a text property, for font-locking later.
+  ;; Set the syntax of all double quotes and backticks to punctuation.
+  (let* ((beg (match-beginning 2))
+         (end (match-end 2))
+         (state (and beg (save-excursion (syntax-ppss beg)))))
+    (when (ruby-syntax-expansion-allowed-p state)
+      (put-text-property beg (1+ beg) 'ruby-expansion-match-data
+                         (match-data))
+      (goto-char beg)
+      (while (re-search-forward "[\"`]" end 'move)
+        (put-text-property (match-beginning 0) (match-end 0)
+                           'syntax-table (string-to-syntax "."))))))
+
+(defun ruby-syntax-expansion-allowed-p (parse-state)
+  "Return non-nil if expression expansion is allowed."
+  (let ((term (nth 3 parse-state)))
+    (cond
+     ((memq term '(?\" ?` ?\n ?/)))
+     ((eq term t)
+      (save-match-data
         (save-excursion
-          (goto-char (nth 8 pss))    ; Go to the beginning of heredoc.
-          (let ((eol (point)))
-            (beginning-of-line)
-            (if (and (re-search-forward (ruby-here-doc-beg-match) eol t) ; If 
there is a heredoc that matches this line...
-                     (not (ruby-in-ppss-context-p 'anything)) ; And that's not 
inside a heredoc/string/comment...
-                     (progn (goto-char (match-end 0)) ; And it's the last 
heredoc on its line...
-                            (not (re-search-forward ruby-here-doc-beg-re eol 
t))))
-                (string-to-syntax "\"")))))))
+          (goto-char (nth 8 parse-state))
+          (looking-at "%\\(?:[QWrxI]\\|\\W\\)")))))))
 
-  (unless (functionp 'syntax-ppss)
-    (defun syntax-ppss (&optional pos)
-      (parse-partial-sexp (point-min) (or pos (point)))))
-  )
+(defun ruby-syntax-propertize-expansions (start end)
+  (save-excursion
+    (goto-char start)
+    (while (re-search-forward ruby-expression-expansion-re end 'move)
+      (ruby-syntax-propertize-expansion))))
 
 (defun ruby-in-ppss-context-p (context &optional ppss)
   (let ((ppss (or ppss (syntax-ppss (point)))))
@@ -1880,14 +1713,6 @@
                   "context name `" (symbol-name context) "' is unknown"))))
         t)))
 
-(if (featurep 'xemacs)
-    (put 'ruby-mode 'font-lock-defaults
-         '((ruby-font-lock-keywords)
-           nil nil nil
-           beginning-of-line
-           (font-lock-syntactic-keywords
-            . ruby-font-lock-syntactic-keywords))))
-
 (defvar ruby-font-lock-syntax-table
   (let ((tbl (copy-syntax-table ruby-mode-syntax-table)))
     (modify-syntax-entry ?_ "w" tbl)
@@ -2082,9 +1907,7 @@
   (setq-local font-lock-keywords ruby-font-lock-keywords)
   (setq-local font-lock-syntax-table ruby-font-lock-syntax-table)
 
-  (if (eval-when-compile (fboundp 'syntax-propertize-rules))
-      (setq-local syntax-propertize-function #'ruby-syntax-propertize-function)
-    (setq-local font-lock-syntactic-keywords 
ruby-font-lock-syntactic-keywords)))
+  (setq-local syntax-propertize-function #'ruby-syntax-propertize-function))
 
 ;;; Invoke ruby-mode when appropriate
 


reply via email to

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