[英]Clojure Emacs etags
我想使用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[az]* \\([az-!]+\\)/\\1/' --regex='/[ \\t\\(]*ns \\([az.]+\\)/\\1/'
查看源代碼,似乎您只需使用--language=lisp
標志運行etags
,因為Lisp識別器會查找字符串'def'。
如果這不起作用,你將不得不修改etags
以便它可以識別Clojure並為它生成一個標簽文件。 這是html化形式的etags
的來源 。 它看起來不像那么困難或者長期工作。 以下是識別Python的規則:
/*
* Python support
* Look for /^[\t]*def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/
* Idea by Eric S. Raymond <esr@thyrsus.com> (1997)
* More ideas by seb bacon <seb@jamkit.com> (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搜索。
@miller49r的回答真的很好。 我修改了一下以識別元數據和一些更可接受的clojure符號chalaracters:
find . \! -name '.*' -name '*.clj' \
| xargs etags \
--regex='/[ \t\(]*def[a-zA-Z!$%&*+\-.\/:<=>?@^_~]*[ \n\t]+\(\^{[^}]*}[ \n\t]+\|\)\([a-zA-Z!$%&*+\-.\/:<=>?@^_~]+\)/\2/s' \
--regex='/[ \t\(]*ns \([a-z.]+\)/\1/'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.