5 files changed,
69 insertions(+),
19 deletions(-)
Author:
Oleksandr Smirnov
olexsmir@gmail.com
Committed at:
2026-09-03 17:01:00 +0300
Authored at:
2026-09-03 16:33:45 +0300
Change ID:
pwtxrktvuyuqltrvtpmlppxotzoukksy
Parent:
961356c
M
internal/lsp/testdata/definition-include.txtar
··· 1 1 -- in.journal -- 2 -include sub.journal 2 +include su^b.journal 3 +include dir/ot^her.journal 3 4 4 5 2024-01-16 Another^ Store 5 - expenses:fo^od 100.00 EUR 6 - assets:ca^sh 6 + expenses:fo^od 100.00 EUR 7 + assets:ca^sh 8 + 9 +-- dir/other.journal -- 10 +account expenses:entertainment 11 + 12 +2024-01-13 Cinema 13 + expenses:entertainment £10 14 + assets:bank 7 15 8 16 -- sub.journal -- 9 17 account expenses:food 10 18 11 19 2024-01-15 Grocery Store 12 - expenses:food $50 13 - assets:cash 20 + expenses:food $50 21 + assets:cash 14 22 15 23 -- expect -- 16 -2:18 in.journal 2:11-2:24 17 -3:15 sub.journal 0:8-0:21 18 -4:13 sub.journal 4:4-4:15 24 +0:10 sub.journal 0:0-0:0 25 +1:14 other.journal 0:0-0:0 26 +3:18 in.journal 3:11-3:24 27 +4:13 sub.journal 0:8-0:21 28 +5:11 sub.journal 4:2-4:13
M
internal/lsp/textdocument_definition.go
··· 2 2 3 3 import ( 4 4 "context" 5 + "path/filepath" 5 6 "slices" 6 7 "sort" 8 + "strings" 7 9 8 10 "go.lsp.dev/protocol" 9 11 "go.lsp.dev/uri" ··· 30 32 if ref == nil { 31 33 return nil 32 34 } 33 - loc := resolveSymbol(ref, an) 34 - if loc == nil { 35 - return nil 36 - } 37 - return protocol.LocationSlice{*loc} 35 + return resolveSymbol(ref, an, docPath) 38 36 } 39 37 40 -func resolveSymbol(ref *symbolRef, an *analyzer.Analysis) *protocol.Location { 38 +func resolveSymbol(ref *symbolRef, an *analyzer.Analysis, docPath string) protocol.LocationSlice { 39 + var loc *protocol.Location 41 40 switch ref.kind { 42 41 case symbolAccount: 43 - return findAccountDefinition(an, ref.name) 42 + loc = findAccountDefinition(an, ref.name) 44 43 case symbolCommodity: 45 - return findCommodityDefinition(an, ref.name) 44 + loc = findCommodityDefinition(an, ref.name) 46 45 case symbolPayee: 47 - return findPayeeDefinition(an, ref.name) 46 + loc = findPayeeDefinition(an, ref.name) 47 + case symbolInclude: 48 + return includeTargets(an, docPath, ref.name) 49 + default: 50 + return nil 48 51 } 49 - return nil 52 + if loc == nil { 53 + return nil 54 + } 55 + return protocol.LocationSlice{*loc} 50 56 } 51 57 52 58 func findAccountDefinition(an *analyzer.Analysis, name string) *protocol.Location { ··· 141 147 return locationFor(an, u.FileIndex, span) 142 148 } 143 149 return nil 150 +} 151 + 152 +func includeTargets(an *analyzer.Analysis, docPath, pattern string) protocol.LocationSlice { 153 + target := filepath.Join(filepath.Dir(docPath), pattern) 154 + glob := strings.ContainsAny(target, "*?[") 155 + found := make(map[string]bool) 156 + var locs protocol.LocationSlice 157 + for _, occ := range an.Files { 158 + if found[occ.Path] { 159 + continue 160 + } 161 + if glob { 162 + if m, _ := filepath.Match(target, occ.Path); !m { 163 + continue 164 + } 165 + } else if occ.Path != target { 166 + continue 167 + } 168 + found[occ.Path] = true 169 + locs = append(locs, protocol.Location{URI: uri.File(occ.Path)}) 170 + } 171 + return locs 144 172 } 145 173 146 174 func fileIndexForEntry(a *analyzer.Analysis, d ast.Entry) int {
M
internal/lsp/textdocument_rename.go
··· 27 27 if ref == nil { 28 28 return nil, nil 29 29 } 30 + switch ref.kind { 31 + case symbolAccount, symbolCommodity, symbolPayee, symbolTag: 32 + default: 33 + return nil, nil // kinds without rename support 34 + } 30 35 31 36 return &protocol.PrepareRenamePlaceholder{ 32 37 Range: state.lineIdx.SpanRange(ref.span), ··· 147 152 if e.Name != nil && spanContains(content, e.Name.Span, cursor) { 148 153 return &symbolRef{symbolPayee, e.Name.Name, e.Name.Span} 149 154 } 155 + case *ast.IncludeDirective: 156 + if spanContains(content, e.Span, cursor) { 157 + return &symbolRef{symbolInclude, e.Path, e.Span} 158 + } 150 159 } 151 160 return nil 152 161 } ··· 160 169 symbolCommodity 161 170 symbolPayee 162 171 symbolTag 172 + symbolInclude 163 173 ) 164 174 165 175 func (s symbolKind) ToProtocol() protocol.SymbolKind {
M
internal/lsp/textdocument_rename_test.go
··· 192 192 if f.Name == "expect" || f.Name == "rename" { 193 193 continue 194 194 } 195 + if err := os.MkdirAll(filepath.Join(dir, filepath.Dir(f.Name)), 0o755); err != nil { 196 + t.Fatal(err) 197 + } 195 198 if err := os.WriteFile(filepath.Join(dir, f.Name), f.Data, 0o644); err != nil { 196 199 t.Fatal(err) 197 200 }