1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* misc/ruby-mode.el: updated to the latest trunk (without encoding

magic comment hook).

* misc/ruby-mode.el (ruby-keyword-end-re): emacs21 support.  a
  patch from Hiroshi Moriyama <hiroshi at kvd.biglobe.ne.jp> in
  [ruby-dev:36471].

* misc/ruby-mode.el (ruby-in-ppss-context-p): ditto.

* misc/ruby-mode.el (ruby-here-doc-end-syntax):

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@19461 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2008-09-22 23:22:16 +00:00
parent 0c06990532
commit 10b3b5536b
2 changed files with 768 additions and 685 deletions

View file

@ -1,3 +1,16 @@
Tue Sep 23 08:20:59 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
* misc/ruby-mode.el: updated to the latest trunk (without encoding
magic comment hook).
* misc/ruby-mode.el (ruby-keyword-end-re): emacs21 support. a
patch from Hiroshi Moriyama <hiroshi at kvd.biglobe.ne.jp> in
[ruby-dev:36471].
* misc/ruby-mode.el (ruby-in-ppss-context-p): ditto.
* misc/ruby-mode.el (ruby-here-doc-end-syntax):
Fri Sep 19 17:41:56 2008 Yukihiro Matsumoto <matz@ruby-lang.org> Fri Sep 19 17:41:56 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
* configure.in: applied OS/2 support patch from Brendan Oakley * configure.in: applied OS/2 support patch from Brendan Oakley

View file

