Skip to content

Commit 8c8539e

Browse files
committed
fix: Use cursor position for navigation to arguments
- VS was passing line spans to ISuggestedActionsSource instead of cursor position - Navigation provider now uses ITextView.Caret.Position when available - Fixes navigation actions not appearing when cursor on template properties - Update CHANGELOG for v0.7.2
1 parent e8fbbcb commit 8c8539e

File tree

3 files changed

+63
-6
lines changed

3 files changed

+63
-6
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.7.2] - 2025-09-21
11+
12+
### Fixed
13+
- Navigation to arguments now properly uses cursor position
14+
- Visual Studio was passing line spans instead of cursor position to ISuggestedActionsSource
15+
- Navigation provider now correctly uses ITextView.Caret.Position for accurate cursor detection
16+
- Fixes issue where navigation actions would not appear when cursor was on template properties
17+
1018
## [0.7.1] - 2025-09-21
1119

1220
### Fixed
@@ -322,6 +330,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
322330
- Customizable colors via Tools > Options > Environment > Fonts and Colors
323331
- Real-time highlighting as you type
324332

333+
[0.7.2]: https://github.com/willibrandon/serilog-syntax/releases/tag/v0.7.2
334+
[0.7.1]: https://github.com/willibrandon/serilog-syntax/releases/tag/v0.7.1
335+
[0.7.0]: https://github.com/willibrandon/serilog-syntax/releases/tag/v0.7.0
336+
[0.6.2]: https://github.com/willibrandon/serilog-syntax/releases/tag/v0.6.2
325337
[0.6.1]: https://github.com/willibrandon/serilog-syntax/releases/tag/v0.6.1
326338
[0.6.0]: https://github.com/willibrandon/serilog-syntax/releases/tag/v0.6.0
327339
[0.5.2]: https://github.com/willibrandon/serilog-syntax/releases/tag/v0.5.2

