diff options
Diffstat (limited to 'lisp')
-rw-r--r-- | lisp/ChangeLog | 11 | ||||
-rw-r--r-- | lisp/progmodes/ruby-mode.el | 42 |
2 files changed, 48 insertions, 5 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index ec6991504bb..3f957874fc4 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,14 @@ +2013-08-29 Stefan Monnier <monnier@iro.umontreal.ca> + + * progmodes/ruby-mode.el (ruby-smie-grammar): Add rule for formal + params of lambda expressions. + (ruby-smie--implicit-semi-p): Refine rule (bug#15208). + (ruby-smie--opening-pipe-p): New function. + (ruby-smie--forward-token, ruby-smie--backward-token): Handle Ruby + symbols and matched |...| for formal params. + (ruby-smie-rules): Don't let the formal params of a "do" prevent it + from being treated as hanging. Handle "rescue". + 2013-08-29 Glenn Morris <rgm@gnu.org> * progmodes/cc-engine.el (c-pull-open-brace): diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index c8fae7ba1e6..7ecd207f4dc 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -254,11 +254,13 @@ Also ignores spaces after parenthesis when 'space." ("for" for-body "end") ("[" expseq "]") ("{" hashvals "}") + ("{" insts "}") ("while" insts "end") ("until" insts "end") ("unless" insts "end") ("if" if-body "end") ("case" cases "end")) + (formal-params ("opening-|" exp "|")) (for-body (for-head ";" insts)) (for-head (id "in" exp)) (cases (exp "then" insts) ;; FIXME: Ruby also allows (exp ":" insts). @@ -285,10 +287,20 @@ Also ignores spaces after parenthesis when 'space." (save-excursion (skip-chars-backward " \t") (not (or (bolp) - (memq (char-before) '(?\; ?- ?+ ?* ?/ ?:)) + (and (memq (char-before) '(?\; ?- ?+ ?* ?/ ?: ?.)) + ;; Make sure it's not the end of a regexp. + (not (eq (car (syntax-after (1- (point)))) 7))) (and (memq (char-before) '(?\? ?=)) - (not (memq (char-syntax (char-before (1- (point)))) - '(?w ?_)))))))) + (let ((tok (ruby-smie--backward-token))) + (or (equal tok "?") + (string-match "\\`\\s." tok)))))))) + +(defun ruby-smie--opening-pipe-p () + (save-excursion + (if (eq ?| (char-before)) (forward-char -1)) + (skip-chars-backward " \t\n") + (or (eq ?\{ (char-before)) + (looking-back "\\_<do" (- (point) 2))))) (defun ruby-smie--forward-token () (skip-chars-forward " \t") @@ -299,12 +311,16 @@ Also ignores spaces after parenthesis when 'space." (if (eolp) (forward-char 1) (forward-comment 1)) ";") (forward-comment (point-max)) + (if (looking-at ":\\s.+") + (progn (goto-char (match-end 0)) (match-string 0)) ;; bug#15208. (let ((tok (smie-default-forward-token))) (cond ((member tok '("unless" "if" "while" "until")) (if (save-excursion (forward-word -1) (ruby-smie--bosp)) tok "iuwu-mod")) - (t tok))))) + ((equal tok "|") + (if (ruby-smie--opening-pipe-p) "opening-|" tok)) + (t tok)))))) (defun ruby-smie--backward-token () (let ((pos (point))) @@ -314,10 +330,14 @@ Also ignores spaces after parenthesis when 'space." (progn (skip-chars-forward " \t") ";") (let ((tok (smie-default-backward-token))) + (when (and (eq ?: (char-before)) (string-match "\\`\\s." tok)) + (forward-char -1) (setq tok (concat ":" tok))) ;; bug#15208. (cond ((member tok '("unless" "if" "while" "until")) (if (ruby-smie--bosp) tok "iuwu-mod")) + ((equal tok "|") + (if (ruby-smie--opening-pipe-p) "opening-|" tok)) (t tok)))))) (defun ruby-smie-rules (kind token) @@ -332,7 +352,19 @@ Also ignores spaces after parenthesis when 'space." ;; For (invalid) code between switch and case. ;; (if (smie-parent-p "switch") 4) 0)) - (`(:before . ,(or `"else" `"then" `"elsif")) 0) + (`(:before . "do") + (when + (save-excursion + (forward-word 1) ;Skip "do" + (skip-chars-forward " \t") + (and (equal (save-excursion (ruby-smie--forward-token)) "opening-|") + (save-excursion (forward-sexp 1) + (skip-chars-forward " \t") + (or (eolp) + (looking-at comment-start-skip))))) + ;; `(column . ,(smie-indent-virtual)) + (smie-rule-parent))) + (`(:before . ,(or `"else" `"then" `"elsif" `"rescue")) 0) (`(:before . ,(or `"when")) (if (not (smie-rule-sibling-p)) 0)) ;; ruby-indent-level ;; Hack attack: Since newlines are separators, don't try to align args that |