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>
* configure.in: applied OS/2 support patch from Brendan Oakley

View file

@ -2,48 +2,66 @@
;;; ruby-mode.el -
;;;
;;; $Author$
;;; $Date$
;;; 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
(progn
(string-match "[0-9.]+" ruby-mode-revision)
(substring ruby-mode-revision (match-beginning 0) (match-end 0))))
(and (string-match "[0-9.]+" ruby-mode-revision)
(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
"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
"\\(while\\|until\\|for\\|rescue\\)\\>[^_]"
)
(concat (regexp-opt '("while" "until" "for" "rescue") t) ruby-keyword-end-re)
"Regexp to match")
(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
"if\\|unless\\|while\\|until"
)
(regexp-opt ruby-modifier-beg-keywords)
"Regexp to match modifiers same as the beginning of blocks.")
(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
"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
"and\\|or\\|not"
)
(defconst ruby-block-op-keywords
'("and" "or" "not")
"Block operators.")
(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\\>")
@ -67,8 +85,8 @@
(let ((match (match-string 1)))
(if (and match (> (length match) 0))
(concat "\\(?:-\\([\"']?\\)\\|\\([\"']\\)" (match-string 1) "\\)"
contents "\\(\\1\\|\\2\\)")
(concat "-?\\([\"']\\|\\)" contents "\\1"))))))
contents "\\b\\(\\1\\|\\2\\)")
(concat "-?\\([\"']\\|\\)" contents "\\b\\1"))))))
(defconst ruby-delimiter
(concat "[?$/%(){}#\"'`.:]\\|<<\\|\\[\\|\\]\\|\\<\\("
@ -80,7 +98,7 @@
(defconst ruby-negative
(concat "^[ \t]*\\(\\(" ruby-block-mid-re "\\)\\>\\|"
ruby-block-end-re "\\|}\\|\\]\\)")
)
"Regexp to match where the indentation gets shallower.")
(defconst 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))
(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)
(goto-char beg)
(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 ()
(set-syntax-table ruby-mode-syntax-table)
(setq local-abbrev-table ruby-mode-abbrev-table)
(setq case-fold-search nil)
(make-local-variable 'indent-line-function)
(setq indent-line-function 'ruby-indent-line)
(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)
(skip-chars-backward ruby-symbol-chars)
(cond
((or (looking-at (concat "\\<\\(" ruby-block-beg-re
"|" ruby-block-op-re
"|" ruby-block-mid-re "\\)\\>")))
((looking-at (regexp-opt
(append ruby-block-beg-keywords
ruby-block-op-keywords
ruby-block-mid-keywords)
'words))
(goto-char (match-end 0))
(not (looking-at "\\s_")))
((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 "\\)\\>"))
(and
(save-match-data
(or (not (looking-at "do\\>[^_]"))
(or (not (looking-at (concat "do" ruby-keyword-end-re)))
(save-excursion
(back-to-indentation)
(not (looking-at ruby-non-block-do-re)))))
@ -608,6 +627,7 @@ The variable ruby-indent-level controls the amount of indentation.
(save-excursion
(beginning-of-line)
(let ((indent-point (point))
(case-fold-search nil)
state bol eol begin op-end
(paren (progn (skip-syntax-forward " ")
(and (char-after) (matching-paren (char-after)))))
@ -701,7 +721,7 @@ The variable ruby-indent-level controls the amount of indentation.
(setq end nil))
(goto-char (or end pos))
(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))))
(or (bobp) (forward-char -1))
(and
@ -749,15 +769,19 @@ The variable ruby-indent-level controls the amount of indentation.
(not (looking-at (concat "\\<\\(" ruby-block-hanging-re "\\)\\>")))
(eq (ruby-deep-indent-paren-p t) 'space)
(not (bobp)))
(save-excursion
(widen)
(goto-char (or begin parse-start))
(skip-syntax-forward " ")
(current-column)))
(current-column))
((car (nth 1 state)) indent)
(t
(+ 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)
(interactive "P")
@ -985,17 +1009,19 @@ balanced expression is found."
"Return current method string."
(condition-case nil
(save-excursion
(let ((mlist nil) (indent 0))
(let (mname mlist (indent 0))
;; get current method (or class/module)
(if (re-search-backward
(concat "^[ \t]*\\(def\\|class\\|module\\)[ \t]+"
"\\("
;; \\. for class method
"\\(" ruby-symbol-re "\\|\\." "\\)"
;; \\. and :: for class method
"\\([A-Za-z_]" ruby-symbol-re "*\\|\\.\\|::" "\\)"
"+\\)")
nil t)
(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))
(setq indent (current-column))
(beginning-of-line)))
@ -1004,7 +1030,7 @@ balanced expression is found."
(re-search-backward
(concat
"^[ \t]*\\(class\\|module\\)[ \t]+"
"\\([A-Z]" ruby-symbol-re "+\\)")
"\\([A-Z]" ruby-symbol-re "*\\)")
nil t))
(goto-char (match-beginning 1))
(if (< (current-column) indent)
@ -1012,10 +1038,33 @@ balanced expression is found."
(setq mlist (cons (match-string 2) mlist))
(setq indent (current-column))
(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
(if (consp mlist)
(mapconcat (function identity) mlist "::")
nil)))))
(setq mlist (mapconcat (function identity) mlist "::")))
(if mname
(if mlist (concat mlist mname) mname)
mlist)))))
(cond
((featurep 'font-lock)
@ -1045,21 +1094,41 @@ balanced expression is found."
(ruby-here-doc-beg-syntax))
(,ruby-here-doc-end-re 3 (ruby-here-doc-end-syntax))))
(defun ruby-in-non-here-doc-string-p ()
(let ((syntax (syntax-ppss)))
(or (nth 4 syntax)
;; In a string *without* a generic delimiter
;; If it's generic, it's a heredoc and we don't care
(unless (functionp 'syntax-ppss)
(defun syntax-ppss (&optional pos)
(parse-partial-sexp (point-min) (or pos (point)))))
(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'
(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 ()
(save-excursion
(let ((old-point (point)))
(let ((old-point (point)) (case-fold-search nil))
(beginning-of-line)
(catch 'found-beg
(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)))
(throw 'found-beg t)))))))
@ -1072,6 +1141,7 @@ buffer position `limit' or the end of the buffer."
(beginning-of-line)
(catch 'done
(let ((eol (save-excursion (end-of-line) (point)))
(case-fold-search nil)
;; Fake match data such that (match-end 0) is at eol
(end-match-data (progn (looking-at ".*$") (match-data)))
beg-match-data end-re)
@ -1093,22 +1163,22 @@ buffer position `limit' or the end of the buffer."
(defun ruby-here-doc-beg-syntax ()
(save-excursion
(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))
(string-to-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
(goto-char (match-end 0))
(let ((old-point (point))
(beg-exists (re-search-backward (ruby-here-doc-beg-match) nil t))
(eol (save-excursion (end-of-line) (point))))
(if (and beg-exists ; If there is a heredoc that matches this line...
(null (syntax-ppss-context (syntax-ppss))) ; And that's not inside a heredoc/string/comment...
(goto-char (nth 8 pss)) ; Go to the beginning of heredoc.
(let ((eol (point)))
(beginning-of-line)
(if (and (re-search-forward (ruby-here-doc-beg-match) eol t) ; 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...
(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)))
(eq old-point (ruby-here-doc-find-end old-point))) ; And it ends at this point...
(string-to-syntax "|")))))
(not (re-search-forward ruby-here-doc-beg-re eol t))))
(string-to-syntax "|")))))))
(if (featurep 'xemacs)
(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)
;; keywords
(cons (concat
"\\(^\\|[^_:.@$]\\|\\.\\.\\)\\b\\(defined\\?\\|\\("
(mapconcat
'identity
"\\(^\\|[^_:.@$]\\|\\.\\.\\)\\b\\(defined\\?\\|"
(regexp-opt
'("alias"
"and"
"begin"
@ -1195,8 +1264,9 @@ buffer position `limit' or the end of the buffer."
"while"
"yield"
)
"\\|")
"\\)\\>\\)")
t)
"\\)"
ruby-keyword-end-re)
2)
;; here-doc beginnings
(list ruby-here-doc-beg-re 0 'font-lock-string-face)