unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#12169: [PATCH] Merge changes from upstream ruby-mode
@ 2012-08-10  0:36 Dmitry Gutov
       [not found] ` <handler.12169.B.13445594689259.ack@debbugs.gnu.org>
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Dmitry Gutov @ 2012-08-10  0:36 UTC (permalink / raw)
  To: 12169

[-- Attachment #1: Type: text/plain, Size: 214 bytes --]

This is part 1, 1 or 2 more to come.

The change to `ruby-syntax-propertize-function' is kind of messy, but I 
don't see how to do it better without seriously rewriting 
`ruby-syntax-propertize-heredoc'.

--Dmitry

[-- Attachment #2: ruby-upstream-1.diff --]
[-- Type: text/plain, Size: 7666 bytes --]

diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 635456a..38379cd 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,17 @@
+2012-08-09  Dmitry Gutov  <dgutov@yandex.ru>
+
+	Merge stuff from upsteam ruby-mode, part 1.
+
+	* progmodes/ruby-mode.el (ruby-mode-map): Remove deprecated
+	binding (use `M-;' instead).
+	(ruby-expr-beg, ruby-parse-partial): ?, _, and : are symbol
+	constituents, ! is not (but kinda should be).
+	(ruby-singleton-class-p): New function.
+	(ruby-expr-beg, ruby-in-here-doc-p)
+	(ruby-syntax-propertize-heredoc): Use it.
+	(ruby-syntax-propertize-function): Adjust for changes in
+	`ruby-syntax-propertize-heredoc'.
+
 2012-08-07  Andreas Schwab  <schwab@linux-m68k.org>
 
 	* calc/calc-prog.el (math-do-defmath): Use backquote forms.  Fix
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 091a7b7..68abaff 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -151,7 +151,6 @@ This should only be called after matching against `ruby-here-doc-beg-re'."
     (define-key map (kbd "C-M-h") 'backward-kill-word)
     (define-key map (kbd "C-j")   'reindent-then-newline-and-indent)
     (define-key map (kbd "C-m")   'newline)
-    (define-key map (kbd "C-c C-c") 'comment-region)
     map)
   "Keymap used in Ruby mode.")
 
@@ -380,11 +379,19 @@ and `\\' when preceded by `?'."
           ((and (eq c ?:) (or (not b) (eq (char-syntax b) ? ))))
           ((eq c ?\\) (eq b ??)))))
 
