Welcome to mirror list, hosted at ThFree Co, Russian Federation.

FSharpBraceMatcher.fs « MonoDevelop.FSharpBinding « fsharpbinding « external « main - github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: e87085a1d7c1193a1e8def908da41fac850f436e (plain)
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)