在Emacs中,如何更合理地使用imenu和C#?

在Emacs中,如何更合理地使用imenu和C#?,c#,emacs,emacs-speedbar,C#,Emacs,Emacs Speedbar,我已经使用emacs很长一段时间了,但是我没有跟上一系列特性的发展。其中之一是,我现在只是简单地研究了一下。另一个是。这两个问题都在报告中提到 使用imenu,我可以跳转到我正在使用的模块中的特定方法。但是,在获得选择(使用自动完成)方法名称的选项之前,我必须协商一个解析层次结构 事情是这样的。我键入M-x imenu,然后使用或类型选择。Using选项允许我跳转到C文件顶层的任何Using语句(对于不懂C的人来说,类似于Java模块中的imports语句)。不是很有帮助。我选择类型。然后,我

我已经使用emacs很长一段时间了,但是我没有跟上一系列特性的发展。其中之一是,我现在只是简单地研究了一下。另一个是。这两个问题都在报告中提到

使用imenu,我可以跳转到我正在使用的模块中的特定方法。但是,在获得选择(使用自动完成)方法名称的选项之前,我必须协商一个解析层次结构

事情是这样的。我键入
M-x imenu
,然后使用
类型选择
。Using选项允许我跳转到C文件顶层的任何Using语句(对于不懂C的人来说,类似于Java模块中的imports语句)。不是很有帮助。我选择类型。然后,我必须选择一个名称空间和一个类,即使源模块中每个名称空间和类只有一个。在这一点上,我可以在变量、类型和方法之间进行选择。如果我选择了方法,我最终得到了可供选择的方法列表。我遍历的层次结构如下所示

Using
Types
  Namespace
    Class
      Types
      Variables
      Methods
         method names
只有到了第五级,我才能选择我真正想跳到的东西:一种特殊的方法


Imenu在源代码模块方面似乎很智能,但有点难以使用。我做错了吗

我使用下面的函数,它将使用ido,只提示您可以跳转到的符号。只需调用它而不是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)))))))
位于的CEDET工具在“contrib”区域中包含一个可以解析C代码的C解析器。然后,CEDET支持speedbar和imenu的专用接口,这将以代码组织而不是标记类型组织的方式塑造菜单结构。在C++中,例如,这样的代码:

namespace foo {
   class bar {
       int somemethod();
   }
}

会给你一棵树,在“foo”下有“bar”,在“bar”下有“somemethod”,所以如果你知道你的结构,你只需要按名称将其展开到你想要的标签上。

这将是更多的工作,但是如果你真的想改进Emacs的C#支持(它似乎非常需要),最完整、最强大的方法是使用Semantic()。这涉及到编写一个完整的语法分析器,但它为您提供了使用这种语法分析器的好处。如果你想找一些快速的东西,那就太过分了。你的问题启发我为makefile模式下的类似问题发送了一个补丁:它以前有两个顶级菜单,“依赖项”和“宏分配”,但在我的补丁中,它们被合并到一个平面列表中(我只是用nil替换了标题字符串)。对C#模式进行同样的操作应该不难。我的补丁: