提交 b0fb1fe8 编写于 作者: J Jason Malinowski

Listen to .editorconfig files for core settings

上级 a542bae6
......@@ -73,7 +73,9 @@
<Compile Include="IntelliSense\Completion\Presentation\VisualStudio15CompletionSet.cs" />
<Compile Include="NavigateTo\Dev15NavigateToOptionsService.cs" />
<Compile Include="Structure\VisualStudio15StructureTaggerProvider.cs" />
<Compile Include="Options\EditorConfigDocumentOptionsProviderFactory.cs" />
<Compile Include="Options\EditorConfigDocumentOptionsProvider.cs" />
</ItemGroup>
<ItemGroup />
<Import Project="..\..\..\build\Targets\VSL.Imports.targets" />
</Project>
\ No newline at end of file
</Project>
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Options;
using Microsoft.VisualStudio.CodingConventions;
namespace Microsoft.CodeAnalysis.Editor.Options
{
// NOTE: this type depends on Dev15 assemblies, which is why the type is in EditorFeatures.Next. But, that library
// is rehostable and once we move .editorconfig support fully through the system, it should be moved to Workspaces
// or perhaps even lower.
internal sealed class EditorConfigDocumentOptionsProvider : IDocumentOptionsProvider
{
private readonly object _gate = new object();
/// <summary>
/// The map of cached contexts for currently open documents.
/// </summary>
private readonly Dictionary<DocumentId, Task<ICodingConventionContext>> _openDocumentContexts = new Dictionary<DocumentId, Task<ICodingConventionContext>>();
private readonly ICodingConventionsManager _codingConventionsManager;
internal EditorConfigDocumentOptionsProvider(Workspace workspace)
{
_codingConventionsManager = CodingConventionsManagerFactory.CreateCodingConventionsManager();
workspace.DocumentOpened += Workspace_DocumentOpened;
workspace.DocumentClosed += Workspace_DocumentClosed;
}
private void Workspace_DocumentClosed(object sender, DocumentEventArgs e)
{
lock (_gate)
{
Task<ICodingConventionContext> contextTask;
if (_openDocumentContexts.TryGetValue(e.Document.Id, out contextTask))
{
_openDocumentContexts.Remove(e.Document.Id);
// Ensure we dispose the context, which we'll do asynchronously
contextTask.ContinueWith(t => t.Result.Dispose(), CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
}
}
}
private void Workspace_DocumentOpened(object sender, DocumentEventArgs e)
{
lock (_gate)
{
_openDocumentContexts.Add(e.Document.Id, Task.Run(() => _codingConventionsManager.GetConventionContextAsync(e.Document.FilePath, CancellationToken.None)));
}
}
public async Task<IDocumentOptions> GetOptionsForDocumentAsync(Document document)
{
Task<ICodingConventionContext> contextTask;
lock (_gate)
{
if (!_openDocumentContexts.TryGetValue(document.Id, out contextTask))
{
return null;
}
}
return new DocumentOptions(await contextTask.ConfigureAwait(false));
}
private class DocumentOptions : IDocumentOptions
{
private ICodingConventionContext _codingConventionContext;
public DocumentOptions(ICodingConventionContext codingConventionContext)
{
_codingConventionContext = codingConventionContext;
}
public bool TryGetDocumentOption(Document document, OptionKey option, out object value)
{
var editorConfigPersistence = option.Option.StorageLocations.OfType<EditorConfigStorageLocation>().SingleOrDefault();
if (editorConfigPersistence == null)
{
value = null;
return false;
}
if (_codingConventionContext.CurrentConventions.TryGetConventionValue(editorConfigPersistence.KeyName, out value))
{
value = editorConfigPersistence.ParseFunction(value.ToString());
return true;
}
else
{
return false;
}
}
}
}
}
using System;
using System.ComponentModel.Composition;
using Microsoft.CodeAnalysis.Options;
namespace Microsoft.CodeAnalysis.Editor.Options
{
[Export(typeof(IDocumentOptionsProviderFactory))]
class EditorConfigDocumentOptionsProviderFactory : IDocumentOptionsProviderFactory
{
public IDocumentOptionsProvider Create(Workspace workspace)
{
return new EditorConfigDocumentOptionsProvider(workspace);
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.CodeAnalysis.Options;
namespace Microsoft.CodeAnalysis.Formatting
{
public static class FormattingOptions
{
public static PerLanguageOption<bool> UseTabs { get; } = new PerLanguageOption<bool>(nameof(FormattingOptions), nameof(UseTabs), defaultValue: false);
public static PerLanguageOption<bool> UseTabs { get; } = new PerLanguageOption<bool>(nameof(FormattingOptions), nameof(UseTabs), defaultValue: false,
storageLocations: new EditorConfigStorageLocation("indent_style", s => s == "tab"));
// This is also serialized by the Visual Studio-specific LanguageSettingsPersister
public static PerLanguageOption<int> TabSize { get; } = new PerLanguageOption<int>(nameof(FormattingOptions), nameof(TabSize), defaultValue: 4);
public static PerLanguageOption<int> TabSize { get; } = new PerLanguageOption<int>(nameof(FormattingOptions), nameof(TabSize), defaultValue: 4,
storageLocations: new EditorConfigStorageLocation("tab_width", s => int.Parse(s)));
// This is also serialized by the Visual Studio-specific LanguageSettingsPersister
public static PerLanguageOption<int> IndentationSize { get; } = new PerLanguageOption<int>(nameof(FormattingOptions), nameof(IndentationSize), defaultValue: 4);
public static PerLanguageOption<int> IndentationSize { get; } = new PerLanguageOption<int>(nameof(FormattingOptions), nameof(IndentationSize), defaultValue: 4,
storageLocations: new EditorConfigStorageLocation("indent_size", s => int.Parse(s)));
// This is also serialized by the Visual Studio-specific LanguageSettingsPersister
public static PerLanguageOption<IndentStyle> SmartIndent { get; } = new PerLanguageOption<IndentStyle>(nameof(FormattingOptions), nameof(SmartIndent), defaultValue: IndentStyle.Smart);
public static PerLanguageOption<string> NewLine { get; } = new PerLanguageOption<string>(nameof(FormattingOptions), nameof(NewLine), defaultValue: "\r\n");
public static PerLanguageOption<string> NewLine { get; } = new PerLanguageOption<string>(nameof(FormattingOptions), nameof(NewLine), defaultValue: "\r\n",
storageLocations: new EditorConfigStorageLocation("end_of_line", ParseEditorConfigEndOfLine));
private static object ParseEditorConfigEndOfLine(string endOfLineValue)
{
switch (endOfLineValue)
{
case "lf": return "\n";
case "cr": return "\r";
case "crlf": return "\r\n";
default: return NewLine.DefaultValue;
}
}
internal static PerLanguageOption<bool> DebugMode { get; } = new PerLanguageOption<bool>(nameof(FormattingOptions), nameof(DebugMode), defaultValue: false);
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.CodeAnalysis.Options
{
/// <summary>
/// Specifies that an option should be read from an .editorconfig file.
/// </summary>
internal sealed class EditorConfigStorageLocation : OptionStorageLocation
{
public string KeyName { get; }
public Func<string, object> ParseFunction { get; }
public EditorConfigStorageLocation(string keyName, Func<string, object> parseFunction)
{
KeyName = keyName;
ParseFunction = parseFunction;
}
}
}
......@@ -242,6 +242,7 @@
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.CSharp.InteractiveEditorFeatures" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.CSharp.Workspaces" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.EditorFeatures" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.EditorFeatures.Next" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.EditorFeatures.Text" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.Features" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.InteractiveEditorFeatures" />
......@@ -390,6 +391,7 @@
<Compile Include="FindSymbols\SymbolTree\SymbolTreeInfo.FirstEntityHandleProvider.cs" />
<Compile Include="FindSymbols\SyntaxTree\IDeclarationInfo.cs" />
<Compile Include="LanguageServices\SyntaxFactsService\AbstractSyntaxFactsService.cs" />
<Compile Include="Options\EditorConfigStorageLocation.cs" />
<Compile Include="Options\GlobalOptionService.cs" />
<Compile Include="Options\IDocumentOptions.cs" />
<Compile Include="Options\IDocumentOptionsProvider.cs" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册