2009-09-26 20 views
11

Emacs'in etiket işlevselliğini kullanabilmem için e-postaları kullanarak clojure dosyalarını indekslemek istiyorum. Ancak etags, clojure işlevlerini tanımıyor. e-postaları clojure tanımlarını içerecek şekilde genişletmek mümkün mü?Clojure Emacs etags

cevap

6

Kaynağa baktığınızda, Lisp tanıyıcı 'def' dizesini aradığı için --language=lisp bayrağını kullanarak etags kodunu çalıştırmanız yeterlidir.

Bu işe yaramazsa, Clojure'ı tanıması ve bunun için bir etiket dosyası oluşturabilmesi için etags'u değiştirmeniz gerekir. Here is the source of etags in htmlized form. Yapılması zor ya da uzun bir iş gibi görünmüyor.

/* 
* Python support 
* Look for /^[\t]*def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/ 
* Idea by Eric S. Raymond <[email protected]> (1997) 
* More ideas by seb bacon <[email protected]> (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 destek biraz daha karmaşıktır:

/* 
* 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(); 
       } 
      } 
     } 
    } 
} 
5
01 miner49 cevabı geliştirmek için: Ben .emacs bu var

(regex hafif değişiklik fark, ctags yaklaşık sahip bağırıyordu "-" regex ortasında bir aralık belirtmek için kullanılmaz olduğunda)

; 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))) 
) 

Başka bir engel benim kutu balçık M-geçersiz kılan oldu. Onun yerine kendi bulma işlevini kullanmak yerine etiketini bul ve bu işlevin düzgün çalışması başarısız oldu. e kendi arama işlevi yerine sonra bulma etiketi ve bu işlev düzgün çalışamadı. TAG dosyasından etiketler bulmak için find-tag seperatley 'u çağırabilirsiniz, ancak yerleşik işlev, oldukça temiz olan bir slime/swank sunucusuna bağlandığında yerleşik işlevlerin kaynağına atlar. elisp becerilerim ikisini birleştirmeyi başaramadı. balçık gerçekleşmesi görünmemektedir hangi başarısız olursa nil dönmek-etiketini bulun beklediğini, bu yüzden aramalar bazlı Etiketler geri getiriyor

(add-hook 'slime-edit-definition-hooks 'find-tag) 

aşağıdaki fakat Swank-sunucu aramaları yok eder.

2

@ miller49r'ın yanıtı gerçekten güzeldi. Metadatayı ve bazı daha kabul edilebilir clojure sembollerini tanımak için biraz değiştirdim: