2013-08-14 8 views
6

Ho sperimentato con cedet e semantico nella mia configurazione di sviluppo c/C++ di emacs e sono abbastanza soddisfatto tranne un piccolo dettaglio.Semantico, cedet come forzare l'analisi dei file sorgente

Io uso ede-cpp-root-project di creare un progetto e dare la directory principale del mio progetto insieme con le directory in cui includono file risiedono come di seguito:

(ede-cpp-root-project "My Project" 
       :name "My Project" 
       :file "/path/to/rootdir/AFILE" 
       :include-path '( 
       "/include2" 
       "/include1" 
           ) 

       ) 

Questo mi permette di saltare facilmente alle dichiarazioni di funzioni con semantic-ia-fast-jump ma non mi porta alle definizioni di quelle funzioni. Quindi sembra che abbia a che fare solo con i file header e ignori totalmente i file sorgente. Anche se vado sulla dichiarazione della funzione e trigger semantic-analyze-proto-impl-toggle mi dirà che non è stata trovata alcuna implementazione adeguata.

Se apro manualmente il file di origine in cui si trova l'implementazione della funzione, allora e solo allora viene analizzato da semantico e tutte le funzioni sopra menzionate funzionano.

Quindi la mia domanda è, aprendo a corto di manualmente tutti i file sorgenti inclusi sotto la directory principale del mio progetto o manualmente includerli nel ede-cpp-root-project tramite l'argomento :spp-files c'è qualche altro modo per forzare l'analisi di tutti i file sorgente in una directory?

Grazie!

risposta

7

Dopo aver ignorato questo problema per un lungo periodo, ho pensato che avrei dovuto dedicare un po 'di tempo alla lettura dell'ELIF e cercare di capire come risolvere il problema. Non è il codice elisp più carino che ci sia, dal momento che utilizzo l'elisp solo per le mie esigenze di emacs ma fa quello che mi serve.

(defvar c-files-regex ".*\\.\\(c\\|cpp\\|h\\|hpp\\)" 
    "A regular expression to match any c/c++ related files under a directory") 

(defun my-semantic-parse-dir (root regex) 
    " 
    This function is an attempt of mine to force semantic to 
    parse all source files under a root directory. Arguments: 
    -- root: The full path to the root directory 
    -- regex: A regular expression against which to match all files in the directory 
    " 
    (let (
     ;;make sure that root has a trailing slash and is a dir 
     (root (file-name-as-directory root)) 
     (files (directory-files root t)) 
     ) 
    ;; remove current dir and parent dir from list 
    (setq files (delete (format "%s." root) files)) 
    (setq files (delete (format "%s.." root) files)) 
    (while files 
     (setq file (pop files)) 
     (if (not(file-accessible-directory-p file)) 
      ;;if it's a file that matches the regex we seek 
      (progn (when (string-match-p regex file) 
       (save-excursion 
       (semanticdb-file-table-object file)) 
      )) 
      ;;else if it's a directory 
      (my-semantic-parse-dir file regex) 
    ) 
    ) 
) 
) 

(defun my-semantic-parse-current-dir (regex) 
    " 
    Parses all files under the current directory matching regex 
    " 
    (my-semantic-parse-dir (file-name-directory(buffer-file-name)) regex) 
) 

(defun lk-parse-curdir-c() 
    " 
    Parses all the c/c++ related files under the current directory 
    and inputs their data into semantic 
    " 
    (interactive) 
    (my-semantic-parse-current-dir c-files-regex) 
) 

(defun lk-parse-dir-c (dir) 
    "Prompts the user for a directory and parses all c/c++ related files 
    under the directory 
    " 
    (interactive (list (read-directory-name "Provide the directory to search in:"))) 
    (my-semantic-parse-dir (expand-file-name dir) c-files-regex) 
) 

(provide 'lk-file-search) 

di usarlo o chiamare direttamente la funzione in questo modo: (my-semantic-parse-dir "path/to/dir/root/" ".*regex") oppure premere M-x lk-parse-curdir-c da un buffer per eseguire la scansione in modo ricorsivo tutti i file di c/C++ correlati da directory nome del file che la visita di buferr.

Un modo alternativo e forse preferibile per chiamare la funzione è richiamando lk-parse-dir-c in modo interattivo che a sua volta richiederà l'analisi di una directory.

Se un guru elisp ha una soluzione o dei suggerimenti migliori per migliorare il codice, mi piacerebbe ascoltarli.

+0

Hey mi sono imbattuto in un blog troppo e questa soluzione sembra buono, ma non lo farà emacs salva il database dei tag attraverso le sessioni. Mi sto perdendo qualcosa? – jarvisteve

+0

hey, è strano. Dovrebbero essere salvati in una directory chiamata .semanticdb all'interno della directory .emacs – Lefteris

+1

Ho avuto un problema in cui il mio elenco di file era così lungo che Emacs era in grado di bloccarsi e apparentemente non fare ulteriori progressi. Lo risolvo aggiungendo una chiamata a (semanticdb-save-all-db) prima di passare alla directory successiva. In questo modo la cache viene aggiornata continuamente. Forse sarebbe d'aiuto. Normalmente la semantica salva solo quando esci da emacs. – RealityMonster

0

Provare a eseguire il comando "bovino". Questo può essere fatto con la combinazione di tasti Meta + X e quindi digitando "bovinate" e premendo il tasto "Invio". Il tasto "Meta" è indicato come il tasto "Alt" in Windows.

+0

hey grazie per aver dedicato del tempo a cadere una risposta, ma non vedo come 'bovinate' può aiutare nella mia situazione – Lefteris

1

Ho implementato questo per Python di recente. Potrebbe essere adottato per C/C++ con modifiche minori.

(defvar python-extention-list (list "py")) 

(defun semanticdb-rescan-directory (pathname) 
    (dolist (file (cddr (directory-files pathname t))) 
    (if (file-directory-p file) 
     (semanticdb-rescan-directory file) 
     (when (member (file-name-extension file) python-extention-list) 
     (message "Parsing %s file." file) 
     (ignore-errors 
      (semanticdb-file-table-object file)))))) 

(defun semantic-python-rescan-includes() 
    (interactive) 
    (dolist (includes (semantic-python-get-system-include-path)) 
    (message "Parsing %s" includes) 
    (semanticdb-rescan-directory includes)))