ruby-mode.el again; imenu this time 
Author Message
 ruby-mode.el again; imenu this time

Hello,

More ruby-mode.el fun today. The following bit of code, when run
though imenu-add-menubar-index, only creates menu entries for the
first class. It appears to be the fact that they're in the same module
that's breaking it:

module Foo
  class Bar
    def meth1
    end
  end

  class Baz
    def meth2
    end
  end
end

Dan
--
/^Dan Debertin$/

www.nodewarrior.org
ignorami: n:
The art of folding problem users into representational shapes.



Fri, 07 Jan 2005 14:37:45 GMT  
 ruby-mode.el again; imenu this time
Hi,

At Mon, 22 Jul 2002 15:36:45 +0900,

Quote:

> More ruby-mode.el fun today. The following bit of code, when run
> though imenu-add-menubar-index, only creates menu entries for the
> first class. It appears to be the fact that they're in the same module
> that's breaking it:

ruby-imenu-create-index didn't work for nested classes.  I'm
not sure if this works well enough for singletons.

Index: misc/ruby-mode.el
===================================================================
RCS file: /cvs/ruby/src/ruby/misc/ruby-mode.el,v
retrieving revision 1.53
diff -u -2 -p -r1.53 ruby-mode.el
--- misc/ruby-mode.el   28 Jun 2002 14:40:54 -0000      1.53

 (eval-when-compile (require 'cl))
-(defun ruby-imenu-create-index ()
-  (let ((index-alist '())
-       class-name class-begin method-name method-begin decl)
-    (goto-char (point-min))
-    (while (re-search-forward "^\\s *\\(class\\|def\\)\\s *\\([^(\n ]+\\)" nil t)
-      (setq decl (buffer-substring (match-beginning 1) (match-end 1)))
+(defun ruby-imenu-create-index (&optional prefix beg end)
+  (let ((index-alist '()) (nest '()) name name-begin name-end pos decl sing)
+    (goto-char (or beg (point-min)))
+    (while (re-search-forward "^\\s *\\(class\\(\\s +<<\\)?\\|module\\|def\\|alias\\)\\s *\\([^(\n ]+\\)" end t)
+      (setq sing (match-beginning 2))
+      (setq decl (if sing "class" (buffer-substring (match-beginning 1) (match-end 1))))
+      (setq name-begin (match-beginning 3))
+      (setq name-end (match-end 3))
+      (setq name (buffer-substring name-begin name-end))
+      (setq pos (match-beginning 0))
       (cond
-       ((string= "class" decl)
-       (setq class-begin (match-beginning 2))
-       (setq class-name (buffer-substring class-begin (match-end 2)))
-       (push (cons class-name (match-beginning 0)) index-alist)
-       (ruby-mark-defun)
-       (save-restriction
-         (narrow-to-region (region-beginning) (region-end))
-         (while (re-search-forward "^\\s *def\\s *\\([^(\n ]+\\)" nil 'move)
-           (setq method-begin (match-beginning 1))
-           (setq method-name (buffer-substring method-begin (match-end 1)))
-           (push (cons (concat class-name "#" method-name) (match-beginning 0)) index-alist))))
-       ((string= "def" decl)
-       (setq method-begin (match-beginning 2))
-       (setq method-name (buffer-substring method-begin (match-end 2)))
-       (push (cons method-name (match-beginning 0)) index-alist))))
+       ((or (string= "def" decl) (string= "alias" 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))
+       (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-end-of-defun)
+       (setq beg (point))
+       (setq index-alist
+             (nconc index-alist
+                    (ruby-imenu-create-index (concat name (if sing "." "#"))
+                                             name-end beg)))
+       (goto-char beg))))
     index-alist))

--
Nobu Nakada



Fri, 07 Jan 2005 18:49:03 GMT  
 ruby-mode.el again; imenu this time
This is better, but still doesn't do what I expect. The code fragment
I mentioned:

module Foo
  class Bar
    def meth1
    end
  end

  class Baz
    def meth2
    end
  end
end

is not a case of nested classes, but of multiple classes within the
same module. The menu, however, comes out nested:

*Rescan*
Foo
Foo::Bar
Foo::Bar::Baz
Foo::Bar#meth1
Foo::Bar::Baz#meth2

Baz is not a nested class under Bar ... right?

Dan
--
/^Dan Debertin$/

www.nodewarrior.org
ignorami: n:
The art of folding problem users into representational shapes.



Sat, 08 Jan 2005 00:33:56 GMT  
 ruby-mode.el again; imenu this time
Hi,

At Tue, 23 Jul 2002 01:32:40 +0900,

Quote:

> is not a case of nested classes, but of multiple classes within the
> same module. The menu, however, comes out nested:

> *Rescan*
> Foo
> Foo::Bar
> Foo::Bar::Baz
> Foo::Bar#meth1
> Foo::Bar::Baz#meth2

> Baz is not a nested class under Bar ... right?

Exactly.  ruby-move-to-block was needed to modify to skip RD
style comments.

Still this patch doesn't work well at here documents...

Index: ruby-mode.el
===================================================================
RCS file: /cvs/ruby/src/ruby/misc/ruby-mode.el,v
retrieving revision 1.53
diff -u -2 -p -r1.53 ruby-mode.el
--- ruby-mode.el        28 Jun 2002 14:40:54 -0000      1.53

 (eval-when-compile (require 'cl))
-(defun ruby-imenu-create-index ()
-  (let ((index-alist '())
-       class-name class-begin method-name method-begin decl)
-    (goto-char (point-min))
-    (while (re-search-forward "^\\s *\\(class\\|def\\)\\s *\\([^(\n ]+\\)" nil t)
-      (setq decl (buffer-substring (match-beginning 1) (match-end 1)))
+(defun ruby-imenu-create-index (&optional prefix beg end)
+  (let ((index-alist '()) (nest '()) (case-fold-search nil)
+       name name-begin name-end pos decl sing)
+    (goto-char (or beg (point-min)))
+    (while (re-search-forward "^\\s *\\(class\\(\\s +<<\\)?\\|module\\|def\\|alias\\)\\>\\s *\\([^(\n ]+\\)" end t)
+      (setq sing (match-beginning 2))
+      (setq decl (if sing "class" (buffer-substring (match-beginning 1) (match-end 1))))
+      (setq name-begin (match-beginning 3))
+      (setq name-end (match-end 3))
+      (setq name (buffer-substring name-begin name-end))
+      (setq pos (match-beginning 0))
       (cond
-       ((string= "class" decl)
-       (setq class-begin (match-beginning 2))
-       (setq class-name (buffer-substring class-begin (match-end 2)))
-       (push (cons class-name (match-beginning 0)) index-alist)
-       (ruby-mark-defun)
-       (save-restriction
-         (narrow-to-region (region-beginning) (region-end))
-         (while (re-search-forward "^\\s *def\\s *\\([^(\n ]+\\)" nil 'move)
-           (setq method-begin (match-beginning 1))
-           (setq method-name (buffer-substring method-begin (match-end 1)))
-           (push (cons (concat class-name "#" method-name) (match-beginning 0)) index-alist))))
-       ((string= "def" decl)
-       (setq method-begin (match-beginning 2))
-       (setq method-name (buffer-substring method-begin (match-end 2)))
-       (push (cons method-name (match-beginning 0)) index-alist))))
+       ((or (string= "def" decl) (string= "alias" 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))
+       (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-end-of-block)
+       (setq beg (point))
+       (setq index-alist
+             (nconc index-alist
+                    (ruby-imenu-create-index (concat name (if sing "." "#"))
+                                             name-end beg)))
+       (goto-char beg))))
     index-alist))

                       (ruby-expr-beg 'expr-qstr)
                       (not (looking-at "%="))
-                      (looking-at "%[Qqrxw]?\\(.\\)"))
+                      (looking-at "%[QqrxWw]?\\(.\\)"))
                  (goto-char (match-beginning 1))
-                 (setq expand (not (eq (char-before) ?q)))
+                 (setq expand (not (memq (char-before) '(?q ?w))))
                  (setq w (buffer-substring (match-beginning 1)

                   ((string= w "(") (setq re ")("))
                   ((string= w "<") (setq re "><"))
-                  ((or (and expand (string= w "\\"))
-                       (member w '("*" "." "+" "?" "^" "$")))
+                  ((and expand (string= w "\\"))
                    (setq w (concat "\\" w))))

 (defun ruby-move-to-block (n)
   (let (start pos done down)
-    (setq start (ruby-calculate-indent))
-    (if (eobp)
-       nil
-      (while (and (not (bobp)) (not (eobp)) (not done))
-       (forward-line n)
+    (while (not (setq start (ruby-calculate-indent)))
+      (setq pos t)
+      (forward-line n))
+    (if pos (backward-line n))
+    (back-to-indentation)
+    (setq down (looking-at (if (< n 0) ruby-block-end-re ruby-block-beg-re)))
+    (while (and (not done) (not (if (< n 0) (bobp) (eobp))))
+      (forward-line n)
+      (cond
+       ((looking-at "^\\s *$"))
+       ((looking-at "^\\s *#"))
+       ((and (> n 0) (looking-at "^=begin\\>"))
+       (re-search-forward "^=end\\>"))
+       ((and (< n 0) (looking-at "^=end\\>"))
+       (re-search-backward "^=begin\\>"))
+       (t
+       (setq pos (current-indentation))
        (cond
-        ((looking-at "^$"))
-        ((looking-at "^\\s *#"))
-        (t
-         (setq pos (current-indentation))
-         (cond
-          ((< start pos)
-           (setq down t))
-          ((and down (= pos start))
-           (setq done t))
-          ((> start pos)
-           (setq done t)))))
-       (if done
-           (progn
-             (back-to-indentation)
-             (if (looking-at ruby-block-mid-re)
-                 (setq done nil)))))))
+        ((< start pos)
+         (setq down t))
+        ((and down (= pos start))
+         (setq done t))
+        ((> start pos)
+         (setq done t)))))
+      (if done
+         (progn
+           (back-to-indentation)
+           (if (looking-at ruby-block-mid-re)
+               (setq done nil))))))
   (back-to-indentation))

--
Nobu Nakada



Sat, 08 Jan 2005 14:13:21 GMT  
 ruby-mode.el again; imenu this time
At Tue, 23 Jul 2002 15:12:07 +0900,

Quote:

> Exactly.  ruby-move-to-block was needed to modify to skip RD
> style comments.

Works perfectly. Many thanks for your work.

Quote:

> Still this patch doesn't work well at here documents...

Well, at least for imenu it treated this construction correctly:

class Foo
  def initialize
    instance_eval <<-EOD
    def meth1
    end
    EOD
  end
end

But this causes a spurious def to appear in the index:

class Foo
  def initialize
    print <<-EOD
    def meth1
      puts "I'm in a fake method"
    end
    EOD
  end
end

As you can see, indenting also thinks I'm in a def. That sounds like
it would be hard to code around, though.

I'm just happy to have a working Imenu. Thanks again.

Dan
--
/^Dan Debertin$/

www.nodewarrior.org
ignorami: n:
The art of folding problem users into representational shapes.



Sun, 09 Jan 2005 00:12:44 GMT  
 ruby-mode.el again; imenu this time
At Wed, 24 Jul 2002 05:02:51 +0900,

Quote:

> I see, hope this works.

Well, it's close ;). Here's the indentation output:

class Foo
  def initialize
    print <<-EOD
def foo
end
EOD
end
end

It's good to see that no bogus method is added to the imenu now
(though it also isn't added if you define a method under one of the
various _eval methods, and it debatably should be), but as you can
see, it's not matching up the end-of-here-document token (EOD) and
going back to normal indentation after it.

Dan
--
/^Dan Debertin$/

www.nodewarrior.org
ignorami: n:
The art of folding problem users into representational shapes.



Sun, 09 Jan 2005 04:54:03 GMT  
 ruby-mode.el again; imenu this time
Hi,

In message "Re: ruby-mode.el again; imenu this time"

|I see, hope this works.
|
|[2 ruby-mode.el.diff.gz <text/x-diff; US-ASCII (base64)>]

Commit them, please.

                                                        matz.



Sun, 09 Jan 2005 09:27:20 GMT  
 ruby-mode.el again; imenu this time
Hi,

In message "Re: ruby-mode.el again; imenu this time"

|> Commit them, please.
|
|I found ruby-move-to-block got TOO slow, perhaps because of too
|many invocations of ruby-calculate-indent and they caused
|backtracks.  Once I tried forward scan from the beginning,
|however it would get slower in larger files, so abandoned.
|After all, reverted ruby-move-to-block almost and modified
|ruby-imenu-create-index.  Both seem to work reasonalbe now.

Hmm, then go ahead.

|And do you okay to merge this?
|
|* misc/ruby-mode.el (ruby-deep-arglist): skips spaces after
|  parenthesis when 'space.

Accepted.

                                                        matz.



Mon, 10 Jan 2005 07:29:39 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. hideshow mode for ruby-mode.el

2. latest ruby-mode.el messing up c++ mode fontification

3. ruby-mode.el was: ruby indenter

4. ruby-mode.el was: ruby indenter

5. ruby-mode.el dies when breaking ternary exp.

6. ruby-mode.el and xemacs

7. A mode-ruby.el for xemacs ?

8. ruby-mode.el indentation issue #2

9. BUG: ruby-mode.el 1.41 disables font-lock coloring

10. XEmacs problems with ruby-mode.el

11. ruby-mode.el indentation issue

12. Bug fix for ruby-mode.el

 

 
Powered by phpBB® Forum Software