+(defun ruby-singleton-class-p (&optional pos)
+  (save-excursion
+    (when pos (goto-char pos))
+    (forward-word -1)
+    (and (or (bolp) (not (eq (char-before (point)) ?_)))
+         (looking-at "class\\s *<<"))))
+
 (defun ruby-expr-beg (&optional option)
   "TODO: document."
   (save-excursion
     (store-match-data nil)
-    (let ((space (skip-chars-backward " \t")))
+    (let ((space (skip-chars-backward " \t"))
+          (start (point)))
       (cond
        ((bolp) t)
        ((progn
@@ -393,7 +400,8 @@ and `\\' when preceded by `?'."
                (or (eq (char-syntax (char-before (point))) ?w)
                    (ruby-special-char-p))))
         nil)
-       ((and (eq option 'heredoc) (< space 0)) t)
+       ((and (eq option 'heredoc) (< space 0))
+        (not (progn (goto-char start) (ruby-singleton-class-p))))
        ((or (looking-at ruby-operator-re)
             (looking-at "[\\[({,;]")
             (and (looking-at "[!?]")
@@ -409,7 +417,7 @@ and `\\' when preceded by `?'."
                                         ruby-block-mid-keywords)
                                 'words))
                    (goto-char (match-end 0))
-                   (not (looking-at "\\s_")))
+                   (not (looking-at "\\s_\\|!")))
                   ((eq option 'expr-qstr)
                    (looking-at "[a-zA-Z][a-zA-z0-9_]* +%[^ \t]"))
                   ((eq option 'expr-re)
@@ -581,9 +589,7 @@ and `\\' when preceded by `?'."
                         (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))
@@ -1159,7 +1165,10 @@ See `add-log-current-defun-function'."
           ("^\\(=\\)begin\\_>" (1 "!"))
           ;; Handle here documents.
           ((concat ruby-here-doc-beg-re ".*\\(\n\\)")
-           (7 (prog1 "\"" (ruby-syntax-propertize-heredoc end))))
+           (7 (unless (ruby-singleton-class-p (match-beginning 0))
+                (put-text-property (match-beginning 7) (match-end 7)
+                                   'syntax-table (string-to-syntax "\""))
+                (ruby-syntax-propertize-heredoc end))))
           ;; Handle percent literals: %w(), %q{}, etc.
           ("\\(?:^\\|[[ \t\n<+(,=]\\)\\(%\\)[qQrswWx]?\\([[:punct:]]\\)"
            (1 (prog1 "|" (ruby-syntax-propertize-general-delimiters end)))))
@@ -1174,7 +1183,8 @@ See `add-log-current-defun-function'."
               (beginning-of-line)
               (while (re-search-forward ruby-here-doc-beg-re
                                         (line-end-position) t)
-                (push (concat (ruby-here-doc-end-match) "\n") res)))
+                (unless (ruby-singleton-class-p (match-beginning 0))
+                  (push (concat (ruby-here-doc-end-match) "\n") res))))
             (let ((start (point)))
               ;; With multiple openers on the same line, we don't know in which
               ;; part `start' is, so we have to go back to the beginning.
@@ -1310,7 +1320,8 @@ isn't in a string or another comment."
       (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)
+          (while (and (re-search-backward ruby-here-doc-beg-re nil t)
+                      (not (ruby-singleton-class-p)))
             (if (not (or (ruby-in-ppss-context-p 'anything)
                          (ruby-here-doc-find-end old-point)))
                 (throw 'found-beg t)))))))
diff --git a/test/ChangeLog b/test/ChangeLog
index 03d43d7..86f3019 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,9 @@
+2012-08-09  Dmitry Gutov  <dgutov@yandex.ru>
+
+	* automated/ruby-mode-tests.el (ruby-should-indent)
+	(ruby-assert-state): New functions.
+	Add new tests.
+
 2012-07-29  David Engster  <deng@randomsample.de>
 
 	* automated/xml-parse-tests.el (xml-parse-tests--qnames): New
diff --git a/test/automated/ruby-mode-tests.el b/test/automated/ruby-mode-tests.el
index 1a91f51..fbe1b8d 100644
--- a/test/automated/ruby-mode-tests.el
+++ b/test/automated/ruby-mode-tests.el
@@ -23,16 +23,39 @@
 
 (require 'ruby-mode)
 
-(ert-deftest indent-line-after-symbol-made-from-string-interpolation ()
+(defun ruby-should-indent (content column)
+  (with-temp-buffer
+    (insert content)
+    (ruby-mode)
+    (ruby-indent-line)
+    (should (= (current-column) column))))
+
+(defun ruby-assert-state (content &rest values-plist)
+  "Assert syntax state values at the end of CONTENT.
+
+VALUES-PLIST is a list with alternating index and value elements."
+  (with-temp-buffer
+    (insert content)
+    (ruby-mode)
+    (syntax-propertize (point))
+    (while values-plist
+      (should (eq (nth (car values-plist)
+                       (parse-partial-sexp (point-min) (point)))
+                  (cadr values-plist)))
+      (setq values-plist (cddr values-plist)))))
+
+(ert-deftest ruby-indent-after-symbol-made-from-string-interpolation ()
   "It can indent the line after symbol made using string interpolation."
-  (let ((initial-content "def foo(suffix)\n  :\"bar#{suffix}\"\n")
-        (expected-content "def foo(suffix)\n  :\"bar#{suffix}\"\n  "))
-    (with-temp-buffer
-      (insert initial-content)
-      (ruby-indent-line) ; Doesn't rely on text properties or the syntax table.
-      (let ((buffer-content (buffer-substring-no-properties (point-min)
-                                                            (point-max))))
-        (should (string= buffer-content expected-content))))))
+  (ruby-should-indent "def foo(suffix)\n  :\"bar#{suffix}\"\n"
+                      ruby-indent-level))
+
+(ert-deftest ruby-indent-after-js-style-symbol-with-block-beg-name ()
+  "JS-style hash symbol can have keyword name."
+  (ruby-should-indent "link_to \"home\", home_path, class: \"foo\"\n" 0))
+
+(ert-deftest ruby-discern-singleton-class-from-heredoc ()
+  (ruby-assert-state "foo <<asd\n" 3 ?\n)
+  (ruby-assert-state "class <<asd\n" 3 nil))
 
 (provide 'ruby-mode-tests)
 

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* bug#12169: Acknowledgement ([PATCH] Merge changes from upstream ruby-mode)
       [not found] ` <handler.12169.B.13445594689259.ack@debbugs.gnu.org>
@ 2012-08-10 14:52   ` Dmitry Gutov
  0 siblings, 0 replies; 7+ messages in thread
From: Dmitry Gutov @ 2012-08-10 14:52 UTC (permalink / raw)
  To: 12169

[-- Attachment #1: Type: text/plain, Size: 693 bytes --]

Here's part 2, in which I'm skipping the next 3 commits:

https://github.com/ruby/ruby/commit/85df40e9ab4559cd4ddde3f106ab56c76a808cc8
https://github.com/ruby/ruby/commit/6b0dc7fd81b25bc66681548b8b82f38258f7e08c
https://github.com/ruby/ruby/commit/862048e28d26112af1e67205cfd1c16564590bce

Because as far as I can tell, they hijack the `ruby-deep-indent-paren' 
behavior. IOW, with these applied, the indentation works as though the 
above variable is always nil (with a small improvement in the nested 
case, to be fair), so they don't make sense.

Instead, I added two tests, for `ruby-deep-indent-paren' enabled and 
disabled, and also ported all examples from test/misc/test_ruby_mode.rb.

[-- Attachment #2: ruby-upstream-2.diff --]
[-- Type: text/plain, Size: 4249 bytes --]

diff --git a/test/ChangeLog b/test/ChangeLog
index 86f3019..c59c3cb 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,11 @@
+2012-08-10  Dmitry Gutov  <dgutov@yandex.ru>
+
+	* automated/ruby-mode-tests.el (ruby-should-indent): Add
+	docstring, check (current-indentation) instead of (current-column).
+	(ruby-should-indent-buffer): New function.
+	Add tests for `ruby-deep-indent-paren' behavior.
+	Port all tests from test/misc/test_ruby_mode.rb in Ruby repo.
+
 2012-08-09  Dmitry Gutov  <dgutov@yandex.ru>
 
 	* automated/ruby-mode-tests.el (ruby-should-indent)
diff --git a/test/automated/ruby-mode-tests.el b/test/automated/ruby-mode-tests.el
index fbe1b8d..f91b6e4 100644
--- a/test/automated/ruby-mode-tests.el
+++ b/test/automated/ruby-mode-tests.el
@@ -24,11 +24,24 @@
 (require 'ruby-mode)
 
 (defun ruby-should-indent (content column)
+  "Assert indentation COLUMN on the last line of CONTENT."
   (with-temp-buffer
     (insert content)
     (ruby-mode)
     (ruby-indent-line)
-    (should (= (current-column) column))))
+    (should (= (current-indentation) column))))
+
+(defun ruby-should-indent-buffer (expected content)
+  "Assert that CONTENT turns into EXPECTED after the buffer is re-indented.
+
+The whitespace before and including \"|\" on each line is removed."
+  (with-temp-buffer
+    (cl-flet ((fix-indent (s) (replace-regexp-in-string "^[ \t]*|" "" s)))
+      (insert (fix-indent content))
+      (ruby-mode)
+      (indent-region (point-min) (point-max))
+      (should (string= (fix-indent expected) (buffer-substring-no-properties
+                                              (point-min) (point-max)))))))
 
 (defun ruby-assert-state (content &rest values-plist)
   "Assert syntax state values at the end of CONTENT.
@@ -57,6 +70,127 @@ VALUES-PLIST is a list with alternating index and value elements."
   (ruby-assert-state "foo <<asd\n" 3 ?\n)
   (ruby-assert-state "class <<asd\n" 3 nil))
 
+(ert-deftest ruby-deep-indent ()
+  (let ((ruby-deep-arglist nil)
+        (ruby-deep-indent-paren '(?\( ?\{ ?\[ ?\] t)))
+    (ruby-should-indent "foo = [1,\n2" 7)
+    (ruby-should-indent "foo = {a: b,\nc: d" 7)
+    (ruby-should-indent "foo(a,\nb" 4)))
+
+(ert-deftest ruby-deep-indent-disabled ()
+  (let ((ruby-deep-arglist nil)
+        (ruby-deep-indent-paren nil))
+    (ruby-should-indent "foo = [\n1" ruby-indent-level)
+    (ruby-should-indent "foo = {\na: b" ruby-indent-level)
+    (ruby-should-indent "foo(\na" ruby-indent-level)))
+
+(ert-deftest ruby-indent-simple ()
+  (ruby-should-indent-buffer
+   "if foo
+   |  bar
+   |end
+   |zot
+   |"
+   "if foo
+   |bar
+   |  end
+   |    zot
+   |"))
+
+(ert-deftest ruby-indent-keyword-label ()
+  (ruby-should-indent-buffer
+   "bar(class: XXX) do
+   |  foo
+   |end
+   |bar
+   |"
+   "bar(class: XXX) do
+   |     foo
+   |  end
+   |    bar
+   |"))
+
+(ert-deftest ruby-indent-method-with-question-mark ()
+  (ruby-should-indent-buffer
+   "if x.is_a?(XXX)
+   |  foo
+   |end
+   |"
+   "if x.is_a?(XXX)
+   | foo
+   |   end
+   |"))
+
+(ert-deftest ruby-indent-expr-in-regexp ()
+  (ruby-should-indent-buffer
+   "if /#{foo}/ =~ s
+   |  x = 1
+   |end
+   |"
+   "if /#{foo}/ =~ s
+   | x = 1
+   |  end
+   |"))
+
+(ert-deftest ruby-indent-singleton-class ()
+  :expected-result :failed   ; Doesn't work yet, when no space before "<<".
+  (ruby-should-indent-buffer
+   "class<<bar
+   |  foo
+   |end
+   |"
+   "class<<bar
+   |foo
+   |   end
+   |"))
+
+(ert-deftest ruby-indent-array-literal ()
+  (let ((ruby-deep-indent-paren nil))
+    (ruby-should-indent-buffer
+     "foo = [
+     |  bar
+     |]
+     |"
+     "foo = [
+     | bar
+     |  ]
+     |"))
+  (ruby-should-indent-buffer
+   "foo do
+   |  [bar]
+   |end
+   |"
+   "foo do
+   |[bar]
+   |  end
+   |"))
+
+(ert-deftest ruby-indent-begin-end ()
+  (ruby-should-indent-buffer
+   "begin
+   |  a[b]
+   |end
+   |"
+   "begin
+   | a[b]
+   |  end
+   |"))
+
+(ert-deftest ruby-indent-array-after-paren-and-space ()
+  (ruby-should-indent-buffer
+   "class A
+   |  def foo
+   |    foo( [])
+   |  end
+   |end
+   |"
+   "class A
+   | def foo
+   |foo( [])
+   |end
+   |  end
+   |"))
+
 (provide 'ruby-mode-tests)
 
 ;;; ruby-mode-tests.el ends here

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* bug#12169: [PATCH] Merge changes from upstream ruby-mode
  2012-08-10  0:36 bug#12169: [PATCH] Merge changes from upstream ruby-mode Dmitry Gutov
       [not found] ` <handler.12169.B.13445594689259.ack@debbugs.gnu.org>
@ 2012-08-10 15:54 ` Glenn Morris
  2012-08-10 20:28 ` Stefan Monnier
  2 siblings, 0 replies; 7+ messages in thread
From: Glenn Morris @ 2012-08-10 15:54 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: 12169


Thanks for this. Are you also the upstream author?
If not, please adjust the ChangeLog entries so that each change has the
correct author (the upstream author for each change, plus you if you did
non-trivial adaptation of a change).





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#12169: [PATCH] Merge changes from upstream ruby-mode
  2012-08-10  0:36 bug#12169: [PATCH] Merge changes from upstream ruby-mode Dmitry Gutov
       [not found] ` <handler.12169.B.13445594689259.ack@debbugs.gnu.org>
  2012-08-10 15:54 ` bug#12169: [PATCH] Merge changes from upstream ruby-mode Glenn Morris
@ 2012-08-10 20:28 ` Stefan Monnier
  2012-08-10 22:15   ` Dmitry Gutov
  2 siblings, 1 reply; 7+ messages in thread
From: Stefan Monnier @ 2012-08-10 20:28 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: 12169

> The change to `ruby-syntax-propertize-function' is kind of messy, but
> I don't see how to do it better without seriously rewriting
> ruby-syntax-propertize-heredoc'.

I think it can be simplified by adding a "\\(\\_<class\\s-*\\)?" pattern to
the here-doc regexp, but that only works for forward searches (which is
what is used in ruby-syntax-propertize but not in the
font-lock-syntactic-keywords code).  So it's probably fine as it is.

I've installed your patch, but please fix the ChangeLog authorship as
pointed out by Glenn (just include the changes in a subsequent patch).

> Here's part 2, in which I'm skipping the next 3 commits:
> https://github.com/ruby/ruby/commit/85df40e9ab4559cd4ddde3f106ab56c76a808cc8
> https://github.com/ruby/ruby/commit/6b0dc7fd81b25bc66681548b8b82f38258f7e08c
> https://github.com/ruby/ruby/commit/862048e28d26112af1e67205cfd1c16564590bce

I also added that patch.  I presume that you're also trying to convince
Ruby's maintainers to undo those changes?
Same as before: please provide a subsequent patch which corrects the
authorship attribution.


        Stefan





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#12169: [PATCH] Merge changes from upstream ruby-mode
  2012-08-10 20:28 ` Stefan Monnier
@ 2012-08-10 22:15   ` Dmitry Gutov
  2012-08-10 23:06     ` Dmitry Gutov
  2012-08-12 22:09     ` Stefan Monnier
  0 siblings, 2 replies; 7+ messages in thread
From: Dmitry Gutov @ 2012-08-10 22:15 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 12169

[-- Attachment #1: Type: text/plain, Size: 1595 bytes --]

On 10.08.2012 19:54, Glenn Morris wrote:
 > Are you also the upstream author?

Nope. Thanks for the reminder.

On 11.08.2012 0:28, Stefan Monnier wrote:
> I've installed your patch, but please fix the ChangeLog authorship as
> pointed out by Glenn (just include the changes in a subsequent patch).

Included.

>> Here's part 2, in which I'm skipping the next 3 commits:
>> https://github.com/ruby/ruby/commit/85df40e9ab4559cd4ddde3f106ab56c76a808cc8
>> https://github.com/ruby/ruby/commit/6b0dc7fd81b25bc66681548b8b82f38258f7e08c
>> https://github.com/ruby/ruby/commit/862048e28d26112af1e67205cfd1c16564590bce

For completeness, this later commit is directly related to the above 3:
https://github.com/ruby/ruby/commit/d9e6b7d6a5e81afb588d79ef923b70890cdec4ba

I also don't include it, and we can see that the relevant test passes fine.

> I also added that patch.  I presume that you're also trying to convince
> Ruby's maintainers to undo those changes?

Not really, no. I will open an issue on Redmine since you asked, but 
nobody seems to be interested in pulling our changes back anyway, and as 
long as we're doing it in one direction, cherry-picking should be fine.

Here's a recent example: http://bugs.ruby-lang.org/issues/5140
A year-old bug, fixed in Emacs trunk, a user posted that information 
there with a patch 4 months ago, and... nothing.

> Same as before: please provide a subsequent patch which corrects the
> authorship attribution.

In my not-a-lawyer opinion, the example code in tests is not 
copyrightable, but okay, I mentioned the original author there too.

--Dmitry

[-- Attachment #2: ruby-upstream-3.diff --]
[-- Type: text/plain, Size: 6795 bytes --]

diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 38379cd..2d63ab6 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,17 +1,29 @@
-2012-08-09  Dmitry Gutov  <dgutov@yandex.ru>
+2012-08-10 Nobuyoshi Nakada  <nobu@ruby-lang.org>
 
-	Merge stuff from upsteam ruby-mode, part 1.
+	* progmodes/ruby-mode.el (ruby-mode-map): Remove unnecessary
+	binding for `newline'.
+	(ruby-move-to-block): When moving backward, stop at block opening,
+	not indentation.
+	* progmodes/ruby-mode.el (ruby-brace-to-do-end)
+	(ruby-do-end-to-brace, ruby-toggle-block): New functions.
+	* progmodes/ruby-mode.el (ruby-mode-map): Add binding for
+	`ruby-toggle-block'.
+
+2012-08-09  Dmitry Gutov  <dgutov@yandex.ru>
 
-	* progmodes/ruby-mode.el (ruby-mode-map): Remove deprecated
-	binding (use `M-;' instead).
 	(ruby-expr-beg, ruby-parse-partial): ?, _, and : are symbol
 	constituents, ! is not (but kinda should be).
-	(ruby-singleton-class-p): New function.
-	(ruby-expr-beg, ruby-in-here-doc-p)
-	(ruby-syntax-propertize-heredoc): Use it.
+	(ruby-syntax-propertize-heredoc): Use `ruby-singleton-class-p'.
 	(ruby-syntax-propertize-function): Adjust for changes in
 	`ruby-syntax-propertize-heredoc'.
 
+2012-08-09 Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	* progmodes/ruby-mode.el (ruby-mode-map): Remove deprecated
+	binding (use `M-;' instead).
+	(ruby-singleton-class-p): New function.
+	(ruby-expr-beg, ruby-in-here-doc-p) Use it.
+
 2012-08-07  Andreas Schwab  <schwab@linux-m68k.org>
 
 	* calc/calc-prog.el (math-do-defmath): Use backquote forms.  Fix
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 68abaff..c430c99 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -150,7 +150,7 @@ This should only be called after matching against `ruby-here-doc-beg-re'."
     (define-key map (kbd "M-C-q") 'ruby-indent-exp)
     (define-key map (kbd "C-M-h") 'backward-kill-word)
     (define-key map (kbd "C-j")   'reindent-then-newline-and-indent)
-    (define-key map (kbd "C-m")   'newline)
+    (define-key map (kbd "C-c {") 'ruby-toggle-block)
     map)
   "Keymap used in Ruby mode.")
 
@@ -881,7 +881,7 @@ or blocks containing the current block."
   ;; TODO: Make this work for n > 1,
   ;; make it not loop for n = 0,
   ;; document body
-  (let (start pos done down)
+  (let (start pos done down (orig (point)))
     (setq start (ruby-calculate-indent))
     (setq down (looking-at (if (< n 0) ruby-block-end-re
                              (concat "\\<\\(" ruby-block-beg-re "\\)\\>"))))
@@ -907,8 +907,18 @@ or blocks containing the current block."
           (save-excursion
             (back-to-indentation)
             (if (looking-at (concat "\\<\\(" ruby-block-mid-re "\\)\\>"))
-                (setq done nil))))))
-  (back-to-indentation))
+                (setq done nil)))))
+    (back-to-indentation)
+    (when (< n 0)
+      (let ((eol (point-at-eol)) state next)
+        (if (< orig eol) (setq eol orig))
+        (setq orig (point))
+        (while (and (setq next (apply 'ruby-parse-partial eol state))
+                    (< (point) eol))
+          (setq state next))
+        (when (cdaadr state)
+          (goto-char (cdaadr state)))
+        (backward-word)))))
 
 (defun ruby-beginning-of-block (&optional arg)
   "Move backward to the beginning of the current block.
@@ -1116,6 +1126,47 @@ See `add-log-current-defun-function'."
               (if mlist (concat mlist mname) mname)
             mlist)))))
 
+(defun ruby-brace-to-do-end ()
+  (when (looking-at "{")
+    (let ((orig (point)) (end (progn (ruby-forward-sexp) (point))))
+      (when (eq (char-before) ?\})
+        (delete-char -1)
+        (if (eq (char-syntax (char-before)) ?w)
+            (insert " "))
+        (insert "end")
+        (if (eq (char-syntax (char-after)) ?w)
+            (insert " "))
+        (goto-char orig)
+        (delete-char 1)
+        (if (eq (char-syntax (char-before)) ?w)
+            (insert " "))
+        (insert "do")
+        (when (looking-at "\\sw\\||")
+          (insert " ")
+          (backward-char))
+        t))))
+
+(defun ruby-do-end-to-brace ()
+  (when (and (or (bolp)
+                 (not (memq (char-syntax (char-before)) '(?w ?_))))
+             (looking-at "\\<do\\(\\s \\|$\\)"))
+    (let ((orig (point)) (end (progn (ruby-forward-sexp) (point))))
+      (backward-char 3)
+      (when (looking-at ruby-block-end-re)
+        (delete-char 3)
+        (insert "}")
+        (goto-char orig)
+        (delete-char 2)
+        (insert "{")
+        (if (looking-at "\\s +|")
+            (delete-char (- (match-end 0) (match-beginning 0) 1)))
+        t))))
+
+(defun ruby-toggle-block ()
+  (interactive)
+  (or (ruby-brace-to-do-end)
+      (ruby-do-end-to-brace)))
+
 (declare-function ruby-syntax-propertize-heredoc "ruby-mode" (limit))
 (declare-function ruby-syntax-general-delimiters-goto-beg "ruby-mode" ())
 (declare-function ruby-syntax-propertize-general-delimiters "ruby-mode" (limit))
diff --git a/test/ChangeLog b/test/ChangeLog
index c59c3cb..9a60f0e 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -5,6 +5,13 @@
 	(ruby-should-indent-buffer): New function.
 	Add tests for `ruby-deep-indent-paren' behavior.
 	Port all tests from test/misc/test_ruby_mode.rb in Ruby repo.
+	(ruby-move-to-block-stops-at-opening): New test.
+	(ruby-toggle-block-to-do-end): New test.
+	(ruby-toggle-block-to-brace): New test.
+
+2012-08-10 Nobuyoshi Nakada  <nobu@ruby-lang.org>
+
+	Original tests in test_ruby_mode.rb in upstream (author).
 
 2012-08-09  Dmitry Gutov  <dgutov@yandex.ru>
 
diff --git a/test/automated/ruby-mode-tests.el b/test/automated/ruby-mode-tests.el
index f91b6e4..df51aa0 100644
--- a/test/automated/ruby-mode-tests.el
+++ b/test/automated/ruby-mode-tests.el
@@ -191,6 +191,32 @@ VALUES-PLIST is a list with alternating index and value elements."
    |  end
    |"))
 
+(ert-deftest ruby-move-to-block-stops-at-opening ()
+  (with-temp-buffer
+    (insert "def f\nend")
+    (beginning-of-line)
+    (ruby-mode)
+    (ruby-move-to-block -1)
+    (should (looking-at "f$"))))
+
+(ert-deftest ruby-toggle-block-to-do-end ()
+  (with-temp-buffer
+    (insert "foo {|b|\n}\n")
+    (ruby-mode)
+    (search-backward "{")
+    (ruby-toggle-block)
+    (should (string= "foo do |b|\nend\n" (buffer-substring-no-properties
+                                          (point-min) (point-max))))))
+
+(ert-deftest ruby-toggle-block-to-brace ()
+  (with-temp-buffer
+    (insert "foo do |b|\nend\n")
+    (ruby-mode)
+    (search-backward "do")
+    (ruby-toggle-block)
+    (should (string= "foo {|b|\n}\n" (buffer-substring-no-properties
+                                      (point-min) (point-max))))))
+
 (provide 'ruby-mode-tests)
 
 ;;; ruby-mode-tests.el ends here

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* bug#12169: [PATCH] Merge changes from upstream ruby-mode
  2012-08-10 22:15   ` Dmitry Gutov
@ 2012-08-10 23:06     ` Dmitry Gutov
  2012-08-12 22:09     ` Stefan Monnier
  1 sibling, 0 replies; 7+ messages in thread
From: Dmitry Gutov @ 2012-08-10 23:06 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 12169

On 11.08.2012 2:15, Dmitry Gutov wrote:
> I will open an issue on Redmine

http://bugs.ruby-lang.org/issues/6854






^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#12169: [PATCH] Merge changes from upstream ruby-mode
  2012-08-10 22:15   ` Dmitry Gutov
  2012-08-10 23:06     ` Dmitry Gutov
@ 2012-08-12 22:09     ` Stefan Monnier
  1 sibling, 0 replies; 7+ messages in thread
From: Stefan Monnier @ 2012-08-12 22:09 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: 12169

> In my not-a-lawyer opinion, the example code in tests is not copyrightable,
> but okay, I mentioned the original author there too.

Great, thanks, installed,


        Stefan





^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2012-08-12 22:09 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-08-10  0:36 bug#12169: [PATCH] Merge changes from upstream ruby-mode Dmitry Gutov
     [not found] ` <handler.12169.B.13445594689259.ack@debbugs.gnu.org>
2012-08-10 14:52   ` bug#12169: Acknowledgement ([PATCH] Merge changes from upstream ruby-mode) Dmitry Gutov
2012-08-10 15:54 ` bug#12169: [PATCH] Merge changes from upstream ruby-mode Glenn Morris
2012-08-10 20:28 ` Stefan Monnier
2012-08-10 22:15   ` Dmitry Gutov
2012-08-10 23:06     ` Dmitry Gutov
2012-08-12 22:09     ` Stefan Monnier

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).