all repos

clerk @ e12aa47

missing tooling for ledger/hledger
3 files changed, 82 insertions(+), 89 deletions(-)
refactor: lsp: better naming of functions; move some stuff around
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2026-09-10 13:33:34 +0300
Authored at: 2026-09-09 14:10:26 +0300
Change ID: xmukzkynsxmntxwysrzzspqnoxtvqnxl
Parent: 1b9e6e1
M internal/lsp/textdocument_definition.go
···
        149
        149
         	return nil

      
        150
        150
         }

      
        151
        151
         

      
        
        152
        +func definitionLocation(an *analyzer.Analysis, s scoredSymbol) *protocol.Location {

      
        
        153
        +	switch s.kind {

      
        
        154
        +	case symbolAccount:

      
        
        155
        +		return findAccountDefinition(an, s.name)

      
        
        156
        +	case symbolTransaction:

      
        
        157
        +		return findTransactionDefinition(an, s.tnxEntry)

      
        
        158
        +	case symbolCommodity:

      
        
        159
        +		return findCommodityDefinition(an, s.name)

      
        
        160
        +	case symbolPayee:

      
        
        161
        +		return findPayeeDefinition(an, s.name)

      
        
        162
        +	case symbolTag:

      
        
        163
        +		return findTagDefinition(an, s.name)

      
        
        164
        +	}

      
        
        165
        +	return nil

      
        
        166
        +}

      
        
        167
        +

      
        152
        168
         func includeTargets(an *analyzer.Analysis, docPath, pattern string) protocol.LocationSlice {

      
        153
        169
         	target := filepath.Join(filepath.Dir(docPath), pattern)

      
        154
        170
         	glob := strings.ContainsAny(target, "*?[")

      
M internal/lsp/textdocument_selection_range.go
···
        60
        60
         func selectionInEntry(content string, e ast.Entry, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) protocol.SelectionRange {

      
        61
        61
         	switch t := e.(type) {

      
        62
        62
         	case *ast.Transaction:

      
        63
        
        -		return transactionSelection(content, t, li, cursor, parent)

      
        
        63
        +		return selTransaction(content, t, li, cursor, parent)

      
        64
        64
         	case *ast.PeriodicTransaction:

      
        65
        
        -		return periodicSelection(content, t, li, cursor, parent)

      
        
        65
        +		return selPeriodicTransaction(content, t, li, cursor, parent)

      
        66
        66
         	case *ast.AutomatedTransaction:

      
        67
        
        -		return automatedSelection(content, t, li, cursor, parent)

      
        
        67
        +		return selAutomatedTransaction(content, t, li, cursor, parent)

      
        68
        68
         	case *ast.AccountDirective:

      
        69
        
        -		return accountDirectiveSelection(content, t, li, cursor, parent)

      
        
        69
        +		return selAccountDirective(content, t, li, cursor, parent)

      
        70
        70
         	case *ast.CommodityDirective:

      
        71
        
        -		return commodityDirectiveSelection(content, t, li, cursor, parent)

      
        
        71
        +		return selCommodityDirective(content, t, li, cursor, parent)

      
        72
        72
         	case *ast.PayeeDirective:

      
        73
        73
         		if t.Name != "" {

      
        74
        
        -			if sel, ok := selectionForSpan(content, li, t.NameSpan, cursor, parent); ok {

      
        
        74
        +			if sel, ok := selForSpan(content, li, t.NameSpan, cursor, parent); ok {

      
        75
        75
         				return sel

      
        76
        76
         			}

      
        77
        77
         		}

      
        78
        78
         		return commentOrParent(content, t.Comment, li, cursor, parent)

      
        79
        79
         	case *ast.TagDirective:

      
        80
        80
         		if sp, ok := tagDirectiveSpan(content, t); ok {

      
        81
        
        -			if sel, ok := selectionForSpan(content, li, sp, cursor, parent); ok {

      
        
        81
        +			if sel, ok := selForSpan(content, li, sp, cursor, parent); ok {

      
        82
        82
         				return sel

      
        83
        83
         			}

      
        84
        84
         		}

      
        85
        85
         		return commentOrParent(content, t.Comment, li, cursor, parent)

      
        86
        86
         	case *ast.AliasDirective:

      
        87
        
        -		if sel, ok := accountSelection(content, &t.From, li, cursor, parent); ok {

      
        
        87
        +		if sel, ok := selAccount(content, &t.From, li, cursor, parent); ok {

      
        88
        88
         			return sel

      
        89
        89
         		}

      
        90
        
        -		if sel, ok := accountSelection(content, &t.To, li, cursor, parent); ok {

      
        
        90
        +		if sel, ok := selAccount(content, &t.To, li, cursor, parent); ok {

      
        91
        91
         			return sel

      
        92
        92
         		}

      
        93
        93
         		return commentOrParent(content, t.Comment, li, cursor, parent)

      
        94
        94
         	case *ast.DefaultCommodityDirective:

      
        95
        
        -		if sel, ok := amountSelection(content, &t.Amount, li, cursor, parent); ok {

      
        
        95
        +		if sel, ok := selAmount(content, &t.Amount, li, cursor, parent); ok {

      
        96
        96
         			return sel

      
        97
        97
         		}

      
        98
        98
         		return commentOrParent(content, t.Comment, li, cursor, parent)

      
        99
        99
         	case *ast.MarketPriceDirective:

      
        100
        
        -		if sel, ok := selectionForSpan(content, li, t.DateTime.Date.Span, cursor, parent); ok {

      
        
        100
        +		if sel, ok := selForSpan(content, li, t.DateTime.Date.Span, cursor, parent); ok {

      
        101
        101
         			return sel

      
        102
        102
         		}

      
        103
        103
         		if t.DateTime.Time != nil {

      
        104
        
        -			if sel, ok := selectionForSpan(content, li, t.DateTime.Time.Span, cursor, parent); ok {

      
        
        104
        +			if sel, ok := selForSpan(content, li, t.DateTime.Time.Span, cursor, parent); ok {

      
        105
        105
         				return sel

      
        106
        106
         			}

      
        107
        107
         		}

      
        108
        
        -		if sel, ok := amountSelection(content, &t.Amount, li, cursor, parent); ok {

      
        
        108
        +		if sel, ok := selAmount(content, &t.Amount, li, cursor, parent); ok {

      
        109
        109
         			return sel

      
        110
        110
         		}

      
        111
        111
         		return commentOrParent(content, t.Comment, li, cursor, parent)

      
        112
        112
         	case *ast.ConversionDirective:

      
        113
        
        -		if sel, ok := amountSelection(content, &t.From, li, cursor, parent); ok {

      
        
        113
        +		if sel, ok := selAmount(content, &t.From, li, cursor, parent); ok {

      
        114
        114
         			return sel

      
        115
        115
         		}

      
        116
        
        -		if sel, ok := amountSelection(content, &t.To, li, cursor, parent); ok {

      
        
        116
        +		if sel, ok := selAmount(content, &t.To, li, cursor, parent); ok {

      
        117
        117
         			return sel

      
        118
        118
         		}

      
        119
        119
         		return commentOrParent(content, t.Comment, li, cursor, parent)

      ···
        121
        121
         	return parent

      
        122
        122
         }

      
        123
        123
         

      
        124
        
        -func transactionSelection(content string, t *ast.Transaction, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) protocol.SelectionRange {

      
        
        124
        +func selTransaction(content string, t *ast.Transaction, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) protocol.SelectionRange {

      
        125
        125
         	var header [6]token.Span // date, second date, status, code, payee, note

      
        126
        126
         	sps := append(header[:0], t.Date.Span)

      
        127
        127
         	if t.SecondDate != nil {

      ···
        140
        140
         		sps = append(sps, t.NoteSpan)

      
        141
        141
         	}

      
        142
        142
         	for _, sp := range sps {

      
        143
        
        -		if sel, ok := selectionForSpan(content, li, sp, cursor, parent); ok {

      
        
        143
        +		if sel, ok := selForSpan(content, li, sp, cursor, parent); ok {

      
        144
        144
         			return sel

      
        145
        145
         		}

      
        146
        146
         	}

      
        147
        
        -	return commentsAndPostingsSelection(content, t.Comment, t.HeaderComments, t.Postings, li, cursor, parent)

      
        
        147
        +	return selCommentsAndPostings(content, t.Comment, t.HeaderComments, t.Postings, li, cursor, parent)

      
        148
        148
         }

      
        149
        149
         

      
        150
        
        -// commentsAndPostingsSelection descends into an entry's inline comment, header

      
        151
        
        -// comments, then postings; returns parent when none contains the cursor.

      
        152
        
        -func commentsAndPostingsSelection(content string, inline *ast.Comment, headers []*ast.Comment, postings []ast.Posting, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) protocol.SelectionRange {

      
        153
        
        -	if sel, ok := commentSelection(content, inline, li, cursor, parent); ok {

      
        
        150
        +func selCommentsAndPostings(content string, inline *ast.Comment, headers []*ast.Comment, postings []ast.Posting, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) protocol.SelectionRange {

      
        
        151
        +	if sel, ok := selComment(content, inline, li, cursor, parent); ok {

      
        154
        152
         		return sel

      
        155
        153
         	}

      
        156
        154
         	for _, c := range headers {

      
        157
        
        -		if sel, ok := commentSelection(content, c, li, cursor, parent); ok {

      
        
        155
        +		if sel, ok := selComment(content, c, li, cursor, parent); ok {

      
        158
        156
         			return sel

      
        159
        157
         		}

      
        160
        158
         	}

      
        161
        
        -	if sel, ok := postingsSelection(content, postings, li, cursor, parent); ok {

      
        
        159
        +	if sel, ok := selPostings(content, postings, li, cursor, parent); ok {

      
        162
        160
         		return sel

      
        163
        161
         	}

      
        164
        162
         	return parent

      
        165
        163
         }

      
        166
        164
         

      
        167
        
        -func periodicSelection(content string, pt *ast.PeriodicTransaction, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) protocol.SelectionRange {

      
        168
        
        -	if sel, ok := selectionForSpan(content, li, pt.Period.Span, cursor, parent); ok {

      
        
        165
        +func selPeriodicTransaction(content string, pt *ast.PeriodicTransaction, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) protocol.SelectionRange {

      
        
        166
        +	if sel, ok := selForSpan(content, li, pt.Period.Span, cursor, parent); ok {

      
        169
        167
         		if d := pt.Period.From; d != nil {

      
        170
        
        -			if sub, ok := selectionForSpan(content, li, d.Span, cursor, sel); ok {

      
        
        168
        +			if sub, ok := selForSpan(content, li, d.Span, cursor, sel); ok {

      
        171
        169
         				return sub

      
        172
        170
         			}

      
        173
        171
         		}

      
        174
        172
         		if d := pt.Period.To; d != nil {

      
        175
        
        -			if sub, ok := selectionForSpan(content, li, d.Span, cursor, sel); ok {

      
        
        173
        +			if sub, ok := selForSpan(content, li, d.Span, cursor, sel); ok {

      
        176
        174
         				return sub

      
        177
        175
         			}

      
        178
        176
         		}

      
        179
        177
         		return sel

      
        180
        178
         	}

      
        181
        179
         	if pt.Description != "" {

      
        182
        
        -		if sel, ok := selectionForSpan(content, li, pt.DescriptionSpan, cursor, parent); ok {

      
        
        180
        +		if sel, ok := selForSpan(content, li, pt.DescriptionSpan, cursor, parent); ok {

      
        183
        181
         			return sel

      
        184
        182
         		}

      
        185
        183
         	}

      
        186
        
        -	return commentsAndPostingsSelection(content, pt.Comment, pt.HeaderComments, pt.Postings, li, cursor, parent)

      
        
        184
        +	return selCommentsAndPostings(content, pt.Comment, pt.HeaderComments, pt.Postings, li, cursor, parent)

      
        187
        185
         }

      
        188
        186
         

      
        189
        
        -func automatedSelection(content string, at *ast.AutomatedTransaction, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) protocol.SelectionRange {

      
        190
        
        -	if sel, ok := selectionForSpan(content, li, at.ExprSpan, cursor, parent); ok {

      
        
        187
        +func selAutomatedTransaction(content string, at *ast.AutomatedTransaction, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) protocol.SelectionRange {

      
        
        188
        +	if sel, ok := selForSpan(content, li, at.ExprSpan, cursor, parent); ok {

      
        191
        189
         		return sel

      
        192
        190
         	}

      
        193
        
        -	return commentsAndPostingsSelection(content, at.Comment, at.HeaderComments, at.Postings, li, cursor, parent)

      
        
        191
        +	return selCommentsAndPostings(content, at.Comment, at.HeaderComments, at.Postings, li, cursor, parent)

      
        194
        192
         }

      
        195
        193
         

      
        196
        
        -func accountDirectiveSelection(content string, d *ast.AccountDirective, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) protocol.SelectionRange {

      
        197
        
        -	if sel, ok := accountSelection(content, &d.Account, li, cursor, parent); ok {

      
        
        194
        +func selAccountDirective(content string, d *ast.AccountDirective, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) protocol.SelectionRange {

      
        
        195
        +	if sel, ok := selAccount(content, &d.Account, li, cursor, parent); ok {

      
        198
        196
         		return sel

      
        199
        197
         	}

      
        200
        198
         	for i := range d.Subdirectives {

      
        201
        199
         		sd := &d.Subdirectives[i]

      
        202
        200
         		if sd.Kind == ast.SubdirectiveComment {

      
        203
        
        -			if sel, ok := commentSelection(content, sd.Comment, li, cursor, parent); ok {

      
        
        201
        +			if sel, ok := selComment(content, sd.Comment, li, cursor, parent); ok {

      
        204
        202
         				return sel

      
        205
        203
         			}

      
        206
        204
         			continue

      
        207
        205
         		}

      
        208
        
        -		if sel, ok := selectionForSpan(content, li, sd.ValueSpan, cursor, parent); ok {

      
        
        206
        +		if sel, ok := selForSpan(content, li, sd.ValueSpan, cursor, parent); ok {

      
        209
        207
         			return sel

      
        210
        208
         		}

      
        211
        209
         	}

      
        212
        210
         	return commentOrParent(content, d.Comment, li, cursor, parent)

      
        213
        211
         }

      
        214
        212
         

      
        215
        
        -func commodityDirectiveSelection(content string, d *ast.CommodityDirective, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) protocol.SelectionRange {

      
        216
        
        -	if sel, ok := selectionForSpan(content, li, d.CommoditySpan, cursor, parent); ok {

      
        
        213
        +func selCommodityDirective(content string, d *ast.CommodityDirective, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) protocol.SelectionRange {

      
        
        214
        +	if sel, ok := selForSpan(content, li, d.CommoditySpan, cursor, parent); ok {

      
        217
        215
         		return sel

      
        218
        216
         	}

      
        219
        217
         	if d.FormatSub != nil {

      
        220
        
        -		if sel, ok := amountSelection(content, &d.FormatSub.Amount, li, cursor, parent); ok {

      
        
        218
        +		if sel, ok := selAmount(content, &d.FormatSub.Amount, li, cursor, parent); ok {

      
        221
        219
         			return sel

      
        222
        220
         		}

      
        223
        221
         	}

      
        224
        222
         	return commentOrParent(content, d.Comment, li, cursor, parent)

      
        225
        223
         }

      
        226
        224
         

      
        227
        
        -// postingsSelection returns the selection inside the posting containing cursor.

      
        228
        
        -func postingsSelection(content string, postings []ast.Posting, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) (protocol.SelectionRange, bool) {

      
        
        225
        +func selPostings(content string, postings []ast.Posting, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) (protocol.SelectionRange, bool) {

      
        229
        226
         	for i := range postings {

      
        230
        227
         		p := &postings[i]

      
        231
        
        -		postingSel, ok := selectionForSpan(content, li, p.Span, cursor, parent)

      
        
        228
        +		postingSel, ok := selForSpan(content, li, p.Span, cursor, parent)

      
        232
        229
         		if !ok {

      
        233
        230
         			continue

      
        234
        231
         		}

      
        235
        
        -		return postingSelection(content, postings[i], li, cursor, postingSel), true

      
        
        232
        +		return selPosting(content, postings[i], li, cursor, postingSel), true

      
        236
        233
         	}

      
        237
        234
         	return protocol.SelectionRange{}, false

      
        238
        235
         }

      
        239
        236
         

      
        240
        
        -func postingSelection(content string, p ast.Posting, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) protocol.SelectionRange {

      
        
        237
        +func selPosting(content string, p ast.Posting, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) protocol.SelectionRange {

      
        241
        238
         	if p.Status != ast.StatusNone {

      
        242
        
        -		if sel, ok := selectionForSpan(content, li, p.StatusSpan, cursor, parent); ok {

      
        
        239
        +		if sel, ok := selForSpan(content, li, p.StatusSpan, cursor, parent); ok {

      
        243
        240
         			return sel

      
        244
        241
         		}

      
        245
        242
         	}

      
        246
        
        -	if sel, ok := accountSelection(content, &p.Account, li, cursor, parent); ok {

      
        
        243
        +	if sel, ok := selAccount(content, &p.Account, li, cursor, parent); ok {

      
        247
        244
         		return sel

      
        248
        245
         	}

      
        249
        
        -	if sel, ok := amountSelection(content, p.Amount, li, cursor, parent); ok {

      
        
        246
        +	if sel, ok := selAmount(content, p.Amount, li, cursor, parent); ok {

      
        250
        247
         		return sel

      
        251
        248
         	}

      
        252
        249
         	if p.Cost != nil {

      
        253
        
        -		if sel, ok := selectionForSpan(content, li, p.Cost.Span, cursor, parent); ok {

      
        
        250
        +		if sel, ok := selForSpan(content, li, p.Cost.Span, cursor, parent); ok {

      
        254
        251
         			return sel

      
        255
        252
         		}

      
        256
        253
         	}

      
        257
        254
         	if p.Balance != nil {

      
        258
        
        -		if sel, ok := selectionForSpan(content, li, p.Balance.Span, cursor, parent); ok {

      
        
        255
        +		if sel, ok := selForSpan(content, li, p.Balance.Span, cursor, parent); ok {

      
        259
        256
         			return sel

      
        260
        257
         		}

      
        261
        258
         	}

      
        262
        
        -	if sel, ok := commentSelection(content, p.Comment, li, cursor, parent); ok {

      
        
        259
        +	if sel, ok := selComment(content, p.Comment, li, cursor, parent); ok {

      
        263
        260
         		return sel

      
        264
        261
         	}

      
        265
        262
         	for i := range p.Comments {

      
        266
        
        -		if sel, ok := commentSelection(content, &p.Comments[i], li, cursor, parent); ok {

      
        
        263
        +		if sel, ok := selComment(content, &p.Comments[i], li, cursor, parent); ok {

      
        267
        264
         			return sel

      
        268
        265
         		}

      
        269
        266
         	}

      
        270
        267
         	return parent

      
        271
        268
         }

      
        272
        269
         

      
        273
        
        -func accountSelection(content string, a *ast.Account, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) (protocol.SelectionRange, bool) {

      
        274
        
        -	accountSel, ok := selectionForSpan(content, li, a.Span, cursor, parent)

      
        
        270
        +func selAccount(content string, a *ast.Account, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) (protocol.SelectionRange, bool) {

      
        
        271
        +	accountSel, ok := selForSpan(content, li, a.Span, cursor, parent)

      
        275
        272
         	if !ok {

      
        276
        273
         		return protocol.SelectionRange{}, false

      
        277
        274
         	}

      ···
        279
        276
         		return accountSel, true

      
        280
        277
         	}

      
        281
        278
         	for i := range a.Name {

      
        282
        
        -		if sel, ok := selectionForSpan(content, li, a.Name[i].Span, cursor, accountSel); ok {

      
        
        279
        +		if sel, ok := selForSpan(content, li, a.Name[i].Span, cursor, accountSel); ok {

      
        283
        280
         			return sel, true

      
        284
        281
         		}

      
        285
        282
         	}

      
        286
        283
         	return accountSel, true

      
        287
        284
         }

      
        288
        285
         

      
        289
        
        -func amountSelection(content string, am *ast.Amount, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) (protocol.SelectionRange, bool) {

      
        
        286
        +func selAmount(content string, am *ast.Amount, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) (protocol.SelectionRange, bool) {

      
        290
        287
         	if am == nil {

      
        291
        288
         		return protocol.SelectionRange{}, false

      
        292
        289
         	}

      
        293
        
        -	amountSel, ok := selectionForSpan(content, li, am.Span, cursor, parent)

      
        
        290
        +	amountSel, ok := selForSpan(content, li, am.Span, cursor, parent)

      
        294
        291
         	if !ok {

      
        295
        292
         		return protocol.SelectionRange{}, false

      
        296
        293
         	}

      
        297
        
        -	if sel, ok := selectionForSpan(content, li, am.CommoditySpan, cursor, amountSel); ok {

      
        
        294
        +	if sel, ok := selForSpan(content, li, am.CommoditySpan, cursor, amountSel); ok {

      
        298
        295
         		return sel, true

      
        299
        296
         	}

      
        300
        297
         	qStart, qEnd := quantitySpan(content, am)

      
        301
        298
         	if qEnd > qStart {

      
        302
        
        -		if sel, ok := selectionForSpan(content, li, token.Span{Start: token.Pos{Offset: qStart}, End: token.Pos{Offset: qEnd}}, cursor, amountSel); ok {

      
        
        299
        +		if sel, ok := selForSpan(content, li, token.Span{Start: token.Pos{Offset: qStart}, End: token.Pos{Offset: qEnd}}, cursor, amountSel); ok {

      
        303
        300
         			return sel, true

      
        304
        301
         		}

      
        305
        302
         	}

      
        306
        303
         	return amountSel, true

      
        307
        304
         }

      
        308
        305
         

      
        309
        
        -// selectionForSpan selects span nested in parent when span contains cursor.

      
        310
        
        -func selectionForSpan(content string, li *lsputil.LineIndex, span token.Span, cursor int, parent protocol.SelectionRange) (protocol.SelectionRange, bool) {

      
        311
        
        -	if !spanContains(content, span, cursor) {

      
        312
        
        -		return protocol.SelectionRange{}, false

      
        313
        
        -	}

      
        314
        
        -	return protocol.SelectionRange{Range: li.SpanRange(span), Parent: &parent}, true

      
        315
        
        -}

      
        316
        
        -

      
        317
        
        -// commentSelection returns a selection inside comment when the cursor is on it:

      
        318
        
        -// the tag key when the cursor is on a tag, else the whole comment line.

      
        319
        
        -func commentSelection(content string, c *ast.Comment, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) (protocol.SelectionRange, bool) {

      
        
        306
        +func selComment(content string, c *ast.Comment, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) (protocol.SelectionRange, bool) {

      
        320
        307
         	if c == nil {

      
        321
        308
         		return protocol.SelectionRange{}, false

      
        322
        309
         	}

      
        323
        
        -	commentSel, ok := selectionForSpan(content, li, c.Span, cursor, parent)

      
        
        310
        +	commentSel, ok := selForSpan(content, li, c.Span, cursor, parent)

      
        324
        311
         	if !ok {

      
        325
        312
         		return protocol.SelectionRange{}, false

      
        326
        313
         	}

      ···
        330
        317
         	return commentSel, true

      
        331
        318
         }

      
        332
        319
         

      
        333
        
        -// commentOrParent is commentSelection with parent as the fallback.

      
        
        320
        +func selForSpan(content string, li *lsputil.LineIndex, span token.Span, cursor int, parent protocol.SelectionRange) (protocol.SelectionRange, bool) {

      
        
        321
        +	if !spanContains(content, span, cursor) {

      
        
        322
        +		return protocol.SelectionRange{}, false

      
        
        323
        +	}

      
        
        324
        +	return protocol.SelectionRange{Range: li.SpanRange(span), Parent: &parent}, true

      
        
        325
        +}

      
        
        326
        +

      
        334
        327
         func commentOrParent(content string, c *ast.Comment, li *lsputil.LineIndex, cursor int, parent protocol.SelectionRange) protocol.SelectionRange {

      
        335
        
        -	if sel, ok := commentSelection(content, c, li, cursor, parent); ok {

      
        
        328
        +	if sel, ok := selComment(content, c, li, cursor, parent); ok {

      
        336
        329
         		return sel

      
        337
        330
         	}

      
        338
        331
         	return parent

      
M internal/lsp/workspace_symbol.go
···
        95
        95
         	return symbols

      
        96
        96
         }

      
        97
        97
         

      
        98
        
        -func definitionLocation(an *analyzer.Analysis, s scoredSymbol) *protocol.Location {

      
        99
        
        -	switch s.kind {

      
        100
        
        -	case symbolAccount:

      
        101
        
        -		return findAccountDefinition(an, s.name)

      
        102
        
        -	case symbolTransaction:

      
        103
        
        -		return findTransactionDefinition(an, s.tnxEntry)

      
        104
        
        -	case symbolCommodity:

      
        105
        
        -		return findCommodityDefinition(an, s.name)

      
        106
        
        -	case symbolPayee:

      
        107
        
        -		return findPayeeDefinition(an, s.name)

      
        108
        
        -	case symbolTag:

      
        109
        
        -		return findTagDefinition(an, s.name)

      
        110
        
        -	}

      
        111
        
        -	return nil

      
        112
        
        -}

      
        113
        
        -

      
        114
        98
         func transactionName(e ast.Entry) string {

      
        115
        99
         	var b strings.Builder

      
        116
        100
         	switch e := e.(type) {