1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
namespace MonoDevelop.FSharp
open System
open System.Threading.Tasks
open MonoDevelop.Core.Text
open MonoDevelop.Ide.Editor
open Microsoft.FSharp.Compiler
module braceMatcher =
let noMatch = Nullable()
let getMatchingBraces (editor:IReadonlyTextDocument) (context:DocumentContext) caretOffset =
async {
let getOffset (range:Range.range) =
editor.LocationToOffset (range.StartLine, range.StartColumn+1)
let projectFileName =
if isNull context.Project then
editor.FileName
else
context.Project.FileName
let location = editor.OffsetToLocation caretOffset
let range = Range.mkRange (context.Name) (Range.mkPos location.Line (location.Column-1)) (Range.mkPos location.Line location.Column)
let! braces = languageService.MatchingBraces(context.Name, projectFileName.ToString(), editor.Text)
let matching =
braces
|> Seq.tryPick
(function
| (startRange, endRange) when startRange = range ->
Some (startRange, endRange, true)
| (startRange, endRange) when endRange = range ->
Some (startRange, endRange, false)
| _ -> None)
return
match matching with
| Some (startBrace, endBrace, isLeft) ->
let startOffset = getOffset startBrace
let endOffset = getOffset endBrace
Nullable(new BraceMatchingResult(new TextSegment(startOffset, 1), new TextSegment(endOffset, 1), isLeft))
| None -> noMatch
}
type FSharpBraceMatcher() =
inherit AbstractBraceMatcher()
let defaultMatcher = new DefaultBraceMatcher()
override x.CanHandle editor =
FileService.supportedFilePath editor.FileName
override x.GetMatchingBracesAsync (editor, context, caretOffset, cancellationToken) =
if caretOffset = -1 || caretOffset >= editor.Length then
Task.FromResult(Nullable())
else
let isFsi = editor.FileName.ToString() = FsiDocumentContext.DocumentName
match editor.GetCharAt(caretOffset), isFsi with
| '(', false
| ')', false ->
braceMatcher.getMatchingBraces editor context caretOffset
|> StartAsyncAsTask cancellationToken
| _ -> defaultMatcher.GetMatchingBracesAsync (editor, context, caretOffset, cancellationToken)
|