In einer ziemlich großen Codebasis mit ein paar Layern gibt es einen Weg in vim oder von der Kommandozeile aus alle Klassen zu finden, die von einer Basis abgeleitet sind Klasse? grep ist eine Option, kann aber langsam sein, da grep nicht indexiert.C++, cscope, ctags und vim: Finden von Klassen, die von dieser Instanz stammen
Antwort
Weder cscope noch ctags uns mit Vererbung direkt behandeln lassen, aber es ist relativ leicht zu umgehen diese Einschränkung, da abgeleiteten Klassen sind auch indiziert.
cscope
In cscope, für "C Symbol" auf der Suche Foobar
listet in der Regel der ursprünglichen Klasse und Klassen von ihm erben. Da die Suche gegen eine Datenbank durchgeführt wird, ist sie blitzschnell.
Alternativ können Sie cscope die egrep Suchfunktionen mit einem Muster wie :.*Foobar
zur Liste nur Klassen von Foobar
vererben verwenden.
Also, auch wenn wir keinen dedizierten Befehl "Klassen von dieser Klasse erben" haben, können wir die Arbeit ohne viel Aufwand erledigen.
ctags
Während ctags Sie mit --fields=+i
Vererbungsinformationen enthalten können, können diese Informationen nicht direkt in Vim verwendet werden. Das Feld inherits
wird jedoch von Vim analysiert. Daher ist es möglicherweise möglich, eine schnelle und schmutzige Lösung mit taglist()
zu erstellen.
ack, ag
Diese beiden Programme funktionieren mehr oder weniger wie grep, aber sie sind in Richtung auf die Suche im Quellcode gezielt so sind sie wirklich schneller als grep.
In meinem Vim Config wird :grep
gesetzt grep
das ag
Programm anstelle des Standard laufen würde so, die Suche nach Klassen abgeleitet aus der Klasse unter dem Cursor wie folgt aussehen: sind
:grep :.*<C-r><C-w><CR>
Hier werden die entsprechenden Zeilen von meinem ~/.vimrc
:
if executable("ag")
set grepprg=ag\ --nogroup\ --nocolor\ --ignore-case\ --column
set grepformat=%f:%l:%c:%m,%f:%l:%m
endif
Ich bemerke etwas beschleunigen mit flüchtigen und vim mit dem ': Ggrep' Befehl. Diese Verbesserung erfordert, dass der Code ein git Repo ist, der in meinem Post nicht erwähnt wurde, aber eine andere Alternative ist. –
In lh-cpp definiere ich den Befehl :Children
. Es beruht auf einer Ctags-Datenbank und ist daher sehr begrenzt.
Es braucht zwei optionale Parameter: den Namespace, nach dem gesucht werden soll (ich habe keinen Weg gefunden, dies zu vermeiden), und den Namen der Elternklasse ->:Children [!] {namespace} {parent-class}
.
Der Befehl versucht, so viele Informationen wie möglich zwischenzuspeichern. Wenn sich relevante Informationen in der Datenbank ctags ändern, muss daher der Cache aktualisiert werden. Es wird durch hämmern den Befehl getan ->:Children!
ich glaube nicht, vim das richtige Werkzeug ist, alle untergeordneten Klassen aufzulisten. Stattdessen sollten wir besser das doxygen verwenden, um Dokumentation für den Quellcode zu generieren.Obwohl der Doxygen einige Zeit benötigt, können wir das Dokument/Diagramme für alle Klassen verwenden, was klar und schnell ist.
Dies wird jedoch davon ausgegangen, dass Sie über eine grafische Benutzeroberfläche entwickeln. Manchmal muss ich minty (cygwins terminal) über ssh verwenden, was bedeutet, dass die Dev Box einen Webserver haben müsste, um die doxygen Dateien zu hosten. –
Ja, genau. Und ein Linux/Unix-Server, der bereits SSH zur Verfügung stellt, kann einen Webserver einfach bereitstellen, es wird auch empfohlen, PHP auf dem Webserver zu aktivieren, der eine einfache Suchmaschine in den doxygen-Seiten bereitstellt. – Chandler
Sowohl Eclipse als auch SlickEdit bieten eine Möglichkeit, Vererbungsbäume für Klassen aufzulisten und eine Baumliste von überschriebenen Methoden. Dies wird in Eclipse als Typhierarchie bezeichnet und ist eine der nützlichsten Funktionen in einer IDE beim Codieren in einer OO-Sprache. Doxygen ist wirklich nützlich, aber es ist ein Overkill, wenn Sie nur einen kurzen Blick auf die "Typhierarchie" werfen müssen. –
Wenn Sie Ihre Tag-Dateien mit Exuberant CTags unter Verwendung von Vererbungsinformationen (see the --fields option) erstellen, funktioniert das folgende Skript. Es fügt einen :Inherits
Befehl hinzu, der entweder den Namen einer Klasse (z. B. :Inherits Foo
) oder einen regulären Ausdruck verwendet.
Wie der :tag
Befehl, zeigen Sie an, dass Sie die Suche mit einer Regex möchten, indem Sie es mit einem '\' Zeichen, z. :Inherits \Foo.*
.
Die Ergebnisse werden in das Fenster der Standortliste setzen, die Sie durchsuchen mit :ll
, :lne
, :lp
usw. VIM scheint nicht Skripte zu ermöglichen, die Tag-Liste zu ändern, das ist, was ich bevorzugen würde.
Wenn Sie sich wundern, warum ich taglist()
dafür nicht verwende, ist es, weil taglist()
auf großen Tag-Dateien unglaublich langsam ist. Der ursprüngliche Post hatte eine Version mit taglist()
, wenn Sie neugierig sind, können Sie den Bearbeitungsverlauf durchsuchen.
" Parse an Exuberant Ctags record using the same format as taglist()
"
" Throws CtagsParseErr if there is a general problem parsing the record
function! ParseCtagsRec(record, tag_dir)
let tag = {}
" Parse the standard fields
let sep_pos = stridx(a:record, "\t")
if sep_pos < 1
throw 'CtagsParseErr'
endif
let tag['name'] = a:record[:sep_pos - 1]
let tail = a:record[sep_pos + 1:]
let sep_pos = stridx(tail, "\t")
if sep_pos < 1
throw 'CtagsParseErr'
endif
" '/' will work as a path separator on most OS's, but there
" should really be an OS independent way to build paths.
let tag['filename'] = a:tag_dir.'/'.tail[:sep_pos - 1]
let tail = tail[sep_pos + 1:]
let sep_pos = stridx(tail, ";\"\t")
if sep_pos < 1
throw 'CtagsParseErr'
endif
let tag['cmd'] = tail[:sep_pos - 1]
" Parse the Exuberant Ctags extension fields
let extensions = tail[sep_pos + 3:]
for extension in split(extensions, '\t')
let sep_pos = stridx(extension, ':')
if sep_pos < 1
if has_key(tag, 'kind')
throw 'CtagsParseErr'
endif
let tag['kind'] = extension
else
let tag[extension[:sep_pos - 1]] = extension[sep_pos + 1:]
endif
endfor
return tag
endfunction
" Find all classes derived from a given class, or a regex (preceded by a '/')
" The results are placed in the current windows location list.
function! Inherits(cls_or_regex)
if a:cls_or_regex[0] == '/'
let regex = a:cls_or_regex[1:]
else
let regex = '\<'.a:cls_or_regex.'\>$'
endif
let loc_list = []
let tfiles = tagfiles()
let tag_count = 0
let found_count = 0
for file in tfiles
let tag_dir = fnamemodify(file, ':p:h')
try
for line in readfile(file)
let tag_count += 1
if tag_count % 10000 == 0
echo tag_count 'tags scanned,' found_count 'matching classes found. Still searching...'
redraw
endif
if line[0] == '!'
continue
endif
let tag = ParseCtagsRec(line, tag_dir)
if has_key(tag, 'inherits')
let baselist = split(tag['inherits'], ',\s*')
for base in baselist
if match(base, regex) != -1
let location = {}
let location['filename'] = tag['filename']
let cmd = tag['cmd']
if cmd[0] == '/' || cmd[0] == '?'
let location['pattern'] = cmd[1:-2]
else
let location['lnum'] = str2nr(cmd)
endif
call add(loc_list, location)
let found_count += 1
endif
endfor
endif
endfor
catch /^OptionErr$/
echo 'Parsing error: Failed to parse an option.'
return
catch /^CtagsParseErr$/
echo 'Parsing error: Tags files does not appear to be an Exuberant Ctags file.'
return
catch
echo 'Could not read tag file:' file
return
endtry
endfor
call setloclist(0, loc_list)
echo tag_count 'tags scanned,' found_count 'matching classes found.'
endfunction
command! -nargs=1 -complete=tag Inherits call Inherits('<args>')
- 1. Deterministische Navigation von C++ - Klassen-Tags in VIM. Ctags funktioniert nicht gut
- 2. Vim & Ctags: Gemeinsame Ctags über alle Projekte?
- 3. Zeige Multilayer-Funktionsbeziehung von cscope in vim
- 4. Vi + Cscope: mit "cscope finden c-Funktion" in vim, findet mehrere Ergebnisse, wie gehe ich weiter
- 5. Definitionen/Verweise auf C++ - Klassenmitglieder in Vim finden
- 6. Vim - ctags: Tag nicht gefunden
- 7. Verwenden von Vim, um die Definition bei der Navigation in/usr/include/files zu finden
- 8. Wie kann ich die Sprungfunktion von cscope abbrechen?
- 9. ctags arbeiten nicht für vim von der Kommandozeile
- 10. Wiederverwendung von vim-Instanz von Linux-Terminal
- 11. Getting Ctags + Vim mit Scoping arbeiten?
- 12. C++ - Code analysieren - CSCope
- 13. Woher stammen die Daten von User.Identity?
- 14. iPhone MoviePlayer Beispiel, wo die Schaltfläche und Label stammen von
- 15. Vim finden letzte Auftreten von
- 16. Finden von Instanz der Methode
- 17. Wie navigiere ich mehrere Ctags in Vim?
- 18. JavaScript-Berechtigungsfehler, die von einem IFrame stammen
- 19. Instanz in Liste von zwei Klassen
- 20. deaktivieren Warnungen stammen von scipy
- 21. C# Array von Klassen
- 22. Masterpage- und Content-Seiten, die von einer einzelnen Klasse stammen
- 23. Trennen von Windows Forms und Klassen C#
- 24. Wie benutze ich cscope?
- 25. Wie ignoriert man Struct-Deklarationen und berücksichtigt nur Definitionen in cscope?
- 26. Kompartimentierung und Design von Klassen in C++
- 27. Der beste Weg, um Vim-Syntax-Dateien und Ctags von Doxygen zu extrahieren?
- 28. Cscope egrep speedup
- 29. ctags best practicies
- 30. Vim - laufen ctags auf aktuellen Python site-packages
Ich glaube nicht, cscope und ctags auf der regex basieren aber nicht wie IDE Syntax –
Haben Sie darüber nachgedacht [Ack] (http://beyondgrep.com/), [Ag der Silver Surfer] (https://github.com/ggreer/the_silver_searcher) oder [git grep] (http://git-scm.com/docs/git-grep)? Diese sind in der Regel viel schneller als Grep. –
Ich bin auch daran interessiert. Ich benutze derzeit Eclipse und SlickEdit, um dies zu tun. In Eclipse wird diese Funktionalität als Typhierarchie bezeichnet. Es gibt ein Projekt namens eclim, das die Eclipse-Funktionalität in Vim integriert, das ist das nächste, was ich in Vim gesehen habe. Eclim isst leider viel RAM und stürzt immer wieder in Windows ab, höchstwahrscheinlich aufgrund von Eclipse und der Forderung nach Eclipse tune Speichereinstellungen .. –