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:
parent
0c06990532
commit
10b3b5536b
2 changed files with 768 additions and 685 deletions
13
ChangeLog
13
ChangeLog
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue