From 6cdf714126ee1c3a00b49f87e282ce8d31123179 Mon Sep 17 00:00:00 2001 From: nobu Date: Sat, 12 Apr 2003 11:59:45 +0000 Subject: * misc/ruby-mode.el (ruby-beginning-of-arg): substitute ruby-backward-arg. * misc/ruby-mode.el (ruby-calculate-indent): fixed wrong indentation in brace block and parentheses. * misc/ruby-mode.el (ruby-forward-sexp, ruby-backward-sexp): support special char literal, and negative arguments. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3674 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- misc/ruby-mode.el | 280 +++++++++++++++++++++++++++++------------------------- 1 file changed, 152 insertions(+), 128 deletions(-) (limited to 'misc/ruby-mode.el') diff --git a/misc/ruby-mode.el b/misc/ruby-mode.el index 9144855983..077866fee5 100644 --- a/misc/ruby-mode.el +++ b/misc/ruby-mode.el @@ -283,9 +283,9 @@ The variable ruby-indent-level controls the amount of indentation. (defun ruby-special-char-p (&optional pnt) (let ((c (char-before pnt))) - (cond ((or (eq c ??) (eq c ?$))) - ((eq c ?\\) - (eq (char-before (1- (or pnt (point)))) ??))))) + (cond ((or (eq c ??) (eq c ?$))) + ((eq c ?\\) + (eq (char-before (1- (or pnt (point)))) ??))))) (defun ruby-expr-beg (&optional option) (save-excursion @@ -296,8 +296,8 @@ The variable ruby-indent-level controls the amount of indentation. ((progn (forward-char -1) (and (looking-at "\\?") - (or (ruby-special-char-p) - (eq (char-syntax (char-before (point)) ?w))))) + (or (eq (char-syntax (char-before (point))) ?w) + (ruby-special-char-p)))) nil) ((or (looking-at ruby-operator-re) (looking-at "[\\[({,;]") @@ -544,36 +544,42 @@ The variable ruby-indent-level controls the amount of indentation. (defun ruby-indent-size (pos nest) (+ pos (* (or nest 1) ruby-indent-level))) -(defconst ruby-assign-re "\\s *\\(&&\\|||\\|<<\\|>>[-+*/%&|^]\\)?=\\s *") - -(defun ruby-backward-arg (limit depth) - (let ((indent (ruby-indent-size 0 depth)) - beg pnt (last (point))) - (when limit - (goto-char limit) - (ruby-forward-sexp) - (setq limit (point))) - (goto-char last) - (setq pnt (point)) - (ruby-backward-sexp) - (while (and - (not (bobp)) - (setq beg (point)) - (progn - (ruby-backward-sexp) - (or (looking-at ruby-block-hanging-re) - (save-excursion - (ruby-forward-sexp) - (looking-at ruby-assign-re))))) - (setq last beg)) - (goto-char last))) +(defconst ruby-assign-re "\\s *\\(&&\\|||\\|<<\\|>>\\|[-+*/%&|^]\\)?=\\s *") + +(defun ruby-beginning-of-arg (start end) + (save-restriction + (narrow-to-region start (1+ end)) + (goto-char start) + (let ((beg t) arg) + (while + (progn + (skip-chars-forward " \t\n") + (and (not (eobp)) + (= (ruby-forward-sexp) 0))) + (skip-syntax-forward " ") + (cond ((looking-at ",") + (forward-char) + (setq arg start beg t)) + ((ruby-expr-beg) t) + ((looking-at "=>\\s *") + (goto-char (match-end 0)) + (setq arg nil beg nil)) + ((looking-at ruby-assign-re) + (goto-char (match-end 0)) + (if beg (setq beg nil arg (point)))) + ((looking-at ruby-operator-re) + (goto-char (match-end 0)) + (if beg (setq beg nil arg (match-end 0)))) + ((not (eq (char-syntax (char-after)) ?\()) + (setq start (point))))) + (goto-char (or arg start))))) (defun ruby-calculate-indent (&optional parse-start) (save-excursion (beginning-of-line) (let ((indent-point (point)) (case-fold-search nil) - state bol eol + state bol eol begin (paren (progn (skip-syntax-forward " ") (and (char-after) (matching-paren (char-after))))) (indent 0)) @@ -587,51 +593,47 @@ The variable ruby-indent-level controls the amount of indentation. (cond ((nth 0 state) ; within string (setq indent nil)) ; do nothing - ((and (car (nth 1 state)) ; in paren - (or (not (eq (car (nth 1 state)) ?\{)) - (save-excursion - (goto-char (1- (cdr (nth 1 state)))) - (or (ruby-expr-beg) (setq paren nil))))) - (goto-char (cdr (nth 1 state))) - (if (ruby-deep-indent-paren-p (car (nth 1 state))) - (let ((s (ruby-parse-region (point) indent-point))) - (cond - ((and (nth 2 s) (> (nth 2 s) 0)) - (goto-char (cdr (nth 1 s))) - (forward-word -1) - (setq indent (ruby-indent-size (current-column) (nth 2 state)))) - (t - (setq indent (current-column)) - (cond (paren (setq indent (1- indent))) - ((eq (car (nth 1 state)) ?\()) - (t (setq indent (ruby-indent-size (1- indent) 1))))))) - (cond - ((nth 3 state) - (goto-char (nth 3 state)) - (setq indent (ruby-indent-size (current-column) (nth 2 state)))) - (t - (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 + ((car (nth 1 state)) ; in paren + (cond + ((and (eq (car (nth 1 state)) ?\{) ; brace block + (save-excursion + (goto-char (1- (cdr (nth 1 state)))) + (not (ruby-expr-beg)))) + (setq paren nil) + (back-to-indentation) + (setq indent (ruby-indent-size (current-column) (nth 2 state)))) + (t + (goto-char (setq begin (cdr (nth 1 state)))) + (let ((deep (ruby-deep-indent-paren-p (car (nth 1 state))))) + (if deep + (cond ((and (eq deep t) (eq (car (nth 1 state)) paren)) + (skip-syntax-backward " ") + (setq indent (1- (current-column)))) + ((let ((s (ruby-parse-region (point) indent-point))) + (and (nth 2 s) (> (nth 2 s) 0) + (or (goto-char (cdr (nth 1 s))) t))) + (forward-word -1) + (setq indent (ruby-indent-size (current-column) (nth 2 state)))) + (t + (setq indent (current-column)) + (cond ((eq deep 'space)) + (paren (setq indent (1- indent))) + (t (setq indent (ruby-indent-size (1- indent) 1)))))) + (if (nth 3 state) (goto-char (nth 3 state)) + (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")) (goto-char (cdr (nth 1 state))) (forward-word -1) ; skip back a keyword + (setq begin (point)) (cond ((looking-at "do\\>[^_]") ; iter block is a special case - (cond - ((nth 3 state) - (goto-char (nth 3 state)) - (setq indent (ruby-indent-size (current-column) (nth 2 state)))) - (t - (goto-char parse-start) - (back-to-indentation) - (setq indent (ruby-indent-size (current-column) (nth 2 state)))))) + (if (nth 3 state) (goto-char (nth 3 state)) + (goto-char parse-start) (back-to-indentation)) + (setq indent (ruby-indent-size (current-column) (nth 2 state)))) (t - (goto-char (1- (cdr (nth 1 state)))) - (ruby-backward-sexp) (setq indent (+ (current-column) ruby-indent-level))))) ((and (nth 2 state) (< (nth 2 state) 0)) ; in negative nest @@ -652,7 +654,8 @@ The variable ruby-indent-level controls the amount of indentation. (save-excursion (beginning-of-line) (not (bobp))) - (null (car (nth 1 state)))) + (or (ruby-deep-indent-paren-p t) + (null (car (nth 1 state))))) ;; goto beginning of non-empty no-comment line (let (end done) (while (not done) @@ -673,6 +676,7 @@ The variable ruby-indent-level controls the amount of indentation. (and (setq state (ruby-parse-region parse-start (point))) (nth 0 state) + (setq begin (nth 1 state)) (goto-char pos))) (or (bobp) (forward-char -1)) (and @@ -684,8 +688,7 @@ The variable ruby-indent-level controls the amount of indentation. (goto-char (match-end 0)) (not (looking-at "[a-z_]")))) (and (looking-at ruby-operator-re) - (not (eq (char-after (1- (point))) ??)) - (not (eq (char-after (1- (point))) ?$)) + (not (ruby-special-char-p)) (or (not (eq ?/ (char-after (point)))) (null (nth 0 (ruby-parse-region parse-start (point))))) (or (not (eq ?| (char-after (point)))) @@ -706,9 +709,9 @@ The variable ruby-indent-level controls the amount of indentation. (cond ((and (not (looking-at ruby-block-hanging-re)) - (ruby-deep-indent-paren-p t) + (eq (ruby-deep-indent-paren-p t) 'space) (not (bobp))) - (ruby-backward-arg (cdr (nth 1 state)) (nth 2 state)) + (ruby-beginning-of-arg (or begin parse-start) (point)) (current-column)) (t (+ indent ruby-indent-level)))))))) @@ -799,64 +802,81 @@ An end of a defun is found by moving forward from the beginning of one." (interactive "p") (if (and (numberp cnt) (< cnt 0)) (ruby-backward-sexp (- cnt)) - (dotimes (i (or cnt 1)) - (skip-chars-forward " \t\n,.:;|&^~=!?\\+\\-\\*") - (cond ((looking-at "\\s(") - (goto-char (scan-sexps (point) 1))) - ((looking-at ruby-block-beg-re) - (ruby-end-of-block) - (forward-word 1)) - ((looking-at "\\(\\$\\|@@?\\)?\\sw") - (while (progn - (while (progn (forward-word 1) (looking-at "_"))) - (cond ((looking-at "::") (forward-char 2) t) - ((> (skip-chars-forward ".") 0)) - ((looking-at "\\?\\|!\\(=[~=>]\\|[^~=]\\)") - (forward-char 1) nil))))) - ((let (state expr) - (while - (progn - (setq expr (or expr (ruby-expr-beg) - (looking-at "%\\sw?\\Sw\\|[\"'`/]"))) - (nth 1 (setq state (apply 'ruby-parse-partial nil state)))) - (setq expr t) - (skip-chars-forward "<")) - (not expr))))))) + (let ((i (or cnt 1))) + (condition-case nil + (while (> i 0) + (skip-syntax-forward " ") + (cond ((looking-at "\\?\\(\\\\[CM]-\\)*\\\\?\\S ") + (goto-char (match-end 0))) + ((progn + (skip-chars-forward ",.:;|&^~=!?\\+\\-\\*") + (looking-at "\\s(")) + (goto-char (scan-sexps (point) 1))) + ((looking-at ruby-block-beg-re) + (ruby-end-of-block) + (forward-word 1)) + ((looking-at "\\(\\$\\|@@?\\)?\\sw") + (while (progn + (while (progn (forward-word 1) (looking-at "_"))) + (cond ((looking-at "::") (forward-char 2) t) + ((> (skip-chars-forward ".") 0)) + ((looking-at "\\?\\|!\\(=[~=>]\\|[^~=]\\)") + (forward-char 1) nil))))) + ((let (state expr) + (while + (progn + (setq expr (or expr (ruby-expr-beg) + (looking-at "%\\sw?\\Sw\\|[\"'`/]"))) + (nth 1 (setq state (apply 'ruby-parse-partial nil state)))) + (setq expr t) + (skip-chars-forward "<")) + (not expr)))) + (setq i (1- i))) + ((error) (forward-word))) + i))) (defun-region-command ruby-backward-sexp (&optional cnt) (interactive "p") - (dotimes (i (or cnt 1)) - (skip-chars-backward " \t\n,.:;|&^~=!?\\+\\-\\*") - (forward-char -1) - (cond ((looking-at "\\s)") - (goto-char (scan-sexps (1+ (point)) -1)) - (case (char-before) - (?% (forward-char -1)) - ('(?q ?Q ?w ?W ?r ?x) - (if (eq (char-before (1- (point))) ?%) (forward-char -2)))) - nil) - ((looking-at "\\s\"\\|\\\\\\S_") - (let ((c (char-to-string (char-before (match-end 0))))) - (while (and (search-backward c) - (oddp (skip-chars-backward "\\"))))) - nil) - ((looking-at "\\s.\\|\\s\\")) - ((looking-at "\\s(") nil) - (t - (forward-char 1) - (while (progn (forward-word -1) - (case (char-before) - (?_ t) - (?. (forward-char -1) t) - ((?$ ?@) - (forward-char -1) - (and (eq (char-before) (char-after)) (forward-char -1))) - (?: - (forward-char -1) - (eq (char-before) :))))) - (if (looking-at ruby-block-end-re) - (ruby-beginning-of-block)) - nil)))) + (if (and (numberp cnt) (< cnt 0)) + (ruby-forward-sexp (- cnt)) + (let ((i (or cnt 1))) + (condition-case nil + (while (> i 0) + (skip-chars-backward " \t\n,.:;|&^~=!?\\+\\-\\*") + (forward-char -1) + (cond ((looking-at "\\s)") + (goto-char (scan-sexps (1+ (point)) -1)) + (case (char-before) + (?% (forward-char -1)) + ('(?q ?Q ?w ?W ?r ?x) + (if (eq (char-before (1- (point))) ?%) (forward-char -2)))) + nil) + ((looking-at "\\s\"\\|\\\\\\S_") + (let ((c (char-to-string (char-before (match-end 0))))) + (while (and (search-backward c) + (oddp (skip-chars-backward "\\"))))) + nil) + ((looking-at "\\s.\\|\\s\\") + (if (ruby-special-char-p) (forward-char -1))) + ((looking-at "\\s(") nil) + (t + (forward-char 1) + (while (progn (forward-word -1) + (case (char-before) + (?_ t) + (?. (forward-char -1) t) + ((?$ ?@) + (forward-char -1) + (and (eq (char-before) (char-after)) (forward-char -1))) + (?: + (forward-char -1) + (eq (char-before) :))))) + (if (looking-at ruby-block-end-re) + (ruby-beginning-of-block)) + nil)) + (setq i (1- i))) + ((error))) + i))) (defun ruby-reindent-then-newline-and-indent () (interactive "*") @@ -1097,7 +1117,11 @@ balanced expression is found." 2 font-lock-reference-face) ;; expression expansion '("#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\)" - 0 font-lock-variable-name-face t)) + 0 font-lock-variable-name-face t) + ;; warn lower camel case + ;'("\\<[a-z]+[a-z0-9]*[A-Z][A-Za-z0-9]*\\([!?]?\\|\\>\\)" + ; 0 font-lock-warning-face) + ) "*Additional expressions to highlight in ruby mode.")) ((featurep 'hilit19) -- cgit v1.2.3