Bug #528 » 0005--misc-.el-untabify-for-interal-consistency-and-c.patch
misc/inf-ruby.el | ||
---|---|---|
;;; (setq auto-mode-alist
|
||
;;; (append '(("\\.rb$" . ruby-mode)) auto-mode-alist))
|
||
;;; (setq interpreter-mode-alist (append '(("ruby" . ruby-mode))
|
||
;;; interpreter-mode-alist))
|
||
;;; interpreter-mode-alist))
|
||
;;;
|
||
;;; (2) set to load inf-ruby and set inf-ruby key definition in ruby-mode.
|
||
;;;
|
||
... | ... | |
;;;
|
||
;;; HISTORY
|
||
;;; senda - 8 Apr 1998: Created.
|
||
;;; $Log$
|
||
;;; Revision 1.7 2004/07/27 08:11:36 matz
|
||
;;; * eval.c (rb_eval): copy on write for argument local variable
|
||
;;; assignment.
|
||
;;; $Log$
|
||
;;; Revision 1.7 2004/07/27 08:11:36 matz
|
||
;;; * eval.c (rb_eval): copy on write for argument local variable
|
||
;;; assignment.
|
||
;;;
|
||
;;; * eval.c (assign): ditto.
|
||
;;; * eval.c (assign): ditto.
|
||
;;;
|
||
;;; * eval.c (rb_call0): update ruby_frame->argv with the default
|
||
;;; value used for the optional arguments.
|
||
;;; * eval.c (rb_call0): update ruby_frame->argv with the default
|
||
;;; value used for the optional arguments.
|
||
;;;
|
||
;;; * object.c (Init_Object): "===" calls rb_obj_equal() directly.
|
||
;;; [ruby-list:39937]
|
||
;;; * object.c (Init_Object): "===" calls rb_obj_equal() directly.
|
||
;;; [ruby-list:39937]
|
||
;;;
|
||
;;; Revision 1.6 2002/09/07 14:35:46 nobu
|
||
;;; * misc/inf-ruby.el (inferior-ruby-error-regexp-alist): regexp
|
||
;;; alist for error message from ruby.
|
||
;;;
|
||
;;; * misc/inf-ruby.el (inferior-ruby-mode): fixed for Emacs.
|
||
;;;
|
||
;;; * misc/inf-ruby.el (ruby-send-region): compilation-parse-errors
|
||
;;; doesn't parse first line, so insert separators before each
|
||
;;; evaluations.
|
||
;;;
|
||
;;; Revision 1.5 2002/08/19 10:05:47 nobu
|
||
;;; * misc/inf-ruby.el (inf-ruby-keys): ruby-send-definition
|
||
;;; conflicted with ruby-insert-end.
|
||
;;;
|
||
;;; * misc/inf-ruby.el (inferior-ruby-mode): compilation-minor-mode.
|
||
;;;
|
||
;;; * misc/inf-ruby.el (ruby-send-region): send as here document to
|
||
;;; adjust source file/line. [ruby-talk:47113], [ruby-dev:17965]
|
||
;;;
|
||
;;; * misc/inf-ruby.el (ruby-send-terminator): added to make unique
|
||
;;; terminator.
|
||
;;;
|
||
;;; Revision 1.4 2002/01/29 07:16:09 matz
|
||
;;; * file.c (rb_stat_rdev_major): added. [new]
|
||
;;;
|
||
;;; * file.c (rb_stat_rdev_minor): added. [new]
|
||
;;;
|
||
;;; * file.c (rb_stat_inspect): print mode in octal.
|
||
;;;
|
||
;;; Revision 1.3 1999/12/01 09:24:18 matz
|
||
;;; 19991201
|
||
;;;
|
||
;;; Revision 1.2 1999/08/13 05:45:18 matz
|
||
;;; 1.4.0
|
||
;;;
|
||
;;; Revision 1.1.1.1.2.1 1999/07/15 07:59:59 matz
|
||
;;; 990715
|
||
;;;
|
||
;;; Revision 1.1.1.1 1999/01/20 04:59:36 matz
|
||
;;; ruby 1.3 cycle
|
||
;;;
|
||
;;; Revision 1.1.2.1 1998/12/16 07:30:36 matz
|
||
;;; first public release of 1.1d (pre1.2) series
|
||
;;;
|
||
;;; Revision 1.4 1998/05/20 02:45:58 senda
|
||
;;; default program to irb
|
||
;;; Revision 1.6 2002/09/07 14:35:46 nobu
|
||
;;; * misc/inf-ruby.el (inferior-ruby-error-regexp-alist): regexp
|
||
;;; alist for error message from ruby.
|
||
;;;
|
||
;;; * misc/inf-ruby.el (inferior-ruby-mode): fixed for Emacs.
|
||
;;;
|
||
;;; * misc/inf-ruby.el (ruby-send-region): compilation-parse-errors
|
||
;;; doesn't parse first line, so insert separators before each
|
||
;;; evaluations.
|
||
;;;
|
||
;;; Revision 1.5 2002/08/19 10:05:47 nobu
|
||
;;; * misc/inf-ruby.el (inf-ruby-keys): ruby-send-definition
|
||
;;; conflicted with ruby-insert-end.
|
||
;;;
|
||
;;; * misc/inf-ruby.el (inferior-ruby-mode): compilation-minor-mode.
|
||
;;;
|
||
;;; * misc/inf-ruby.el (ruby-send-region): send as here document to
|
||
;;; adjust source file/line. [ruby-talk:47113], [ruby-dev:17965]
|
||
;;;
|
||
;;; * misc/inf-ruby.el (ruby-send-terminator): added to make unique
|
||
;;; terminator.
|
||
;;;
|
||
;;; Revision 1.4 2002/01/29 07:16:09 matz
|
||
;;; * file.c (rb_stat_rdev_major): added. [new]
|
||
;;;
|
||
;;; * file.c (rb_stat_rdev_minor): added. [new]
|
||
;;;
|
||
;;; * file.c (rb_stat_inspect): print mode in octal.
|
||
;;;
|
||
;;; Revision 1.3 1999/12/01 09:24:18 matz
|
||
;;; 19991201
|
||
;;;
|
||
;;; Revision 1.2 1999/08/13 05:45:18 matz
|
||
;;; 1.4.0
|
||
;;;
|
||
;;; Revision 1.1.1.1.2.1 1999/07/15 07:59:59 matz
|
||
;;; 990715
|
||
;;;
|
||
;;; Revision 1.1.1.1 1999/01/20 04:59:36 matz
|
||
;;; ruby 1.3 cycle
|
||
;;;
|
||
;;; Revision 1.1.2.1 1998/12/16 07:30:36 matz
|
||
;;; first public release of 1.1d (pre1.2) series
|
||
;;;
|
||
;;; Revision 1.4 1998/05/20 02:45:58 senda
|
||
;;; default program to irb
|
||
;;;
|
||
;;; Revision 1.3 1998/04/10 04:11:30 senda
|
||
;;; modification by Matsumoto san (1.1b9_09)
|
||
;;; remove-in-string defined
|
||
;;; global variable :
|
||
;;; inferior-ruby-first-prompt-pattern
|
||
;;; inferior-ruby-prompt-pattern
|
||
;;; defined
|
||
;;; Revision 1.3 1998/04/10 04:11:30 senda
|
||
;;; modification by Matsumoto san (1.1b9_09)
|
||
;;; remove-in-string defined
|
||
;;; global variable :
|
||
;;; inferior-ruby-first-prompt-pattern
|
||
;;; inferior-ruby-prompt-pattern
|
||
;;; defined
|
||
;;;
|
||
;;; Revision 1.2 1998/04/09 07:53:42 senda
|
||
;;; remove M-C-x in inferior-ruby-mode
|
||
;;; Revision 1.2 1998/04/09 07:53:42 senda
|
||
;;; remove M-C-x in inferior-ruby-mode
|
||
;;;
|
||
;;; Revision 1.1 1998/04/09 07:28:36 senda
|
||
;;; Initial revision
|
||
;;; Revision 1.1 1998/04/09 07:28:36 senda
|
||
;;; Initial revision
|
||
;;;
|
||
;;;
|
||
... | ... | |
(defconst inferior-ruby-error-regexp-alist
|
||
'(("SyntaxError: compile error\n^\\([^\(].*\\):\\([1-9][0-9]*\\):" 1 2)
|
||
("^\tfrom \\([^\(].*\\):\\([1-9][0-9]*\\)\\(:in `.*'\\)?$" 1 2)))
|
||
("^\tfrom \\([^\(].*\\):\\([1-9][0-9]*\\)\\(:in `.*'\\)?$" 1 2)))
|
||
(cond ((not inferior-ruby-mode-map)
|
||
(setq inferior-ruby-mode-map
|
||
(copy-keymap comint-mode-map))
|
||
(copy-keymap comint-mode-map))
|
||
; (define-key inferior-ruby-mode-map "\M-\C-x" ;gnu convention
|
||
; 'ruby-send-definition)
|
||
; 'ruby-send-definition)
|
||
; (define-key inferior-ruby-mode-map "\C-x\C-e" 'ruby-send-last-sexp)
|
||
(define-key inferior-ruby-mode-map "\C-c\C-l" 'ruby-load-file)
|
||
))
|
||
... | ... | |
(let ((rtn-str "") (start 0) match prev-start)
|
||
(while (setq match (string-match regexp str start))
|
||
(setq prev-start start
|
||
start (match-end 0)
|
||
rtn-str (concat rtn-str (substring str prev-start match))))
|
||
start (match-end 0)
|
||
rtn-str (concat rtn-str (substring str prev-start match))))
|
||
(concat rtn-str (substring str start))))
|
||
(defun ruby-get-old-input ()
|
||
... | ... | |
(let ((end (point)))
|
||
(re-search-backward inferior-ruby-first-prompt-pattern)
|
||
(remove-in-string (buffer-substring (point) end)
|
||
inferior-ruby-prompt-pattern)
|
||
inferior-ruby-prompt-pattern)
|
||
)))
|
||
(defun ruby-args-to-list (string)
|
||
(let ((where (string-match "[ \t]" string)))
|
||
(cond ((null where) (list string))
|
||
((not (= where 0))
|
||
(cons (substring string 0 where)
|
||
(ruby-args-to-list (substring string (+ 1 where)
|
||
(length string)))))
|
||
(t (let ((pos (string-match "[^ \t]" string)))
|
||
(if (null pos)
|
||
nil
|
||
(ruby-args-to-list (substring string pos
|
||
(length string)))))))))
|
||
((not (= where 0))
|
||
(cons (substring string 0 where)
|
||
(ruby-args-to-list (substring string (+ 1 where)
|
||
(length string)))))
|
||
(t (let ((pos (string-match "[^ \t]" string)))
|
||
(if (null pos)
|
||
nil
|
||
(ruby-args-to-list (substring string pos
|
||
(length string)))))))))
|
||
(defun run-ruby (cmd)
|
||
"Run an inferior Ruby process, input and output via buffer *ruby*.
|
||
... | ... | |
\(Type \\[describe-mode] in the process buffer for a list of commands.)"
|
||
(interactive (list (if current-prefix-arg
|
||
(read-string "Run Ruby: " ruby-program-name)
|
||
ruby-program-name)))
|
||
(read-string "Run Ruby: " ruby-program-name)
|
||
ruby-program-name)))
|
||
(if (not (comint-check-proc "*ruby*"))
|
||
(let ((cmdlist (ruby-args-to-list cmd)))
|
||
(set-buffer (apply 'make-comint "ruby" (car cmdlist)
|
||
nil (cdr cmdlist)))
|
||
(inferior-ruby-mode)))
|
||
(set-buffer (apply 'make-comint "ruby" (car cmdlist)
|
||
nil (cdr cmdlist)))
|
||
(inferior-ruby-mode)))
|
||
(setq ruby-program-name cmd)
|
||
(setq ruby-buffer "*ruby*")
|
||
(pop-to-buffer "*ruby*"))
|
||
... | ... | |
(let (term (file (buffer-file-name)) line)
|
||
(save-excursion
|
||
(save-restriction
|
||
(widen)
|
||
(goto-char start)
|
||
(setq line (+ start (forward-line (- start)) 1))
|
||
(goto-char start)
|
||
(while (progn
|
||
(setq term (apply 'format ruby-send-terminator (random) (current-time)))
|
||
(re-search-forward (concat "^" (regexp-quote term) "$") end t)))))
|
||
(widen)
|
||
(goto-char start)
|
||
(setq line (+ start (forward-line (- start)) 1))
|
||
(goto-char start)
|
||
(while (progn
|
||
(setq term (apply 'format ruby-send-terminator (random) (current-time)))
|
||
(re-search-forward (concat "^" (regexp-quote term) "$") end t)))))
|
||
;; compilation-parse-errors parses from second line.
|
||
(save-excursion
|
||
(let ((m (process-mark (ruby-proc))))
|
||
(set-buffer (marker-buffer m))
|
||
(goto-char m)
|
||
(insert ruby-eval-separator "\n")
|
||
(set-marker m (point))))
|
||
(set-buffer (marker-buffer m))
|
||
(goto-char m)
|
||
(insert ruby-eval-separator "\n")
|
||
(set-marker m (point))))
|
||
(comint-send-string (ruby-proc) (format "eval <<'%s', nil, %S, %d\n" term file line))
|
||
(comint-send-region (ruby-proc) start end)
|
||
(comint-send-string (ruby-proc) (concat "\n" term "\n"))))
|
||
... | ... | |
(pop-to-buffer ruby-buffer)
|
||
(error "No current process buffer. See variable ruby-buffer."))
|
||
(cond (eob-p
|
||
(push-mark)
|
||
(goto-char (point-max)))))
|
||
(push-mark)
|
||
(goto-char (point-max)))))
|
||
(defun ruby-send-region-and-go (start end)
|
||
"Send the current region to the inferior Ruby process.
|
||
... | ... | |
(defun ruby-load-file (file-name)
|
||
"Load a Ruby file into the inferior Ruby process."
|
||
(interactive (comint-get-source "Load Ruby file: " ruby-prev-l/c-dir/file
|
||
ruby-source-modes t)) ; T because LOAD
|
||
ruby-source-modes t)) ; T because LOAD
|
||
; needs an exact name
|
||
(comint-check-source file-name) ; Check to see if buffer needs saved.
|
||
(setq ruby-prev-l/c-dir/file (cons (file-name-directory file-name)
|
||
(file-name-nondirectory file-name)))
|
||
(file-name-nondirectory file-name)))
|
||
(comint-send-string (ruby-proc) (concat "(load \""
|
||
file-name
|
||
"\"\)\n")))
|
||
file-name
|
||
"\"\)\n")))
|
||
(defun ruby-proc ()
|
||
"Returns the current ruby process. See variable ruby-buffer."
|
||
(let ((proc (get-buffer-process (if (eq major-mode 'inferior-ruby-mode)
|
||
(current-buffer)
|
||
ruby-buffer))))
|
||
(current-buffer)
|
||
ruby-buffer))))
|
||
(or proc
|
||
(error "No current process. See variable ruby-buffer"))))
|
||
(error "No current process. See variable ruby-buffer"))))
|
||
;;; Do the user's customisation...
|
||
(defvar inf-ruby-load-hook nil
|
||
"This hook is run when inf-ruby is loaded in.
|
||
This is a good place to put keybindings.")
|
||
|
||
|
||
(run-hooks 'inf-ruby-load-hook)
|
||
(provide 'inf-ruby)
|
misc/ruby-electric.el | ||
---|---|---|
"*List of contexts where matching delimiter should be
|
||
inserted. The word 'all' will do all insertions."
|
||
:type '(set :extra-offset 8
|
||
(const :tag "Everything" all )
|
||
(const :tag "Curly brace" ?\{ )
|
||
(const :tag "Square brace" ?\[ )
|
||
(const :tag "Round brace" ?\( )
|
||
(const :tag "Quote" ?\' )
|
||
(const :tag "Double quote" ?\" )
|
||
(const :tag "Back quote" ?\` )
|
||
(const :tag "Vertical bar" ?\| ))
|
||
(const :tag "Everything" all )
|
||
(const :tag "Curly brace" ?\{ )
|
||
(const :tag "Square brace" ?\[ )
|
||
(const :tag "Round brace" ?\( )
|
||
(const :tag "Quote" ?\' )
|
||
(const :tag "Double quote" ?\" )
|
||
(const :tag "Back quote" ?\` )
|
||
(const :tag "Vertical bar" ?\| ))
|
||
:group 'ruby-electric)
|
||
(defcustom ruby-electric-newline-before-closing-bracket nil
|
||
... | ... | |
(self-insert-command (prefix-numeric-value arg))
|
||
(if (ruby-electric-space-can-be-expanded-p)
|
||
(save-excursion
|
||
(ruby-indent-line t)
|
||
(newline)
|
||
(ruby-insert-end))))
|
||
(ruby-indent-line t)
|
||
(newline)
|
||
(ruby-insert-end))))
|
||
(defun ruby-electric-code-at-point-p()
|
||
(and ruby-electric-mode
|
||
(let* ((properties (text-properties-at (point))))
|
||
(and (null (memq 'font-lock-string-face properties))
|
||
(null (memq 'font-lock-comment-face properties))))))
|
||
(and (null (memq 'font-lock-string-face properties))
|
||
(null (memq 'font-lock-comment-face properties))))))
|
||
(defun ruby-electric-string-at-point-p()
|
||
(and ruby-electric-mode
|
||
... | ... | |
(defun ruby-electric-space-can-be-expanded-p()
|
||
(if (ruby-electric-code-at-point-p)
|
||
(let* ((ruby-electric-keywords-re
|
||
(concat ruby-electric-simple-keywords-re "\\s-$"))
|
||
(ruby-electric-single-keyword-in-line-re
|
||
(concat "\\s-*" ruby-electric-keywords-re)))
|
||
(save-excursion
|
||
(backward-word 1)
|
||
(or (looking-at ruby-electric-expandable-do-re)
|
||
(and (looking-at ruby-electric-keywords-re)
|
||
(not (string= "do" (match-string 1)))
|
||
(progn
|
||
(beginning-of-line)
|
||
(looking-at ruby-electric-single-keyword-in-line-re))))))))
|
||
(concat ruby-electric-simple-keywords-re "\\s-$"))
|
||
(ruby-electric-single-keyword-in-line-re
|
||
(concat "\\s-*" ruby-electric-keywords-re)))
|
||
(save-excursion
|
||
(backward-word 1)
|
||
(or (looking-at ruby-electric-expandable-do-re)
|
||
(and (looking-at ruby-electric-keywords-re)
|
||
(not (string= "do" (match-string 1)))
|
||
(progn
|
||
(beginning-of-line)
|
||
(looking-at ruby-electric-single-keyword-in-line-re))))))))
|
||
(defun ruby-electric-curlies(arg)
|
||
... | ... | |
(self-insert-command (prefix-numeric-value arg))
|
||
(if (ruby-electric-is-last-command-char-expandable-punct-p)
|
||
(cond ((ruby-electric-code-at-point-p)
|
||
(insert " ")
|
||
(save-excursion
|
||
(if ruby-electric-newline-before-closing-bracket
|
||
(newline))
|
||
(insert "}")))
|
||
((ruby-electric-string-at-point-p)
|
||
(save-excursion
|
||
(backward-char 1)
|
||
(when (char-equal ?\# (preceding-char))
|
||
(forward-char 1)
|
||
(insert "}")))))))
|
||
(insert " ")
|
||
(save-excursion
|
||
(if ruby-electric-newline-before-closing-bracket
|
||
(newline))
|
||
(insert "}")))
|
||
((ruby-electric-string-at-point-p)
|
||
(save-excursion
|
||
(backward-char 1)
|
||
(when (char-equal ?\# (preceding-char))
|
||
(forward-char 1)
|
||
(insert "}")))))))
|
||
(defun ruby-electric-matching-char(arg)
|
||
(interactive "P")
|
||
... | ... | |
(and (ruby-electric-is-last-command-char-expandable-punct-p)
|
||
(ruby-electric-code-at-point-p)
|
||
(save-excursion
|
||
(insert (cdr (assoc last-command-char
|
||
ruby-electric-matching-delimeter-alist))))))
|
||
(insert (cdr (assoc last-command-char
|
||
ruby-electric-matching-delimeter-alist))))))
|
||
(defun ruby-electric-bar(arg)
|
||
(interactive "P")
|
||
... | ... | |
(and (ruby-electric-is-last-command-char-expandable-punct-p)
|
||
(ruby-electric-code-at-point-p)
|
||
(and (save-excursion (re-search-backward ruby-electric-expandable-bar nil t))
|
||
(= (point) (match-end 0))) ;looking-back is missing on XEmacs
|
||
(= (point) (match-end 0))) ;looking-back is missing on XEmacs
|
||
(save-excursion
|
||
(insert "|"))))
|
||
(insert "|"))))
|
||
(provide 'ruby-electric)
|
misc/ruby-mode.el | ||
---|---|---|
(defun ruby-here-doc-end-match ()
|
||
(concat "^"
|
||
(if (match-string 2) "[ \t]*" nil)
|
||
(regexp-quote
|
||
(or (match-string 4)
|
||
(match-string 5)
|
||
(match-string 6)))))
|
||
(if (match-string 2) "[ \t]*" nil)
|
||
(regexp-quote
|
||
(or (match-string 4)
|
||
(match-string 5)
|
||
(match-string 6)))))
|
||
(defun ruby-here-doc-beg-match ()
|
||
(let ((contents (regexp-quote (concat (match-string 2) (match-string 3)))))
|
||
... | ... | |
(defconst ruby-delimiter
|
||
(concat "[?$/%(){}#\"'`.:]\\|<<\\|\\[\\|\\]\\|\\<\\("
|
||
ruby-block-beg-re
|
||
"\\)\\>\\|" ruby-block-end-re
|
||
"\\|^=begin\\|" ruby-here-doc-beg-re)
|
||
ruby-block-beg-re
|
||
"\\)\\>\\|" ruby-block-end-re
|
||
"\\|^=begin\\|" ruby-here-doc-beg-re)
|
||
)
|
||
(defconst ruby-negative
|
||
(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 "-,.+*/%&|^~=<>:")
|
||
... | ... | |
(setq pos (match-beginning 0))
|
||
(cond
|
||
((string= "alias" decl)
|
||
(if prefix (setq name (concat prefix name)))
|
||
(push (cons name pos) index-alist))
|
||
(if prefix (setq name (concat prefix name)))
|
||
(push (cons name pos) index-alist))
|
||
((string= "def" decl)
|
||
(if prefix
|
||
(setq name
|
||
(cond
|
||
((string-match "^self\." name)
|
||
(concat (substring prefix 0 -1) (substring name 4)))
|
||
(t (concat prefix name)))))
|
||
(push (cons name pos) index-alist)
|
||
(ruby-accurate-end-of-block end))
|
||
(if prefix
|
||
(setq name
|
||
(cond
|
||
((string-match "^self\." name)
|
||
(concat (substring prefix 0 -1) (substring name 4)))
|
||
(t (concat prefix name)))))
|
||
(push (cons name pos) index-alist)
|
||
(ruby-accurate-end-of-block end))
|
||
(t
|
||
(if (string= "self" name)
|
||
(if prefix (setq name (substring prefix 0 -1)))
|
||
(if prefix (setq name (concat (substring prefix 0 -1) "::" name)))
|
||
(push (cons name pos) index-alist))
|
||
(ruby-accurate-end-of-block end)
|
||
(setq beg (point))
|
||
(setq index-alist
|
||
(nconc (ruby-imenu-create-index-in-block
|
||
(concat name (if sing "." "#"))
|
||
next beg) index-alist))
|
||
(goto-char beg))))
|
||
(if (string= "self" name)
|
||
(if prefix (setq name (substring prefix 0 -1)))
|
||
(if prefix (setq name (concat (substring prefix 0 -1) "::" name)))
|
||
(push (cons name pos) index-alist))
|
||
(ruby-accurate-end-of-block end)
|
||
(setq beg (point))
|
||
(setq index-alist
|
||
(nconc (ruby-imenu-create-index-in-block
|
||
(concat name (if sing "." "#"))
|
||
next beg) index-alist))
|
||
(goto-char beg))))
|
||
index-alist))
|
||
(defun ruby-imenu-create-index ()
|
||
... | ... | |
(let (state)
|
||
(or end (setq end (point-max)))
|
||
(while (and (setq state (apply 'ruby-parse-partial end state))
|
||
(>= (nth 2 state) 0) (< (point) end)))))
|
||
(>= (nth 2 state) 0) (< (point) end)))))
|
||
(defun ruby-mode-variables ()
|
||
(set-syntax-table ruby-mode-syntax-table)
|
||
... | ... | |
(when (re-search-forward "[^\0-\177]" nil t)
|
||
(goto-char (point-min))
|
||
(let ((coding-system
|
||
(or coding-system-for-write
|
||
buffer-file-coding-system)))
|
||
(if coding-system
|
||
(setq coding-system
|
||
(or (coding-system-get coding-system 'mime-charset)
|
||
(coding-system-change-eol-conversion coding-system nil))))
|
||
(setq coding-system
|
||
(if coding-system
|
||
(symbol-name
|
||
(or (and ruby-use-encoding-map
|
||
(cdr (assq coding-system ruby-encoding-map)))
|
||
coding-system))
|
||
"ascii-8bit"))
|
||
(if (looking-at "^#![^\n]*ruby") (beginning-of-line 2))
|
||
(cond ((looking-at "\\s *#.*-\*-\\s *\\(en\\)?coding\\s *:\\s *\\([-a-z0-9_]*\\)\\s *\\(;\\|-\*-\\)")
|
||
(unless (string= (match-string 2) coding-system)
|
||
(goto-char (match-beginning 2))
|
||
(delete-region (point) (match-end 2))
|
||
(and (looking-at "-\*-")
|
||
(let ((n (skip-chars-backward " ")))
|
||
(cond ((= n 0) (insert " ") (backward-char))
|
||
((= n -1) (insert " "))
|
||
((forward-char)))))
|
||
(insert coding-system)))
|
||
((looking-at "\\s *#.*coding\\s *[:=]"))
|
||
(t (insert "# -*- coding: " coding-system " -*-\n"))
|
||
)))))
|
||
(or coding-system-for-write
|
||
buffer-file-coding-system)))
|
||
(if coding-system
|
||
(setq coding-system
|
||
(or (coding-system-get coding-system 'mime-charset)
|
||
(coding-system-change-eol-conversion coding-system nil))))
|
||
(setq coding-system
|
||
(if coding-system
|
||
(symbol-name
|
||
(or (and ruby-use-encoding-map
|
||
(cdr (assq coding-system ruby-encoding-map)))
|
||
coding-system))
|
||
"ascii-8bit"))
|
||
(if (looking-at "^#![^\n]*ruby") (beginning-of-line 2))
|
||
(cond ((looking-at "\\s *#.*-\*-\\s *\\(en\\)?coding\\s *:\\s *\\([-a-z0-9_]*\\)\\s *\\(;\\|-\*-\\)")
|
||
(unless (string= (match-string 2) coding-system)
|
||
(goto-char (match-beginning 2))
|
||
(delete-region (point) (match-end 2))
|
||
(and (looking-at "-\*-")
|
||
(let ((n (skip-chars-backward " ")))
|
||
(cond ((= n 0) (insert " ") (backward-char))
|
||
((= n -1) (insert " "))
|
||
((forward-char)))))
|
||
(insert coding-system)))
|
||
((looking-at "\\s *#.*coding\\s *[:=]"))
|
||
(t (insert "# -*- coding: " coding-system " -*-\n"))
|
||
)))))
|
||
;;;###autoload
|
||
(defun ruby-mode ()
|
||
... | ... | |
(add-hook
|
||
(cond ((boundp 'before-save-hook)
|
||
(make-local-variable 'before-save-hook)
|
||
'before-save-hook)
|
||
((boundp 'write-contents-functions) 'write-contents-functions)
|
||
((boundp 'write-contents-hooks) 'write-contents-hooks))
|
||
(make-local-variable 'before-save-hook)
|
||
'before-save-hook)
|
||
((boundp 'write-contents-functions) 'write-contents-functions)
|
||
((boundp 'write-contents-hooks) 'write-contents-hooks))
|
||
'ruby-mode-set-encoding)
|
||
(set (make-local-variable 'font-lock-defaults) '((ruby-font-lock-keywords) nil nil))
|
||
... | ... | |
(defun ruby-indent-to (x)
|
||
(if x
|
||
(let (shift top beg)
|
||
(and (< x 0) (error "invalid nest"))
|
||
(setq shift (current-column))
|
||
(beginning-of-line)
|
||
(setq beg (point))
|
||
(back-to-indentation)
|
||
(setq top (current-column))
|
||
(skip-chars-backward " \t")
|
||
(if (>= shift top) (setq shift (- shift top))
|
||
(setq shift 0))
|
||
(if (and (bolp)
|
||
(= x top))
|
||
(move-to-column (+ x shift))
|
||
(move-to-column top)
|
||
(delete-region beg (point))
|
||
(beginning-of-line)
|
||
(indent-to x)
|
||
(move-to-column (+ x shift))))))
|
||
(and (< x 0) (error "invalid nest"))
|
||
(setq shift (current-column))
|
||
(beginning-of-line)
|
||
(setq beg (point))
|
||
(back-to-indentation)
|
||
(setq top (current-column))
|
||
(skip-chars-backward " \t")
|
||
(if (>= shift top) (setq shift (- shift top))
|
||
(setq shift 0))
|
||
(if (and (bolp)
|
||
(= x top))
|
||
(move-to-column (+ x shift))
|
||
(move-to-column top)
|
||
(delete-region beg (point))
|
||
(beginning-of-line)
|
||
(indent-to x)
|
||
(move-to-column (+ x shift))))))
|
||
(defun ruby-special-char-p (&optional pnt)
|
||
(setq pnt (or pnt (point)))
|
||
(let ((c (char-before pnt)) (b (and (< (point-min) pnt) (char-before (1- pnt)))))
|
||
(cond ((or (eq c ??) (eq c ?$)))
|
||
((and (eq c ?:) (or (not b) (eq (char-syntax b) ? ))))
|
||
((eq c ?\\) (eq b ??)))))
|
||
((and (eq c ?:) (or (not b) (eq (char-syntax b) ? ))))
|
||
((eq c ?\\) (eq b ??)))))
|
||
(defun ruby-expr-beg (&optional option)
|
||
(save-excursion
|
||
(store-match-data nil)
|
||
(let ((space (skip-chars-backward " \t"))
|
||
(start (point)))
|
||
(start (point)))
|
||
(cond
|
||
((bolp) t)
|
||
((progn
|
||
(forward-char -1)
|
||
(and (looking-at "\\?")
|
||
(or (eq (char-syntax (char-before (point))) ?w)
|
||
(ruby-special-char-p))))
|
||
nil)
|
||
(forward-char -1)
|
||
(and (looking-at "\\?")
|
||
(or (eq (char-syntax (char-before (point))) ?w)
|
||
(ruby-special-char-p))))
|
||
nil)
|
||
((and (eq option 'heredoc) (< space 0)) t)
|
||
((or (looking-at ruby-operator-re)
|
||
(looking-at "[\\[({,;]")
|
||
(and (looking-at "[!?]")
|
||
(or (not (eq option 'modifier))
|
||
(bolp)
|
||
(save-excursion (forward-char -1) (looking-at "\\Sw$"))))
|
||
(and (looking-at ruby-symbol-re)
|
||
(skip-chars-backward ruby-symbol-chars)
|
||
(cond
|
||
((looking-at (regexp-opt
|
||
(looking-at "[\\[({,;]")
|
||
(and (looking-at "[!?]")
|
||
(or (not (eq option 'modifier))
|
||
(bolp)
|
||
(save-excursion (forward-char -1) (looking-at "\\Sw$"))))
|
||
(and (looking-at ruby-symbol-re)
|
||
(skip-chars-backward ruby-symbol-chars)
|
||
(cond
|
||
((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)
|
||
(looking-at "[a-zA-Z][a-zA-z0-9_]* +%[^ \t]"))
|
||
((eq option 'expr-re)
|
||
(looking-at "[a-zA-Z][a-zA-z0-9_]* +/[^ \t]"))
|
||
(t nil)))))))))
|
||
(goto-char (match-end 0))
|
||
(not (looking-at "\\s_")))
|
||
((eq option 'expr-qstr)
|
||
(looking-at "[a-zA-Z][a-zA-z0-9_]* +%[^ \t]"))
|
||
((eq option 'expr-re)
|
||
(looking-at "[a-zA-Z][a-zA-z0-9_]* +/[^ \t]"))
|
||
(t nil)))))))))
|
||
(defun ruby-forward-string (term &optional end no-error expand)
|
||
(let ((n 1) (c (string-to-char term))
|
||
(re (if expand
|
||
(concat "[^\\]\\(\\\\\\\\\\)*\\([" term "]\\|\\(#{\\)\\)")
|
||
(concat "[^\\]\\(\\\\\\\\\\)*[" term "]"))))
|
||
(re (if expand
|
||
(concat "[^\\]\\(\\\\\\\\\\)*\\([" term "]\\|\\(#{\\)\\)")
|
||
(concat "[^\\]\\(\\\\\\\\\\)*[" term "]"))))
|
||
(while (and (re-search-forward re end no-error)
|
||
(if (match-beginning 3)
|
||
(ruby-forward-string "}{" end no-error nil)
|
||
(> (setq n (if (eq (char-before (point)) c)
|
||
(1- n) (1+ n))) 0)))
|
||
(if (match-beginning 3)
|
||
(ruby-forward-string "}{" end no-error nil)
|
||
(> (setq n (if (eq (char-before (point)) c)
|
||
(1- n) (1+ n))) 0)))
|
||
(forward-char -1))
|
||
(cond ((zerop n))
|
||
(no-error nil)
|
||
((error "unterminated string")))))
|
||
(no-error nil)
|
||
((error "unterminated string")))))
|
||
(defun ruby-deep-indent-paren-p (c)
|
||
(cond ((listp ruby-deep-indent-paren)
|
||
(let ((deep (assoc c ruby-deep-indent-paren)))
|
||
(cond (deep
|
||
(or (cdr deep) ruby-deep-indent-paren-style))
|
||
((memq c ruby-deep-indent-paren)
|
||
ruby-deep-indent-paren-style))))
|
||
((eq c ruby-deep-indent-paren) ruby-deep-indent-paren-style)
|
||
((eq c ?\( ) ruby-deep-arglist)))
|
||
(let ((deep (assoc c ruby-deep-indent-paren)))
|
||
(cond (deep
|
||
(or (cdr deep) ruby-deep-indent-paren-style))
|
||
((memq c ruby-deep-indent-paren)
|
||
ruby-deep-indent-paren-style))))
|
||
((eq c ruby-deep-indent-paren) ruby-deep-indent-paren-style)
|
||
((eq c ?\( ) ruby-deep-arglist)))
|
||
(defun ruby-parse-partial (&optional end in-string nest depth pcol indent)
|
||
(or depth (setq depth 0))
|
||
... | ... | |
(goto-char (match-beginning 0))
|
||
(cond
|
||
((and (memq (char-before) '(?@ ?$)) (looking-at "\\sw"))
|
||
(goto-char pnt))
|
||
((looking-at "[\"`]") ;skip string
|
||
(cond
|
||
((and (not (eobp))
|
||
(ruby-forward-string (buffer-substring (point) (1+ (point))) end t t))
|
||
nil)
|
||
(t
|
||
(setq in-string (point))
|
||
(goto-char end))))
|
||
(goto-char pnt))
|
||
((looking-at "[\"`]") ;skip string
|
||
(cond
|
||
((and (not (eobp))
|
||
(ruby-forward-string (buffer-substring (point) (1+ (point))) end t t))
|
||
nil)
|
||
(t
|
||
(setq in-string (point))
|
||
(goto-char end))))
|
||
((looking-at "'")
|
||
(cond
|
||
((and (not (eobp))
|
||
(re-search-forward "[^\\]\\(\\\\\\\\\\)*'" end t))
|
||
nil)
|
||
(t
|
||
(setq in-string (point))
|
||
(goto-char end))))
|
||
(cond
|
||
((and (not (eobp))
|
||
(re-search-forward "[^\\]\\(\\\\\\\\\\)*'" end t))
|
||
nil)
|
||
(t
|
||
(setq in-string (point))
|
||
(goto-char end))))
|
||
((looking-at "/=")
|
||
(goto-char pnt))
|
||
(goto-char pnt))
|
||
((looking-at "/")
|
||
(cond
|
||
((and (not (eobp)) (ruby-expr-beg 'expr-re))
|
||
(if (ruby-forward-string "/" end t t)
|
||
nil
|
||
(setq in-string (point))
|
||
(goto-char end)))
|
||
(t
|
||
(goto-char pnt))))
|
||
(cond
|
||
((and (not (eobp)) (ruby-expr-beg 'expr-re))
|
||
(if (ruby-forward-string "/" end t t)
|
||
nil
|
||
(setq in-string (point))
|
||
(goto-char end)))
|
||
(t
|
||
(goto-char pnt))))
|
||
((looking-at "%")
|
||
(cond
|
||
((and (not (eobp))
|
||
(ruby-expr-beg 'expr-qstr)
|
||
(not (looking-at "%="))
|
||
(looking-at "%[QqrxWw]?\\([^a-zA-Z0-9 \t\n]\\)"))
|
||
(goto-char (match-beginning 1))
|
||
(setq expand (not (memq (char-before) '(?q ?w))))
|
||
(setq w (match-string 1))
|
||
(cond
|
||
((string= w "[") (setq re "]["))
|
||
((string= w "{") (setq re "}{"))
|
||
((string= w "(") (setq re ")("))
|
||
((string= w "<") (setq re "><"))
|
||
((and expand (string= w "\\"))
|
||
(setq w (concat "\\" w))))
|
||
(unless (cond (re (ruby-forward-string re end t expand))
|
||
(expand (ruby-forward-string w end t t))
|
||
(t (re-search-forward
|
||
(if (string= w "\\")
|
||
"\\\\[^\\]*\\\\"
|
||
(concat "[^\\]\\(\\\\\\\\\\)*" w))
|
||
end t)))
|
||
(setq in-string (point))
|
||
(goto-char end)))
|
||
(t
|
||
(goto-char pnt))))
|
||
((looking-at "\\?") ;skip ?char
|
||
(cond
|
||
((and (ruby-expr-beg)
|
||
(looking-at "?\\(\\\\C-\\|\\\\M-\\)*\\\\?."))
|
||
(goto-char (match-end 0)))
|
||
(t
|
||
(goto-char pnt))))
|
||
((looking-at "\\$") ;skip $char
|
||
(goto-char pnt)
|
||
(forward-char 1))
|
||
((looking-at "#") ;skip comment
|
||
(forward-line 1)
|
||
(goto-char (point))
|
||
)
|
||
(cond
|
||
((and (not (eobp))
|
||
(ruby-expr-beg 'expr-qstr)
|
||
(not (looking-at "%="))
|
||
(looking-at "%[QqrxWw]?\\([^a-zA-Z0-9 \t\n]\\)"))
|
||
(goto-char (match-beginning 1))
|
||
(setq expand (not (memq (char-before) '(?q ?w))))
|
||
(setq w (match-string 1))
|
||
(cond
|
||
((string= w "[") (setq re "]["))
|
||
((string= w "{") (setq re "}{"))
|
||
((string= w "(") (setq re ")("))
|
||
((string= w "<") (setq re "><"))
|
||
((and expand (string= w "\\"))
|
||
(setq w (concat "\\" w))))
|
||
(unless (cond (re (ruby-forward-string re end t expand))
|
||
(expand (ruby-forward-string w end t t))
|
||
(t (re-search-forward
|
||
(if (string= w "\\")
|
||
"\\\\[^\\]*\\\\"
|
||
(concat "[^\\]\\(\\\\\\\\\\)*" w))
|
||
end t)))
|
||
(setq in-string (point))
|
||
(goto-char end)))
|
||
(t
|
||
(goto-char pnt))))
|
||
((looking-at "\\?") ;skip ?char
|
||
(cond
|
||
((and (ruby-expr-beg)
|
||
(looking-at "?\\(\\\\C-\\|\\\\M-\\)*\\\\?."))
|
||
(goto-char (match-end 0)))
|
||
(t
|
||
(goto-char pnt))))
|
||
((looking-at "\\$") ;skip $char
|
||
(goto-char pnt)
|
||
(forward-char 1))
|
||
((looking-at "#") ;skip comment
|
||
(forward-line 1)
|
||
(goto-char (point))
|
||
)
|
||
((looking-at "[\\[{(]")
|
||
(let ((deep (ruby-deep-indent-paren-p (char-after))))
|
||
(if (and deep (or (not (eq (char-after) ?\{)) (ruby-expr-beg)))
|
||
(progn
|
||
(and (eq deep 'space) (looking-at ".\\s +[^# \t\n]")
|
||
(setq pnt (1- (match-end 0))))
|
||
(setq nest (cons (cons (char-after (point)) pnt) nest))
|
||
(setq pcol (cons (cons pnt depth) pcol))
|
||
(setq depth 0))
|
||
(setq nest (cons (cons (char-after (point)) pnt) nest))
|
||
(setq depth (1+ depth))))
|
||
(goto-char pnt)
|
||
)
|
||
(let ((deep (ruby-deep-indent-paren-p (char-after))))
|
||
(if (and deep (or (not (eq (char-after) ?\{)) (ruby-expr-beg)))
|
||
(progn
|
||
(and (eq deep 'space) (looking-at ".\\s +[^# \t\n]")
|
||
(setq pnt (1- (match-end 0))))
|
||
(setq nest (cons (cons (char-after (point)) pnt) nest))
|
||
(setq pcol (cons (cons pnt depth) pcol))
|
||
(setq depth 0))
|
||
(setq nest (cons (cons (char-after (point)) pnt) nest))
|
||
(setq depth (1+ depth))))
|
||
(goto-char pnt)
|
||
)
|
||
((looking-at "[])}]")
|
||
(if (ruby-deep-indent-paren-p (matching-paren (char-after)))
|
||
(setq depth (cdr (car pcol)) pcol (cdr pcol))
|
||
(setq depth (1- depth)))
|
||
(setq nest (cdr nest))
|
||
(goto-char pnt))
|
||
(if (ruby-deep-indent-paren-p (matching-paren (char-after)))
|
||
(setq depth (cdr (car pcol)) pcol (cdr pcol))
|
||
(setq depth (1- depth)))
|
||
(setq nest (cdr nest))
|
||
(goto-char pnt))
|
||
((looking-at ruby-block-end-re)
|
||
(if (or (and (not (bolp))
|
||
(progn
|
||
(forward-char -1)
|
||
(setq w (char-after (point)))
|
||
(or (eq ?_ w)
|
||
(eq ?. w))))
|
||
(progn
|
||
(goto-char pnt)
|
||
(setq w (char-after (point)))
|
||
(or (eq ?_ w)
|
||
(eq ?! w)
|
||
(eq ?? w))))
|
||
nil
|
||
(setq nest (cdr nest))
|
||
(setq depth (1- depth)))
|
||
(goto-char pnt))
|
||
(if (or (and (not (bolp))
|
||
(progn
|
||
(forward-char -1)
|
||
(setq w (char-after (point)))
|
||
(or (eq ?_ w)
|
||
(eq ?. w))))
|
||
(progn
|
||
(goto-char pnt)
|
||
(setq w (char-after (point)))
|
||
(or (eq ?_ w)
|
||
(eq ?! w)
|
||
(eq ?? w))))
|
||
nil
|
||
(setq nest (cdr nest))
|
||
(setq depth (1- depth)))
|
||
(goto-char pnt))
|
||
((looking-at "def\\s +[^(\n;]*")
|
||
(if (or (bolp)
|
||
(progn
|
||
(forward-char -1)
|
||
(not (eq ?_ (char-after (point))))))
|
||
(progn
|
||
(setq nest (cons (cons nil pnt) nest))
|
||
(setq depth (1+ depth))))
|
||
(goto-char (match-end 0)))
|
||
(if (or (bolp)
|
||
(progn
|
||
(forward-char -1)
|
||
(not (eq ?_ (char-after (point))))))
|
||
(progn
|
||
(setq nest (cons (cons nil pnt) nest))
|
||
(setq depth (1+ depth))))
|
||
(goto-char (match-end 0)))
|
||
((looking-at (concat "\\<\\(" ruby-block-beg-re "\\)\\>"))
|
||
(and
|
||
(save-match-data
|
||
(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")
|
||
(goto-char (match-beginning 0))
|
||
(or (not (looking-at ruby-modifier-re))
|
||
(ruby-expr-beg 'modifier))
|
||
(goto-char pnt)
|
||
(setq nest (cons (cons nil pnt) nest))
|
||
(setq depth (1+ depth)))
|
||
(goto-char pnt))
|
||
(and
|
||
(save-match-data
|
||
(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")
|
||
(goto-char (match-beginning 0))
|
||
(or (not (looking-at ruby-modifier-re))
|
||
(ruby-expr-beg 'modifier))
|
||
(goto-char pnt)
|
||
(setq nest (cons (cons nil pnt) nest))
|
||
(setq depth (1+ depth)))
|
||
(goto-char pnt))
|
||
((looking-at ":\\(['\"]\\)")
|
||
(goto-char (match-beginning 1))
|
||
(ruby-forward-string (buffer-substring (match-beginning 1) (match-end 1)) end))
|
||
(goto-char (match-beginning 1))
|
||
(ruby-forward-string (buffer-substring (match-beginning 1) (match-end 1)) end))
|
||
((looking-at ":\\([-,.+*/%&|^~<>]=?\\|===?\\|<=>\\)")
|
||
(goto-char (match-end 0)))
|
||
(goto-char (match-end 0)))
|
||
((looking-at ":\\([a-zA-Z_][a-zA-Z_0-9]*[!?=]?\\)?")
|
||
(goto-char (match-end 0)))
|
||
(goto-char (match-end 0)))
|
||
((or (looking-at "\\.\\.\\.?")
|
||
(looking-at "\\.[0-9]+")
|
||
(looking-at "\\.[a-zA-Z_0-9]+")
|
||
(looking-at "\\."))
|
||
(goto-char (match-end 0)))
|
||
(looking-at "\\.[0-9]+")
|
||
(looking-at "\\.[a-zA-Z_0-9]+")
|
||
(looking-at "\\."))
|
||
(goto-char (match-end 0)))
|
||
((looking-at "^=begin")
|
||
(if (re-search-forward "^=end" end t)
|
||
(forward-line 1)
|
||
(setq in-string (match-end 0))
|
||
(goto-char end)))
|
||
(if (re-search-forward "^=end" end t)
|
||
(forward-line 1)
|
||
(setq in-string (match-end 0))
|
||
(goto-char end)))
|
||
((looking-at "<<")
|
||
(cond
|
||
((and (ruby-expr-beg 'heredoc)
|
||
(looking-at "<<\\(-\\)?\\(\\([\"'`]\\)\\([^\n]+?\\)\\3\\|\\(?:\\sw\\|\\s_\\)+\\)"))
|
||
(setq re (regexp-quote (or (match-string 4) (match-string 2))))
|
||
(if (match-beginning 1) (setq re (concat "\\s *" re)))
|
||
(let* ((id-end (goto-char (match-end 0)))
|
||
(line-end-position (save-excursion (end-of-line) (point)))
|
||
(state (list in-string nest depth pcol indent)))
|
||
;; parse the rest of the line
|
||
(while (and (> line-end-position (point))
|
||
(setq state (apply 'ruby-parse-partial
|
||
line-end-position state))))
|
||
(setq in-string (car state)
|
||
nest (nth 1 state)
|
||
depth (nth 2 state)
|
||
pcol (nth 3 state)
|
||
indent (nth 4 state))
|
||
;; skip heredoc section
|
||
(if (re-search-forward (concat "^" re "$") end 'move)
|
||
(forward-line 1)
|
||
(setq in-string id-end)
|
||
(goto-char end))))
|
||
(t
|
||
(goto-char pnt))))
|
||
(cond
|
||
((and (ruby-expr-beg 'heredoc)
|
||
(looking-at "<<\\(-\\)?\\(\\([\"'`]\\)\\([^\n]+?\\)\\3\\|\\(?:\\sw\\|\\s_\\)+\\)"))
|
||
(setq re (regexp-quote (or (match-string 4) (match-string 2))))
|
||
(if (match-beginning 1) (setq re (concat "\\s *" re)))
|
||
(let* ((id-end (goto-char (match-end 0)))
|
||
(line-end-position (save-excursion (end-of-line) (point)))
|
||
(state (list in-string nest depth pcol indent)))
|
||
;; parse the rest of the line
|
||
(while (and (> line-end-position (point))
|
||
(setq state (apply 'ruby-parse-partial
|
||
line-end-position state))))
|
||
(setq in-string (car state)
|
||
nest (nth 1 state)
|
||
depth (nth 2 state)
|
||
pcol (nth 3 state)
|
||
indent (nth 4 state))
|
||
;; skip heredoc section
|
||
(if (re-search-forward (concat "^" re "$") end 'move)
|
||
(forward-line 1)
|
||
(setq in-string id-end)
|
||
(goto-char end))))
|
||
(t
|
||
(goto-char pnt))))
|
||
((looking-at "^__END__$")
|
||
(goto-char pnt))
|
||
(goto-char pnt))
|
||
((looking-at ruby-here-doc-beg-re)
|
||
(if (re-search-forward (ruby-here-doc-end-match)
|
||
indent-point t)
|
||
(forward-line 1)
|
||
(setq in-string (match-end 0))
|
||
(goto-char indent-point)))
|
||
(if (re-search-forward (ruby-here-doc-end-match)
|
||
indent-point t)
|
||
(forward-line 1)
|
||
(setq in-string (match-end 0))
|
||
(goto-char indent-point)))
|
||
(t
|
||
(error (format "bad string %s"
|
||
(buffer-substring (point) pnt)
|
||
))))))
|
||
(error (format "bad string %s"
|
||
(buffer-substring (point) pnt)
|
||
))))))
|
||
(list in-string nest depth pcol))
|
||
(defun ruby-parse-region (start end)
|
||
(let (state)
|
||
(save-excursion
|
||
(if start
|
||
(goto-char start)
|
||
(ruby-beginning-of-indent))
|
||
(goto-char start)
|
||
(ruby-beginning-of-indent))
|
||
(save-restriction
|
||
(narrow-to-region (point) end)
|
||
(while (and (> end (point))
|
||
(setq state (apply 'ruby-parse-partial end state))))))
|
||
(list (nth 0 state) ; in-string
|
||
(car (nth 1 state)) ; nest
|
||
(nth 2 state) ; depth
|
||
(car (car (nth 3 state))) ; pcol
|
||
;(car (nth 5 state)) ; indent
|
||
)))
|
||
(narrow-to-region (point) end)
|
||
(while (and (> end (point))
|
||
(setq state (apply 'ruby-parse-partial end state))))))
|
||
(list (nth 0 state) ; in-string
|
||
(car (nth 1 state)) ; nest
|
||
(nth 2 state) ; depth
|
||
(car (car (nth 3 state))) ; pcol
|
||
;(car (nth 5 state)) ; indent
|
||
)))
|
||
(defun ruby-indent-size (pos nest)
|
||
(+ pos (* (or nest 1) ruby-indent-level)))
|
||
... | ... | |
(save-excursion
|
||
(beginning-of-line)
|
||
(let ((indent-point (point))
|
||
state bol eol begin op-end
|
||
(paren (progn (skip-syntax-forward " ")
|
||
(and (char-after) (matching-paren (char-after)))))
|
||
(indent 0))
|
||
state bol eol begin op-end
|
||
(paren (progn (skip-syntax-forward " ")
|
||
(and (char-after) (matching-paren (char-after)))))
|
||
(indent 0))
|
||
(if parse-start
|
||
(goto-char parse-start)
|
||
(ruby-beginning-of-indent)
|
||
(setq parse-start (point)))
|
||
(goto-char parse-start)
|
||
(ruby-beginning-of-indent)
|
||
(setq parse-start (point)))
|
||
(back-to-indentation)
|
||
(setq indent (current-column))
|
||
(setq state (ruby-parse-region parse-start indent-point))
|
||
(cond
|
||
((nth 0 state) ; within string
|
||
(setq indent nil)) ; do nothing
|
||
((car (nth 1 state)) ; in paren
|
||
(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 (eq (car (nth 1 state)) paren)
|
||
(ruby-deep-indent-paren-p (matching-paren paren))
|
||
(search-backward (char-to-string paren))
|
||
(setq indent (current-column)))))
|
||
((nth 0 state) ; within string
|
||
(setq indent nil)) ; do nothing
|
||
((car (nth 1 state)) ; in paren
|
||
(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 (eq (car (nth 1 state)) paren)
|
||
(ruby-deep-indent-paren-p (matching-paren paren))
|
||
(search-backward (char-to-string paren))
|
||
(setq indent (current-column)))))
|
||
((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
|
||
(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
|
||
(setq indent (+ (current-column) ruby-indent-level)))))
|
||
(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
|
||
(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
|
||
(setq indent (+ (current-column) ruby-indent-level)))))
|
||
|
||
((and (nth 2 state) (< (nth 2 state) 0)) ; in negative nest
|
||
(setq indent (ruby-indent-size (current-column) (nth 2 state)))))
|
||
(setq indent (ruby-indent-size (current-column) (nth 2 state)))))
|
||
(when indent
|
||
(goto-char indent-point)
|
||
(end-of-line)
|
||
(setq eol (point))
|
||
(beginning-of-line)
|
||
(cond
|
||
((and (not (ruby-deep-indent-paren-p paren))
|
||
(re-search-forward ruby-negative eol t))
|
||
(and (not (eq ?_ (char-after (match-end 0))))
|
||
(setq indent (- indent ruby-indent-level))))
|
||
((and
|
||
(save-excursion
|
||
(beginning-of-line)
|
||
(not (bobp)))
|
||
(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)
|
||
(skip-chars-backward " \t\n")
|
||
(setq end (point))
|
||
(beginning-of-line)
|
||
(if (re-search-forward "^\\s *#" end t)
|
||
(beginning-of-line)
|
||
(setq done t))))
|
||
(setq bol (point))
|
||
(end-of-line)
|
||
;; skip the comment at the end
|
||
(skip-chars-backward " \t")
|
||
(let (end (pos (point)))
|
||
(beginning-of-line)
|
||
(while (and (re-search-forward "#" pos t)
|
||
(setq end (1- (point)))
|
||
(or (ruby-special-char-p end)
|
||
(and (setq state (ruby-parse-region parse-start end))
|
||
(nth 0 state))))
|
||
(setq end nil))
|
||
(goto-char (or end pos))
|
||
(skip-chars-backward " \t")
|
||
(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
|
||
(or (and (looking-at ruby-symbol-re)
|
||
(skip-chars-backward ruby-symbol-chars)
|
||
(looking-at (concat "\\<\\(" ruby-block-hanging-re "\\)\\>"))
|
||
(not (eq (point) (nth 3 state)))
|
||
(save-excursion
|
||
(goto-char (match-end 0))
|
||
(not (looking-at "[a-z_]"))))
|
||
(and (looking-at ruby-operator-re)
|
||
(not (ruby-special-char-p))
|
||
;; operator at the end of line
|
||
(let ((c (char-after (point))))
|
||
(and
|
||
;; (or (null begin)
|
||
;; (save-excursion
|
||
;; (goto-char begin)
|
||
;; (skip-chars-forward " \t")
|
||
;; (not (or (eolp) (looking-at "#")
|
||
;; (and (eq (car (nth 1 state)) ?{)
|
||
;; (looking-at "|"))))))
|
||
(or (not (eq ?/ c))
|
||
(null (nth 0 (ruby-parse-region (or begin parse-start) (point)))))
|
||
(or (not (eq ?| (char-after (point))))
|
||
(save-excursion
|
||
(or (eolp) (forward-char -1))
|
||
(cond
|
||
((search-backward "|" nil t)
|
||
(skip-chars-backward " \t\n")
|
||
(and (not (eolp))
|
||
(progn
|
||
(forward-char -1)
|
||
(not (looking-at "{")))
|
||
(progn
|
||
(forward-word -1)
|
||
(not (looking-at "do\\>[^_]")))))
|
||
(t t))))
|
||
(not (eq ?, c))
|
||
(setq op-end t)))))
|
||
(setq indent
|
||
(cond
|
||
((and
|
||
(null op-end)
|
||
(not (looking-at (concat "\\<\\(" ruby-block-hanging-re "\\)\\>")))
|
||
(eq (ruby-deep-indent-paren-p t) 'space)
|
||
(not (bobp)))
|
||
(widen)
|
||
(goto-char (or begin parse-start))
|
||
(skip-syntax-forward " ")
|
||
(current-column))
|
||
((car (nth 1 state)) indent)
|
||
(t
|
||
(+ indent ruby-indent-level))))))))
|
||
(goto-char indent-point)
|
||
(end-of-line)
|
||
(setq eol (point))
|
||
(beginning-of-line)
|
||
(cond
|
||
((and (not (ruby-deep-indent-paren-p paren))
|
||
(re-search-forward ruby-negative eol t))
|
||
(and (not (eq ?_ (char-after (match-end 0))))
|
||
(setq indent (- indent ruby-indent-level))))
|
||
((and
|
||
(save-excursion
|
||
(beginning-of-line)
|
||
(not (bobp)))
|
||
(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)
|
||
(skip-chars-backward " \t\n")
|
||
(setq end (point))
|
||
(beginning-of-line)
|
||
(if (re-search-forward "^\\s *#" end t)
|
||
(beginning-of-line)
|
||
(setq done t))))
|
||
(setq bol (point))
|
||
(end-of-line)
|
||
;; skip the comment at the end
|
||
(skip-chars-backward " \t")
|
||
(let (end (pos (point)))
|
||
(beginning-of-line)
|
||
(while (and (re-search-forward "#" pos t)
|
||
(setq end (1- (point)))
|
||
(or (ruby-special-char-p end)
|
||
(and (setq state (ruby-parse-region parse-start end))
|
||
(nth 0 state))))
|
||
(setq end nil))
|
||
(goto-char (or end pos))
|
||
(skip-chars-backward " \t")
|
||
(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
|
||
(or (and (looking-at ruby-symbol-re)
|
||
(skip-chars-backward ruby-symbol-chars)
|
||
(looking-at (concat "\\<\\(" ruby-block-hanging-re "\\)\\>"))
|
||
(not (eq (point) (nth 3 state)))
|
||
(save-excursion
|
||
(goto-char (match-end 0))
|
||
(not (looking-at "[a-z_]"))))
|
||
(and (looking-at ruby-operator-re)
|
||
(not (ruby-special-char-p))
|
||
;; operator at the end of line
|
||
(let ((c (char-after (point))))
|
||
(and
|
||
;; (or (null begin)
|
||
;; (save-excursion
|
||
;; (goto-char begin)
|
||
;; (skip-chars-forward " \t")
|
||
;; (not (or (eolp) (looking-at "#")
|
||
;; (and (eq (car (nth 1 state)) ?{)
|
||
;; (looking-at "|"))))))
|
||
(or (not (eq ?/ c))
|
||
(null (nth 0 (ruby-parse-region (or begin parse-start) (point)))))
|
||
(or (not (eq ?| (char-after (point))))
|
||
(save-excursion
|
||
(or (eolp) (forward-char -1))
|
||
(cond
|
||
((search-backward "|" nil t)
|
||
(skip-chars-backward " \t\n")
|
||
(and (not (eolp))
|
||
(progn
|
||
(forward-char -1)
|
||
(not (looking-at "{")))
|
||
(progn
|
||
(forward-word -1)
|
||
(not (looking-at "do\\>[^_]")))))
|
||
(t t))))
|
||
(not (eq ?, c))
|
||
(setq op-end t)))))
|
||
(setq indent
|
||
(cond
|
||
((and
|
||
(null op-end)
|
||
(not (looking-at (concat "\\<\\(" ruby-block-hanging-re "\\)\\>")))
|
||
(eq (ruby-deep-indent-paren-p t) 'space)
|
||
(not (bobp)))
|
||
(widen)
|
||
(goto-char (or begin parse-start))
|
||
(skip-syntax-forward " ")
|
||
(current-column))
|
||
((car (nth 1 state)) indent)
|
||
(t
|
||
(+ indent ruby-indent-level))))))))
|
||
(goto-char indent-point)
|
||
(beginning-of-line)
|
||
(skip-syntax-forward " ")
|
||
(if (looking-at "\\.[^.]")
|
||
(+ indent ruby-indent-level)
|
||
indent))))
|
||
(+ indent ruby-indent-level)
|
||
indent))))
|
||
(defun ruby-electric-brace (arg)
|
||
(interactive "P")
|
||
... | ... | |
(defmacro defun-region-command (func args &rest body)
|
||
(let ((intr (car body)))
|
||
(when (featurep 'xemacs)
|
||
(if (stringp intr) (setq intr (cadr body)))
|
||
(and (eq (car intr) 'interactive)
|
||
(setq intr (cdr intr))
|