]> code.delx.au - gnu-emacs/commitdiff
Allow using the left shift operator without spaces on both sides
authorDmitry Gutov <dgutov@yandex.ru>
Tue, 8 Mar 2016 13:46:19 +0000 (15:46 +0200)
committerDmitry Gutov <dgutov@yandex.ru>
Wed, 9 Mar 2016 15:22:56 +0000 (17:22 +0200)
* lisp/progmodes/ruby-mode.el (ruby-singleton-class-p): Rename to
ruby-verify-heredoc, reverse the meaning of the return value, and
short-circuit if preceded by a symbol not separated by whitespace.

* test/automated/ruby-mode-tests.el (ruby-no-heredoc-left-shift)
(ruby-no-heredoc-class-self): New tests.

lisp/progmodes/ruby-mode.el
test/automated/ruby-mode-tests.el

index 2ecda9530aa7bb870c8d4573972db30610bdc947..b846dfe91914312f1f20ca427953a07fcdeb48a1 100644 (file)
@@ -894,12 +894,18 @@ and `\\' when preceded by `?'."
           ((and (eq c ?:) (or (not b) (eq (char-syntax b) ? ))))
           ((eq c ?\\) (eq b ??)))))
 
-(defun ruby-singleton-class-p (&optional pos)
+(defun ruby-verify-heredoc (&optional pos)
   (save-excursion
     (when pos (goto-char pos))
-    (forward-word-strictly -1)
-    (and (or (bolp) (not (eq (char-before (point)) ?_)))
-         (looking-at ruby-singleton-class-re))))
+    ;; Not right after a symbol or prefix character.
+    ;; Method names are only allowed when separated by
+    ;; whitespace.  Not a limitation in Ruby, but it's hard for
+    ;; us to do better.
+    (when (not (memq (car (syntax-after (1- (point)))) '(2 3 6 10)))
+      (or (not (memq (char-before) '(?\s ?\t)))
+          (ignore (forward-word-strictly -1))
+          (eq (char-before) ?_)
+          (not (looking-at ruby-singleton-class-re))))))
 
 (defun ruby-expr-beg (&optional option)
   "Check if point is possibly at the beginning of an expression.
@@ -919,7 +925,7 @@ Can be one of `heredoc', `modifier', `expr-qstr', `expr-re'."
         nil)
        ((looking-at ruby-operator-re))
        ((eq option 'heredoc)
-        (and (< space 0) (not (ruby-singleton-class-p start))))
+        (and (< space 0) (ruby-verify-heredoc start)))
        ((or (looking-at "[\\[({,;]")
             (and (looking-at "[!?]")
                  (or (not (eq option 'modifier))
@@ -1894,9 +1900,9 @@ It will be properly highlighted even when the call omits parens.")
       ("^\\(=\\)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)))
+       (7 (when (and (not (nth 8 (save-excursion
+                                   (syntax-ppss (match-beginning 0)))))
+                     (ruby-verify-heredoc (match-beginning 0)))
             (put-text-property (match-beginning 7) (match-end 7)
                                'syntax-table (string-to-syntax "\""))
             (ruby-syntax-propertize-heredoc end))))
@@ -1920,7 +1926,7 @@ It will be properly highlighted even when the call omits parens.")
         (beginning-of-line)
         (while (re-search-forward ruby-here-doc-beg-re
                                   (line-end-position) t)
-          (unless (ruby-singleton-class-p (match-beginning 0))
+          (when (ruby-verify-heredoc (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
@@ -2166,7 +2172,7 @@ See `font-lock-syntax-table'.")
      (1 font-lock-builtin-face))
     ;; Here-doc beginnings.
     (,ruby-here-doc-beg-re
-     (0 (unless (ruby-singleton-class-p (match-beginning 0))
+     (0 (when (ruby-verify-heredoc (match-beginning 0))
           'font-lock-string-face)))
     ;; Perl-ish keywords.
     "\\_<\\(?:BEGIN\\|END\\)\\_>\\|^__END__$"
index 7073f7a04e229ff0c5f7648236786ab7197167f4..4fa7470218afad8c0115c2be3110d34e83e11bce 100644 (file)
@@ -91,6 +91,15 @@ VALUES-PLIST is a list with alternating index and value elements."
 (ert-deftest ruby-no-heredoc-inside-quotes ()
   (ruby-assert-state "\"<<\", \"\",\nfoo" 3 nil))
 
+(ert-deftest ruby-no-heredoc-left-shift ()
+  ;; We can't really detect the left shift operator (like in similar
+  ;; cases, it depends on the type of foo), so we just require for <<
+  ;; to be preceded by a character from a known set.
+  (ruby-assert-state "foo(a<<b)" 3 nil))
+
+(ert-deftest ruby-no-heredoc-class-self ()
+  (ruby-assert-state "class <<self\nend" 3 nil))
+
 (ert-deftest ruby-exit!-font-lock ()
   (ruby-assert-face "exit!" 5 font-lock-builtin-face))