Skip to content

Commit

Permalink
Better classification: such colors, much wow (dotnet#9511)
Browse files Browse the repository at this point in the history
* First go at updated classifications

* More complete classification

* More accurate classification that roughly matches glyph computations

* Proper measure classification and tests

* remove ze comments

* Add clarifying comment

* Distinguish property setter args from named argument labels

* Color local values, don't color properties and property-like things that way

* Dont't do the dumb

* We can't distinguish between params and locals right now

* Updates per feedback from myself

* do discards right

* Accessible colors for disposables + some fixes

* Remove exports for things we don't do anymore

* Softer green

* Reduce diff
  • Loading branch information
cartermp committed Jun 23, 2020
1 parent 91447b8 commit d454960
Showing 1 changed file with 44 additions and 76 deletions.
120 changes: 44 additions & 76 deletions Classification/ClassificationDefinitions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -21,36 +21,45 @@ open FSharp.Compiler.SourceCodeServices

[<RequireQualifiedAccess>]
module internal FSharpClassificationTypes =
let [<Literal>] Function = "FSharp.Function"
let [<Literal>] MutableVar = "FSharp.MutableVar"
let [<Literal>] Printf = "FSharp.Printf"
let [<Literal>] ReferenceType = ClassificationTypeNames.ClassName
let [<Literal>] Module = ClassificationTypeNames.ModuleName
let [<Literal>] ValueType = ClassificationTypeNames.StructName
let [<Literal>] Keyword = ClassificationTypeNames.Keyword
let [<Literal>] Enum = ClassificationTypeNames.EnumName
let [<Literal>] Property = "FSharp.Property"
let [<Literal>] Interface = ClassificationTypeNames.InterfaceName
let [<Literal>] TypeArgument = ClassificationTypeNames.TypeParameterName
let [<Literal>] Operator = ClassificationTypeNames.Operator
let [<Literal>] Disposable = "FSharp.Disposable"

let getClassificationTypeName = function
| SemanticClassificationType.ReferenceType -> ReferenceType
| SemanticClassificationType.Module -> Module
| SemanticClassificationType.ValueType -> ValueType
| SemanticClassificationType.Function -> Function
| SemanticClassificationType.MutableRecordField
| SemanticClassificationType.MutableVar -> MutableVar
| SemanticClassificationType.Printf -> Printf
| SemanticClassificationType.DisposableValue
| SemanticClassificationType.DisposableType -> Disposable
| SemanticClassificationType.NameSpace -> ClassificationTypeNames.NamespaceName
| SemanticClassificationType.Exception
| SemanticClassificationType.Module
| SemanticClassificationType.Type
| SemanticClassificationType.TypeDef
| SemanticClassificationType.ConstructorForReferenceType
| SemanticClassificationType.Printf
| SemanticClassificationType.ReferenceType -> ClassificationTypeNames.ClassName
| SemanticClassificationType.ConstructorForValueType
| SemanticClassificationType.ValueType -> ClassificationTypeNames.StructName
| SemanticClassificationType.ComputationExpression
| SemanticClassificationType.IntrinsicFunction -> Keyword
| SemanticClassificationType.IntrinsicFunction -> ClassificationTypeNames.Keyword
| SemanticClassificationType.UnionCase
| SemanticClassificationType.Enumeration -> Enum
| SemanticClassificationType.Property -> Property
| SemanticClassificationType.Interface -> Interface
| SemanticClassificationType.TypeArgument -> TypeArgument
| SemanticClassificationType.Operator -> Operator
| SemanticClassificationType.Disposable -> Disposable
| SemanticClassificationType.Enumeration -> ClassificationTypeNames.EnumName
| SemanticClassificationType.Field
| SemanticClassificationType.UnionCaseField -> ClassificationTypeNames.FieldName
| SemanticClassificationType.Interface -> ClassificationTypeNames.InterfaceName
| SemanticClassificationType.TypeArgument -> ClassificationTypeNames.TypeParameterName
| SemanticClassificationType.Operator -> ClassificationTypeNames.Operator
| SemanticClassificationType.Function
| SemanticClassificationType.Method -> ClassificationTypeNames.MethodName
| SemanticClassificationType.ExtensionMethod -> ClassificationTypeNames.ExtensionMethodName
| SemanticClassificationType.Literal -> ClassificationTypeNames.ConstantName
| SemanticClassificationType.Property
| SemanticClassificationType.RecordFieldAsFunction
| SemanticClassificationType.RecordField -> ClassificationTypeNames.PropertyName // TODO - maybe pick something that isn't white by default like Property?
| SemanticClassificationType.NamedArgument -> ClassificationTypeNames.LabelName
| SemanticClassificationType.Event -> ClassificationTypeNames.EventName
| SemanticClassificationType.Delegate -> ClassificationTypeNames.DelegateName
| SemanticClassificationType.Value -> ClassificationTypeNames.Identifier
| SemanticClassificationType.LocalValue -> ClassificationTypeNames.LocalName

module internal ClassificationDefinitions =

Expand All @@ -73,13 +82,11 @@ module internal ClassificationDefinitions =
let themeService = serviceProvider.GetService(typeof<SVsColorThemeService>) :?> IVsColorThemeService
themeService.CurrentTheme.ThemeId

let colorData = // name, (light, dark)
[ FSharpClassificationTypes.Function, (Colors.Black, Color.FromRgb(220uy, 220uy, 220uy))
FSharpClassificationTypes.MutableVar, (Color.FromRgb(160uy, 128uy, 0uy), Color.FromRgb(255uy, 210uy, 28uy))
FSharpClassificationTypes.Printf, (Color.FromRgb(43uy, 145uy, 175uy), Color.FromRgb(78uy, 220uy, 176uy))
FSharpClassificationTypes.Property, (Colors.Black, Color.FromRgb(220uy, 220uy, 220uy))
FSharpClassificationTypes.Disposable, (Color.FromRgb(43uy, 145uy, 175uy), Color.FromRgb(78uy, 220uy, 176uy)) ]

let customColorData = // name, (light, dark)
[
FSharpClassificationTypes.MutableVar, (Color.FromRgb(160uy, 128uy, 0uy), Color.FromRgb(255uy, 210uy, 28uy))
FSharpClassificationTypes.Disposable, (Colors.Green, Color.FromRgb(2uy, 183uy, 43uy))
]

let setColors _ =
let fontAndColorStorage = serviceProvider.GetService(typeof<SVsFontAndColorStorage>) :?> IVsFontAndColorStorage
Expand All @@ -90,15 +97,16 @@ module internal ClassificationDefinitions =
let formatMap = classificationformatMapService.GetClassificationFormatMap(category = "text")
try
formatMap.BeginBatchUpdate()
for ctype, (light, dark) in colorData do
for ctype, (light, dark) in customColorData do
// we don't touch the changes made by the user
if fontAndColorStorage.GetItem(ctype, Array.zeroCreate 1) <> VSConstants.S_OK then
let ict = classificationTypeRegistry.GetClassificationType(ctype)
let oldProps = formatMap.GetTextProperties(ict)
let newProps = match getCurrentThemeId() with
| LightTheme -> oldProps.SetForeground light
| DarkTheme -> oldProps.SetForeground dark
| UnknownTheme -> oldProps
let newProps =
match getCurrentThemeId() with
| LightTheme -> oldProps.SetForeground light
| DarkTheme -> oldProps.SetForeground dark
| UnknownTheme -> oldProps
formatMap.SetTextProperties(ict, newProps)
fontAndColorStorage.CloseCategory() |> ignore
finally formatMap.EndBatchUpdate()
Expand All @@ -108,40 +116,21 @@ module internal ClassificationDefinitions =
interface IDisposable with member __.Dispose() = VSColorTheme.remove_ThemeChanged handler

member __.GetColor(ctype) =
let light, dark = colorData |> Map.ofList |> Map.find ctype
let light, dark = customColorData |> Map.ofList |> Map.find ctype
match getCurrentThemeId() with
| LightTheme -> Nullable light
| DarkTheme -> Nullable dark
| UnknownTheme -> Nullable()

interface ISetThemeColors with member this.SetColors() = setColors()


[<Export; Name(FSharpClassificationTypes.Function); BaseDefinition(PredefinedClassificationTypeNames.FormalLanguage)>]
let FSharpFunctionClassificationType : ClassificationTypeDefinition = null

[<Export; Name(FSharpClassificationTypes.MutableVar); BaseDefinition(PredefinedClassificationTypeNames.FormalLanguage)>]
let FSharpMutableVarClassificationType : ClassificationTypeDefinition = null

[<Export; Name(FSharpClassificationTypes.Printf); BaseDefinition(PredefinedClassificationTypeNames.FormalLanguage)>]
let FSharpPrintfClassificationType : ClassificationTypeDefinition = null

[<Export; Name(FSharpClassificationTypes.Property); BaseDefinition(PredefinedClassificationTypeNames.FormalLanguage)>]
let FSharpPropertyClassificationType : ClassificationTypeDefinition = null

[<Export; Name(FSharpClassificationTypes.Disposable); BaseDefinition(PredefinedClassificationTypeNames.FormalLanguage)>]
let FSharpDisposableClassificationType : ClassificationTypeDefinition = null

[<Export(typeof<EditorFormatDefinition>)>]
[<ClassificationType(ClassificationTypeNames = FSharpClassificationTypes.Function)>]
[<Name(FSharpClassificationTypes.Function)>]
[<UserVisible(true)>]
[<Order(After = PredefinedClassificationTypeNames.Keyword)>]
type internal FSharpFunctionTypeFormat() as self =
inherit ClassificationFormatDefinition()

do self.DisplayName <- SR.FSharpFunctionsOrMethodsClassificationType()

[<Export(typeof<EditorFormatDefinition>)>]
[<ClassificationType(ClassificationTypeNames = FSharpClassificationTypes.MutableVar)>]
[<Name(FSharpClassificationTypes.MutableVar)>]
Expand All @@ -153,27 +142,6 @@ module internal ClassificationDefinitions =
do self.DisplayName <- SR.FSharpMutableVarsClassificationType()
self.ForegroundColor <- theme.GetColor FSharpClassificationTypes.MutableVar

[<Export(typeof<EditorFormatDefinition>)>]
[<ClassificationType(ClassificationTypeNames = FSharpClassificationTypes.Printf)>]
[<Name(FSharpClassificationTypes.Printf)>]
[<UserVisible(true)>]
[<Order(After = PredefinedClassificationTypeNames.String)>]
type internal FSharpPrintfTypeFormat [<ImportingConstructor>](theme: ThemeColors) as self =
inherit ClassificationFormatDefinition()

do self.DisplayName <- SR.FSharpPrintfFormatClassificationType()
self.ForegroundColor <- theme.GetColor FSharpClassificationTypes.Printf

[<Export(typeof<EditorFormatDefinition>)>]
[<ClassificationType(ClassificationTypeNames = FSharpClassificationTypes.Property)>]
[<Name(FSharpClassificationTypes.Property)>]
[<UserVisible(true)>]
[<Order(After = PredefinedClassificationTypeNames.Keyword)>]
type internal FSharpPropertyFormat() as self =
inherit ClassificationFormatDefinition()

do self.DisplayName <- SR.FSharpPropertiesClassificationType()

[<Export(typeof<EditorFormatDefinition>)>]
[<ClassificationType(ClassificationTypeNames = FSharpClassificationTypes.Disposable)>]
[<Name(FSharpClassificationTypes.Disposable)>]
Expand Down

0 comments on commit d454960

Please sign in to comment.