diff options
| author | Dmitry Gutov | 2016-03-08 15:46:19 +0200 |
|---|---|---|
| committer | Dmitry Gutov | 2016-03-09 17:22:56 +0200 |
| commit | 366ec7719f3cfde5f003d97ae9f5d02609827b0c (patch) | |
| tree | 72ac583d68224497c7486d5edf6f89a00b23d74d | |
| parent | 02bf7cc4632dae6bd679f34307fc83ccc8510471 (diff) | |
| download | emacs-366ec7719f3cfde5f003d97ae9f5d02609827b0c.tar.gz emacs-366ec7719f3cfde5f003d97ae9f5d02609827b0c.zip | |
Allow using the left shift operator without spaces on both sides
* 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.
| -rw-r--r-- | lisp/progmodes/ruby-mode.el | 26 | ||||
| -rw-r--r-- | test/automated/ruby-mode-tests.el | 9 |
2 files changed, 25 insertions, 10 deletions
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index 2ecda9530aa..b846dfe9191 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el | |||
| @@ -894,12 +894,18 @@ and `\\' when preceded by `?'." | |||
| 894 | ((and (eq c ?:) (or (not b) (eq (char-syntax b) ? )))) | 894 | ((and (eq c ?:) (or (not b) (eq (char-syntax b) ? )))) |
| 895 | ((eq c ?\\) (eq b ??))))) | 895 | ((eq c ?\\) (eq b ??))))) |
| 896 | 896 | ||
| 897 | (defun ruby-singleton-class-p (&optional pos) | 897 | (defun ruby-verify-heredoc (&optional pos) |
| 898 | (save-excursion | 898 | (save-excursion |
| 899 | (when pos (goto-char pos)) | 899 | (when pos (goto-char pos)) |
| 900 | (forward-word-strictly -1) | 900 | ;; Not right after a symbol or prefix character. |
| 901 | (and (or (bolp) (not (eq (char-before (point)) ?_))) | 901 | ;; Method names are only allowed when separated by |
| 902 | (looking-at ruby-singleton-class-re)))) | 902 | ;; whitespace. Not a limitation in Ruby, but it's hard for |
| 903 | ;; us to do better. | ||
| 904 | (when (not (memq (car (syntax-after (1- (point)))) '(2 3 6 10))) | ||
| 905 | (or (not (memq (char-before) '(?\s ?\t))) | ||
| 906 | (ignore (forward-word-strictly -1)) | ||
| 907 | (eq (char-before) ?_) | ||
| 908 | (not (looking-at ruby-singleton-class-re)))))) | ||
| 903 | 909 | ||
| 904 | (defun ruby-expr-beg (&optional option) | 910 | (defun ruby-expr-beg (&optional option) |
| 905 | "Check if point is possibly at the beginning of an expression. | 911 | "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'." | |||
| 919 | nil) | 925 | nil) |
| 920 | ((looking-at ruby-operator-re)) | 926 | ((looking-at ruby-operator-re)) |
| 921 | ((eq option 'heredoc) | 927 | ((eq option 'heredoc) |
| 922 | (and (< space 0) (not (ruby-singleton-class-p start)))) | 928 | (and (< space 0) (ruby-verify-heredoc start))) |
| 923 | ((or (looking-at "[\\[({,;]") | 929 | ((or (looking-at "[\\[({,;]") |
| 924 | (and (looking-at "[!?]") | 930 | (and (looking-at "[!?]") |
| 925 | (or (not (eq option 'modifier)) | 931 | (or (not (eq option 'modifier)) |
| @@ -1894,9 +1900,9 @@ It will be properly highlighted even when the call omits parens.") | |||
| 1894 | ("^\\(=\\)begin\\_>" (1 "!")) | 1900 | ("^\\(=\\)begin\\_>" (1 "!")) |
| 1895 | ;; Handle here documents. | 1901 | ;; Handle here documents. |
| 1896 | ((concat ruby-here-doc-beg-re ".*\\(\n\\)") | 1902 | ((concat ruby-here-doc-beg-re ".*\\(\n\\)") |
| 1897 | (7 (unless (or (nth 8 (save-excursion | 1903 | (7 (when (and (not (nth 8 (save-excursion |
| 1898 | (syntax-ppss (match-beginning 0)))) | 1904 | (syntax-ppss (match-beginning 0))))) |
| 1899 | (ruby-singleton-class-p (match-beginning 0))) | 1905 | (ruby-verify-heredoc (match-beginning 0))) |
| 1900 | (put-text-property (match-beginning 7) (match-end 7) | 1906 | (put-text-property (match-beginning 7) (match-end 7) |
| 1901 | 'syntax-table (string-to-syntax "\"")) | 1907 | 'syntax-table (string-to-syntax "\"")) |
| 1902 | (ruby-syntax-propertize-heredoc end)))) | 1908 | (ruby-syntax-propertize-heredoc end)))) |
| @@ -1920,7 +1926,7 @@ It will be properly highlighted even when the call omits parens.") | |||
| 1920 | (beginning-of-line) | 1926 | (beginning-of-line) |
| 1921 | (while (re-search-forward ruby-here-doc-beg-re | 1927 | (while (re-search-forward ruby-here-doc-beg-re |
| 1922 | (line-end-position) t) | 1928 | (line-end-position) t) |
| 1923 | (unless (ruby-singleton-class-p (match-beginning 0)) | 1929 | (when (ruby-verify-heredoc (match-beginning 0)) |
| 1924 | (push (concat (ruby-here-doc-end-match) "\n") res)))) | 1930 | (push (concat (ruby-here-doc-end-match) "\n") res)))) |
| 1925 | (save-excursion | 1931 | (save-excursion |
| 1926 | ;; With multiple openers on the same line, we don't know in which | 1932 | ;; With multiple openers on the same line, we don't know in which |
| @@ -2166,7 +2172,7 @@ See `font-lock-syntax-table'.") | |||
| 2166 | (1 font-lock-builtin-face)) | 2172 | (1 font-lock-builtin-face)) |
| 2167 | ;; Here-doc beginnings. | 2173 | ;; Here-doc beginnings. |
| 2168 | (,ruby-here-doc-beg-re | 2174 | (,ruby-here-doc-beg-re |
| 2169 | (0 (unless (ruby-singleton-class-p (match-beginning 0)) | 2175 | (0 (when (ruby-verify-heredoc (match-beginning 0)) |
| 2170 | 'font-lock-string-face))) | 2176 | 'font-lock-string-face))) |
| 2171 | ;; Perl-ish keywords. | 2177 | ;; Perl-ish keywords. |
| 2172 | "\\_<\\(?:BEGIN\\|END\\)\\_>\\|^__END__$" | 2178 | "\\_<\\(?:BEGIN\\|END\\)\\_>\\|^__END__$" |
diff --git a/test/automated/ruby-mode-tests.el b/test/automated/ruby-mode-tests.el index 7073f7a04e2..4fa7470218a 100644 --- a/test/automated/ruby-mode-tests.el +++ b/test/automated/ruby-mode-tests.el | |||
| @@ -91,6 +91,15 @@ VALUES-PLIST is a list with alternating index and value elements." | |||
| 91 | (ert-deftest ruby-no-heredoc-inside-quotes () | 91 | (ert-deftest ruby-no-heredoc-inside-quotes () |
| 92 | (ruby-assert-state "\"<<\", \"\",\nfoo" 3 nil)) | 92 | (ruby-assert-state "\"<<\", \"\",\nfoo" 3 nil)) |
| 93 | 93 | ||
| 94 | (ert-deftest ruby-no-heredoc-left-shift () | ||
| 95 | ;; We can't really detect the left shift operator (like in similar | ||
| 96 | ;; cases, it depends on the type of foo), so we just require for << | ||
| 97 | ;; to be preceded by a character from a known set. | ||
| 98 | (ruby-assert-state "foo(a<<b)" 3 nil)) | ||
| 99 | |||
| 100 | (ert-deftest ruby-no-heredoc-class-self () | ||
| 101 | (ruby-assert-state "class <<self\nend" 3 nil)) | ||
| 102 | |||
| 94 | (ert-deftest ruby-exit!-font-lock () | 103 | (ert-deftest ruby-exit!-font-lock () |
| 95 | (ruby-assert-face "exit!" 5 font-lock-builtin-face)) | 104 | (ruby-assert-face "exit!" 5 font-lock-builtin-face)) |
| 96 | 105 | ||