Skip to content

Commit 5ae9fae

Browse files
committed
try to account for format specifiers
1 parent f771230 commit 5ae9fae

File tree

2 files changed

+36
-14
lines changed

2 files changed

+36
-14
lines changed

src/FsAutoComplete.Core/NestedLanguages.fs

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ type private StringParameter =
1717
rangesToRemove: Range array
1818
parameterPosition: int }
1919

20+
let private pattern =
21+
System.Text.RegularExpressions.Regex(
22+
@"(?<percent>%)(?<flags>[0\+\-]?)(?<width>\d*)(\.(?<precision>\d+))?(?<type>[bscdiuxXoBeEfFgGMOAat%])",
23+
System.Text.RegularExpressions.RegexOptions.Compiled
24+
)
25+
26+
let private isFormatSpecifier (text: string) = pattern.Match(text)
2027

2128
/// for virtual documents based on interpolated strings we need to remove two kinds of trivia from the overall string portions.
2229
/// * for interpolation expressions we need to remove the entire range of the expression - this will be invisible to the virtual document since it is F# code.
@@ -35,19 +42,33 @@ let private discoverRangesToRemoveForInterpolatedString
3542
match part with
3643
| SynInterpolatedStringPart.FillExpr(fillExpr = e) -> [| e.Range |]
3744
// for the first part we have whatever 'leading' element on the left and a trailing interpolation piece (which can include a format specifier) on the right
38-
| SynInterpolatedStringPart.String(range = range) when index = 0 ->
45+
| SynInterpolatedStringPart.String(value = value; range = range) when index = 0 ->
3946
[|
4047
// leading tokens adjustment
4148
// GAP: we don't know how many interpolation $ or " there are, so we are guessing
42-
match stringKind with
43-
| SynStringKind.Regular ->
44-
// 'regular' means $" leading identifier
45-
range.WithEnd(range.Start.WithColumn(range.StartColumn + 2))
46-
| SynStringKind.TripleQuote ->
47-
// 'triple quote' means $""" leading identifier
48-
range.WithEnd(range.Start.WithColumn(range.StartColumn + 4))
49-
// there's no such thing as a verbatim interpolated string
50-
| SynStringKind.Verbatim -> ()
49+
let startRange =
50+
match stringKind with
51+
| SynStringKind.Regular ->
52+
// 'regular' means $" leading identifier
53+
range.WithEnd(range.Start.WithColumn(range.StartColumn + 2))
54+
| SynStringKind.TripleQuote ->
55+
// 'triple quote' means $""" leading identifier
56+
range.WithEnd(range.Start.WithColumn(range.StartColumn + 4))
57+
// there's no such thing as a verbatim interpolated string
58+
| SynStringKind.Verbatim -> range
59+
60+
61+
// GAP: we don't know if there's a format specifier at the front: %[flags][width][.precision][type]
62+
// flags are 0,+,-, width is an integer, precision is `.` followed by an integer, type is one of the following: b, s, c, d, i, u, x, X, o, B, e, E, f, F, g, G, M, O, A, a, t, %
63+
let adjustedRangeForFormatSpecifier =
64+
let formatmatch = isFormatSpecifier value
65+
66+
if formatmatch.Success then
67+
startRange.WithEnd(startRange.End.WithColumn(startRange.StartColumn + formatmatch.Index - 1))
68+
else
69+
startRange
70+
71+
adjustedRangeForFormatSpecifier
5172

5273
// trailing token adjustment- only an opening bracket {
5374
// GAP: this is the feature gap - we don't know about format specifiers

test/FsAutoComplete.Tests.Lsp/NestedLanguageTests.fs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@ let private getDocumentText (lines: string[]) (ranges: Range array) : string =
2121
let endLine = lines.[int r.End.Line]
2222

2323
if r.Start.Line = r.End.Line then
24-
startLine.Substring(int r.Start.Character, int (r.End.Character - r.Start.Character))
24+
startLine.Substring(int r.Start.Character, int (r.End.Character - r.Start.Character))
2525
else
26-
let start = startLine.Substring(int r.Start.Character)
26+
let start = startLine.Substring(int r.Start.Character)
2727
let ``end`` = endLine.Substring(0, int r.End.Character)
2828

2929
let middle =
30-
lines.[int (r.Start.Line + 1u) .. int (r.End.Line - 1u)] |> Array.map (fun l -> l.Trim())
30+
lines.[int (r.Start.Line + 1u) .. int (r.End.Line - 1u)]
31+
|> Array.map (fun l -> l.Trim())
3132

3233
let middle = String.Join(" ", middle)
3334
start + middle + ``end``)
@@ -89,7 +90,7 @@ let hasLanguages name source expectedLanguages server =
8990
let tests state =
9091
testList
9192
"nested languages"
92-
[ ptestList
93+
[ testList
9394
"unsupported scenarios"
9495
// pending because class members don't return attributes in the FCS Parameter API
9596
[ serverTestList "class member" state defaultConfigDto None (fun server ->

0 commit comments

Comments
 (0)