[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] /srv/bzr/emacs/trunk r108021: * ruby-mode.el: Handle gener
From: |
Stefan Monnier |
Subject: |
[Emacs-diffs] /srv/bzr/emacs/trunk r108021: * ruby-mode.el: Handle general delimited literals. |
Date: |
Tue, 24 Apr 2012 13:08:55 -0400 |
User-agent: |
Bazaar (2.3.1) |
------------------------------------------------------------
revno: 108021 [merge]
fixes bug(s): http://debbugs.gnu.org/cgi/bugreport.cgi?bug=6286
committer: Stefan Monnier <address@hidden>
branch nick: trunk
timestamp: Tue 2012-04-24 13:08:55 -0400
message:
* ruby-mode.el: Handle general delimited literals.
added:
test/indent/ruby.rb
modified:
lisp/ChangeLog
lisp/progmodes/ruby-mode.el
test/ChangeLog
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog 2012-04-24 15:19:07 +0000
+++ b/lisp/ChangeLog 2012-04-24 17:08:55 +0000
@@ -1,3 +1,25 @@
+2012-04-24 Stefan Monnier <address@hidden>
+
+ * progmodes/ruby-mode.el: Simplify last change, and cleanup code.
+ (ruby-syntax-propertize-regexp): Remove.
+ (ruby-syntax-propertize-function): Split regexp into chunks.
+ Match following code directly.
+
+2012-04-24 Dmitry Gutov <address@hidden>
+
+ * progmodes/ruby-mode.el: Handle Cucumber defs (bug#6286).
+ (ruby-syntax-propertize-regexp): New function.
+ (ruby-syntax-propertize-function): Use it to handle regexp not preceded
+ by a special keyword.
+
+ * progmodes/ruby-mode.el: Handle general delimited literals (bug#6286).
+ (ruby-syntax-general-delimiters-goto-beg)
+ (ruby-syntax-propertize-general-delimiters): New functions.
+ (ruby-syntax-propertize-function): Use them to handle GDL.
+ (ruby-font-lock-keywords): Move old handling of GDL...
+ (ruby-font-lock-syntactic-keywords): .. to here.
+ (ruby-calculate-indent): Adjust indentation for GDL.
+
2012-04-24 Michael Albinus <address@hidden>
* notifications.el (notifications-interface)
=== modified file 'lisp/progmodes/ruby-mode.el'
--- a/lisp/progmodes/ruby-mode.el 2012-03-21 18:33:07 +0000
+++ b/lisp/progmodes/ruby-mode.el 2012-04-24 17:02:46 +0000
@@ -784,7 +784,7 @@
(not (looking-at "[a-z_]"))))
(and (looking-at ruby-operator-re)
(not (ruby-special-char-p))
- ;; operator at the end of line
+ ;; Operator at the end of line.
(let ((c (char-after (point))))
(and
;; (or (null begin)
@@ -794,8 +794,9 @@
;; (not (or (eolp) (looking-at "#")
;; (and (eq (car (nth 1 state)) ?{)
;; (looking-at "|"))))))
- (or (not (eq ?/ c))
- (null (nth 0 (ruby-parse-region (or begin
parse-start) (point)))))
+ ;; Not a regexp or general delimited literal.
+ (null (nth 0 (ruby-parse-region (or begin parse-start)
+ (point))))
(or (not (eq ?| (char-after (point))))
(save-excursion
(or (eolp) (forward-char -1))
@@ -1110,6 +1111,8 @@
mlist)))))
(declare-function ruby-syntax-propertize-heredoc "ruby-mode" (limit))
+(declare-function ruby-syntax-general-delimiters-goto-beg "ruby-mode" ())
+(declare-function ruby-syntax-propertize-general-delimiters "ruby-mode"
(limit))
(if (eval-when-compile (fboundp #'syntax-propertize-rules))
;; New code that works independently from font-lock.
@@ -1118,26 +1121,48 @@
"Syntactic keywords for Ruby mode. See `syntax-propertize-function'."
(goto-char start)
(ruby-syntax-propertize-heredoc end)
+ (ruby-syntax-general-delimiters-goto-beg)
(funcall
(syntax-propertize-rules
- ;; #{ }, #$hoge, address@hidden are not comments
+ ;; #{ }, #$hoge, address@hidden are not comments.
("\\(#\\)address@hidden" (1 "."))
- ;; $' $" $` .... are variables
- ;; ?' ?" ?` are ascii codes
+ ;; $' $" $` .... are variables.
+ ;; ?' ?" ?` are ascii codes.
("\\([?$]\\)[#\"'`]"
(1 (unless (save-excursion
;; Not within a string.
(nth 3 (syntax-ppss (match-beginning 0))))
(string-to-syntax "\\"))))
- ;; regexps
- ("\\(^\\|[[=(,~?:;<>]\\|\\(^\\|\\s
\\)\\(if\\|elsif\\|unless\\|while\\|until\\|when\\|and\\|or\\|&&\\|||\\)\\|g?sub!?\\|scan\\|split!?\\)\\s
*\\(/\\)[^/\n\\\\]*\\(\\\\.[^/\n\\\\]*\\)*\\(/\\)"
- (4 "\"/")
- (6 "\"/"))
+ ;; Regexps: regexps are distinguished from division either because
+ ;; of the keyword/symbol before them, or because of the code
+ ;; following them.
+ ((concat
+ ;; Special tokens that can't be followed by a division operator.
+ "\\(?:\\(^\\|[[=(,~?:;<>]\\|\\(?:^\\|\\s \\)"
+ (regexp-opt '("if" "elsif" "unless" "while" "until" "when" "and"
+ "or" "&&" "||"
+ "gsub" "gsub!" "sub" "sub!" "scan" "split" "split!"))
+ "\\)\\s *\\)?"
+ ;; The regular expression itself.
+ "\\(/\\)[^/\n\\\\]*\\(?:\\\\.[^/\n\\\\]*\\)*\\(/\\)"
+ ;; Special code that cannot follow a division operator.
+ ;; FIXME: Just because the second slash of "/foo/ do bar" can't
+ ;; be a division, doesn't mean it can't *start* a regexp, as in
+ ;; "x = toto/foo; if /do bar/".
+ "\\([imxo]*\\s *\\(?:,\\|\\_<do\\_>\\)\\)?")
+ (2 (when (or (match-beginning 1) (match-beginning 4))
+ (string-to-syntax "\"/")))
+ (3 (if (or (match-beginning 1) (match-beginning 4))
+ (string-to-syntax "\"/")
+ (goto-char (match-end 2)))))
("^=en\\(d\\)\\_>" (1 "!"))
("^\\(=\\)begin\\_>" (1 "!"))
;; Handle here documents.
((concat ruby-here-doc-beg-re ".*\\(\n\\)")
- (7 (prog1 "\"" (ruby-syntax-propertize-heredoc end)))))
+ (7 (prog1 "\"" (ruby-syntax-propertize-heredoc end))))
+ ;; Handle percent literals: %w(), %q{}, etc.
+ ("\\(?:^\\|[[ \t\n<+(,=]\\)\\(%\\)[qQrswWx]?\\([[:punct:]]\\)"
+ (1 (prog1 "|" (ruby-syntax-propertize-general-delimiters end)))))
(point) end))
(defun ruby-syntax-propertize-heredoc (limit)
@@ -1163,6 +1188,41 @@
;; Make extra sure we don't move back, lest we could fall into an
;; inf-loop.
(if (< (point) start) (goto-char start))))))
+
+ (defun ruby-syntax-general-delimiters-goto-beg ()
+ (let ((state (syntax-ppss)))
+ ;; Move to the start of the literal, in case it's multiline.
+ ;; TODO: determine the literal type more reliably here?
+ (when (eq t (nth 3 state))
+ (goto-char (nth 8 state))
+ (beginning-of-line))))
+
+ (defun ruby-syntax-propertize-general-delimiters (limit)
+ (goto-char (match-beginning 2))
+ (let* ((op (char-after))
+ (ops (char-to-string op))
+ (cl (or (cdr (aref (syntax-table) op))
+ (cdr (assoc op '((?< . ?>))))))
+ parse-sexp-lookup-properties)
+ (ignore-errors
+ (if cl
+ (progn ; 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))
+ ;; If we reached here, the closing delimiter was found.
+ (put-text-property (1- (point)) (point)
+ 'syntax-table (string-to-syntax "|")))))
)
;; For Emacsen where syntax-propertize-rules is not (yet) available,
@@ -1207,6 +1267,10 @@
(4 (7 . ?/))
(6 (7 . ?/)))
("^=en\\(d\\)\\_>" 1 "!")
+ ;; General delimited string.
+ ("\\(^\\|[[ \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:
;;
@@ -1415,9 +1479,6 @@
1 font-lock-variable-name-face)
'("\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+"
0 font-lock-variable-name-face)
- ;; general delimited string
- '("\\(^\\|[[ \t\n<+(,=]\\)\\(%[xrqQwW]?\\([^<[{(a-zA-Z0-9
\n]\\)[^\n\\\\]*\\(\\\\.[^\n\\\\]*\\)*\\(\\3\\)\\)"
- (2 font-lock-string-face))
;; constants
'("\\(^\\|[^_]\\)\\b\\([A-Z]+\\(\\w\\|_\\)*\\)"
2 font-lock-type-face)
=== modified file 'test/ChangeLog'
--- a/test/ChangeLog 2012-04-11 03:24:26 +0000
+++ b/test/ChangeLog 2012-04-24 17:06:12 +0000
@@ -1,3 +1,7 @@
+2012-04-24 Stefan Monnier <address@hidden>
+
+ * indent/ruby.rb: New file, to test new syntax-propertize code.
+
2012-04-11 Glenn Morris <address@hidden>
* automated/vc-bzr.el (vc-bzr-test-faulty-bzr-autoloads): New test.
=== added file 'test/indent/ruby.rb'
--- a/test/indent/ruby.rb 1970-01-01 00:00:00 +0000
+++ b/test/indent/ruby.rb 2012-04-24 17:02:46 +0000
@@ -0,0 +1,19 @@
+# Don't mis-match "sub" at the end of words.
+a = asub / aslb + bsub / bslb;
+
+b = %Q{This is a "string"}
+c = %w(foo
+ bar
+ baz)
+d = %!hello!
+
+# A "do" after a slash means that slash is not a division, but it doesn't imply
+# it's a regexp-ender, since it can be a regexp-starter instead!
+x = toto / foo; if /do bar/ then
+ toto = 1
+ end
+
+# Some Cucumber code:
+Given /toto/ do
+ print "hello"
+end
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] /srv/bzr/emacs/trunk r108021: * ruby-mode.el: Handle general delimited literals.,
Stefan Monnier <=