@@ -23,16 +23,19 @@ type HoverHit struct {
2323// 検索戦略(ripgrep 時):
2424// 1. ヘッダ(*.h,*.hpp)のみ検索 → struct/enum/define/typedef はここで完結
2525// 2. func の宣言しか見つからなかった場合、ソースファイルも追加検索して定義本体を取得
26- func FindHover (ctx context.Context , word , dir , glob string , includeChain ... map [string ]bool ) ([]HoverHit , error ) {
26+ func FindHover (ctx context.Context , word , dir , glob , root string , includeChain ... map [string ]bool ) ([]HoverHit , error ) {
2727 chain := map [string ]bool {}
2828 if len (includeChain ) > 0 && includeChain [0 ] != nil {
2929 chain = includeChain [0 ]
3030 }
31+ if root == "" {
32+ root = dir
33+ }
3134
3235 var hits []DefHit
3336
3437 // GNU Global が使えるなら定義位置をインデックスから直接取得
35- if GtagsAvailable (dir ) {
38+ if GtagsAvailable (root ) {
3639 gHits , err := GtagsFindHoverHits (ctx , word , dir )
3740 if err == nil && len (gHits ) > 0 {
3841 hits = gHits
@@ -44,26 +47,42 @@ func FindHover(ctx context.Context, word, dir, glob string, includeChain ...map[
4447 const maxPerQuery = 5
4548 headerGlob := "*.h,*.hpp"
4649
47- // Phase 1: ヘッダのみ
48- var err error
49- hits , err = FindDefinitionsN (ctx , word , dir , headerGlob , maxPerQuery )
50- if err != nil && ctx .Err () != nil {
51- return nil , err
50+ type phaseResult struct { hits []DefHit }
51+ ch1 := make (chan phaseResult , 1 )
52+ ch2 := make (chan phaseResult , 1 )
53+
54+ // Phase 1 と Phase 2 を並列実行
55+ go func () {
56+ h , _ := FindDefinitionsN (ctx , word , dir , headerGlob , maxPerQuery )
57+ ch1 <- phaseResult {h }
58+ }()
59+ go func () {
60+ if glob == headerGlob {
61+ ch2 <- phaseResult {}
62+ return
63+ }
64+ h , _ := FindDefinitionsN (ctx , word , dir , glob , maxPerQuery )
65+ ch2 <- phaseResult {h }
66+ }()
67+
68+ r1 , r2 := <- ch1 , <- ch2
69+ if ctx .Err () != nil {
70+ return nil , ctx .Err ()
5271 }
5372
54- // Phase 2: ソースファイルも検索してマージ
55- if glob != headerGlob && ctx . Err () == nil {
56- srcHits , _ := FindDefinitionsN ( ctx , word , dir , glob , maxPerQuery )
57- seen := map [ string ] bool {}
58- for _ , h := range hits {
59- seen [ fmt . Sprintf ( "%s:%d" , h . File , h . Line )] = true
73+ seen := map [ string ] bool {}
74+ for _ , h := range r1 . hits {
75+ key := fmt . Sprintf ( "%s:%d" , h . File , h . Line )
76+ if ! seen [ key ] {
77+ seen [ key ] = true
78+ hits = append ( hits , h )
6079 }
61- for _ , h := range srcHits {
62- key := fmt . Sprintf ( "%s:%d" , h . File , h . Line )
63- if ! seen [ key ] {
64- hits = append ( hits , h )
65- seen [key ] = true
66- }
80+ }
81+ for _ , h := range r2 . hits {
82+ key := fmt . Sprintf ( "%s:%d" , h . File , h . Line )
83+ if ! seen [ key ] {
84+ seen [key ] = true
85+ hits = append ( hits , h )
6786 }
6887 }
6988 }
0 commit comments