提交 9a6ac3da 编写于 作者: J Jakub Majocha 提交者: Kevin Ransom (msft)

Settings store and Text Editor option pages (#2805)

* settings store and editor options

* show CLIMutable record use, guid constants

* saner composition

* fix CompletionProvider tests

* fix public surface area

* localization

* move xaml into separate project

* updated vsintegration readme

* correct type in change handler

* use Newtonsoft's PopulateObject for cheap schema evolution

* cleanup added project

* Revert "cleanup added project"

This reverts commit 163ebdaabc0d3b206fc436b0b47a622f91e20658.

* cleanup, another attempt
上级 dc6f54ea

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26206.0
VisualStudioVersion = 15.0.26403.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler", "src\fsharp\FSharp.Compiler\FSharp.Compiler.fsproj", "{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}"
EndProject
......@@ -136,6 +136,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utils", "Utils", "{D086C8C6
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "LanguageServiceProfiling", "vsintegration\Utils\LanguageServiceProfiling\LanguageServiceProfiling.fsproj", "{E7FA3A71-51AF-4FCA-9C2F-7C853E515903}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FSharp.UIResources", "vsintegration\src\FSharp.UIResources\FSharp.UIResources.csproj", "{C4586A06-1402-48BC-8E35-A1B8642F895B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
......@@ -749,6 +751,18 @@ Global
{E7FA3A71-51AF-4FCA-9C2F-7C853E515903}.Release|Any CPU.Build.0 = Release|Any CPU
{E7FA3A71-51AF-4FCA-9C2F-7C853E515903}.Release|x86.ActiveCfg = Release|Any CPU
{E7FA3A71-51AF-4FCA-9C2F-7C853E515903}.Release|x86.Build.0 = Release|Any CPU
{C4586A06-1402-48BC-8E35-A1B8642F895B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C4586A06-1402-48BC-8E35-A1B8642F895B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C4586A06-1402-48BC-8E35-A1B8642F895B}.Debug|x86.ActiveCfg = Debug|Any CPU
{C4586A06-1402-48BC-8E35-A1B8642F895B}.Debug|x86.Build.0 = Debug|Any CPU
{C4586A06-1402-48BC-8E35-A1B8642F895B}.Proto|Any CPU.ActiveCfg = Proto|Any CPU
{C4586A06-1402-48BC-8E35-A1B8642F895B}.Proto|Any CPU.Build.0 = Proto|Any CPU
{C4586A06-1402-48BC-8E35-A1B8642F895B}.Proto|x86.ActiveCfg = Proto|Any CPU
{C4586A06-1402-48BC-8E35-A1B8642F895B}.Proto|x86.Build.0 = Proto|Any CPU
{C4586A06-1402-48BC-8E35-A1B8642F895B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C4586A06-1402-48BC-8E35-A1B8642F895B}.Release|Any CPU.Build.0 = Release|Any CPU
{C4586A06-1402-48BC-8E35-A1B8642F895B}.Release|x86.ActiveCfg = Release|Any CPU
{C4586A06-1402-48BC-8E35-A1B8642F895B}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......@@ -811,5 +825,6 @@ Global
{2E60864A-E3FF-4BCC-810F-DC7C34E6B236} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449}
{D086C8C6-D00D-4C3B-9AB2-A4286C9F5922} = {4C7B48D7-19AF-4AE7-9D1D-3BB289D5480D}
{E7FA3A71-51AF-4FCA-9C2F-7C853E515903} = {D086C8C6-D00D-4C3B-9AB2-A4286C9F5922}
{C4586A06-1402-48BC-8E35-A1B8642F895B} = {4C7B48D7-19AF-4AE7-9D1D-3BB289D5480D}
EndGlobalSection
EndGlobal
......@@ -56,6 +56,7 @@ rem Disable strong-name validation for F# binaries built from open source that a
%SN32% -q -Vr FSharp.Compiler,b03f5f7f11d50a3a
%SN32% -q -Vr FSharp.Compiler.Server.Shared,b03f5f7f11d50a3a
%SN32% -q -Vr FSharp.Editor,b03f5f7f11d50a3a
%SN32% -q -Vr FSharp.UIResources,b03f5f7f11d50a3a
%SN32% -q -Vr FSharp.LanguageService,b03f5f7f11d50a3a
%SN32% -q -Vr FSharp.LanguageService.Base,b03f5f7f11d50a3a
%SN32% -q -Vr FSharp.LanguageService.Compiler,b03f5f7f11d50a3a
......@@ -81,6 +82,7 @@ if /i "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
%SN64% -q -Vr FSharp.Compiler,b03f5f7f11d50a3a
%SN64% -q -Vr FSharp.Compiler.Server.Shared,b03f5f7f11d50a3a
%SN64% -q -Vr FSharp.Editor,b03f5f7f11d50a3a
%SN64% -q -Vr FSharp.UIResources,b03f5f7f11d50a3a
%SN64% -q -Vr FSharp.LanguageService,b03f5f7f11d50a3a
%SN64% -q -Vr FSharp.LanguageService.Base,b03f5f7f11d50a3a
%SN64% -q -Vr FSharp.LanguageService.Compiler,b03f5f7f11d50a3a
......
......@@ -20,6 +20,7 @@
<Action Type="Ngen" Path="FSharp.Compiler.Server.Shared.dll" />
<Action Type="Ngen" Path="FSharp.Core.dll" />
<Action Type="Ngen" Path="FSharp.Editor.dll" />
<Action Type="Ngen" Path="FSharp.UIResources.dll" />
<Action Type="Ngen" Path="FSharp.LanguageService.Base.dll" />
<Action Type="Ngen" Path="FSharp.LanguageService.Compiler.dll" />
<Action Type="Ngen" Path="FSharp.LanguageService.dll" />
......@@ -65,6 +66,6 @@
<Asset Type="Microsoft.VisualStudio.MefComponent" d:Source="Project" d:ProjectName="ProjectSystem.Base" Path="|ProjectSystem.Base|" />
</Assets>
<Prerequisites>
<Prerequisite Id="Microsoft.VisualStudio.Component.CoreEditor" Version="[15.0,16.0)" DisplayName="Visual Studio core editor" />
<Prerequisite Id="Microsoft.VisualStudio.Component.CoreEditor" Version="[15.0,16.0)" DisplayName="Visual Studio core editor" />
</Prerequisites>
</PackageManifest>
......@@ -166,6 +166,13 @@
<IncludeOutputGroupsInVSIXLocalOnly>DebugSymbolsProjectOutputGroup%3b</IncludeOutputGroupsInVSIXLocalOnly>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="$(FSharpSourcesRoot)\..\vsintegration\src\FSharp.UIResources\FSharp.UIResources.csproj">
<Project>{c4586a06-1402-48bc-8e35-a1b8642f895b}</Project>
<Name>FSharp.UIResources</Name>
<IncludeOutputGroupsInVSIX>BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bSatelliteDllsProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
<IncludeOutputGroupsInVSIXLocalOnly>DebugSymbolsProjectOutputGroup%3b</IncludeOutputGroupsInVSIXLocalOnly>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="$(FSharpSourcesRoot)\..\vsintegration\src\FSharp.LanguageService.Base\FSharp.LanguageService.Base.csproj">
<Project>{1C5C163C-37EA-4A3C-8CCC-0D34B74BF8EF}</Project>
<Name>FSharp.LanguageService.Base</Name>
......@@ -313,6 +320,12 @@
<Private>True</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>$(FSharpSourcesRoot)\..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<Import Project="$(FSharpSourcesRoot)\..\vsintegration\src\FSharp.tools.targets" />
<Import Project="$(FSharpSourcesRoot)\Microbuild.Settings.targets" />
<Target Name="GatherBinariesToBeSigned" AfterTargets="Localize" Condition="'$(UseGatherBinaries)' == 'true'">
......@@ -323,4 +336,4 @@
</FilesToSign>
</ItemGroup>
</Target>
</Project>
</Project>
\ No newline at end of file
......@@ -20,6 +20,7 @@
<Action Type="Ngen" Path="FSharp.Compiler.Server.Shared.dll" />
<Action Type="Ngen" Path="FSharp.Core.dll" />
<Action Type="Ngen" Path="FSharp.Editor.dll" />
<Action Type="Ngen" Path="FSharp.UIResources.dll" />
<Action Type="Ngen" Path="FSharp.LanguageService.Base.dll" />
<Action Type="Ngen" Path="FSharp.LanguageService.Compiler.dll" />
<Action Type="Ngen" Path="FSharp.LanguageService.dll" />
......
......@@ -165,6 +165,13 @@
<IncludeOutputGroupsInVSIXLocalOnly>DebugSymbolsProjectOutputGroup%3b</IncludeOutputGroupsInVSIXLocalOnly>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="$(FSharpSourcesRoot)\..\vsintegration\src\FSharp.UIResources\FSharp.UIResources.csproj">
<Project>{c4586a06-1402-48bc-8e35-a1b8642f895b}</Project>
<Name>FSharp.UIResources</Name>
<IncludeOutputGroupsInVSIX>BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bSatelliteDllsProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
<IncludeOutputGroupsInVSIXLocalOnly>DebugSymbolsProjectOutputGroup%3b</IncludeOutputGroupsInVSIXLocalOnly>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="$(FSharpSourcesRoot)\..\vsintegration\src\FSharp.LanguageService.Base\FSharp.LanguageService.Base.csproj">
<Project>{1C5C163C-37EA-4A3C-8CCC-0D34B74BF8EF}</Project>
<Name>FSharp.LanguageService.Base</Name>
......@@ -312,6 +319,12 @@
<Private>True</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>$(FSharpSourcesRoot)\..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<Import Project="$(FSharpSourcesRoot)\..\vsintegration\src\FSharp.tools.targets" />
<Import Project="$(FSharpSourcesRoot)\Microbuild.Settings.targets" />
<Target Name="GatherBinariesToBeSigned" AfterTargets="Localize" Condition="'$(UseGatherBinaries)' == 'true'">
......
......@@ -7,6 +7,7 @@
<ItemGroup>
<ProjectFiles Include="src\FSharp.Editor\FSharp.Editor.fsproj" />
<ProjectFiles Include="src\FSharp.LanguageService\FSharp.LanguageService.fsproj" />
<ProjectFiles Include="src\FSharp.UIResources\FSharp.UIResources.csproj" />
<ProjectFiles Include="src\FSharp.LanguageService.Base\FSharp.LanguageService.Base.csproj" />
<ProjectFiles Include="src\FSharp.ProjectSystem.Base\Project\ProjectSystem.Base.csproj" />
<ProjectFiles Include="src\FSharp.ProjectSystem.FSharp\ProjectSystem.fsproj" />
......
......@@ -68,6 +68,6 @@
<package id="Microsoft.VisualStudio.Platform.VSEditor" version="15.0.26201-alpha" targetFramework="net46" />
<package id="Microsoft.VisualStudio.Platform.VSEditor.Interop" version="15.0.26201-alpha" targetFramework="net46" />
<package id="Microsoft.VisualStudio.Telemetry" version="15.0.777-rtm6FAA2C78" targetFramework="net45" />
<package id="Newtonsoft.Json" version="10.0.2.0"/>
</packages>
......@@ -4,6 +4,10 @@ This folder contains projects and tests related to Visual Studio tooling and IDE
main project for Visual F# tooling
# src/FSharp.UIResources
GUI controls and resources for Visual F# tooling
# src/FSharp.LanguageService
legacy bits (before roslyn workspace)
......
......@@ -9,6 +9,8 @@ open Microsoft.VisualStudio.Shell
[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("VisualFSharp.Salsa, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
[<assembly: ProvideCodeBase(CodeBase = @"$PackageFolder$\FSharp.Editor.dll")>]
[<assembly: ProvideCodeBase(CodeBase = @"$PackageFolder$\FSharp.UIResources.dll")>]
[<assembly: ProvideCodeBase(CodeBase = @"$PackageFolder$\Newtonsoft.Json.dll")>]
do()
......@@ -22,10 +22,6 @@ module internal FSharpConstants =
/// "4EB7CCB7-4336-4FFD-B12B-396E9FD079A9"
let editorFactoryGuidString = "4EB7CCB7-4336-4FFD-B12B-396E9FD079A9"
[<Literal>]
/// "9B164E40-C3A2-4363-9BC5-EB4039DEF653"
let svsSettingsPersistenceManagerGuidString = "9B164E40-C3A2-4363-9BC5-EB4039DEF653"
[<Literal>]
/// "F#"
let FSharpLanguageName = "F#"
......@@ -51,4 +47,20 @@ module internal FSharpProviderConstants =
[<Literal>]
/// "Session Capturing Quick Info Source Provider"
let SessionCapturingProvider = "Session Capturing Quick Info Source Provider"
\ No newline at end of file
let SessionCapturingProvider = "Session Capturing Quick Info Source Provider"
[<RequireQualifiedAccess>]
module internal Guids =
[<Literal>]
/// "9B164E40-C3A2-4363-9BC5-EB4039DEF653"
let svsSettingsPersistenceManagerIdString = "9B164E40-C3A2-4363-9BC5-EB4039DEF653"
[<Literal>]
/// "9b3c6b8a-754a-461d-9ebe-de1a682d57c1"
let intelliSenseOptionPageIdString = "9b3c6b8a-754a-461d-9ebe-de1a682d57c1"
[<Literal>]
/// "1e2b3290-4d67-41ff-a876-6f41f868e28f"
let quickInfoOptionPageIdString = "1e2b3290-4d67-41ff-a876-6f41f868e28f"
\ No newline at end of file
......@@ -55,7 +55,7 @@ type internal FSharpCompletionProvider
static let noCommitOnSpaceRules =
CompletionItemRules.Default.WithCommitCharacterRule(CharacterSetModificationRule.Create(CharacterSetModificationKind.Remove, ' ', '.', '<', '>', '(', ')', '!'))
static let getRules() = if IntelliSenseSettings.ShowAfterCharIsTyped then noCommitOnSpaceRules else CompletionItemRules.Default
static let getRules() = if Settings.IntelliSense.ShowAfterCharIsTyped then noCommitOnSpaceRules else CompletionItemRules.Default
static let mruItems = Dictionary<(* Item.FullName *) string, (* hints *) int>()
......@@ -80,7 +80,7 @@ type internal FSharpCompletionProvider
else
let documentId, filePath, defines = getInfo()
CompletionUtils.shouldProvideCompletion(documentId, filePath, defines, sourceText, triggerPosition) &&
(IntelliSenseSettings.ShowAfterCharIsTyped && CompletionUtils.isStartingNewWord(sourceText, triggerPosition))
(Settings.IntelliSense.ShowAfterCharIsTyped && CompletionUtils.isStartingNewWord(sourceText, triggerPosition))
static member ProvideCompletionsAsyncAux(checker: FSharpChecker, sourceText: SourceText, caretPosition: int, options: FSharpProjectOptions, filePath: string,
textVersionHash: int, getAllSymbols: unit -> AssemblySymbol list) =
......
......@@ -39,6 +39,9 @@
<Compile Include="Common\RoslynHelpers.fs" />
<Compile Include="Common\CodeAnalysisExtensions.fs" />
<Compile Include="Common\ContentType.fs" />
<Compile Include="Options\SettingsPersistence.fs" />
<Compile Include="Options\UIHelpers.fs" />
<Compile Include="Options\EditorOptions.fs" />
<Compile Include="LanguageService\Tokenizer.fs" />
<Compile Include="LanguageService\Symbols.fs" />
<Compile Include="LanguageService\TypedAstUtils.fs" />
......@@ -46,7 +49,6 @@
<Compile Include="LanguageService\LanguageService.fs" />
<Compile Include="LanguageService\AssemblyContentProvider.fs" />
<Compile Include="LanguageService\SymbolHelpers.fs" />
<Compile Include="Properties\IntelliSensePropertyPage.fs" />
<Compile Include="Classification\ClassificationDefinitions.fs" />
<Compile Include="Classification\ColorizationService.fs" />
<Compile Include="Formatting\BraceMatchingService.fs" />
......@@ -104,6 +106,11 @@
<Name>FSharp.LanguageService.Compiler</Name>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="$(FSharpSourcesRoot)\..\vsintegration\src\FSharp.UIResources\FSharp.UIResources.csproj">
<Name>FSharp.UIResources</Name>
<Project>{c4586a06-1402-48bc-8e35-a1b8642f895b}</Project>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="..\FSharp.VS.FSI\FSharp.VS.FSI.fsproj">
<Name>FSharp.VS.FSI</Name>
<Project>{991dcf75-c2eb-42b6-9a0d-aa1d2409d519}</Project>
......@@ -252,6 +259,9 @@
<HintPath>$(FSharpSourcesRoot)\..\packages\System.Collections.Immutable.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>$(FSharpSourcesRoot)\..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<Import Project="$(FSharpSourcesRoot)\FSharpSource.targets" />
<Import Project="$(VsSDKTargets)" />
......
......@@ -162,13 +162,7 @@
<data name="6008" xml:space="preserve">
<value>IntelliSense</value>
</data>
<data name="IntelliSensePropertyPageMiscCategory" xml:space="preserve">
<value>Misc</value>
</data>
<data name="IntelliSensePropertyPageShowAfterCharIsTyped" xml:space="preserve">
<value>Show after a character is typed</value>
</data>
<data name="IntelliSensePropertyPageShowAfterCharIsTypedDescr" xml:space="preserve">
<value>Show completion list after a character is typed</value>
<data name="6009" xml:space="preserve">
<value>QuickInfo</value>
</data>
</root>
\ No newline at end of file
......@@ -31,11 +31,6 @@ open Microsoft.VisualStudio.Shell.Interop
open Microsoft.VisualStudio.FSharp.LanguageService
open Microsoft.VisualStudio.ComponentModelHost
// Workaround to access non-public settings persistence type.
// GetService( ) with this will work as long as the GUID matches the real type.
[<Guid(FSharpConstants.svsSettingsPersistenceManagerGuidString)>]
type internal SVsSettingsPersistenceManager = class end
// Exposes FSharpChecker as MEF export
[<Export(typeof<FSharpCheckerProvider>); Composition.Shared>]
type internal FSharpCheckerProvider
......@@ -195,6 +190,8 @@ type internal FSharpCheckerWorkspaceServiceFactory
type
[<Guid(FSharpConstants.packageGuidString)>]
[<ProvideLanguageEditorOptionPage(typeof<OptionsUI.IntelliSenseOptionPage>, "F#", null, "IntelliSense", "6008")>]
[<ProvideLanguageEditorOptionPage(typeof<OptionsUI.QuickInfoOptionPage>, "F#", null, "QuickInfo", "6009")>]
[<ProvideLanguageService(languageService = typeof<FSharpLanguageService>,
strLanguageName = FSharpConstants.FSharpLanguageName,
languageResourceID = 100,
......@@ -213,7 +210,12 @@ type
ShowDropDownOptions = true)>]
internal FSharpPackage() =
inherit AbstractPackage<FSharpPackage, FSharpLanguageService>()
override this.Initialize() =
base.Initialize()
//initialize settings
this.ComponentModel.GetService<SettingsPersistence.ISettings>() |> ignore
override this.RoslynLanguageName = FSharpConstants.FSharpLanguageName
override this.CreateWorkspace() = this.ComponentModel.GetService<VisualStudioWorkspaceImpl>()
......
namespace Microsoft.VisualStudio.FSharp.Editor
open System.ComponentModel.Composition
open System.Runtime.InteropServices
open Microsoft.VisualStudio.FSharp.UIResources
open SettingsPersistence
open OptionsUIHelpers
// CLIMutable to make the record work also as a view model
[<CLIMutable>]
type IntelliSenseOptions =
{ ShowAfterCharIsTyped: bool
ShowAfterCharIsDeleted: bool }
[<RequireQualifiedAccess>]
type QuickInfoUnderlineStyle = Dot | Dash | Solid
// autoproperties can be used to both define defaults and faciliate data binding in WPF controls,
// but the type should otherwise be treated as immutable.
type QuickInfoOptions() =
member val DisplayLinks = true with get, set
member val UnderlineStyle = QuickInfoUnderlineStyle.Solid with get, set
[<Export(typeof<ISettings>)>]
type internal Settings [<ImportingConstructor>](store: SettingsStore) =
do // Initialize default settings
{ ShowAfterCharIsTyped = true
ShowAfterCharIsDeleted = false }
|> store.RegisterDefault
QuickInfoOptions()
|> store.RegisterDefault
interface ISettings
static member IntelliSense : IntelliSenseOptions = getSettings()
static member QuickInfo : QuickInfoOptions = getSettings()
module internal OptionsUI =
[<Guid(Guids.intelliSenseOptionPageIdString)>]
type internal IntelliSenseOptionPage() =
inherit AbstractOptionPage<IntelliSenseOptions>()
override this.CreateView() =
let view = IntelliSenseOptionControl()
view.charTyped.Unchecked.Add <| fun _ -> view.charDeleted.IsChecked <- System.Nullable false
upcast view
[<Guid(Guids.quickInfoOptionPageIdString)>]
type internal QuickInfoOptionPage() =
inherit AbstractOptionPage<QuickInfoOptions>()
override this.CreateView() =
let view = QuickInfoOptionControl()
let path = "UnderlineStyle"
bindRadioButton view.solid path QuickInfoUnderlineStyle.Solid
bindRadioButton view.dot path QuickInfoUnderlineStyle.Dot
bindRadioButton view.dash path QuickInfoUnderlineStyle.Dash
bindCheckBox view.displayLinks "DisplayLinks"
upcast view
namespace Microsoft.VisualStudio.FSharp.Editor
open System
open System.Collections.Concurrent
open System.ComponentModel.Composition
open System.Reflection
open System.Runtime.InteropServices
open Microsoft.VisualStudio.Settings
open Microsoft.VisualStudio.Shell
open Newtonsoft.Json
module internal SettingsPersistence =
// Each group of settings is a value of some named type, for example 'IntelliSenseOptions', 'QuickInfoOptions'
// We cache exactly one instance of each, treating them as immutable.
// This cache is updated by the SettingsStore when the user changes an option.
let private cache = ConcurrentDictionary<Type, obj>()
let getSettings() : 't =
match cache.TryGetValue(typeof<'t>) with
| true, value -> value :?> 't
| _ -> failwithf "Settings %s are not registered." typeof<'t>.Name
let setSettings( settings: 't) =
cache.[typeof<'t>] <- settings
[<Guid(Guids.svsSettingsPersistenceManagerIdString)>]
type SVsSettingsPersistenceManager = class end
// marker interface for default settings export
type ISettings = interface end
[<Export>]
type SettingsStore
[<ImportingConstructor>]
(
[<Import(typeof<SVsServiceProvider>)>]
serviceProvider: IServiceProvider
) =
let settingsManager = serviceProvider.GetService(typeof<SVsSettingsPersistenceManager>) :?> ISettingsManager
// settings quallified type names are used as keys, this should be enough to avoid collisions
let storageKey (typ: Type) = typ.Namespace + "." + typ.Name
let save (settings: 't) =
// we replace default serialization with Newtonsoft.Json for easy schema evolution
settingsManager.SetValueAsync(storageKey typeof<'t>, JsonConvert.SerializeObject settings, false)
|> Async.AwaitTask
let tryPopulate (settings: 't) =
let result, json = settingsManager.TryGetValue(storageKey typeof<'t>)
if result = GetValueResult.Success then
// if it fails we just return what we got
try JsonConvert.PopulateObject(json, settings) with _ -> ()
settings
let ensureTrackingChanges (settings: 't) =
settings |> tryPopulate |> setSettings
let subset = settingsManager.GetSubset(storageKey typeof<'t>)
subset.add_SettingChangedAsync
<| PropertyChangedAsyncEventHandler (fun _ _ ->
(getSettings() : 't) |> tryPopulate |> setSettings
System.Threading.Tasks.Task.CompletedTask )
member this.LoadSettings() : 't =
getSettings() |> tryPopulate
member this.SaveSettings(settings: 't) =
save settings
member __.RegisterDefault(defaultValue: 't) =
ensureTrackingChanges defaultValue
\ No newline at end of file
namespace Microsoft.VisualStudio.FSharp.Editor
open System
open System.Windows
open System.Windows.Data
open System.Windows.Markup
open System.Windows.Controls
open Microsoft.VisualStudio.Shell
open Microsoft.VisualStudio.ComponentModelHost
open SettingsPersistence
module internal OptionsUIHelpers =
[<AbstractClass>]
type AbstractOptionPage<'t>() as this =
inherit UIElementDialogPage()
let view = lazy this.CreateView()
let store =
lazy
let scm = this.Site.GetService(typeof<SComponentModel>) :?> IComponentModel
// make sure settings are initialized to default values
scm.GetService<ISettings>() |> ignore
scm.GetService<SettingsStore>()
abstract CreateView : unit -> FrameworkElement
member this.View = view.Value
member this.Store = store.Value
override this.Child = upcast this.View
override this.SaveSettingsToStorage() =
this.GetResult() |> this.Store.SaveSettings |> Async.StartImmediate
override this.LoadSettingsFromStorage() =
this.Store.LoadSettings() |> this.SetViewModel
//Override this method when using immutable settings type
member this.SetViewModel(settings: 't) =
// this is needed in case when settings are a CLIMutable record
this.View.DataContext <- null
this.View.DataContext <- settings
//Override this method when using immutable settings type
member this.GetResult() : 't =
downcast this.View.DataContext
//data binding helpers
let radioButtonCoverter =
{ new IValueConverter with
member this.Convert(value, _, parameter, _) =
upcast value.Equals(parameter)
member this.ConvertBack(value, _, parameter, _) =
if value.Equals(true) then parameter else Binding.DoNothing }
let bindRadioButton (radioButton: RadioButton) path value =
let binding = Binding (path, Converter = radioButtonCoverter, ConverterParameter = value)
radioButton.SetBinding(RadioButton.IsCheckedProperty, binding) |> ignore
let bindCheckBox (checkBox: CheckBox) (path: string) =
checkBox.SetBinding(CheckBox.IsCheckedProperty, path) |> ignore
// some helpers to create option views in code instead of XAML
let ( *** ) (control : #IAddChild) (children: UIElement list) =
children |> List.iter control.AddChild
control
let ( +++ ) (control : #IAddChild) content =
control.AddChild content
control
let withDefaultStyles (element: FrameworkElement) =
let groupBoxStyle = System.Windows.Style(typeof<GroupBox>)
groupBoxStyle.Setters.Add(Setter(GroupBox.PaddingProperty, Thickness(Left = 7.0, Right = 7.0, Top = 7.0 )))
groupBoxStyle.Setters.Add(Setter(GroupBox.MarginProperty, Thickness(Bottom = 3.0)))
groupBoxStyle.Setters.Add(Setter(GroupBox.ForegroundProperty, DynamicResourceExtension(SystemColors.WindowTextBrushKey)))
element.Resources.Add(typeof<GroupBox>, groupBoxStyle)
let checkBoxStyle = new System.Windows.Style(typeof<CheckBox>)
checkBoxStyle.Setters.Add(new Setter(CheckBox.MarginProperty, new Thickness(Bottom = 7.0 )))
checkBoxStyle.Setters.Add(new Setter(CheckBox.ForegroundProperty, new DynamicResourceExtension(SystemColors.WindowTextBrushKey)))
element.Resources.Add(typeof<CheckBox>, checkBoxStyle)
let textBoxStyle = new System.Windows.Style(typeof<TextBox>)
textBoxStyle.Setters.Add(new Setter(TextBox.MarginProperty, new Thickness(Left = 7.0, Right = 7.0 )))
textBoxStyle.Setters.Add(new Setter(TextBox.ForegroundProperty, new DynamicResourceExtension(SystemColors.WindowTextBrushKey)))
element.Resources.Add(typeof<TextBox>, textBoxStyle);
let radioButtonStyle = new System.Windows.Style(typeof<RadioButton>)
radioButtonStyle.Setters.Add(new Setter(RadioButton.MarginProperty, new Thickness(Bottom = 7.0 )))
radioButtonStyle.Setters.Add(new Setter(RadioButton.ForegroundProperty, new DynamicResourceExtension(SystemColors.WindowTextBrushKey)))
element.Resources.Add(typeof<RadioButton>, radioButtonStyle)
element
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.VisualStudio.FSharp.Editor
open System
open System.Runtime.InteropServices
open Microsoft.VisualStudio.Shell
module internal IntelliSenseSettings =
let mutable ShowAfterCharIsTyped = true
[<ComVisible(true)>]
[<CLSCompliant(false)>]
[<ClassInterface(ClassInterfaceType.AutoDual)>]
[<Guid("285A7B09-D942-464E-B69E-3BD06D665F5E")>]
type IntelliSensePropertyPage() =
inherit DialogPage()
[<SR.SRCategoryAttribute(SR.IntelliSensePropertyPageMiscCategory)>]
[<SR.SRDisplayNameAttribute(SR.IntelliSensePropertyPageShowAfterCharIsTyped)>]
[<SR.SRDescription(SR.IntelliSensePropertyPageShowAfterCharIsTypedDescr)>]
member this.ShowAfterCharIsTyped with get() = IntelliSenseSettings.ShowAfterCharIsTyped and set (x:bool) = IntelliSenseSettings.ShowAfterCharIsTyped <- x
......@@ -47,23 +47,35 @@ module private SessionHandling =
member __.AugmentQuickInfoSession(session,_,_) = currentSession <- Some session
member __.Dispose() = () }
type internal SourceLink(run) as this =
inherit Documents.Hyperlink(run)
let lessOpacity =
module private SourceLink =
let solid = 70uy, DashStyles.Solid
let dot = 255uy, DashStyle([1.0; 5.0], 0.0)
let dash = 90uy, DashStyle([5.0; 5.0], 0.0)
let none = 0uy, DashStyles.Solid
let opacityCoverter =
{ new IValueConverter with
member this.Convert(value, targetType, _, _) =
member this.Convert(value, _, parameter, _) =
match value with
| :? Color as c when targetType = typeof<Color> ->
// return same color but slightly transparent
Color.FromArgb(70uy, c.R, c.G, c.B) :> _
| _ -> DependencyProperty.UnsetValue
member this.ConvertBack(_,_,_,_) = DependencyProperty.UnsetValue }
| :? Color as c -> Color.FromArgb(unbox parameter, c.R, c.G, c.B) :> _
| _ -> Binding.DoNothing
member this.ConvertBack(_,_,_,_) = Binding.DoNothing }
let getUnderlineStyle() =
if not Settings.QuickInfo.DisplayLinks then none
else
match Settings.QuickInfo.UnderlineStyle with
| QuickInfoUnderlineStyle.Solid -> solid
| QuickInfoUnderlineStyle.Dot -> dot
| QuickInfoUnderlineStyle.Dash -> dash
type internal SourceLink(run) as this =
inherit Documents.Hyperlink(run)
let opacity, dashStyle = SourceLink.getUnderlineStyle()
let underlineBrush = Media.SolidColorBrush()
do BindingOperations.SetBinding(underlineBrush, SolidColorBrush.ColorProperty, Binding("Foreground.Color", Source = this, Converter = lessOpacity)) |> ignore
do BindingOperations.SetBinding(underlineBrush, SolidColorBrush.ColorProperty, Binding("Foreground.Color", Source = this, Converter = SourceLink.opacityCoverter, ConverterParameter = opacity)) |> ignore
let normalUnderline = TextDecorationCollection [TextDecoration(Location = TextDecorationLocation.Underline, PenOffset = 1.0)]
let slightUnderline = TextDecorationCollection [TextDecoration(Location = TextDecorationLocation.Underline, PenOffset = 1.0, Pen = Pen(Brush = underlineBrush))]
let slightUnderline = TextDecorationCollection [TextDecoration(Location = TextDecorationLocation.Underline, PenOffset = 1.0, Pen = Pen(Brush = underlineBrush, DashStyle = dashStyle))]
do this.TextDecorations <- slightUnderline
override this.OnMouseEnter(e) =
......
......@@ -31,13 +31,6 @@ module SR =
let FSharpDisposablesClassificationType = lazy (GetString "FSharpDisposablesClassificationType")
let RemoveUnusedOpens = lazy (GetString "RemoveUnusedOpens")
let UnusedOpens = lazy (GetString "UnusedOpens")
[<Literal>]
let IntelliSensePropertyPageMiscCategory = "IntelliSensePropertyPageMiscCategory"
[<Literal>]
let IntelliSensePropertyPageShowAfterCharIsTyped = "IntelliSensePropertyPageShowAfterCharIsTyped"
[<Literal>]
let IntelliSensePropertyPageShowAfterCharIsTypedDescr = "IntelliSensePropertyPageShowAfterCharIsTypedDescr"
//--------------------------------------------------------------------------------------
// Attributes used to mark up editable properties
......
......@@ -168,10 +168,6 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
"F# Tools", "F# Interactive", // category/sub-category on Tools>Options...
6000s, 6001s, // resource id for localisation of the above
true)>] // true = supports automation
[<ProvideOptionPage(typeof<IntelliSensePropertyPage>,
"F# Tools", "IntelliSense", // category/sub-category on Tools>Options...
6000s, 6008s, // resource id for localisation of the above
true)>] // true = supports automation
[<ProvideKeyBindingTable("{dee22b65-9761-4a26-8fb2-759b971d6dfc}", 6001s)>] // <-- resource ID for localised name
[<ProvideToolWindow(typeof<Microsoft.VisualStudio.FSharp.Interactive.FsiToolWindow>,
// The following should place the ToolWindow with the OutputWindow by default.
......@@ -320,8 +316,6 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
Microsoft.VisualStudio.FSharp.Interactive.Hooks.fsiConsoleWindowPackageInitalizeSited (this :> Package) commandService
// FSI-LINKAGE-POINT: private method GetDialogPage forces fsi options to be loaded
let _fsiPropertyPage = this.GetDialogPage(typeof<Microsoft.VisualStudio.FSharp.Interactive.FsiPropertyPage>)
// private method GetDialogPage forces intellisense options to be loaded
let _intelliSensePropertyPage = this.GetDialogPage(typeof<IntelliSensePropertyPage>)
this.RegisterForIdleTime()
()
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.-->
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<FSharpSourcesRoot>$(MSBuildProjectDirectory)\..\..\..\src</FSharpSourcesRoot>
<ProjectLanguage>CSharp</ProjectLanguage>
<SIGN_WITH_MSFT_KEY>true</SIGN_WITH_MSFT_KEY>
<MicroBuildAssemblyVersion>15.4.1.0</MicroBuildAssemblyVersion>
<MicroBuildAssemblyFileLanguage>cs</MicroBuildAssemblyFileLanguage>
</PropertyGroup>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<TargetFramework Condition=" '$(TargetFramework)' == '' ">net40</TargetFramework>
<OutputPath>$(FSharpSourcesRoot)\..\$(Configuration)\$(TargetFramework)\bin</OutputPath>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{C4586A06-1402-48BC-8E35-A1B8642F895B}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.VisualStudio.FSharp.UIResources</RootNamespace>
<AssemblyName>FSharp.UIResources</AssemblyName>
<TargetType>LIBRARY</TargetType>
<UseVsVersion>true</UseVsVersion>
<DefineConstants>$(DefineConstants)</DefineConstants>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<DefineConstants>$(DefineConstants);FSHARP_CORE_4_5</DefineConstants>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<ItemGroup>
<FilesToLocalize Include="$(OutDir)$(AssemblyName).dll">
<TranslationFile>$(FSharpSourcesRoot)\..\loc\lcl\{Lang}\$(AssemblyName).dll.lcl</TranslationFile>
<LciCommentFile>$(FSharpSourcesRoot)\..\loc\lci\$(AssemblyName).dll.lci</LciCommentFile>
<HasLceComments>false</HasLceComments>
<InProject>false</InProject>
</FilesToLocalize>
</ItemGroup>
<PropertyGroup>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>$(FSharpSourcesRoot)\fsharp\msft.pubkey</AssemblyOriginatorKeyFile>
<DefineConstants>STRONG_NAME_AND_DELAY_SIGN_FSHARP_COMPILER_WITH_MSFT_KEY;$(DefineConstants)</DefineConstants>
<StrongNames>true</StrongNames>
<DelaySign>true</DelaySign>
</PropertyGroup>
<Import Project="$(FSharpSourcesRoot)\FSharpSource.settings.targets" />
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System.Drawing" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Windows" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="IntelliSenseOptionControl.xaml.cs">
<DependentUpon>IntelliSenseOptionControl.xaml</DependentUpon>
</Compile>
<Compile Include="InternalsVisibleTo.cs" />
<Compile Include="QuickInfoOptionControl.xaml.cs">
<DependentUpon>QuickInfoOptionControl.xaml</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Strings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Strings.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Page Include="IntelliSenseOptionControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="OptionPageStyle.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="QuickInfoOptionControl.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Strings.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(FSharpSourcesRoot)\Microbuild.Settings.targets" />
<Target Name="GatherBinariesToBeSigned" AfterTargets="Localize" Condition="'$(UseGatherBinaries)' == 'true'">
<ItemGroup>
<BinariesToBeSigned Include="$(OutDir)$(AssemblyName).dll" />
<BinariesToBeSigned Include="$(OutDir)localize\**\$(AssemblyName).resources.dll" />
<FilesToSign Include="@(BinariesToBeSigned)">
<Authenticode>Microsoft</Authenticode>
<StrongName>StrongName</StrongName>
</FilesToSign>
</ItemGroup>
</Target>
</Project>
\ No newline at end of file
<UserControl x:Class="Microsoft.VisualStudio.FSharp.UIResources.IntelliSenseOptionControl"
x:ClassModifier="internal"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Microsoft.VisualStudio.FSharp.UIResources"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="OptionPageStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel>
<GroupBox Header="{x:Static local:Strings.Completion_Lists}">
<StackPanel>
<CheckBox x:Name="charTyped" IsChecked="{Binding ShowAfterCharIsTyped}"
Content="{x:Static local:Strings.Show_completion_list_after_a_character_is_typed}"/>
<StackPanel Margin="15 0 0 0">
<CheckBox x:Name="charDeleted" IsEnabled="{Binding IsChecked, ElementName=charTyped}" IsChecked="{Binding ShowAfterCharIsDeleted}"
Content="{x:Static local:Strings.Show_completion_list_after_a_character_is_deleted}"/>
</StackPanel>
</StackPanel>
</GroupBox>
</StackPanel>
</ScrollViewer>
</Grid>
</UserControl>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Microsoft.VisualStudio.FSharp.UIResources
{
/// <summary>
/// Interaction logic for IntelliSenseOptionControl.xaml
/// </summary>
internal partial class IntelliSenseOptionControl : UserControl
{
public IntelliSenseOptionControl()
{
InitializeComponent();
}
}
}
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("VisualFSharp.Salsa, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")]
[assembly: InternalsVisibleTo("VisualFSharp.Unittests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")]
[assembly: InternalsVisibleTo("FSharp.LanguageService, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")]
[assembly: InternalsVisibleTo("FSharp.ProjectSystem.Base, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")]
[assembly: InternalsVisibleTo("FSharp.ProjectSystem.FSharp, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")]
[assembly: InternalsVisibleTo("FSharp.Editor, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")]
// Expose internals to testhook infrastructure and the test driver
[assembly: InternalsVisibleTo("Tao.VSLanguages.FSharp, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")]
[assembly: InternalsVisibleTo("TNugget, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")]
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Microsoft.VisualStudio.FSharp.UIResources">
<Style TargetType="GroupBox">
<Setter Property="Padding" Value="7 7 7 0"/>
<Setter Property="Margin" Value="0 0 0 3"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
</Style>
<Style TargetType="CheckBox">
<Setter Property="Margin" Value="0 0 0 7"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
</Style>
<Style TargetType="TextBox">
<Setter Property="Margin" Value="7 0 7 0"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
</Style>
<Style TargetType="RadioButton">
<Setter Property="Margin" Value="0 0 0 7"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
</Style>
</ResourceDictionary>
\ No newline at end of file
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("FSharp.UIResources")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft.VisualFSharpTools")]
[assembly: AssemblyProduct("FSharp.UIResources")]
[assembly: AssemblyCopyright("Copyright (c) Microsoft Corporation.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
<UserControl x:Class="Microsoft.VisualStudio.FSharp.UIResources.QuickInfoOptionControl"
x:ClassModifier="internal"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Microsoft.VisualStudio.FSharp.UIResources"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="OptionPageStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel>
<GroupBox Header="{x:Static local:Strings.Navigation_links}">
<StackPanel>
<StackPanel>
<CheckBox x:Name="displayLinks" Content="{x:Static local:Strings.Show_navigation_links_as}"/>
</StackPanel>
<StackPanel x:Name="underlineStyle" Margin="15 0 0 0">
<RadioButton x:Name="solid" Content="{x:Static local:Strings.Solid_underline}" IsEnabled="{Binding IsChecked, ElementName=displayLinks}"/>
<RadioButton x:Name="dot" Content="{x:Static local:Strings.Dot_underline}" IsEnabled="{Binding IsChecked, ElementName=displayLinks}"/>
<RadioButton x:Name="dash" Content="{x:Static local:Strings.Dash_underline}" IsEnabled="{Binding IsChecked, ElementName=displayLinks}"/>
</StackPanel>
</StackPanel>
</GroupBox>
</StackPanel>
</ScrollViewer>
</Grid>
</UserControl>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Microsoft.VisualStudio.FSharp.UIResources
{
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
internal partial class QuickInfoOptionControl : UserControl
{
public QuickInfoOptionControl()
{
InitializeComponent();
}
}
}
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Microsoft.VisualStudio.FSharp.UIResources {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Strings {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Strings() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.VisualStudio.FSharp.UIResources.Strings", typeof(Strings).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Completion Lists.
/// </summary>
public static string Completion_Lists {
get {
return ResourceManager.GetString("Completion_Lists", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to D_ash underline.
/// </summary>
public static string Dash_underline {
get {
return ResourceManager.GetString("Dash_underline", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to D_ot underline.
/// </summary>
public static string Dot_underline {
get {
return ResourceManager.GetString("Dot_underline", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Navigation links.
/// </summary>
public static string Navigation_links {
get {
return ResourceManager.GetString("Navigation_links", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show completion list after a character is _deleted.
/// </summary>
public static string Show_completion_list_after_a_character_is_deleted {
get {
return ResourceManager.GetString("Show_completion_list_after_a_character_is_deleted", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to _Show completion list after a character is typed.
/// </summary>
public static string Show_completion_list_after_a_character_is_typed {
get {
return ResourceManager.GetString("Show_completion_list_after_a_character_is_typed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to S_how navigation links as.
/// </summary>
public static string Show_navigation_links_as {
get {
return ResourceManager.GetString("Show_navigation_links_as", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to _Solid underline.
/// </summary>
public static string Solid_underline {
get {
return ResourceManager.GetString("Solid_underline", resourceCulture);
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Completion_Lists" xml:space="preserve">
<value>Completion Lists</value>
</data>
<data name="Dash_underline" xml:space="preserve">
<value>D_ash underline</value>
</data>
<data name="Dot_underline" xml:space="preserve">
<value>D_ot underline</value>
</data>
<data name="Navigation_links" xml:space="preserve">
<value>Navigation links</value>
</data>
<data name="Show_completion_list_after_a_character_is_deleted" xml:space="preserve">
<value>Show completion list after a character is _deleted</value>
</data>
<data name="Show_completion_list_after_a_character_is_typed" xml:space="preserve">
<value>_Show completion list after a character is typed</value>
</data>
<data name="Show_navigation_links_as" xml:space="preserve">
<value>S_how navigation links as</value>
</data>
<data name="Solid_underline" xml:space="preserve">
<value>_Solid underline</value>
</data>
</root>
\ No newline at end of file
......@@ -82,6 +82,10 @@ let VerifyCompletionListExactly(fileContents: string, marker: string, expected:
let VerifyNoCompletionList(fileContents: string, marker: string) =
VerifyCompletionListExactly(fileContents, marker, [])
[<OneTimeSetUp>]
let usingDefaultSettings() =
SettingsPersistence.setSettings { ShowAfterCharIsTyped = true; ShowAfterCharIsDeleted = false }
[<Test>]
let ShouldTriggerCompletionAtCorrectMarkers() =
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册