我想使用etags索引clojure文件,以便我可以使用Emacs的标记功能.但是etags不承认clojure功能.是否可以扩展etags以包含clojure定义?
基于http://nakkaya.com/2009/12/13/getting-etags-to-index-clojure-files/
以下命令全部在一行上
find . \! -name '.*' -name '*.clj' | xargs etags --regex='/[ \t\(]*def[a-z]* \([a-z-!]+\)/\1/' --regex='/[ \t\(]*ns \([a-z.]+\)/\1/'
看看源代码,似乎你只需要etags
使用--language=lisp
标志运行,因为Lisp识别器会查找字符串'def'.
如果这不起作用,则必须进行修改,etags
以便它可以识别Clojure并为其生成标记文件.这是etags
html化表单的来源.它看起来不像那么困难或者长期工作.以下是识别Python的规则:
/* * Python support * Look for /^[\t]*def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/ * Idea by Eric S. Raymond(1997) * More ideas by seb bacon (2002) */ static void Python_functions (inf) FILE *inf; { register char *cp; LOOP_ON_INPUT_LINES (inf, lb, cp) { cp = skip_spaces (cp); if (LOOKING_AT (cp, "def") || LOOKING_AT (cp, "class")) { char *name = cp; while (!notinname (*cp) && *cp != ':') cp++; make_tag (name, cp - name, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); } } }
Lisp支持更多一些:
/* * Lisp tag functions * look for (def or (DEF, quote or QUOTE */ static void L_getit __P((void)); static void L_getit () { if (*dbp == '\'') /* Skip prefix quote */ dbp++; else if (*dbp == '(') { dbp++; /* Try to skip "(quote " */ if (!LOOKING_AT (dbp, "quote") && !LOOKING_AT (dbp, "QUOTE")) /* Ok, then skip "(" before name in (defstruct (foo)) */ dbp = skip_spaces (dbp); } get_tag (dbp, NULL); } static void Lisp_functions (inf) FILE *inf; { LOOP_ON_INPUT_LINES (inf, lb, dbp) { if (dbp[0] != '(') continue; if (strneq (dbp+1, "def", 3) || strneq (dbp+1, "DEF", 3)) { dbp = skip_non_spaces (dbp); dbp = skip_spaces (dbp); L_getit (); } else { /* Check for (foo::defmumble name-defined ... */ do dbp++; while (!notinname (*dbp) && *dbp != ':'); if (*dbp == ':') { do dbp++; while (*dbp == ':'); if (strneq (dbp, "def", 3) || strneq (dbp, "DEF", 3)) { dbp = skip_non_spaces (dbp); dbp = skip_spaces (dbp); L_getit (); } } } } }
改进miner49的答案:
我在我的.emacs中有这个(注意正则表达式的细微变化,ctags在正则表达式中间有" - "而不用于指定范围时大喊大叫)
; Recursively generate tags for all *.clj files, ; creating tags for def* and namespaces (defun create-clj-tags (dir-name) "Create tags file." (interactive "Directory: ") (shell-command (format "%s --langdef=Clojure --langmap=Clojure:.clj --regex-Clojure='/[ \t\(]*def[a-z]* \([a-z!-]+\)/\1/' --regex-Clojure='/[ \t\(]*ns \([a-z.]+\)/\1/' -f %s/TAGS -e -R %s" path-to-ctags dir-name (directory-file-name dir-name))) )
另一个障碍是我的盒子上的粘液覆盖了M-.使用它自己的查找函数而不是find-tag,并且该函数无法正常工作.它是自己的查找函数而不是find-tag,并且该函数无法正常工作.你可以调用find-tag seperatley来从TAG文件中找到标签,但是当连接到slime/swank服务器时,内置函数会跳转到内置函数的源,这非常简洁.我的elisp技能未能巩固这两个.slime希望find-tag返回nil如果它失败似乎没有发生,所以以下
(add-hook 'slime-edit-definition-hooks 'find-tag)
带回基于TAGS的搜索,但会破坏swank-server搜索.