SerilogSyntax/Navigation/SerilogNavigationProvider.cs

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,27 @@ public async Task<bool> HasSuggestedActionsAsync(
7070
return await Task.Run(() =>
7171
{
7272
DiagnosticLogger.Log("=== HasSuggestedActionsAsync called ===");
73+
74+
// VS seems to be passing the line span instead of cursor span
75+
// Use the caret position if available, otherwise fall back to range
7376
var triggerPoint = range.Start;
77+
if (textView != null && textView.Caret != null)
78+
{
79+
triggerPoint = textView.Caret.Position.BufferPosition;
80+
DiagnosticLogger.Log($"Using caret position: {triggerPoint.Position}");
81+
}
82+
else
83+
{
84+
DiagnosticLogger.Log($"Using range start: {triggerPoint.Position}");
85+
}
86+
7487
var line = triggerPoint.GetContainingLine();
7588
var lineText = line.GetText();
7689
var lineStart = line.Start.Position;
7790

7891
DiagnosticLogger.Log($"Line text: '{lineText}'");
7992
DiagnosticLogger.Log($"Trigger position: {triggerPoint.Position}");
93+
DiagnosticLogger.Log($"Line start position: {lineStart}");
8094

8195
// Check if we're in a Serilog call
8296
var serilogMatch = SerilogCallDetector.FindSerilogCall(lineText);
@@ -102,11 +116,12 @@ public async Task<bool> HasSuggestedActionsAsync(
102116
string template;
103117
int templateStartPosition;
104118
int templateEndPosition;
105-
119+
106120
if (serilogCallLine == line)
107121
{
108122
// Same-line scenario: template starts on the same line as the Serilog call
109123
var templateMatch = FindTemplateString(lineText, serilogMatch.Index + serilogMatch.Length);
124+
DiagnosticLogger.Log($"FindTemplateString result: {(templateMatch.HasValue ? $"Found at [{templateMatch.Value.Item1}, {templateMatch.Value.Item2}]" : "Not found")}");
110125
if (!templateMatch.HasValue)
111126
{
112127
// No complete template found on this line - check if it's a multi-line template starting here
@@ -129,11 +144,18 @@ public async Task<bool> HasSuggestedActionsAsync(
129144
template = lineText.Substring(templateStart, templateEnd - templateStart);
130145
templateStartPosition = lineStart + templateStart;
131146
templateEndPosition = lineStart + templateEnd;
132-
147+
148+
DiagnosticLogger.Log($"Template found: '{template}'");
149+
DiagnosticLogger.Log($"Template position: [{templateStartPosition}, {templateEndPosition}]");
150+
133151
// Check if cursor is within template
134152
var positionInLine = triggerPoint.Position - lineStart;
153+
DiagnosticLogger.Log($"Position in line: {positionInLine}, template range in line: [{templateStart}, {templateEnd}]");
135154
if (positionInLine < templateStart || positionInLine > templateEnd)
155+
{
156+
DiagnosticLogger.Log("Cursor is outside template bounds");
136157
return false;
158+
}
137159
}
138160
}
139161
else
@@ -154,13 +176,29 @@ public async Task<bool> HasSuggestedActionsAsync(
154176

155177
// Parse template to find properties
156178
var properties = _parser.Parse(template).ToList();
157-
179+
DiagnosticLogger.Log($"Found {properties.Count} properties in template");
180+
158181
// Find which property the cursor is on
159182
var cursorPosInTemplate = triggerPoint.Position - templateStartPosition;
160-
var property = properties.FirstOrDefault(p =>
161-
cursorPosInTemplate >= p.BraceStartIndex &&
183+
DiagnosticLogger.Log($"Cursor position in template: {cursorPosInTemplate}");
184+
185+
var property = properties.FirstOrDefault(p =>
186+
cursorPosInTemplate >= p.BraceStartIndex &&
162187
cursorPosInTemplate <= p.BraceEndIndex);
163188

189+
if (property != null)
190+
{
191+
DiagnosticLogger.Log($"Found property: {property.Name} at [{property.BraceStartIndex}, {property.BraceEndIndex}]");
192+
}
193+
else
194+
{
195+
DiagnosticLogger.Log("No property found at cursor position");
196+
foreach (var p in properties)
197+
{
198+
DiagnosticLogger.Log($" Property '{p.Name}' at [{p.BraceStartIndex}, {p.BraceEndIndex}]");
199+
}
200+
}
201+
164202
return property != null;
165203
}, cancellationToken);
166204
}
@@ -177,7 +215,14 @@ public IEnumerable<SuggestedActionSet> GetSuggestedActions(
177215
SnapshotSpan range,
178216
CancellationToken cancellationToken)
179217
{
218+
// VS seems to be passing the line span instead of cursor span
219+
// Use the caret position if available, otherwise fall back to range
180220
var triggerPoint = range.Start;
221+
if (textView != null && textView.Caret != null)
222+
{
223+
triggerPoint = textView.Caret.Position.BufferPosition;
224+
}
225+
181226
var line = triggerPoint.GetContainingLine();
182227
var lineText = line.GetText();
183228
var lineStart = line.Start.Position;

SerilogSyntax/source.extension.vsixmanifest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
33
<Metadata>
4-
<Identity Id="SerilogSyntax.33851f71-44fa-46e0-9f66-e0f039ca2681" Version="0.1.0" Language="en-US" Publisher="mtlog" />
4+
<Identity Id="SerilogSyntax.33851f71-44fa-46e0-9f66-e0f039ca2681" Version="0.7.2" Language="en-US" Publisher="mtlog" />
55
<DisplayName>Serilog Syntax Highlighting</DisplayName>
66
<Description>Provides syntax highlighting, navigation, and brace matching for Serilog message templates in C#/.NET projects. Supports all property types including standard, destructured, stringified, and positional properties.</Description>
77
<MoreInfo>https://github.com/willibrandon/serilog-syntax</MoreInfo>

0 commit comments

Comments
 (0)