diff options
| -rw-r--r-- | lisp/ChangeLog | 13 | ||||
| -rw-r--r-- | lisp/progmodes/ruby-mode.el | 29 | ||||
| -rw-r--r-- | test/ChangeLog | 6 | ||||
| -rw-r--r-- | test/automated/ruby-mode-tests.el | 41 |
4 files changed, 71 insertions, 18 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 0295afa866f..c715059c135 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,16 @@ | |||
| 1 | 2012-08-09 Dmitry Gutov <dgutov@yandex.ru> | ||
| 2 | |||
| 3 | Merge stuff from upsteam ruby-mode, part 1 (bug#12169). | ||
| 4 | * progmodes/ruby-mode.el (ruby-mode-map): Remove deprecated | ||
| 5 | binding (use `M-;' instead). | ||
| 6 | (ruby-expr-beg, ruby-parse-partial): ?, _, and : are symbol | ||
| 7 | constituents, ! is not (but kinda should be). | ||
| 8 | (ruby-singleton-class-p): New function. | ||
| 9 | (ruby-expr-beg, ruby-in-here-doc-p) | ||
| 10 | (ruby-syntax-propertize-heredoc): Use it. | ||
| 11 | (ruby-syntax-propertize-function): Adjust for changes in | ||
| 12 | `ruby-syntax-propertize-heredoc'. | ||
| 13 | |||
| 1 | 2012-08-10 Stefan Monnier <monnier@iro.umontreal.ca> | 14 | 2012-08-10 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 15 | ||
| 3 | * emacs-lisp/cl-macs.el (cl-loop): Improve debug spec. | 16 | * emacs-lisp/cl-macs.el (cl-loop): Improve debug spec. |
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index 091a7b74df2..68abaff21d2 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el | |||
| @@ -151,7 +151,6 @@ This should only be called after matching against `ruby-here-doc-beg-re'." | |||
| 151 | (define-key map (kbd "C-M-h") 'backward-kill-word) | 151 | (define-key map (kbd "C-M-h") 'backward-kill-word) |
| 152 | (define-key map (kbd "C-j") 'reindent-then-newline-and-indent) | 152 | (define-key map (kbd "C-j") 'reindent-then-newline-and-indent) |
| 153 | (define-key map (kbd "C-m") 'newline) | 153 | (define-key map (kbd "C-m") 'newline) |
| 154 | (define-key map (kbd "C-c C-c") 'comment-region) | ||
| 155 | map) | 154 | map) |
| 156 | "Keymap used in Ruby mode.") | 155 | "Keymap used in Ruby mode.") |
| 157 | 156 | ||
| @@ -380,11 +379,19 @@ and `\\' when preceded by `?'." | |||
| 380 | ((and (eq c ?:) (or (not b) (eq (char-syntax b) ? )))) | 379 | ((and (eq c ?:) (or (not b) (eq (char-syntax b) ? )))) |
| 381 | ((eq c ?\\) (eq b ??))))) | 380 | ((eq c ?\\) (eq b ??))))) |
| 382 | 381 | ||
| 382 | (defun ruby-singleton-class-p (&optional pos) | ||
| 383 | (save-excursion | ||
| 384 | (when pos (goto-char pos)) | ||
| 385 | (forward-word -1) | ||
| 386 | (and (or (bolp) (not (eq (char-before (point)) ?_))) | ||
| 387 | (looking-at "class\\s *<<")))) | ||
| 388 | |||
| 383 | (defun ruby-expr-beg (&optional option) | 389 | (defun ruby-expr-beg (&optional option) |
| 384 | "TODO: document." | 390 | "TODO: document." |
| 385 | (save-excursion | 391 | (save-excursion |
| 386 | (store-match-data nil) | 392 | (store-match-data nil) |
| 387 | (let ((space (skip-chars-backward " \t"))) | 393 | (let ((space (skip-chars-backward " \t")) |
| 394 | (start (point))) | ||
| 388 | (cond | 395 | (cond |
| 389 | ((bolp) t) | 396 | ((bolp) t) |
| 390 | ((progn | 397 | ((progn |
| @@ -393,7 +400,8 @@ and `\\' when preceded by `?'." | |||
| 393 | (or (eq (char-syntax (char-before (point))) ?w) | 400 | (or (eq (char-syntax (char-before (point))) ?w) |
| 394 | (ruby-special-char-p)))) | 401 | (ruby-special-char-p)))) |
| 395 | nil) | 402 | nil) |
| 396 | ((and (eq option 'heredoc) (< space 0)) t) | 403 | ((and (eq option 'heredoc) (< space 0)) |
| 404 | (not (progn (goto-char start) (ruby-singleton-class-p)))) | ||
| 397 | ((or (looking-at ruby-operator-re) | 405 | ((or (looking-at ruby-operator-re) |
| 398 | (looking-at "[\\[({,;]") | 406 | (looking-at "[\\[({,;]") |
| 399 | (and (looking-at "[!?]") | 407 | (and (looking-at "[!?]") |
| @@ -409,7 +417,7 @@ and `\\' when preceded by `?'." | |||
| 409 | ruby-block-mid-keywords) | 417 | ruby-block-mid-keywords) |
| 410 | 'words)) | 418 | 'words)) |
| 411 | (goto-char (match-end 0)) | 419 | (goto-char (match-end 0)) |
| 412 | (not (looking-at "\\s_"))) | 420 | (not (looking-at "\\s_\\|!"))) |
| 413 | ((eq option 'expr-qstr) | 421 | ((eq option 'expr-qstr) |
| 414 | (looking-at "[a-zA-Z][a-zA-z0-9_]* +%[^ \t]")) | 422 | (looking-at "[a-zA-Z][a-zA-z0-9_]* +%[^ \t]")) |
| 415 | ((eq option 'expr-re) | 423 | ((eq option 'expr-re) |
| @@ -581,9 +589,7 @@ and `\\' when preceded by `?'." | |||
| 581 | (eq ?. w))))) | 589 | (eq ?. w))))) |
| 582 | (goto-char pnt) | 590 | (goto-char pnt) |
| 583 | (setq w (char-after (point))) | 591 | (setq w (char-after (point))) |
| 584 | (not (eq ?_ w)) | ||
| 585 | (not (eq ?! w)) | 592 | (not (eq ?! w)) |
| 586 | (not (eq ?? w)) | ||
| 587 | (skip-chars-forward " \t") | 593 | (skip-chars-forward " \t") |
| 588 | (goto-char (match-beginning 0)) | 594 | (goto-char (match-beginning 0)) |
| 589 | (or (not (looking-at ruby-modifier-re)) | 595 | (or (not (looking-at ruby-modifier-re)) |
| @@ -1159,7 +1165,10 @@ See `add-log-current-defun-function'." | |||
| 1159 | ("^\\(=\\)begin\\_>" (1 "!")) | 1165 | ("^\\(=\\)begin\\_>" (1 "!")) |
| 1160 | ;; Handle here documents. | 1166 | ;; Handle here documents. |
| 1161 | ((concat ruby-here-doc-beg-re ".*\\(\n\\)") | 1167 | ((concat ruby-here-doc-beg-re ".*\\(\n\\)") |
| 1162 | (7 (prog1 "\"" (ruby-syntax-propertize-heredoc end)))) | 1168 | (7 (unless (ruby-singleton-class-p (match-beginning 0)) |
| 1169 | (put-text-property (match-beginning 7) (match-end 7) | ||
| 1170 | 'syntax-table (string-to-syntax "\"")) | ||
| 1171 | (ruby-syntax-propertize-heredoc end)))) | ||
| 1163 | ;; Handle percent literals: %w(), %q{}, etc. | 1172 | ;; Handle percent literals: %w(), %q{}, etc. |
| 1164 | ("\\(?:^\\|[[ \t\n<+(,=]\\)\\(%\\)[qQrswWx]?\\([[:punct:]]\\)" | 1173 | ("\\(?:^\\|[[ \t\n<+(,=]\\)\\(%\\)[qQrswWx]?\\([[:punct:]]\\)" |
| 1165 | (1 (prog1 "|" (ruby-syntax-propertize-general-delimiters end))))) | 1174 | (1 (prog1 "|" (ruby-syntax-propertize-general-delimiters end))))) |
| @@ -1174,7 +1183,8 @@ See `add-log-current-defun-function'." | |||
| 1174 | (beginning-of-line) | 1183 | (beginning-of-line) |
| 1175 | (while (re-search-forward ruby-here-doc-beg-re | 1184 | (while (re-search-forward ruby-here-doc-beg-re |
| 1176 | (line-end-position) t) | 1185 | (line-end-position) t) |
| 1177 | (push (concat (ruby-here-doc-end-match) "\n") res))) | 1186 | (unless (ruby-singleton-class-p (match-beginning 0)) |
| 1187 | (push (concat (ruby-here-doc-end-match) "\n") res)))) | ||
| 1178 | (let ((start (point))) | 1188 | (let ((start (point))) |
| 1179 | ;; With multiple openers on the same line, we don't know in which | 1189 | ;; With multiple openers on the same line, we don't know in which |
| 1180 | ;; part `start' is, so we have to go back to the beginning. | 1190 | ;; part `start' is, so we have to go back to the beginning. |
| @@ -1310,7 +1320,8 @@ isn't in a string or another comment." | |||
| 1310 | (let ((old-point (point)) (case-fold-search nil)) | 1320 | (let ((old-point (point)) (case-fold-search nil)) |
| 1311 | (beginning-of-line) | 1321 | (beginning-of-line) |
| 1312 | (catch 'found-beg | 1322 | (catch 'found-beg |
| 1313 | (while (re-search-backward ruby-here-doc-beg-re nil t) | 1323 | (while (and (re-search-backward ruby-here-doc-beg-re nil t) |
| 1324 | (not (ruby-singleton-class-p))) | ||
| 1314 | (if (not (or (ruby-in-ppss-context-p 'anything) | 1325 | (if (not (or (ruby-in-ppss-context-p 'anything) |
| 1315 | (ruby-here-doc-find-end old-point))) | 1326 | (ruby-here-doc-find-end old-point))) |
| 1316 | (throw 'found-beg t))))))) | 1327 | (throw 'found-beg t))))))) |
diff --git a/test/ChangeLog b/test/ChangeLog index 03d43d72b54..86f3019cb08 100644 --- a/test/ChangeLog +++ b/test/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2012-08-09 Dmitry Gutov <dgutov@yandex.ru> | ||
| 2 | |||
| 3 | * automated/ruby-mode-tests.el (ruby-should-indent) | ||
| 4 | (ruby-assert-state): New functions. | ||
| 5 | Add new tests. | ||
| 6 | |||
| 1 | 2012-07-29 David Engster <deng@randomsample.de> | 7 | 2012-07-29 David Engster <deng@randomsample.de> |
| 2 | 8 | ||
| 3 | * automated/xml-parse-tests.el (xml-parse-tests--qnames): New | 9 | * automated/xml-parse-tests.el (xml-parse-tests--qnames): New |
diff --git a/test/automated/ruby-mode-tests.el b/test/automated/ruby-mode-tests.el index 1a91f518b92..fbe1b8de9ae 100644 --- a/test/automated/ruby-mode-tests.el +++ b/test/automated/ruby-mode-tests.el | |||
| @@ -23,16 +23,39 @@ | |||
| 23 | 23 | ||
| 24 | (require 'ruby-mode) | 24 | (require 'ruby-mode) |
| 25 | 25 | ||
| 26 | (ert-deftest indent-line-after-symbol-made-from-string-interpolation () | 26 | (defun ruby-should-indent (content column) |
| 27 | (with-temp-buffer | ||
| 28 | (insert content) | ||
| 29 | (ruby-mode) | ||
| 30 | (ruby-indent-line) | ||
| 31 | (should (= (current-column) column)))) | ||
| 32 | |||
| 33 | (defun ruby-assert-state (content &rest values-plist) | ||
| 34 | "Assert syntax state values at the end of CONTENT. | ||
| 35 | |||
| 36 | VALUES-PLIST is a list with alternating index and value elements." | ||
| 37 | (with-temp-buffer | ||
| 38 | (insert content) | ||
| 39 | (ruby-mode) | ||
| 40 | (syntax-propertize (point)) | ||
| 41 | (while values-plist | ||
| 42 | (should (eq (nth (car values-plist) | ||
| 43 | (parse-partial-sexp (point-min) (point))) | ||
| 44 | (cadr values-plist))) | ||
| 45 | (setq values-plist (cddr values-plist))))) | ||
| 46 | |||
| 47 | (ert-deftest ruby-indent-after-symbol-made-from-string-interpolation () | ||
| 27 | "It can indent the line after symbol made using string interpolation." | 48 | "It can indent the line after symbol made using string interpolation." |
| 28 | (let ((initial-content "def foo(suffix)\n :\"bar#{suffix}\"\n") | 49 | (ruby-should-indent "def foo(suffix)\n :\"bar#{suffix}\"\n" |
| 29 | (expected-content "def foo(suffix)\n :\"bar#{suffix}\"\n ")) | 50 | ruby-indent-level)) |
| 30 | (with-temp-buffer | 51 | |
| 31 | (insert initial-content) | 52 | (ert-deftest ruby-indent-after-js-style-symbol-with-block-beg-name () |
| 32 | (ruby-indent-line) ; Doesn't rely on text properties or the syntax table. | 53 | "JS-style hash symbol can have keyword name." |
| 33 | (let ((buffer-content (buffer-substring-no-properties (point-min) | 54 | (ruby-should-indent "link_to \"home\", home_path, class: \"foo\"\n" 0)) |
| 34 | (point-max)))) | 55 | |
| 35 | (should (string= buffer-content expected-content)))))) | 56 | (ert-deftest ruby-discern-singleton-class-from-heredoc () |
| 57 | (ruby-assert-state "foo <<asd\n" 3 ?\n) | ||
| 58 | (ruby-assert-state "class <<asd\n" 3 nil)) | ||
| 36 | 59 | ||
| 37 | (provide 'ruby-mode-tests) | 60 | (provide 'ruby-mode-tests) |
| 38 | 61 | ||