diff options
Diffstat (limited to 'misc/ruby-mode.el')
-rw-r--r-- | misc/ruby-mode.el | 125 |
1 files changed, 101 insertions, 24 deletions
diff --git a/misc/ruby-mode.el b/misc/ruby-mode.el index 75efbf012b..763c076d8a 100644 --- a/misc/ruby-mode.el +++ b/misc/ruby-mode.el @@ -17,6 +17,10 @@ "class\\|module\\|def\\|if\\|unless\\|case\\|while\\|until\\|for\\|begin\\|do" ) +(defconst ruby-non-block-do-re + "\\(while\\|until\\|for\\|rescue\\)\\>" + ) + (defconst ruby-indent-beg-re "\\(\\s *\\(class\\|module\\|def\\)\\)\\|if\\|unless\\|case\\|while\\|until\\|for\\|begin" ) @@ -114,6 +118,31 @@ (defvar ruby-indent-level 2 "*Indentation of ruby statements.") +(eval-when-compile (require 'cl)) +(defun ruby-imenu-create-index () + (let ((index-alist '()) + class-name class-begin method-name method-begin decl) + (goto-char (point-min)) + (while (re-search-forward "^\\s *\\(class\\|def\\)\\s *\\([^(\n ]+\\)" nil t) + (setq decl (buffer-substring (match-beginning 1) (match-end 1))) + (cond + ((string= "class" decl) + (setq class-begin (match-beginning 2)) + (setq class-name (buffer-substring class-begin (match-end 2))) + (push (cons class-name (match-beginning 0)) index-alist) + (ruby-mark-defun) + (save-restriction + (narrow-to-region (region-beginning) (region-end)) + (while (re-search-forward "^\\s *def\\s *\\([^(\n ]+\\)" nil t) + (setq method-begin (match-beginning 1)) + (setq method-name (buffer-substring method-begin (match-end 1))) + (push (cons (concat class-name "#" method-name) (match-beginning 0)) index-alist)))) + ((string= "def" decl) + (setq method-begin (match-beginning 2)) + (setq method-name (buffer-substring method-begin (match-end 2))) + (push (cons method-name (match-beginning 0)) index-alist)))) + index-alist)) + (defun ruby-mode-variables () (set-syntax-table ruby-mode-syntax-table) (setq local-abbrev-table ruby-mode-abbrev-table) @@ -153,6 +182,9 @@ The variable ruby-indent-level controls the amount of indentation. (setq major-mode 'ruby-mode) (ruby-mode-variables) + (make-local-variable 'imenu-create-index-function) + (setq imenu-create-index-function 'ruby-imenu-create-index) + (run-hooks 'ruby-mode-hook)) (defun ruby-current-indentation () @@ -172,8 +204,7 @@ The variable ruby-indent-level controls the amount of indentation. (defun ruby-indent-to (x) (if x (let (shift top beg) - (and (< x 0) - (error "invalid nest")) + (and (< x 0) (error "invalid nest")) (setq shift (current-column)) (beginning-of-line) (setq beg (point)) @@ -191,7 +222,7 @@ The variable ruby-indent-level controls the amount of indentation. (indent-to x) (move-to-column (+ x shift)))))) -(defun ruby-expr-beg (&optional modifier) +(defun ruby-expr-beg (&optional option) (save-excursion (if (looking-at "\\?") (progn @@ -203,10 +234,11 @@ The variable ruby-indent-level controls the amount of indentation. (or (bolp) (looking-at ruby-operator-re) (looking-at "[\\[({]") - (and (not modifier) (looking-at "[!?]")) + (and (not (eq option 'modifier)) + (looking-at "[!?]")) (and (looking-at ruby-symbol-re) - (forward-word -1) - (if (and (not modifier) (bolp)) + (skip-chars-backward ruby-symbol-chars) + (if (and (not (eq option 'modifier)) (bolp)) t (if (or (looking-at ruby-block-beg-re) (looking-at ruby-block-op-re) @@ -214,7 +246,8 @@ The variable ruby-indent-level controls the amount of indentation. (progn (goto-char (match-end 0)) (looking-at "\\>")) - (looking-at "[a-zA-Z][a-zA-z0-9_]* +/[^ \t]")))))))) + (and (not (eq option 'expr-arg)) + (looking-at "[a-zA-Z][a-zA-z0-9_]* +/[^ \t]"))))))))) (defun ruby-parse-region (start end) (let ((indent-point end) @@ -250,7 +283,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 (re-search-forward "[^\\]\\(\\\\\\\\\\)*/" indent-point t) nil (setq in-string (point)) (goto-char indent-point))) @@ -258,18 +291,24 @@ The variable ruby-indent-level controls the amount of indentation. (goto-char pnt)))) ((looking-at "%") (cond - ((and (not (eobp)) (ruby-expr-beg) + ((and (not (eobp)) (ruby-expr-beg 'expr-arg) (not (looking-at "%=")) (looking-at "%[Qqrxw]?\\(.\\)")) + (goto-char (match-beginning 1)) (setq w (buffer-substring (match-beginning 1) (match-end 1))) (cond - ((string= w "[") (setq w "]")) + ((string= w "[") (setq w "\\]")) ((string= w "{") (setq w "}")) ((string= w "(") (setq w ")")) - ((string= w "<") (setq w ">"))) - (goto-char (match-end 0)) - (if (search-forward w indent-point t) + ((string= w "<") (setq w ">")) + ((member w '("*" "." "+" "?" "^" "$")) + (setq w (concat "\\" w)))) + (if (re-search-forward + (if (string= w "\\") + "\\\\[^\\]*\\\\" + (concat "[^\\]\\(\\\\\\\\\\)*" w)) + indent-point t) nil (setq in-string (point)) (goto-char indent-point))) @@ -313,7 +352,9 @@ The variable ruby-indent-level controls the amount of indentation. (if (or (and (not (bolp)) (progn (forward-char -1) - (eq ?_ (char-after (point))))) + (setq w (char-after (point))) + (or (eq ?_ w) + (eq ?. w)))) (progn (goto-char pnt) (setq w (char-after (point))) @@ -335,10 +376,45 @@ The variable ruby-indent-level controls the amount of indentation. (goto-char (match-end 0))) ((looking-at ruby-block-beg-re) (and + (or (not (looking-at "do\\>[^_]")) + (save-excursion + (back-to-indentation) + (not (looking-at ruby-non-block-do-re)))) + (or (bolp) + (progn + (forward-char -1) + (setq w (char-after (point))) + (not (or (eq ?_ w) + (eq ?. w))))) + (goto-char pnt) + (setq w (char-after (point))) + (not (eq ?_ w)) + (not (eq ?! w)) + (not (eq ?? w)) + (skip-chars-forward " \t") + (if (not (eolp)) + (progn + (goto-char (match-beginning 0)) + (if (looking-at ruby-modifier-re) + (ruby-expr-beg 'modifier) + t)) + t) + (goto-char pnt) + (setq nest (cons (cons nil pnt) nest)) + (setq depth (1+ depth))) + (goto-char pnt)) + ((looking-at ruby-block-beg-re) + (and + (or (not (looking-at "do\\>[^_]")) + (save-excursion + (back-to-indentation) + (not (looking-at ruby-non-block-do-re)))) (or (bolp) (progn (forward-char -1) - (not (eq ?_ (char-after (point)))))) + (setq w (char-after (point))) + (not (or (eq ?_ w) + (eq ?. w))))) (goto-char pnt) (setq w (char-after (point))) (not (eq ?_ w)) @@ -349,7 +425,7 @@ The variable ruby-indent-level controls the amount of indentation. (progn (goto-char (match-beginning 0)) (if (looking-at ruby-modifier-re) - (ruby-expr-beg t) + (ruby-expr-beg 'modifier) t)) t) (goto-char pnt) @@ -423,7 +499,7 @@ The variable ruby-indent-level controls the amount of indentation. (goto-char (cdr (nth 1 state))) (forward-word -1) ; skip back a keyword (cond - ((looking-at "do") ; iter block is a special case + ((looking-at "do\\>[^_]") ; iter block is a special case (cond ((nth 3 state) (goto-char (nth 3 state)) @@ -621,12 +697,12 @@ An end of a defun is found by moving forward from the beginning of one." (setq font-lock-keywords ruby-font-lock-keywords))) (defun ruby-font-lock-docs (limit) - (if (re-search-forward "^=begin\\s *$" limit t) + (if (re-search-forward "^=begin\\(\\s \\|$\\)" limit t) (let (beg) (beginning-of-line) (setq beg (point)) (forward-line 1) - (if (re-search-forward "^=end\\s *$" limit t) + (if (re-search-forward "^=end\\(\\s \\|$\\)" limit t) (progn (set-match-data (list beg (point))) t))))) @@ -671,12 +747,13 @@ An end of a defun is found by moving forward from the beginning of one." "until" "when" "while" + "yield" ) "\\|") - "\\)\\>[^_]") + "\\)\\>\\([^_]\\|$\\)") 2) ;; variables - '("\\(^\\|[^_:.@$]\\|\\.\\.\\)\\b\\(nil\\|self\\|true\\|false\\)\\b[^_]" + '("\\(^\\|[^_:.@$]\\|\\.\\.\\)\\b\\(nil\\|self\\|true\\|false\\)\\b\\([^_]\\|$\\)" 2 font-lock-variable-name-face) ;; variables '("[$@].\\(\\w\\|_\\)*" @@ -688,7 +765,7 @@ An end of a defun is found by moving forward from the beginning of one." '("\\(^\\|[^_]\\)\\b\\([A-Z]+\\(\\w\\|_\\)*\\)" 2 font-lock-type-face) ;; functions - '("^\\s *def\\s *\\([^( ]+\\)" + '("^\\s *def\\s +\\([^( ]+\\)" 1 font-lock-function-name-face) ;; symbols '("\\(^\\|[^:]\\)\\(:\\(\\w\\|_\\)+\\??\\)\\b" @@ -707,8 +784,8 @@ An end of a defun is found by moving forward from the beginning of one." ("^\\s *\\(require\\|load\\).*$" nil include) ("^\\s *\\(include\\|alias\\|undef\\).*$" nil decl) ("^\\s *\\<\\(class\\|def\\|module\\)\\>" "[)\n;]" defun) - ("[^_]\\<\\(begin\\|case\\|else\\|elsif\\|end\\|ensure\\|for\\|if\\|unless\\|rescue\\|then\\|when\\|while\\|until\\|do\\)\\>[^_]" 1 defun) - ("[^_]\\<\\(and\\|break\\|next\\|raise\\|fail\\|in\\|not\\|or\\|redo\\|retry\\|return\\|super\\|yield\\|catch\\|throw\\|self\\|nil\\)\\>[^_]" 1 keyword) + ("[^_]\\<\\(begin\\|case\\|else\\|elsif\\|end\\|ensure\\|for\\|if\\|unless\\|rescue\\|then\\|when\\|while\\|until\\|do\\|yield\\)\\>\\([^_]\\|$\\)" 1 defun) + ("[^_]\\<\\(and\\|break\\|next\\|raise\\|fail\\|in\\|not\\|or\\|redo\\|retry\\|return\\|super\\|yield\\|catch\\|throw\\|self\\|nil\\)\\>\\([^_]\\|$\\)" 1 keyword) ("\\$\\(.\\|\\sw+\\)" nil type) ("[$@].[a-zA-Z_0-9]*" nil struct) ("^__END__" nil label)))) |