From 7e1549c91db69fab8818318112f8a793d50ad731 Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Thu, 19 Dec 2013 06:21:44 +0200 Subject: [PATCH] * lisp/progmodes/ruby-mode.el (ruby-smie--args-separator-p): Allow the first arg to be a string (fixed dead code), or an operator symbol. (ruby-smie--forward-token): Tokenize ` @ ' before strings and operator symbols. (ruby-smie-rules): Remove parent token check in the `.' clause, it did nothing. Don't respond to `(:after ".")', it will be called with :before anyway. Remove the ` @ ' rule, it didn't seem to change anything. Only return indentation for binary operators when they are hanging. De-dent opening paren when its parent is `.', otherwise it looks bad when the dot is not at bol or eol. Fixes: debbugs:16182 --- lisp/ChangeLog | 14 +++++++++++++ lisp/progmodes/ruby-mode.el | 42 +++++++++++++++++++------------------ test/indent/ruby.rb | 23 ++++++++++++++------ 3 files changed, 53 insertions(+), 26 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 3599830ae4b..09d4cebb6f5 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,17 @@ +2013-12-19 Dmitry Gutov + + * progmodes/ruby-mode.el (ruby-smie--args-separator-p): Allow the + first arg to be a string (fixed dead code), or an operator symbol. + (ruby-smie--forward-token): Tokenize ` @ ' before strings and + operator symbols. + (ruby-smie-rules): Remove parent token check in the `.' clause, it + did nothing. Don't respond to `(:after ".")', it will be called + with :before anyway. Remove the ` @ ' rule, it didn't seem to + change anything. Only return indentation for binary operators + when they are hanging. De-dent opening paren when its parent is + `.', otherwise it looks bad when the dot is not at bol or eol + (bug#16182). + 2013-12-19 Juri Linkov * replace.el (query-replace-read-args): Split a non-negative arg diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index 54eba5b9164..e291acec327 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -411,8 +411,8 @@ It is used when `ruby-encoding-magic-comment-style' is set to `custom'." (not (looking-at (regexp-opt '("unless" "if" "while" "until" "or" "else" "elsif" "do" "end" "and") 'symbols)))) - (memq (syntax-after pos) '(7 15)) - (looking-at "[([]\\|[-+!~:]\\sw"))))) + (memq (car (syntax-after pos)) '(7 15)) + (looking-at "[([]\\|[-+!~]\\sw\\|:\\(?:\\sw\\|\\s.\\)"))))) (defun ruby-smie--at-dot-call () (and (eq ?w (char-syntax (following-char))) @@ -423,12 +423,10 @@ It is used when `ruby-encoding-magic-comment-style' is set to `custom'." (let ((pos (point))) (skip-chars-forward " \t") (cond - ((looking-at "\\s\"") ;A heredoc or a string. - (if (not (looking-at "\n")) - "" - ;; Tokenize the whole heredoc as semicolon. - (goto-char (scan-sexps (point) 1)) - ";")) + ((and (looking-at "\n") (looking-at "\\s\"")) ;A heredoc. + ;; Tokenize the whole heredoc as semicolon. + (goto-char (scan-sexps (point) 1)) + ";") ((and (looking-at "[\n#]") (ruby-smie--implicit-semi-p)) ;Only add implicit ; when needed. (if (eolp) (forward-char 1) (forward-comment 1)) @@ -436,12 +434,13 @@ It is used when `ruby-encoding-magic-comment-style' is set to `custom'." (t (forward-comment (point-max)) (cond - ((looking-at ":\\s.+") - (goto-char (match-end 0)) (match-string 0)) ;; bug#15208. ((and (< pos (point)) (save-excursion (ruby-smie--args-separator-p (prog1 (point) (goto-char pos))))) " @ ") + ((looking-at ":\\s.+") + (goto-char (match-end 0)) (match-string 0)) ;bug#15208. + ((looking-at "\\s\"") "") ;A string. (t (let ((dot (ruby-smie--at-dot-call)) (tok (smie-default-forward-token))) @@ -549,11 +548,15 @@ It is used when `ruby-encoding-magic-comment-style' is set to `custom'." (ruby-smie--indent-to-stmt)) ((smie-rule-hanging-p) ;; Treat purely syntactic block-constructs as being part of their parent, - ;; when the opening token is hanging and the parent is not an open-paren. - (let ((state (smie-backward-sexp 'halfsexp))) - (unless (and (eq t (car state)) - (not (eq (cadr state) (point-min)))) - (cons 'column (smie-indent-virtual))))))) + ;; when the opening token is hanging and the parent is not an + ;; open-paren. + (cond + ((eq (car (smie-indent--parent)) t) nil) + ;; When after `.', let's always de-indent, + ;; because when `.' is inside the line, the + ;; additional indentation from it looks out of place. + ((smie-rule-parent-p ".") (smie-rule-parent (- ruby-indent-level))) + (t (smie-rule-parent)))))) (`(:after . ,(or `"(" "[" "{")) ;; FIXME: Shouldn't this be the default behavior of ;; `smie-indent-after-keyword'? @@ -564,11 +567,8 @@ It is used when `ruby-encoding-magic-comment-style' is set to `custom'." ;; because we want to reject hanging tokens at bol, too. (unless (or (eolp) (forward-comment 1)) (cons 'column (current-column))))) - (`(:after . " @ ") (smie-rule-parent)) (`(:before . "do") (ruby-smie--indent-to-stmt)) - (`(,(or :before :after) . ".") - (unless (smie-rule-parent-p ".") - (smie-rule-parent ruby-indent-level))) + (`(:before . ".") ruby-indent-level) (`(:before . ,(or `"else" `"then" `"elsif" `"rescue" `"ensure")) 0) (`(:before . ,(or `"when")) (if (not (smie-rule-sibling-p)) 0)) ;; ruby-indent-level @@ -576,7 +576,9 @@ It is used when `ruby-encoding-magic-comment-style' is set to `custom'." "<=>" ">" "<" ">=" "<=" "==" "===" "!=" "<<" ">>" "+=" "-=" "*=" "/=" "%=" "**=" "&=" "|=" "^=" "|" "<<=" ">>=" "&&=" "||=" "and" "or")) - (if (smie-rule-parent-p ";" nil) ruby-indent-level)) + (and (smie-rule-parent-p ";" nil) + (smie-indent--hanging-p) + ruby-indent-level)) (`(:after . ,(or "?" ":")) ruby-indent-level) (`(:before . "begin") (unless (save-excursion (skip-chars-backward " \t") (bolp)) diff --git a/test/indent/ruby.rb b/test/indent/ruby.rb index c132b01fd86..0bf4bc14fbb 100644 --- a/test/indent/ruby.rb +++ b/test/indent/ruby.rb @@ -51,12 +51,12 @@ }) bar = foo( - a, [ - 1, - ], - :qux => [ - 3 - ]) + a, [ + 1, + ], + :qux => [ + 3 + ]) foo( [ @@ -219,6 +219,9 @@ def foo c, :d => :e, f: g +desc "abc", + defg + it "is a method call with block" do |asd| foo end @@ -334,3 +337,11 @@ def qux qux = foo ? bar : tee + +zoo.keep.bar!( + {x: y, + z: t}) + +zoo + .lose( + q, p)