Skip to content

Commit 9984b9c

Browse files
committed
Try to find previous non-empty line for correct indentation
Fix #1980.
1 parent 60b2b94 commit 9984b9c

File tree

2 files changed

+28
-13
lines changed

2 files changed

+28
-13
lines changed

vsintegration/src/FSharp.Editor/IndentationService.fs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,33 @@ open Microsoft.FSharp.Compiler.SourceCodeServices
3030
[<ExportLanguageService(typeof<ISynchronousIndentationService>, FSharpCommonConstants.FSharpLanguageName)>]
3131
type internal FSharpIndentationService() =
3232

33-
static member GetDesiredIndentation(sourceText: SourceText, lineNumber: int, tabSize: int): Option<int> =
33+
static member GetDesiredIndentation(sourceText: SourceText, lineNumber: int, tabSize: int): Option<int> =
34+
// Match indentation with previous line
35+
let rec tryFindPreviousNonEmptyLine l =
36+
if l <= 0 then
37+
None
38+
else
39+
let previousLine = sourceText.Lines.[l - 1]
40+
if not (String.IsNullOrEmpty(previousLine.ToString())) then
41+
Some previousLine
42+
else
43+
tryFindPreviousNonEmptyLine (l - 1)
44+
// No indentation on the first line of a document
3445
if lineNumber = 0 then
35-
// No indentation on the first line of a document
3646
None
3747
else
38-
// Match indentation with previous line
39-
let previousLine = sourceText.Lines.[lineNumber - 1]
40-
let rec loop column spaces =
41-
if previousLine.Start + column >= previousLine.End then
42-
spaces
43-
else match previousLine.Text.[previousLine.Start + column] with
44-
| ' ' -> loop (column + 1) (spaces + 1)
45-
| '\t' -> loop (column + 1) (((spaces / tabSize) + 1) * tabSize)
46-
| _ -> spaces
47-
Some(loop 0 0)
48+
match tryFindPreviousNonEmptyLine lineNumber with
49+
| None -> Some 0
50+
| Some previousLine ->
51+
let rec loop column spaces =
52+
if previousLine.Start + column >= previousLine.End then
53+
spaces
54+
else
55+
match previousLine.Text.[previousLine.Start + column] with
56+
| ' ' -> loop (column + 1) (spaces + 1)
57+
| '\t' -> loop (column + 1) (((spaces / tabSize) + 1) * tabSize)
58+
| _ -> spaces
59+
Some (loop 0 0)
4860

4961
interface ISynchronousIndentationService with
5062
member this.GetDesiredIndentation(document: Document, lineNumber: int, cancellationToken: CancellationToken): Nullable<IndentationResult> =

vsintegration/tests/unittests/IndentationServiceTests.fs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ type Class1() =
3434
static let nestedTypesTemplate = "
3535
namespace testspace
3636
type testtype
37-
static member testmember = 1"
37+
static member testmember = 1
38+
39+
"
3840

3941
static member private testCases: Object[][] = [|
4042
[| None; 0; consoleProjectTemplate |]
@@ -59,6 +61,7 @@ namespace testspace
5961
[| Some(0); 2; nestedTypesTemplate |]
6062
[| Some(4); 3; nestedTypesTemplate |]
6163
[| Some(8); 4; nestedTypesTemplate |]
64+
[| Some(8); 5; nestedTypesTemplate |]
6265
|]
6366

6467
[<TestCaseSource("testCases")>]

0 commit comments

Comments
 (0)