forked from nosami/visualfsharp
/
Views.fs
102 lines (94 loc) · 4.6 KB
/
Views.fs
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace Microsoft.VisualStudio.FSharp.Editor
open System.Collections.Generic
open Internal.Utilities.StructuredFormat
open Microsoft.CodeAnalysis.Classification
open FSharp.Compiler
open Microsoft.VisualStudio.Core.Imaging
open Microsoft.VisualStudio.Language.StandardClassification
open Microsoft.VisualStudio.Text.Adornments
module internal QuickInfoViewProvider =
let layoutTagToClassificationTag (layoutTag:LayoutTag) =
match layoutTag with
| ActivePatternCase
| ActivePatternResult
| UnionCase
| Enum -> ClassificationTypeNames.EnumName
| Struct -> ClassificationTypeNames.StructName
| TypeParameter -> ClassificationTypeNames.TypeParameterName
| Alias
| Class
| Record
| Union
| UnknownType // Default to class until/unless we use classification data
| Module -> ClassificationTypeNames.ClassName
| Interface -> ClassificationTypeNames.InterfaceName
| Keyword -> ClassificationTypeNames.Keyword
| Member
| Function
| Method -> ClassificationTypeNames.MethodName
| Property
| RecordField -> ClassificationTypeNames.PropertyName
| Parameter
| Local -> ClassificationTypeNames.LocalName
| ModuleBinding -> ClassificationTypeNames.Identifier
| Namespace -> ClassificationTypeNames.NamespaceName
| Delegate -> ClassificationTypeNames.DelegateName
| Event -> ClassificationTypeNames.EventName
| Field -> ClassificationTypeNames.FieldName
| LineBreak
| Space -> ClassificationTypeNames.WhiteSpace
| NumericLiteral -> ClassificationTypeNames.NumericLiteral
| Operator -> ClassificationTypeNames.Operator
| StringLiteral -> ClassificationTypeNames.StringLiteral
| Punctuation -> ClassificationTypeNames.Punctuation
| UnknownEntity
| Text -> ClassificationTypeNames.Text
let provideContent
(
imageId:ImageId option,
description:#seq<Layout.TaggedText>,
documentation:#seq<Layout.TaggedText>,
navigation:QuickInfoNavigation
) =
let buildContainerElement (itemGroup:#seq<Layout.TaggedText>) =
let finalCollection = List<ContainerElement>()
let currentContainerItems = List<obj>()
let runsCollection = List<ClassifiedTextRun>()
let flushRuns() =
if runsCollection.Count > 0 then
let element = ClassifiedTextElement(runsCollection)
currentContainerItems.Add(element :> obj)
runsCollection.Clear()
let flushContainer() =
if currentContainerItems.Count > 0 then
let element = ContainerElement(ContainerElementStyle.Wrapped, currentContainerItems)
finalCollection.Add(element)
currentContainerItems.Clear()
for item in itemGroup do
let classificationTag = layoutTagToClassificationTag item.Tag
match item with
| :? Layout.NavigableTaggedText as nav when navigation.IsTargetValid nav.Range ->
flushRuns()
let navigableTextRun = NavigableTextRun(classificationTag, item.Text, fun () -> navigation.NavigateTo nav.Range)
currentContainerItems.Add(navigableTextRun :> obj)
| _ when item.Tag = LineBreak ->
flushRuns()
// preserve succesive linebreaks
if currentContainerItems.Count = 0 then
runsCollection.Add(ClassifiedTextRun(PredefinedClassificationTypeNames.Other, System.String.Empty))
flushRuns()
flushContainer()
| _ ->
let newRun = ClassifiedTextRun(classificationTag, item.Text)
runsCollection.Add(newRun)
flushRuns()
flushContainer()
ContainerElement(ContainerElementStyle.Stacked, finalCollection |> Seq.map box)
let innerElement =
match imageId with
| Some imageId ->
ContainerElement(ContainerElementStyle.Wrapped, ImageElement(imageId), buildContainerElement description)
| None ->
ContainerElement(ContainerElementStyle.Wrapped, buildContainerElement description)
ContainerElement(ContainerElementStyle.Stacked, innerElement, buildContainerElement documentation)