2014-09-04 3 views
5

몇 개의 레이어가있는 약간 큰 코드베이스에는 vim 또는 명령 줄에서 기본 클래스에서 파생 된 모든 클래스를 찾는 방법이 있습니다 수업? grep은 옵션이지만 grep이 색인을 생성하지 않기 때문에 속도가 느릴 수 있습니다.C++, cscope, ctags 및 vim :이 클래스에서 상속받은 클래스 찾기

+0

내가 그렇게, cscope를하고 ctags를이 정규식을 기반으로 생각하지만, IDE –

+0

같은 구문하지 않는 당신이 생각 해 봤나 [긍정] (http://beyondgrep.com/), [의 Ag 실버 서퍼] (https://github.com/ggreer/the_silver_searcher) 또는 [git grep] (http://git-scm.com/docs/git-grep)? 이들은 일반적으로 grep보다 훨씬 빠릅니다. –

+0

나는 이것에도 관심이있다. 현재 Eclipse와 SlickEdit을 사용하고 있습니다. Eclipse에서이 기능을 유형 계층 구조라고합니다. 이클립스 기능을 Vim에 통합 한 eclim이라는 프로젝트가있다. Vim에서 가장 친숙한 프로그램이다. 불행하게도 eclim은 많은 RAM을 필요로하며, Windows에서 끊임없이 충돌한다. –

답변

3

어느 cscope의도 ctags를 우리가 직접 상속을 처리 할 수 ​​있지만 파생 클래스는 또한 색인하고 있기 때문에 그 문제를 해결하려면 상대적으로 쉽게 입니다 - 명령을 두드리는하여 수행됩니다. "C 기호"Foobar을 찾고 cscope의에서

cscope의

은 일반적으로 원래의 클래스 그것을 상속 클래스를 나열합니다. 검색은 데이터베이스에 대해 수행되므로 번개가 빠릅니다.

또는, Foobar에서 상속 클래스를 나열하는 :.*Foobar 같은 패턴으로 cscope의의 egrep을 검색하는 기능을 사용할 수 있습니다.

그래서 "이 클래스에서 상속 한 클래스 찾기"명령을 사용하지 않아도 많은 노력을 기울이지 않아도 작업을 완료 할 수 있습니다.

ctags를

ctags를 사용하면 --fields=+i와 상속 정보를 포함 할 수 있지만이 정보는 빔에서 직접 사용할 수 없습니다. inherits 필드는 Vim에서 구문 분석되므로 taglist()을 사용하여 빠르고 더러운 솔루션을 작성할 수 있습니다.

ACK, AG

그 두 프로그램이 더 많거나 적은 그렙처럼 작동하지만,이 소스 코드에서 검색으로 대상으로는 그래서 그들은 그렙에 비해 정말 빠릅니다. 관련 라인은 여기

:grep :.*<C-r><C-w><CR> 

: 내 빔 설정에서

:grep은 같을 것이다 커서 아래에있는 클래스에서 파생 된 클래스 검색, 그래서 기본 grep 대신 ag 프로그램을 실행하도록 설정되어 내 ~/.vimrc에서 :

if executable("ag") 
    set grepprg=ag\ --nogroup\ --nocolor\ --ignore-case\ --column 
    set grepformat=%f:%l:%c:%m,%f:%l:%m 
endif 
+0

': Ggrep' 명령으로 fugitive와 vim을 사용하여 속도를 높이고 있습니다. 이 개선은 코드가 내 게시물에서 언급되지 않은 git repo가되어야하지만 또 다른 대안입니다. –

2

lh-cpp에서 나는 :Children 명령을 정의합니다. 그것은 ctags 데이터베이스에 의존하고 결과적으로 매우 제한적입니다.

두 가지 옵션 매개 변수가 필요합니다. 찾을 수있는 네임 스페이스 (피할 수있는 방법을 찾지 못했습니다)와 상위 클래스의 이름 ->:Children [!] {namespace} {parent-class}입니다.

이 명령은 최대한 많은 정보를 캐시하려고합니다. 따라서 ctags 데이터베이스에서 관련 정보가 변경되면 캐시를 업데이트해야합니다. >:Children!

1

나는 정력이 모든 자식 클래스를 나열 할 수있는 올바른 도구입니다 생각하지 않습니다. 대신 doxygen을 사용하여 소스 코드에 대한 문서를 생성하는 것이 좋습니다.doxygen이 약간의 시간을 필요로하지만 모든 클래스에 대해 문서/다이어그램을 사용할 수 있으며 이는 분명하고 빠릅니다.

+0

이것은 그래픽 인터페이스를 사용하여 개발 중이라고 가정합니다. 때로는 devbox가 doxygen 파일을 호스트 할 웹 서버를 가지고 있어야한다는 것을 의미하는 ssh를 통해 minty (cygwins 터미널)를 사용해야합니다. –

+0

네, 그렇습니다. 그리고 이미 SSH를 제공하고있는 Linux/Unix 서버는 웹 서버를 쉽게 배포 할 수 있으며 doxygen 페이지 내에 간단한 검색 엔진을 제공하는 웹 서버에서 PHP를 활성화하는 것이 좋습니다. – Chandler

+0

Eclipse와 SlickEdit에는 클래스에 대한 상속 트리와 재정의 된 메소드의 트리 목록을 나열하는 방법이 있습니다. Eclipse에서 Type Hierarchy라고하며 OO 언어로 코딩 할 때 IDE에서 가장 유용한 기능 중 하나입니다. Doxygen은 정말 유용하지만, "Type Hierarchy"를 간략하게 살펴볼 필요가있을 때 과잉입니다. –

2

상속 정보 (see the --fields option)를 사용하여 Exuberant CTags로 태그 파일을 빌드하면 다음 스크립트가 작동합니다. 클래스 이름 (예 : :Inherits Foo) 또는 정규 표현식을 사용하는 :Inherits 명령을 추가합니다.

:tag 명령과 마찬가지로, 정규식을 사용하여 검색하려면 '\'문자를 앞에 붙여야합니다. :Inherits \Foo.*.

:ll, :lne, :lp 등으로 검색 한 결과가 창 위치 목록에 저장됩니다. VIM은 스크립트가 내가 선호하는 태그 목록을 수정하는 것을 허용하지 않습니다.

내가 taglist()을 사용하지 않는 이유가 궁금하다면 큰 태그 파일의 경우 taglist()이 매우 느리기 때문입니다. 원래 게시물의 버전이 taglist()이었습니다. 궁금한 점이 있으면 편집 기록을 탐색 할 수 있습니다.

" 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>')