aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Gutov2013-05-31 10:04:33 +0400
committerDmitry Gutov2013-05-31 10:04:33 +0400
commit19bb8e629352f9438e95e62559bf73940cd3d885 (patch)
treee3961dcd8917d9bd15873252ac0c87534119cac5
parentfc186a96df6853da2a94b76b40b6f3f8b24e52ac (diff)
downloademacs-19bb8e629352f9438e95e62559bf73940cd3d885.tar.gz
emacs-19bb8e629352f9438e95e62559bf73940cd3d885.zip
* lisp/progmodes/ruby-mode.el (ruby-syntax-expansion-allowed-p): New
function, checks if expression expansion is allowed in given parse state. (ruby-syntax-propertize-expansion): Use it. (ruby-syntax-propertize-function): Bind `case-fold-search' to nil around the body. * test/automated/ruby-mode-tests.el: New tests, for percent literals and expression expansion.
-rw-r--r--lisp/ChangeLog9
-rw-r--r--lisp/progmodes/ruby-mode.el110
-rw-r--r--test/ChangeLog5
-rw-r--r--test/automated/ruby-mode-tests.el17
4 files changed, 93 insertions, 48 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 87774cdb2a5..c4dc36245f2 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,12 @@
12013-05-31 Dmitry Gutov <dgutov@yandex.ru>
2
3 * progmodes/ruby-mode.el (ruby-syntax-expansion-allowed-p): New
4 function, checks if point is inside a literal that allows
5 expression expansion.
6 (ruby-syntax-propertize-expansion): Use it.
7 (ruby-syntax-propertize-function): Bind `case-fold-search' to nil
8 around the body.
9
12013-05-30 Juri Linkov <juri@jurta.org> 102013-05-30 Juri Linkov <juri@jurta.org>
2 11
3 * isearch.el (isearch-mode-map): Bind `isearch-toggle-invisible' 12 * isearch.el (isearch-mode-map): Bind `isearch-toggle-invisible'
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index a96ee64a229..b7a635199ab 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -1349,6 +1349,7 @@ If the result is do-end block, it will always be multiline."
1349(declare-function ruby-syntax-propertize-percent-literal "ruby-mode" (limit)) 1349(declare-function ruby-syntax-propertize-percent-literal "ruby-mode" (limit))
1350;; Unusual code layout confuses the byte-compiler. 1350;; Unusual code layout confuses the byte-compiler.
1351(declare-function ruby-syntax-propertize-expansion "ruby-mode" ()) 1351(declare-function ruby-syntax-propertize-expansion "ruby-mode" ())
1352(declare-function ruby-syntax-expansion-allowed-p "ruby-mode" (parse-state))
1352 1353
1353(if (eval-when-compile (fboundp #'syntax-propertize-rules)) 1354(if (eval-when-compile (fboundp #'syntax-propertize-rules))
1354 ;; New code that works independently from font-lock. 1355 ;; New code that works independently from font-lock.
@@ -1380,51 +1381,52 @@ It will be properly highlighted even when the call omits parens.")
1380 1381
1381 (defun ruby-syntax-propertize-function (start end) 1382 (defun ruby-syntax-propertize-function (start end)
1382 "Syntactic keywords for Ruby mode. See `syntax-propertize-function'." 1383 "Syntactic keywords for Ruby mode. See `syntax-propertize-function'."
1383 (goto-char start) 1384 (let (case-fold-search)
1384 (remove-text-properties start end '(ruby-expansion-match-data)) 1385 (goto-char start)
1385 (ruby-syntax-propertize-heredoc end) 1386 (remove-text-properties start end '(ruby-expansion-match-data))
1386 (ruby-syntax-enclosing-percent-literal end) 1387 (ruby-syntax-propertize-heredoc end)
1387 (funcall 1388 (ruby-syntax-enclosing-percent-literal end)
1388 (syntax-propertize-rules 1389 (funcall
1389 ;; $' $" $` .... are variables. 1390 (syntax-propertize-rules
1390 ;; ?' ?" ?` are ascii codes. 1391 ;; $' $" $` .... are variables.
1391 ("\\([?$]\\)[#\"'`]" 1392 ;; ?' ?" ?` are ascii codes.
1392 (1 (unless (save-excursion 1393 ("\\([?$]\\)[#\"'`]"
1393 ;; Not within a string. 1394 (1 (unless (save-excursion
1394 (nth 3 (syntax-ppss (match-beginning 0)))) 1395 ;; Not within a string.
1395 (string-to-syntax "\\")))) 1396 (nth 3 (syntax-ppss (match-beginning 0))))
1396 ;; Regular expressions. Start with matching unescaped slash. 1397 (string-to-syntax "\\"))))
1397 ("\\(?:\\=\\|[^\\]\\)\\(?:\\\\\\\\\\)*\\(/\\)" 1398 ;; Regular expressions. Start with matching unescaped slash.
1398 (1 (let ((state (save-excursion (syntax-ppss (match-beginning 1))))) 1399 ("\\(?:\\=\\|[^\\]\\)\\(?:\\\\\\\\\\)*\\(/\\)"
1399 (when (or 1400 (1 (let ((state (save-excursion (syntax-ppss (match-beginning 1)))))
1400 ;; Beginning of a regexp. 1401 (when (or
1401 (and (null (nth 8 state)) 1402 ;; Beginning of a regexp.
1402 (save-excursion 1403 (and (null (nth 8 state))
1403 (forward-char -1) 1404 (save-excursion
1404 (looking-back ruby-syntax-before-regexp-re 1405 (forward-char -1)
1405 (point-at-bol)))) 1406 (looking-back ruby-syntax-before-regexp-re
1406 ;; End of regexp. We don't match the whole 1407 (point-at-bol))))
1407 ;; regexp at once because it can have 1408 ;; End of regexp. We don't match the whole
1408 ;; string interpolation inside, or span 1409 ;; regexp at once because it can have
1409 ;; several lines. 1410 ;; string interpolation inside, or span
1410 (eq ?/ (nth 3 state))) 1411 ;; several lines.
1411 (string-to-syntax "\"/"))))) 1412 (eq ?/ (nth 3 state)))
1412 ;; Expression expansions in strings. We're handling them 1413 (string-to-syntax "\"/")))))
1413 ;; here, so that the regexp rule never matches inside them. 1414 ;; Expression expansions in strings. We're handling them
1414 (ruby-expression-expansion-re 1415 ;; here, so that the regexp rule never matches inside them.
1415 (0 (ignore (ruby-syntax-propertize-expansion)))) 1416 (ruby-expression-expansion-re
1416 ("^=en\\(d\\)\\_>" (1 "!")) 1417 (0 (ignore (ruby-syntax-propertize-expansion))))
1417 ("^\\(=\\)begin\\_>" (1 "!")) 1418 ("^=en\\(d\\)\\_>" (1 "!"))
1418 ;; Handle here documents. 1419 ("^\\(=\\)begin\\_>" (1 "!"))
1419 ((concat ruby-here-doc-beg-re ".*\\(\n\\)") 1420 ;; Handle here documents.
1420 (7 (unless (ruby-singleton-class-p (match-beginning 0)) 1421 ((concat ruby-here-doc-beg-re ".*\\(\n\\)")
1421 (put-text-property (match-beginning 7) (match-end 7) 1422 (7 (unless (ruby-singleton-class-p (match-beginning 0))
1422 'syntax-table (string-to-syntax "\"")) 1423 (put-text-property (match-beginning 7) (match-end 7)
1423 (ruby-syntax-propertize-heredoc end)))) 1424 'syntax-table (string-to-syntax "\""))
1424 ;; Handle percent literals: %w(), %q{}, etc. 1425 (ruby-syntax-propertize-heredoc end))))
1425 ((concat "\\(?:^\\|[[ \t\n<+(,=]\\)" ruby-percent-literal-beg-re) 1426 ;; Handle percent literals: %w(), %q{}, etc.
1426 (1 (prog1 "|" (ruby-syntax-propertize-percent-literal end))))) 1427 ((concat "\\(?:^\\|[[ \t\n<+(,=]\\)" ruby-percent-literal-beg-re)
1427 (point) end)) 1428 (1 (prog1 "|" (ruby-syntax-propertize-percent-literal end)))))
1429 (point) end)))
1428 1430
1429 (defun ruby-syntax-propertize-heredoc (limit) 1431 (defun ruby-syntax-propertize-heredoc (limit)
1430 (let ((ppss (syntax-ppss)) 1432 (let ((ppss (syntax-ppss))
@@ -1496,9 +1498,10 @@ It will be properly highlighted even when the call omits parens.")
1496 (defun ruby-syntax-propertize-expansion () 1498 (defun ruby-syntax-propertize-expansion ()
1497 ;; Save the match data to a text property, for font-locking later. 1499 ;; Save the match data to a text property, for font-locking later.
1498 ;; Set the syntax of all double quotes and backticks to punctuation. 1500 ;; Set the syntax of all double quotes and backticks to punctuation.
1499 (let ((beg (match-beginning 2)) 1501 (let* ((beg (match-beginning 2))
1500 (end (match-end 2))) 1502 (end (match-end 2))
1501 (when (and beg (save-excursion (nth 3 (syntax-ppss beg)))) 1503 (state (and beg (save-excursion (syntax-ppss beg)))))
1504 (when (ruby-syntax-expansion-allowed-p state)
1502 (put-text-property beg (1+ beg) 'ruby-expansion-match-data 1505 (put-text-property beg (1+ beg) 'ruby-expansion-match-data
1503 (match-data)) 1506 (match-data))
1504 (goto-char beg) 1507 (goto-char beg)
@@ -1506,6 +1509,17 @@ It will be properly highlighted even when the call omits parens.")
1506 (put-text-property (match-beginning 0) (match-end 0) 1509 (put-text-property (match-beginning 0) (match-end 0)
1507 'syntax-table (string-to-syntax ".")))))) 1510 'syntax-table (string-to-syntax "."))))))
1508 1511
1512 (defun ruby-syntax-expansion-allowed-p (parse-state)
1513 "Return non-nil if expression expansion is allowed."
1514 (let ((term (nth 3 parse-state)))
1515 (cond
1516 ((memq term '(?\" ?` ?\n)))
1517 ((eq term t)
1518 (save-match-data
1519 (save-excursion
1520 (goto-char (nth 8 parse-state))
1521 (looking-at "%\\(?:[QWrx]\\|\\W\\)")))))))
1522
1509 (defun ruby-syntax-propertize-expansions (start end) 1523 (defun ruby-syntax-propertize-expansions (start end)
1510 (save-excursion 1524 (save-excursion
1511 (goto-char start) 1525 (goto-char start)
diff --git a/test/ChangeLog b/test/ChangeLog
index 56e019ec4af..98fb2e3da1f 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,8 @@
12013-05-31 Dmitry Gutov <dgutov@yandex.ru>
2
3 * automated/ruby-mode-tests.el: New tests, for percent literals
4 and expression expansion.
5
12013-05-29 Leo Liu <sdl.web@gmail.com> 62013-05-29 Leo Liu <sdl.web@gmail.com>
2 7
3 * indent/octave.m: Tweak. 8 * indent/octave.m: Tweak.
diff --git a/test/automated/ruby-mode-tests.el b/test/automated/ruby-mode-tests.el
index e52927a2968..6ed2a8ad377 100644
--- a/test/automated/ruby-mode-tests.el
+++ b/test/automated/ruby-mode-tests.el
@@ -353,6 +353,23 @@ VALUES-PLIST is a list with alternating index and value elements."
353 ;; It's confused by the closing paren in the middle. 353 ;; It's confused by the closing paren in the middle.
354 (ruby-assert-state s 8 nil))) 354 (ruby-assert-state s 8 nil)))
355 355
356(ert-deftest ruby-interpolation-inside-double-quoted-percent-literals ()
357 (ruby-assert-face "%Q{foo #@bar}" 8 font-lock-variable-name-face)
358 (ruby-assert-face "%W{foo #@bar}" 8 font-lock-variable-name-face)
359 (ruby-assert-face "%r{foo #@bar}" 8 font-lock-variable-name-face)
360 (ruby-assert-face "%x{foo #@bar}" 8 font-lock-variable-name-face))
361
362(ert-deftest ruby-no-interpolation-in-single-quoted-literals ()
363 (ruby-assert-face "'foo #@bar'" 7 font-lock-string-face)
364 (ruby-assert-face "%q{foo #@bar}" 8 font-lock-string-face)
365 (ruby-assert-face "%w{foo #@bar}" 8 font-lock-string-face)
366 (ruby-assert-face "%s{foo #@bar}" 8 font-lock-string-face))
367
368(ert-deftest ruby-no-unknown-percent-literals ()
369 ;; No folding of case.
370 (ruby-assert-face "%S{foo}" 4 nil)
371 (ruby-assert-face "%R{foo}" 4 nil))
372
356(ert-deftest ruby-add-log-current-method-examples () 373(ert-deftest ruby-add-log-current-method-examples ()
357 (let ((pairs '(("foo" . "#foo") 374 (let ((pairs '(("foo" . "#foo")
358 ("C.foo" . ".foo") 375 ("C.foo" . ".foo")