I've used emacs for a long time, but I haven't been keeping up with a bunch of features. One of these is speedbar, which I just briefly investigated now. Another is imenu. Both of these were mentioned in in-emacs-how-can-i-jump-between-functions-in-the-current-file?
Using imenu, I can jump to particular methods in the module I'm working in. But there is a parse hierarchy that I have to negotiate before I get the option to choose (with autocomplete) the method name.
It goes like this. I type M-x imenu
and then I get to choose Using
or Types
. The Using choice allows me to jump to any of the using statements at the top level of the C# file (something like imports statements in a Java module, for those of you who don't know C#). Not super helpful. I choose Types. Then I have to choose a namespace and a class, even though there is just one of each in the source module. At that point I can choose between variables, types, and methods. If I choose methods I finally get the list of methods to choose from. The hierarchy I traverse looks like this;
Using
Types
Namespace
Class
Types
Variables
Methods
method names
Only after I get to the 5th level do I get to select the thing I really want to jump to: a particular method.
Imenu seems intelligent about the source module, but kind of hard to use. Am I doing it wrong?
The CEDET tools at http://cedet.sf.net includes a C# parser in the 'contrib' area that can parse C# code. CEDET then supports specialized interfaces for both speedbar and imenu, that will shape your menu constructs in a way that code organized, not tag type organized. In c++, for example, code like this:
namespace foo {
class bar {
int somemethod();
}
}
would give you a tree that had "bar" under "foo", and "somemethod" under "bar", so if you know your structure, you just need to unwind by name to the tag you want.
I use the following function, which will use ido and just prompt for the symbols you can jump to. Just call it instead of imenu:
(defun ido-goto-symbol ()
"Will update the imenu index and then use ido to select a symbol to navigate to"
(interactive)
(imenu--make-index-alist)
(let ((name-and-pos '())
(symbol-names '()))
(flet ((addsymbols (symbol-list)
(when (listp symbol-list)
(dolist (symbol symbol-list)
(let ((name nil) (position nil))
(cond
((and (listp symbol) (imenu--subalist-p symbol))
(addsymbols symbol))
((listp symbol)
(setq name (car symbol))
(setq position (cdr symbol)))
((stringp symbol)
(setq name symbol)
(setq position (get-text-property 1 'org-imenu-marker symbol))))
(unless (or (null position) (null name))
(add-to-list 'symbol-names name)
(add-to-list 'name-and-pos (cons name position))))))))
(addsymbols imenu--index-alist)
(let* ((symbol-at-point (symbol-name (symbol-at-point)))
(selected-symbol (ido-completing-read
"Symbol? "
(if (member symbol-at-point symbol-names)
(cons symbol-at-point (remove-if (lambda (x) (string-equal x symbol-at-point))
symbol-names))
symbol-names)))
(position (cdr (assoc selected-symbol name-and-pos))))
(if (markerp position)
(goto-char position) (goto-char (overlay-start position)))))))
(goto-char position) (goto-char (overlay-start position)))))))
In case it helps anybody, i made my own code following the instructions at imenu emacs documentation. You should be able to add this to your init.el (or in my case to my .spacemacs file under dotspacemacs/user-config)
(setq csharp-imenu-functions
'(("Variables" "^\\s-*[a-zA-Z0-9._ ]* \\([a-zA-Z0-9_]*\\)\\( = \\sw*\\|\\s-*\\);$" 1)
("Functions" "^\\s-*[^/]* \\([a-zA-Z0-9_]+\\)(.*)\\(\\s-*.*\n\\|\\ *\\)\\s-*{" 1)
("Classes" "^\\s-*\\(.*\\)class +\\([a-zA-Z0-9_]+\\)" 2)
("Namespaces" "^namespace +\\([a-z0-9_]*\\)" 1)))
(add-hook 'csharp-mode-hook
(lambda()
(setq imenu-generic-expression csharp-imenu-functions)))
I'll try to keep this up to date if I make any changes. Right now it recognizes "using" statements as variables. No other bugs that I'm aware.
P.S. I have not tried @Eric's solution, maybe its much better than mine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With