В Emacs, как я могу более разумно использовать imenu с C#?
Я использовал emacs в течение долгого времени, но я не поспевал за множеством функций. Одним из них является спидбар, который я сейчас кратко исследовал. Другой это имя. Оба из них были упомянуты в in-emacs-как-можно-прыгать-между-функциями-в-текущем-файле?
Используя imenu, я могу перейти к определенным методам в модуле, в котором я работаю. Но есть иерархия разбора, с которой мне нужно договориться, прежде чем я получу возможность выбрать (с автозаполнением) имя метода.
Это идет так. Я печатаю M-x imenu
и тогда я выбираю Using
или же Types
, Выбор использования позволяет мне перейти к любому из операторов using на верхнем уровне файла C# (что-то вроде операторов импорта в модуле Java для тех из вас, кто не знает C#). Не супер полезно. Я выбираю Типы. Затем я должен выбрать пространство имен и класс, хотя в исходном модуле есть только одно из них. На этом этапе я могу выбирать между переменными, типами и методами. Если я выбираю методы, я, наконец, получаю список методов на выбор. Иерархия, которую я пересекаю, выглядит следующим образом;
Using
Types
Namespace
Class
Types
Variables
Methods
method names
Только после того, как я достигну 5-го уровня, я могу выбрать то, к чему я действительно хочу перейти: конкретный метод.
Имену кажется умным в отношении исходного модуля, но довольно сложен в использовании. Я делаю это неправильно?
3 ответа
Инструменты CEDET на http://cedet.sf.net/ включают анализатор C# в области "contrib", который может анализировать код C#. Затем CEDET поддерживает специализированные интерфейсы как для панели быстрого доступа, так и для меню, которые будут формировать конструкции вашего меню таким образом, чтобы код был организован, а не тип тега. Например, в C++ такой код:
namespace foo {
class bar {
int somemethod();
}
}
даст вам дерево с надписью "bar" под "foo" и "somemethod" под "bar", поэтому, если вы знаете свою структуру, вам просто нужно развернуть имя по тегу, который вы хотите.
На случай, если это кому-нибудь поможет, я сделал свой собственный код, следуя инструкциям в документации imenu emacs . Вы должны иметь возможность добавить это в свой init.el (или, в моем случае, в мой файл .spacemacs в 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)))
Я постараюсь держать это в курсе, если я внесу какие-либо изменения. Прямо сейчас он распознает «использующие» операторы как переменные. Других ошибок я не знаю.
PS Я не пробовал решение @Eric, возможно, оно намного лучше моего.
Я использую следующую функцию, которая будет использовать ido и просто запрашивать символы, к которым вы можете перейти. Просто назовите это вместо имени:
(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)))))))