At Tue, 1 Jan 2002 11:43:50 +0900, Le Wang <lewang@?.?.bigfoot.com (nospam)> wrote: > ><code> > >puts "a", > > "b", > > "c #{var}", > >"d" # tab here doesn't indent properly > ></code> > > > >The setup is ruby-mode.el 1.39 (fully patched) + XEmacs 21.4.6. > > > >The problem, I think is {} within double-quotes. > > > >Thanks. > >-lw > > > Here's another one: > > <code> > class Test > def moveSeries (series, askIncomplete = true) > dirName = "#{series.array[0][ 0..series.preIdIndex - > 1]}#{series.array.first[series.preIdIndex..series.postIdIndex]}-#{series.array.last[series.preIdIndex..series.postIdIndex]}#{series.array[0][series.postIdIndex+1..-5]}" > if missingPart = (SeriesGroup.notContinuous series) > puts '*' * 70, series.array, '-' * 70, "preIdIndex: > #{series.preIdIndex}", "integerOnly: #{series.integerOnly}", '-' * 70, > "missing: #{C.warnMessage missingPart.inspect}" > dirName << " - missing #{missingPart.inspect.gsub(/"/, "'")}" > print "Move these files to #{C.emphasisMessage dirName}? (y/n)" > if askIncomplete # press TAB here > input = CharInput::getChar(/[yYnN]/) > 'nN'.index (input) and return nil > end > end > Dir.mkdir (dirName) > series.array.each do |j| > File.rename j, dirName + "/#{j}" > end > end > end > </code> > > If you press tab on line 8, everything after that gets really screwed > up, I can't even type anything and get "invalid nest" errors. > > I think the problem starts on line 6, because the font-lock colors > start messing up there... Indentation may be fixed by this additional patch to 29370, 29527, 29558 and 29595, but it seem to be difficult to fix font-lock issue. Since Emacs syntax-table doesn't consider nested expressions in strings.
--- misc/ruby-mode.el~ Mon Dec 31 03:53:47 2001 +++ misc/ruby-mode.el Fri Jan 4 09:24:57 2002 @@ -254,4 +254,19 @@ The variable ruby-indent-level controls (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) @@ -271,14 +286,20 @@ The variable ruby-indent-level controls (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 @@ -300,4 +321,5 @@ The variable ruby-indent-level controls (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))) @@ -307,22 +329,14 @@ The variable ruby-indent-level controls ((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))) @@ -529,17 +543,9 @@ The variable ruby-indent-level controls (skip-chars-backward " \t") (let ((pos (point))) - (and - (re-search-backward "#" (save-excursion - (beginning-of-line) - (point)) t) - (unless (= (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)
-- Nobu Nakada