summaryrefslogtreecommitdiff
path: root/misc/ruby-mode.el
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-01-05 03:25:02 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-01-05 03:25:02 +0000
commit8090c2f214e6c4f8981ccb4e6a1213bd1284fa08 (patch)
tree4642d9b1a7d667b174467e02e2374886a1cd570b /misc/ruby-mode.el
parent0ad520443c6cb44eb9f6866e79d4ed8f5489fe33 (diff)
* misc/ruby-mode.el (ruby-forward-string): forward a string. [new]
* misc/ruby-mode.el (ruby-parse-region): handle nested parentheses in a string and terminators in #{}. * misc/ruby-mode.el (ruby-calculate-indent): ditto. * misc/ruby-mode.el (ruby-font-lock-syntactic-keywords): fix font-lock problem [ruby-talk:29296]. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1965 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'misc/ruby-mode.el')
-rw-r--r--misc/ruby-mode.el162
1 files changed, 84 insertions, 78 deletions
diff --git a/misc/ruby-mode.el b/misc/ruby-mode.el
index a3bd3bea9a..a118a49587 100644
--- a/misc/ruby-mode.el
+++ b/misc/ruby-mode.el
@@ -253,6 +253,21 @@ The variable ruby-indent-level controls the amount of indentation.
(and (not (eq option 'expr-arg))
(looking-at "[a-zA-Z][a-zA-z0-9_]* +/[^ \t]"))))))))))
+(defun ruby-forward-string (term &optional end no-error expand)
+ (let ((n 1) (c (string-to-char term))
+ (re (if expand
+ (concat "[^\\]\\(\\\\\\\\\\)*\\([" term "]\\|\\(#{\\)\\)")
+ (concat "[^\\]\\(\\\\\\\\\\)*[" term "]"))))
+ (while (and (re-search-forward re end no-error)
+ (if (match-beginning 3)
+ (ruby-forward-string "}{" end no-error nil)
+ (> (setq n (if (eq (char-before (point)) c)
+ (1- n) (1+ n))) 0)))
+ (forward-char -1))
+ (cond ((zerop n))
+ (no-error nil)
+ (error "unterminated string"))))
+
(defun ruby-parse-region (start end)
(let ((indent-point end)
(indent 0)
@@ -270,16 +285,22 @@ The variable ruby-indent-level controls the amount of indentation.
(while (and (> indent-point (point))
(re-search-forward ruby-delimiter indent-point t))
(or depth (setq depth 0))
- (let ((pnt (point)) w re)
+ (let ((pnt (point)) w re expand)
(goto-char (match-beginning 0))
(cond
((or (looking-at "\"") ;skip string
- (looking-at "'")
(looking-at "`"))
- (setq w (char-after (point)))
(cond
((and (not (eobp))
- (re-search-forward (format "[^\\]\\(\\\\\\\\\\)*%c" w) indent-point t))
+ (ruby-forward-string (buffer-substring (point) (1+ (point))) indent-point t t))
+ nil)
+ (t
+ (setq in-string (point))
+ (goto-char indent-point))))
+ ((looking-at "'")
+ (cond
+ ((and (not (eobp))
+ (re-search-forward "[^\\]\\(\\\\\\\\\\)*'" indent-point t))
nil)
(t
(setq in-string (point))
@@ -287,7 +308,7 @@ The variable ruby-indent-level controls the amount of indentation.
((looking-at "/")
(cond
((and (not (eobp)) (ruby-expr-beg))
- (if (re-search-forward "[^\\]\\(\\\\\\\\\\)*/" indent-point t)
+ (if (ruby-forward-string "/" indent-point t t)
nil
(setq in-string (point))
(goto-char indent-point)))
@@ -299,6 +320,7 @@ The variable ruby-indent-level controls the amount of indentation.
(not (looking-at "%="))
(looking-at "%[Qqrxw]?\\(.\\)"))
(goto-char (match-beginning 1))
+ (setq expand (not (eq (char-before) ?q)))
(setq w (buffer-substring (match-beginning 1)
(match-end 1)))
(cond
@@ -306,24 +328,16 @@ The variable ruby-indent-level controls the amount of indentation.
((string= w "{") (setq re "}{"))
((string= w "(") (setq re ")("))
((string= w "<") (setq re "><"))
- ((member w '("*" "." "+" "?" "^" "$"))
+ ((or (and expand (string= w "\\"))
+ (member w '("*" "." "+" "?" "^" "$")))
(setq w (concat "\\" w))))
- (if (if re
- (let ((n 1))
- (setq re (concat "[^\\]\\(\\\\\\\\\\)*[" re "]"))
- (while (and (re-search-forward re indent-point t)
- (> (setq n (if (eq (char-before (point))
- (string-to-char w))
- (1+ n) (1- n)))
- 0))
- (forward-char -1))
- (zerop n))
- (re-search-forward
- (if (string= w "\\")
- "\\\\[^\\]*\\\\"
- (concat "[^\\]\\(\\\\\\\\\\)*" w))
- indent-point t))
- nil
+ (unless (cond (re (ruby-forward-string re indent-point t expand))
+ (expand (ruby-forward-string w indent-point t t))
+ (t (re-search-forward
+ (if (string= w "\\")
+ "\\\\[^\\]*\\\\"
+ (concat "[^\\]\\(\\\\\\\\\\)*" w))
+ indent-point t)))
(setq in-string (point))
(goto-char indent-point)))
(t
@@ -462,7 +476,7 @@ The variable ruby-indent-level controls the amount of indentation.
(goto-char (cdr (nth 1 s)))
(forward-word -1)
(setq indent (ruby-indent-size (current-column) (nth 2 state))))
- (t
+ (t
(setq indent (current-column)))))
(cond
((nth 3 state)
@@ -472,7 +486,7 @@ The variable ruby-indent-level controls the amount of indentation.
(goto-char parse-start)
(back-to-indentation)
(setq indent (ruby-indent-size (current-column) (nth 2 state)))))
- ))
+ ))
((and (nth 2 state)(> (nth 2 state) 0)) ; in nest
(if (null (cdr (nth 1 state)))
(error "invalid nest"))
@@ -500,7 +514,7 @@ The variable ruby-indent-level controls the amount of indentation.
(end-of-line)
(setq eol (point))
(beginning-of-line)
- (cond
+ (cond
((re-search-forward ruby-negative eol t)
(and (not (eq ?_ (char-after (match-end 0))))
(setq indent (- indent ruby-indent-level))))
@@ -528,19 +542,11 @@ The variable ruby-indent-level controls the amount of indentation.
(end-of-line)
(skip-chars-backward " \t")
(let ((pos (point)))
- (and
- (re-search-backward "#" (save-excursion
- (beginning-of-line)
- (point)) t)
- (if (not (= (point) (point-min)))
- (save-excursion
- (forward-char -1)
- (not (looking-at "\\?"))))
- (skip-chars-backward " \t")
- (if (save-excursion
- (forward-char -1)
- (looking-at "\\?"))
- (skip-chars-forward " \t"))
+ (while (and (re-search-backward "#" bol t)
+ (= (char-before) ??))
+ (forward-char -1))
+ (skip-chars-backward " \t")
+ (and
(setq state (ruby-parse-region parse-start (point)))
(nth 0 state)
(goto-char pos)))
@@ -681,45 +687,45 @@ An end of a defun is found by moving forward from the beginning of one."
(or (boundp 'font-lock-variable-name-face)
(setq font-lock-variable-name-face font-lock-type-face))
-
- (add-hook 'ruby-mode-hook
- '(lambda ()
- (make-local-variable 'ruby-font-lock-syntactic-keywords)
- (setq ruby-font-lock-syntactic-keywords
- '(
- ;; #{ }, #$hoge, #@foo are not comments
- ("\\(#\\)[{$@]" 1 (1 . nil))
- ;; the last $' in the string ,'...$' is not variable
- ;; the last ?' in the string ,'...?' is not ascii code
- ("\\(^\\|[[\\s <+(,=]\\)\\('\\)[^'\n\\\\]*\\(\\\\.[^'\n\\\\]*\\)*[?$]\\('\\)"
- (2 (7 . nil))
- (4 (7 . nil)))
- ;; the last $` in the string ,`...$` is not variable
- ;; the last ?` in the string ,`...?` is not ascii code
- ("\\(^\\|[[\\s <+(,=]\\)\\(`\\)[^`\n\\\\]*\\(\\\\.[^`\n\\\\]*\\)*[?$]\\(`\\)"
- (2 (7 . nil))
- (4 (7 . nil)))
- ;; the last $" in the string ,"...$" is not variable
- ;; the last ?" in the string ,"...?" is not ascii code
- ("\\(^\\|[[\\s <+(,=]\\)\\(\"\\)[^\"\n\\\\]*\\(\\\\.[^\"\n\\\\]*\\)*[?$]\\(\"\\)"
- (2 (7 . nil))
- (4 (7 . nil)))
- ;; $' $" $` .... are variables
- ;; ?' ?" ?` are ascii codes
- ("[?$][#\"'`]" 0 (1 . nil))
- ;; regexps
- ("\\(^\\|[=(,~?:;]\\|\\(^\\|\\s \\)\\(if\\|elsif\\|unless\\|while\\|until\\|when\\|and\\|or\\|&&\\|||\\)\\|g?sub!?\\|scan\\|split!?\\)\\s *\\(/\\)[^/\n\\\\]*\\(\\\\.[^/\n\\\\]*\\)*\\(/\\)"
- (4 (7 . ?/))
- (6 (7 . ?/)))
- ;; %Q!...!
- ("\\(^\\|[[\\s <+(,=]\\)%[xrqQ]?\\([^a-zA-Z0-9 \n]\\)[^\n\\\\]*\\(\\\\.[^\n\\\\]*\\)*\\(\\2\\)"
- (2 (7 . nil))
- (4 (7 . nil)))
- ("^\\(=\\)begin\\(\\s \\|$\\)" 1 (7 . nil))
- ("^\\(=\\)end\\(\\s \\|$\\)" 1 (7 . nil))))
- (make-local-variable 'font-lock-defaults)
- (setq font-lock-defaults '((ruby-font-lock-keywords) nil nil))
- (setq font-lock-keywords ruby-font-lock-keywords)))
+ (setq ruby-font-lock-syntactic-keywords
+ '(
+ ;; #{ }, #$hoge, #@foo are not comments
+ ("\\(#\\)[{$@]" 1 (1 . nil))
+ ;; the last $' in the string ,'...$' is not variable
+ ;; the last ?' in the string ,'...?' is not ascii code
+ ("\\(^\\|[[\\s <+(,=]\\)\\('\\)[^'\n\\\\]*\\(\\\\.[^'\n\\\\]*\\)*[?$]\\('\\)"
+ (2 (7 . nil))
+ (4 (7 . nil)))
+ ;; the last $` in the string ,`...$` is not variable
+ ;; the last ?` in the string ,`...?` is not ascii code
+ ("\\(^\\|[[\\s <+(,=]\\)\\(`\\)[^`\n\\\\]*\\(\\\\.[^`\n\\\\]*\\)*[?$]\\(`\\)"
+ (2 (7 . nil))
+ (4 (7 . nil)))
+ ;; the last $" in the string ,"...$" is not variable
+ ;; the last ?" in the string ,"...?" is not ascii code
+ ("\\(^\\|[[\\s <+(,=]\\)\\(\"\\)[^\"\n\\\\]*\\(\\\\.[^\"\n\\\\]*\\)*[?$]\\(\"\\)"
+ (2 (7 . nil))
+ (4 (7 . nil)))
+ ;; $' $" $` .... are variables
+ ;; ?' ?" ?` are ascii codes
+ ("[?$][#\"'`]" 0 (1 . nil))
+ ;; regexps
+ ("\\(^\\|[=(,~?:;]\\|\\(^\\|\\s \\)\\(if\\|elsif\\|unless\\|while\\|until\\|when\\|and\\|or\\|&&\\|||\\)\\|g?sub!?\\|scan\\|split!?\\)\\s *\\(/\\)[^/\n\\\\]*\\(\\\\.[^/\n\\\\]*\\)*\\(/\\)"
+ (4 (7 . ?/))
+ (6 (7 . ?/)))
+ ;; %Q!...!
+ ("\\(^\\|[[\\s <+(,=]\\)%[xrqQ]?\\([^a-zA-Z0-9 \n]\\)[^\n\\\\]*\\(\\\\.[^\n\\\\]*\\)*\\(\\2\\)"
+ (2 (7 . nil))
+ (4 (7 . nil)))
+ ("^\\(=\\)begin\\(\\s \\|$\\)" 1 (7 . nil))
+ ("^\\(=\\)end\\(\\s \\|$\\)" 1 (7 . nil))))
+
+ (put 'ruby-mode 'font-lock-defaults
+ '((ruby-font-lock-keywords)
+ nil nil nil
+ beginning-of-line
+ (font-lock-syntactic-keywords
+ . ruby-font-lock-syntactic-keywords)))
(defun ruby-font-lock-docs (limit)
(if (re-search-forward "^=begin\\(\\s \\|$\\)" limit t)
@@ -797,7 +803,7 @@ An end of a defun is found by moving forward from the beginning of one."
2 font-lock-variable-name-face)
;; variables
'("\\(\\$\\([^a-zA-Z0-9 \n]\\|[0-9]\\)\\)\\W"
- 1 font-lock-variable-name-face)
+ 1 font-lock-variable-name-face)
'("\\(\\$\\|@\\|@@\\)\\(\\w\\(\\w\\|_\\)*\\|#{\\)"
0 font-lock-variable-name-face)
;; embedded document