@ -2,48 +2,66 @@
;;; ruby-mode.el - ;;; ruby-mode.el -
;;; ;;;
;;; $Author$ ;;; $Author$
;;; $Date$
;;; created at: Fri Feb 4 14:49:13 JST 1994 ;;; created at: Fri Feb 4 14:49:13 JST 1994
;;; ;;;
(defconst ruby-mode-revision "$Revision$") (defconst ruby-mode-revision "$Revision$"
"Ruby mode revision string.")
(defconst ruby-mode-version (defconst ruby-mode-version
(progn (and (string-match "[0-9.]+" ruby-mode-revision)
(string-match "[0-9.]+" ruby-mode-revision) (substring ruby-mode-revision (match-beginning 0) (match-end 0)))
(substring ruby-mode-revision (match-beginning 0) (match-end 0)))) "Ruby mode version number.")
(defconst ruby-keyword-end-re
(if (string-match "\\_>" "ruby")
"\\_>"
"\\>"))
(defconst ruby-block-beg-keywords
'("class" "module" "def" "if" "unless" "case" "while" "until" "for" "begin" "do")
"Keywords at the beginning of blocks.")
(defconst ruby-block-beg-re (defconst ruby-block-beg-re
"class\\|module\\|def\\|if\\|unless\\|case\\|while\\|until\\|for\\|begin\\|do" (regexp-opt ruby-block-beg-keywords)
) "Regexp to match the beginning of blocks.")
(defconst ruby-non-block-do-re (defconst ruby-non-block-do-re
"\\(while\\|until\\|for\\|rescue\\)\\>[^_]" (concat (regexp-opt '("while" "until" "for" "rescue") t) ruby-keyword-end-re)
) "Regexp to match")
(defconst ruby-indent-beg-re (defconst ruby-indent-beg-re
"\\(\\s *\\(class\\|module\\|def\\)\\)\\|if\\|unless\\|case\\|while\\|until\\|for\\|begin" (concat "\\(\\s *" (regexp-opt '("class" "module" "def") t) "\\)"
) (regexp-opt '("if" "unless" "case" "while" "until" "for" "begin")))
"Regexp to match where the indentation gets deeper.")
(defconst ruby-modifier-beg-keywords
'("if" "unless" "while" "until")
"Modifiers that are the same as the beginning of blocks.")
(defconst ruby-modifier-beg-re (defconst ruby-modifier-beg-re
"if\\|unless\\|while\\|until" (regexp-opt ruby-modifier-beg-keywords)
) "Regexp to match modifiers same as the beginning of blocks.")
(defconst ruby-modifier-re (defconst ruby-modifier-re
(concat ruby-modifier-beg-re "\\|rescue") (regexp-opt (cons "rescue" ruby-modifier-beg-keywords))
) "Regexp to match modifiers.")
(defconst ruby-block-mid-keywords
'("then" "else" "elsif" "when" "rescue" "ensure")
"Keywords where the indentation gets shallower in middle of block statements.")
(defconst ruby-block-mid-re (defconst ruby-block-mid-re
"then\\|else\\|elsif\\|when\\|rescue\\|ensure" (regexp-opt ruby-block-mid-keywords)
) "Regexp to match where the indentation gets shallower in middle of block statements.")
(defconst ruby-block-op-re (defconst ruby-block-op-keywords
"and\\|or\\|not" '("and" "or" "not")
) "Block operators.")
(defconst ruby-block-hanging-re (defconst ruby-block-hanging-re
(concat ruby-modifier-beg-re "\\|" ruby-block-op-re) (regexp-opt (append ruby-modifier-beg-keywords ruby-block-op-keywords))
) "Regexp to match hanging block modifiers.")
(defconst ruby-block-end-re "\\<end\\>") (defconst ruby-block-end-re "\\<end\\>")
@ -67,8 +85,8 @@
(let ((match (match-string 1))) (let ((match (match-string 1)))
(if (and match (> (length match) 0)) (if (and match (> (length match) 0))
(concat "\\(?:-\\([\"']?\\)\\|\\([\"']\\)" (match-string 1) "\\)" (concat "\\(?:-\\([\"']?\\)\\|\\([\"']\\)" (match-string 1) "\\)"
contents "\\(\\1\\|\\2\\)") contents "\\b\\(\\1\\|\\2\\)")
(concat "-?\\([\"']\\|\\)" contents "\\1")))))) (concat "-?\\([\"']\\|\\)" contents "\\b\\1"))))))
(defconst ruby-delimiter (defconst ruby-delimiter
(concat "[?$/%(){}#\"'`.:]\\|<<\\|\\[\\|\\]\\|\\<\\(" (concat "[?$/%(){}#\"'`.:]\\|<<\\|\\[\\|\\]\\|\\<\\("
@ -80,7 +98,7 @@
(defconst ruby-negative (defconst ruby-negative
(concat "^[ \t]*\\(\\(" ruby-block-mid-re "\\)\\>\\|" (concat "^[ \t]*\\(\\(" ruby-block-mid-re "\\)\\>\\|"
ruby-block-end-re "\\|}\\|\\]\\)") ruby-block-end-re "\\|}\\|\\]\\)")
) "Regexp to match where the indentation gets shallower.")
(defconst ruby-operator-chars "-,.+*/%&|^~=<>:") (defconst ruby-operator-chars "-,.+*/%&|^~=<>:")
(defconst ruby-operator-re (concat "[" ruby-operator-chars "]")) (defconst ruby-operator-re (concat "[" ruby-operator-chars "]"))
@ -175,7 +193,7 @@ Also ignores spaces after parenthesis when 'space."
(eval-when-compile (require 'cl)) (eval-when-compile (require 'cl))
(defun ruby-imenu-create-index-in-block (prefix beg end) (defun ruby-imenu-create-index-in-block (prefix beg end)
(let ((index-alist '()) (let ((index-alist '()) (case-fold-search nil)
name next pos decl sing) name next pos decl sing)
(goto-char beg) (goto-char beg)
(while (re-search-forward "^\\s *\\(\\(class\\s +\\|\\(class\\s *<<\\s *\\)\\|module\\s +\\)\\([^\(<\n ]+\\)\\|\\(def\\|alias\\)\\s +\\([^\(\n ]+\\)\\)" end t) (while (re-search-forward "^\\s *\\(\\(class\\s +\\|\\(class\\s *<<\\s *\\)\\|module\\s +\\)\\([^\(<\n ]+\\)\\|\\(def\\|alias\\)\\s +\\([^\(\n ]+\\)\\)" end t)
@ -223,7 +241,6 @@ Also ignores spaces after parenthesis when 'space."
(defun ruby-mode-variables () (defun ruby-mode-variables ()
(set-syntax-table ruby-mode-syntax-table) (set-syntax-table ruby-mode-syntax-table)
(setq local-abbrev-table ruby-mode-abbrev-table) (setq local-abbrev-table ruby-mode-abbrev-table)
(setq case-fold-search nil)
(make-local-variable 'indent-line-function) (make-local-variable 'indent-line-function)
(setq indent-line-function 'ruby-indent-line) (setq indent-line-function 'ruby-indent-line)
(make-local-variable 'require-final-newline) (make-local-variable 'require-final-newline)
@ -344,9 +361,11 @@ The variable ruby-indent-level controls the amount of indentation.
(and (looking-at ruby-symbol-re) (and (looking-at ruby-symbol-re)
(skip-chars-backward ruby-symbol-chars) (skip-chars-backward ruby-symbol-chars)
(cond (cond
((or (looking-at (concat "\\<\\(" ruby-block-beg-re ((looking-at (regexp-opt
"|" ruby-block-op-re (append ruby-block-beg-keywords
"|" ruby-block-mid-re "\\)\\>"))) ruby-block-op-keywords
ruby-block-mid-keywords)
'words))
(goto-char (match-end 0)) (goto-char (match-end 0))
(not (looking-at "\\s_"))) (not (looking-at "\\s_")))
((eq option 'expr-qstr) ((eq option 'expr-qstr)
@ -505,7 +524,7 @@ The variable ruby-indent-level controls the amount of indentation.
((looking-at (concat "\\<\\(" ruby-block-beg-re "\\)\\>")) ((looking-at (concat "\\<\\(" ruby-block-beg-re "\\)\\>"))
(and (and
(save-match-data (save-match-data
(or (not (looking-at "do\\>[^_]")) (or (not (looking-at (concat "do" ruby-keyword-end-re)))
(save-excursion (save-excursion
(back-to-indentation) (back-to-indentation)
(not (looking-at ruby-non-block-do-re))))) (not (looking-at ruby-non-block-do-re)))))
@ -608,6 +627,7 @@ The variable ruby-indent-level controls the amount of indentation.
(save-excursion (save-excursion
(beginning-of-line) (beginning-of-line)
(let ((indent-point (point)) (let ((indent-point (point))
(case-fold-search nil)
state bol eol begin op-end state bol eol begin op-end
(paren (progn (skip-syntax-forward " ") (paren (progn (skip-syntax-forward " ")
(and (char-after) (matching-paren (char-after))))) (and (char-after) (matching-paren (char-after)))))
@ -701,7 +721,7 @@ The variable ruby-indent-level controls the amount of indentation.
(setq end nil)) (setq end nil))
(goto-char (or end pos)) (goto-char (or end pos))
(skip-chars-backward " \t") (skip-chars-backward " \t")
(setq begin (if (nth 0 state) pos (cdr (nth 1 state)))) (setq begin (if (and end (nth 0 state)) pos (cdr (nth 1 state))))
(setq state (ruby-parse-region parse-start (point)))) (setq state (ruby-parse-region parse-start (point))))
(or (bobp) (forward-char -1)) (or (bobp) (forward-char -1))
(and (and
@ -749,15 +769,19 @@ The variable ruby-indent-level controls the amount of indentation.
(not (looking-at (concat "\\<\\(" ruby-block-hanging-re "\\)\\>"))) (not (looking-at (concat "\\<\\(" ruby-block-hanging-re "\\)\\>")))
(eq (ruby-deep-indent-paren-p t) 'space) (eq (ruby-deep-indent-paren-p t) 'space)
(not (bobp))) (not (bobp)))
(save-excursion
(widen) (widen)
(goto-char (or begin parse-start)) (goto-char (or begin parse-start))
(skip-syntax-forward " ") (skip-syntax-forward " ")
(current-column))) (current-column))
((car (nth 1 state)) indent) ((car (nth 1 state)) indent)
(t (t
(+ indent ruby-indent-level)))))))) (+ indent ruby-indent-level))))))))
indent))) (goto-char indent-point)
(beginning-of-line)
(skip-syntax-forward " ")
(if (looking-at "\\.[^.]")
(+ indent ruby-indent-level)
indent))))
(defun ruby-electric-brace (arg) (defun ruby-electric-brace (arg)
(interactive "P") (interactive "P")
@ -985,17 +1009,19 @@ balanced expression is found."
"Return current method string." "Return current method string."
(condition-case nil (condition-case nil
(save-excursion (save-excursion
(let ((mlist nil) (indent 0)) (let (mname mlist (indent 0))
;; get current method (or class/module) ;; get current method (or class/module)
(if (re-search-backward (if (re-search-backward
(concat "^[ \t]*\\(def\\|class\\|module\\)[ \t]+" (concat "^[ \t]*\\(def\\|class\\|module\\)[ \t]+"
"\\(" "\\("
;; \\. for class method ;; \\. and :: for class method
"\\(" ruby-symbol-re "\\|\\." "\\)" "\\([A-Za-z_]" ruby-symbol-re "*\\|\\.\\|::" "\\)"
"+\\)") "+\\)")
nil t) nil t)
(progn (progn
(setq mlist (list (match-string 2))) (setq mname (match-string 2))
(unless (string-equal "def" (match-string 1))
(setq mlist (list mname) mname nil))
(goto-char (match-beginning 1)) (goto-char (match-beginning 1))
(setq indent (current-column)) (setq indent (current-column))
(beginning-of-line))) (beginning-of-line)))
@ -1004,7 +1030,7 @@ balanced expression is found."
(re-search-backward (re-search-backward
(concat (concat
"^[ \t]*\\(class\\|module\\)[ \t]+" "^[ \t]*\\(class\\|module\\)[ \t]+"
"\\([A-Z]" ruby-symbol-re "+\\)") "\\([A-Z]" ruby-symbol-re "*\\)")
nil t)) nil t))
(goto-char (match-beginning 1)) (goto-char (match-beginning 1))
(if (< (current-column) indent) (if (< (current-column) indent)
@ -1012,10 +1038,33 @@ balanced expression is found."
(setq mlist (cons (match-string 2) mlist)) (setq mlist (cons (match-string 2) mlist))
(setq indent (current-column)) (setq indent (current-column))
(beginning-of-line)))) (beginning-of-line))))
(when mname
(let ((mn (split-string mname "\\.\\|::")))
(if (cdr mn)
(progn
(cond
((string-equal "" (car mn))
(setq mn (cdr mn) mlist nil))
((string-equal "self" (car mn))
(setq mn (cdr mn)))
((let ((ml (nreverse mlist)))
(while ml
(if (string-equal (car ml) (car mn))
(setq mlist (nreverse (cdr ml)) ml nil))
(or (setq ml (cdr ml)) (nreverse mlist))))))
(if mlist
(setcdr (last mlist) mn)
(setq mlist mn))
(setq mn (last mn 2))
(setq mname (concat "." (cadr mn)))
(setcdr mn nil))
(setq mname (concat "#" mname)))))
;; generate string ;; generate string
(if (consp mlist) (if (consp mlist)
(mapconcat (function identity) mlist "::") (setq mlist (mapconcat (function identity) mlist "::")))
nil))))) (if mname
(if mlist (concat mlist mname) mname)
mlist)))))
(cond (cond
((featurep 'font-lock) ((featurep 'font-lock)
@ -1045,21 +1094,41 @@ balanced expression is found."
(ruby-here-doc-beg-syntax)) (ruby-here-doc-beg-syntax))
(,ruby-here-doc-end-re 3 (ruby-here-doc-end-syntax)))) (,ruby-here-doc-end-re 3 (ruby-here-doc-end-syntax))))
(defun ruby-in-non-here-doc-string-p () (unless (functionp 'syntax-ppss)
(let ((syntax (syntax-ppss))) (defun syntax-ppss (&optional pos)
(or (nth 4 syntax) (parse-partial-sexp (point-min) (or pos (point)))))
;; In a string *without* a generic delimiter
;; If it's generic, it's a heredoc and we don't care (defun ruby-in-ppss-context-p (context &optional ppss)
(let ((ppss (or ppss (syntax-ppss (point)))))
(if (cond
((eq context 'anything)
(or (nth 3 ppss)
(nth 4 ppss)))
((eq context 'string)
(nth 3 ppss))
((eq context 'heredoc)
(and (nth 3 ppss)
;; If it's generic string, it's a heredoc and we don't care
;; See `parse-partial-sexp' ;; See `parse-partial-sexp'
(numberp (nth 3 syntax))))) (not (numberp (nth 3 ppss)))))
((eq context 'non-heredoc)
(and (ruby-in-ppss-context-p 'anything)
(not (ruby-in-ppss-context-p 'heredoc))))
((eq context 'comment)
(nth 4 ppss))
(t
(error (concat
"Internal error on `ruby-in-ppss-context-p': "
"context name `" (symbol-name context) "' is unknown"))))
t)))
(defun ruby-in-here-doc-p () (defun ruby-in-here-doc-p ()
(save-excursion (save-excursion
(let ((old-point (point))) (let ((old-point (point)) (case-fold-search nil))
(beginning-of-line) (beginning-of-line)
(catch 'found-beg (catch 'found-beg
(while (re-search-backward ruby-here-doc-beg-re nil t) (while (re-search-backward ruby-here-doc-beg-re nil t)
(if (not (or (syntax-ppss-context (syntax-ppss)) (if (not (or (ruby-in-ppss-context-p 'anything)
(ruby-here-doc-find-end old-point))) (ruby-here-doc-find-end old-point)))
(throw 'found-beg t))))))) (throw 'found-beg t)))))))
@ -1072,6 +1141,7 @@ buffer position `limit' or the end of the buffer."
(beginning-of-line) (beginning-of-line)
(catch 'done (catch 'done
(let ((eol (save-excursion (end-of-line) (point))) (let ((eol (save-excursion (end-of-line) (point)))
(case-fold-search nil)
;; Fake match data such that (match-end 0) is at eol ;; Fake match data such that (match-end 0) is at eol
(end-match-data (progn (looking-at ".*$") (match-data))) (end-match-data (progn (looking-at ".*$") (match-data)))
beg-match-data end-re) beg-match-data end-re)
@ -1093,22 +1163,22 @@ buffer position `limit' or the end of the buffer."
(defun ruby-here-doc-beg-syntax () (defun ruby-here-doc-beg-syntax ()
(save-excursion (save-excursion
(goto-char (match-beginning 0)) (goto-char (match-beginning 0))
(unless (or (ruby-in-non-here-doc-string-p) (unless (or (ruby-in-ppss-context-p 'non-heredoc)
(ruby-in-here-doc-p)) (ruby-in-here-doc-p))
(string-to-syntax "|")))) (string-to-syntax "|"))))
(defun ruby-here-doc-end-syntax () (defun ruby-here-doc-end-syntax ()
(let ((pss (syntax-ppss)) (case-fold-search nil))
(when (ruby-in-ppss-context-p 'heredoc pss)
(save-excursion (save-excursion
(goto-char (match-end 0)) (goto-char (nth 8 pss)) ; Go to the beginning of heredoc.
(let ((old-point (point)) (let ((eol (point)))
(beg-exists (re-search-backward (ruby-here-doc-beg-match) nil t)) (beginning-of-line)
(eol (save-excursion (end-of-line) (point)))) (if (and (re-search-forward (ruby-here-doc-beg-match) eol t) ; If there is a heredoc that matches this line...
(if (and beg-exists ; If there is a heredoc that matches this line... (not (ruby-in-ppss-context-p 'anything)) ; And that's not inside a heredoc/string/comment...
(null (syntax-ppss-context (syntax-ppss))) ; And that's not inside a heredoc/string/comment...
(progn (goto-char (match-end 0)) ; And it's the last heredoc on its line... (progn (goto-char (match-end 0)) ; And it's the last heredoc on its line...
(not (re-search-forward ruby-here-doc-beg-re eol t))) (not (re-search-forward ruby-here-doc-beg-re eol t))))
(eq old-point (ruby-here-doc-find-end old-point))) ; And it ends at this point... (string-to-syntax "|")))))))
(string-to-syntax "|")))))
(if (featurep 'xemacs) (if (featurep 'xemacs)
(put 'ruby-mode 'font-lock-defaults (put 'ruby-mode 'font-lock-defaults
@ -1156,9 +1226,8 @@ buffer position `limit' or the end of the buffer."
1 font-lock-function-name-face) 1 font-lock-function-name-face)
;; keywords ;; keywords
(cons (concat (cons (concat
"\\(^\\|[^_:.@$]\\|\\.\\.\\)\\b\\(defined\\?\\|\\(" "\\(^\\|[^_:.@$]\\|\\.\\.\\)\\b\\(defined\\?\\|"
(mapconcat (regexp-opt
'identity
'("alias" '("alias"
"and" "and"
"begin" "begin"
@ -1195,8 +1264,9 @@ buffer position `limit' or the end of the buffer."
"while" "while"
"yield" "yield"
) )
"\\|") t)
"\\)\\>\\)") "\\)"
ruby-keyword-end-re)
2) 2)
;; here-doc beginnings ;; here-doc beginnings
(list ruby-here-doc-beg-re 0 'font-lock-string-face) (list ruby-here-doc-beg-re 0 'font-lock-string-face)