提交 2f6734b1 编写于 作者: C CyrusNajmabadi

Add options to control outlining and indent guides.

上级 65b8f159
......@@ -76,7 +76,12 @@ protected sealed override ITaggerEventSource CreateEventSource(ITextView textVie
return TaggerEventSources.Compose(
TaggerEventSources.OnTextChanged(subjectBuffer, TaggerDelay.OnIdle),
TaggerEventSources.OnParseOptionChanged(subjectBuffer, TaggerDelay.OnIdle),
TaggerEventSources.OnWorkspaceRegistrationChanged(subjectBuffer, TaggerDelay.OnIdle));
TaggerEventSources.OnWorkspaceRegistrationChanged(subjectBuffer, TaggerDelay.OnIdle),
TaggerEventSources.OnOptionChanged(subjectBuffer, BlockStructureOptions.ShowBlockStructureGuidesForCodeLevelConstructs, TaggerDelay.NearImmediate),
TaggerEventSources.OnOptionChanged(subjectBuffer, BlockStructureOptions.ShowBlockStructureGuidesForDeclarationLevelConstructs, TaggerDelay.NearImmediate),
TaggerEventSources.OnOptionChanged(subjectBuffer, BlockStructureOptions.ShowOutliningForCodeLevelConstructs, TaggerDelay.NearImmediate),
TaggerEventSources.OnOptionChanged(subjectBuffer, BlockStructureOptions.ShowOutliningForDeclarationLevelConstructs, TaggerDelay.NearImmediate),
TaggerEventSources.OnOptionChanged(subjectBuffer, BlockStructureOptions.ShowOutliningForCommentsAndPreprocessorRegions, TaggerDelay.NearImmediate));
}
/// <summary>
......@@ -90,11 +95,11 @@ protected sealed override ITaggerEventSource CreateEventSource(ITextView textVie
var outliningService = TryGetService(context, documentSnapshotSpan);
if (outliningService != null)
{
var cancellationToken = context.CancellationToken;
var blockStructure = await outliningService.GetBlockStructureAsync(
documentSnapshotSpan.Document, context.CancellationToken).ConfigureAwait(false);
ProcessSpans(
context, documentSnapshotSpan.SnapshotSpan, outliningService,
blockStructure.Spans);
documentSnapshotSpan.Document, cancellationToken).ConfigureAwait(false);
ProcessSpans(context, documentSnapshotSpan, outliningService, blockStructure.Spans);
}
}
catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
......@@ -121,9 +126,8 @@ protected sealed override ITaggerEventSource CreateEventSource(ITextView textVie
// and make a blocking call against the async service.
var blockStructure = outliningService.GetBlockStructure(document, cancellationToken);
ProcessSpans(
context, documentSnapshotSpan.SnapshotSpan, outliningService,
blockStructure.Spans);
ProcessSpans(context, documentSnapshotSpan, outliningService, blockStructure.Spans);
}
}
catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
......@@ -151,13 +155,13 @@ protected sealed override ITaggerEventSource CreateEventSource(ITextView textVie
private void ProcessSpans(
TaggerContext<TRegionTag> context,
SnapshotSpan snapshotSpan,
DocumentSnapshotSpan documentSnapshotSpan,
BlockStructureService outliningService,
ImmutableArray<BlockSpan> spans)
{
try
{
ProcessSpansWorker(context, snapshotSpan, outliningService, spans);
ProcessSpansWorker(context, documentSnapshotSpan, outliningService, spans);
}
catch (TypeLoadException)
{
......@@ -170,12 +174,14 @@ protected sealed override ITaggerEventSource CreateEventSource(ITextView textVie
private void ProcessSpansWorker(
TaggerContext<TRegionTag> context,
SnapshotSpan snapshotSpan,
DocumentSnapshotSpan documentSnapshotSpan,
BlockStructureService outliningService,
ImmutableArray<BlockSpan> spans)
{
if (spans != null)
{
var document = documentSnapshotSpan.Document;
var snapshotSpan = documentSnapshotSpan.SnapshotSpan;
var snapshot = snapshotSpan.Snapshot;
spans = GetMultiLineRegions(outliningService, spans, snapshot);
......@@ -206,8 +212,7 @@ protected sealed override ITaggerEventSource CreateEventSource(ITextView textVie
}
}
protected abstract TRegionTag CreateTag(
TRegionTag parentTag, ITextSnapshot snapshot, BlockSpan region);
protected abstract TRegionTag CreateTag(TRegionTag parentTag, ITextSnapshot snapshot, BlockSpan region);
private static bool s_exceptionReported = false;
......
......@@ -53,9 +53,9 @@ public override int GetHashCode(IOutliningRegionTag obj)
}
protected override IOutliningRegionTag CreateTag(
IOutliningRegionTag parentTag, ITextSnapshot snapshot, BlockSpan region)
IOutliningRegionTag parentTag, ITextSnapshot snapshot, BlockSpan blockSpan)
{
if (!region.IsCollapsible)
if (!blockSpan.IsCollapsible)
{
return null;
}
......@@ -64,7 +64,7 @@ public override int GetHashCode(IOutliningRegionTag obj)
this.TextEditorFactoryService,
this.ProjectionBufferFactoryService,
this.EditorOptionsFactoryService,
snapshot, region);
snapshot, blockSpan);
}
}
}
\ No newline at end of file
......@@ -56,9 +56,12 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<None Include="project.json" />
......
......@@ -5,6 +5,10 @@
using System.ComponentModel.Composition;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using Microsoft.CodeAnalysis.Editor.Implementation.Structure;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
......@@ -98,9 +102,39 @@ private object CreateContent()
var result = new ViewHostingControl(
CreateElisionBufferView, CreateProjectionBufferForBlockHeaders);
result.Loaded += (s, e) => Result_IsVisibleChanged(result);
return result;
}
private void Result_IsVisibleChanged(ViewHostingControl control)
{
var tooltip = GetToolTop(control);
if (tooltip == null)
{
return;
}
tooltip.PlacementTarget = ((IWpfTextView)this.TextView).VisualElement;
tooltip.Placement = PlacementMode.Relative;
tooltip.HorizontalOffset = 0;
tooltip.VerticalOffset = 0;
tooltip.UpdateLayout();
}
private ToolTip GetToolTop(ViewHostingControl control)
{
for (DependencyObject current = control; current != null; current = VisualTreeHelper.GetParent(current))
{
var tooltip = current as ToolTip;
if (tooltip != null)
{
return tooltip;
}
}
return null;
}
private IWpfTextView CreateElisionBufferView(ITextBuffer finalBuffer)
{
return RoslynOutliningRegionTag.CreateShrunkenTextView(
......
......@@ -56,6 +56,55 @@ public override int GetHashCode(IBlockTag obj)
parentTag, snapshot, region);
}
private static string ConvertType(string type)
{
switch (type)
{
case BlockTypes.Nonstructural: return PredefinedStructureTypes.Nonstructural;
// Top level declarations. Note that Enum is not currently supported
// and that we map Module down to Class.
case BlockTypes.Namespace: return PredefinedStructureTypes.Namespace;
case BlockTypes.Structure: return PredefinedStructureTypes.Struct;
case BlockTypes.Interface: return PredefinedStructureTypes.Interface;
case BlockTypes.Module:
case BlockTypes.Class: return PredefinedStructureTypes.Class;
// Member declarations
case BlockTypes.Accessor: return PredefinedStructureTypes.AccessorBlock;
case BlockTypes.Constructor: return PredefinedStructureTypes.Constructor;
case BlockTypes.Destructor: return PredefinedStructureTypes.Destructor;
case BlockTypes.Method: return PredefinedStructureTypes.Method;
case BlockTypes.Operator: return PredefinedStructureTypes.Operator;
// Map events/indexers/properties all to the 'property' type.
case BlockTypes.Event:
case BlockTypes.Indexer:
case BlockTypes.Property: return PredefinedStructureTypes.PropertyBlock;
// Statements
case BlockTypes.Case: return PredefinedStructureTypes.Case;
case BlockTypes.Conditional: return PredefinedStructureTypes.Conditional;
case BlockTypes.Lock: return PredefinedStructureTypes.Lock;
case BlockTypes.Loop: return PredefinedStructureTypes.Loop;
case BlockTypes.TryCatchFinally: return PredefinedStructureTypes.TryCatchFinally;
case BlockTypes.Standalone: return PredefinedStructureTypes.Standalone;
// Expressions
case BlockTypes.AnonymousMethod: return PredefinedStructureTypes.AnonymousMethodBlock;
// These types don't currently map to any editor types. Just make them
// the 'Unknown' type for now.
case BlockTypes.Enum:
case BlockTypes.Xml:
case BlockTypes.LocalFunction:
case BlockTypes.Using:
case BlockTypes.Switch:
default:
return PredefinedStructureTypes.Unknown;
}
}
private class RoslynBlockTag : RoslynOutliningRegionTag, IBlockTag
{
public IBlockTag Parent { get; }
......@@ -63,8 +112,7 @@ private class RoslynBlockTag : RoslynOutliningRegionTag, IBlockTag
public SnapshotSpan Span { get; }
public SnapshotSpan StatementSpan { get; }
public string Type => ConvertType(BlockSpan.Type);
public string Type { get; }
public bool IsCollapsible => BlockSpan.IsCollapsible;
public RoslynBlockTag(
......@@ -73,68 +121,17 @@ private class RoslynBlockTag : RoslynOutliningRegionTag, IBlockTag
IEditorOptionsFactoryService editorOptionsFactoryService,
IBlockTag parent,
ITextSnapshot snapshot,
BlockSpan outliningSpan) :
BlockSpan blockSpan) :
base(textEditorFactoryService,
projectionBufferFactoryService,
editorOptionsFactoryService,
snapshot, outliningSpan)
snapshot, blockSpan)
{
Parent = parent;
Level = parent == null ? 0 : parent.Level + 1;
Span = outliningSpan.TextSpan.ToSnapshotSpan(snapshot);
StatementSpan = outliningSpan.HintSpan.ToSnapshotSpan(snapshot);
}
private string ConvertType(string type)
{
switch (type)
{
// Basic types.
case BlockTypes.Structural: return PredefinedStructureTypes.Structural;
case BlockTypes.Nonstructural: return PredefinedStructureTypes.Nonstructural;
// Top level declarations. Note that Enum is not currently supported
// and that we map Module down to Class.
case BlockTypes.Namespace: return PredefinedStructureTypes.Namespace;
case BlockTypes.Structure: return PredefinedStructureTypes.Struct;
case BlockTypes.Interface: return PredefinedStructureTypes.Interface;
case BlockTypes.Module:
case BlockTypes.Class: return PredefinedStructureTypes.Class;
// Member declarations
case BlockTypes.Accessor: return PredefinedStructureTypes.AccessorBlock;
case BlockTypes.Constructor: return PredefinedStructureTypes.Constructor;
case BlockTypes.Destructor: return PredefinedStructureTypes.Destructor;
case BlockTypes.Method: return PredefinedStructureTypes.Method;
case BlockTypes.Operator: return PredefinedStructureTypes.Operator;
// Map events/indexers/properties all to the 'property' type.
case BlockTypes.Event:
case BlockTypes.Indexer:
case BlockTypes.Property: return PredefinedStructureTypes.PropertyBlock;
// Statements
case BlockTypes.Case: return PredefinedStructureTypes.Case;
case BlockTypes.Conditional: return PredefinedStructureTypes.Conditional;
case BlockTypes.Lock: return PredefinedStructureTypes.Lock;
case BlockTypes.Loop: return PredefinedStructureTypes.Loop;
case BlockTypes.TryCatchFinally: return PredefinedStructureTypes.TryCatchFinally;
case BlockTypes.Standalone: return PredefinedStructureTypes.Standalone;
// Expressions
case BlockTypes.AnonymousMethod: return PredefinedStructureTypes.AnonymousMethodBlock;
// These types don't currently map to any editor types. Just make them
// the 'Unknown' type for now.
case BlockTypes.Enum:
case BlockTypes.Other:
case BlockTypes.Xml:
case BlockTypes.LocalFunction:
case BlockTypes.Using:
case BlockTypes.Switch:
default:
return PredefinedStructureTypes.Unknown;
}
Span = blockSpan.TextSpan.ToSnapshotSpan(snapshot);
StatementSpan = blockSpan.HintSpan.ToSnapshotSpan(snapshot);
Type = ConvertType(blockSpan.Type);
}
}
}
......
......@@ -142,9 +142,9 @@ private static string GetCommentBannerText(SyntaxTrivia comment)
isCollapsible: true,
textSpan: span,
hintSpan: span,
type: BlockTypes.Comment,
bannerText: GetCommentBannerText(startComment),
autoCollapse: true,
type: BlockTypes.Nonstructural);
autoCollapse: true);
}
// For testing purposes
......
......@@ -26,11 +26,15 @@ internal class BlockSyntaxStructureProvider : AbstractSyntaxNodeStructureProvide
parentKind == SyntaxKind.FinallyClause ||
parentKind == SyntaxKind.ElseClause)
{
spans.Add(new BlockSpan(
isCollapsible: node.IsParentKind(SyntaxKind.LocalFunctionStatement),
textSpan: GetTextSpan(node),
hintSpan: node.Parent.Span,
type: GetType(node.Parent)));
var type = GetType(node.Parent);
if (type != null)
{
spans.Add(new BlockSpan(
isCollapsible: node.IsParentKind(SyntaxKind.LocalFunctionStatement),
textSpan: GetTextSpan(node),
hintSpan: node.Parent.Span,
type: type));
}
}
// Switch sections are somewhat special. Say you have the following:
......@@ -94,9 +98,9 @@ private string GetType(SyntaxNode parent)
case SyntaxKind.Block: return BlockTypes.Standalone;
case SyntaxKind.LocalFunctionStatement: return BlockTypes.LocalFunction;
default: return BlockTypes.Other;
}
return null;
}
}
}
\ No newline at end of file
......@@ -25,7 +25,7 @@ internal class CompilationUnitStructureProvider : AbstractSyntaxNodeStructurePro
spans.Add(CSharpStructureHelpers.CreateBlockSpan(
externsAndUsings, autoCollapse: true,
type: BlockTypes.Nonstructural, isCollapsible: true));
type: BlockTypes.Imports, isCollapsible: true));
if (compilationUnit.Usings.Count > 0 ||
compilationUnit.Externs.Count > 0 ||
......
......@@ -94,6 +94,7 @@ internal class DisabledTextTriviaStructureProvider : AbstractSyntaxTriviaStructu
spans.Add(new BlockSpan(
isCollapsible: true,
textSpan: span,
type: BlockTypes.PreprocessorRegion,
bannerText: CSharpStructureHelpers.Ellipsis,
autoCollapse: true));
}
......
......@@ -120,6 +120,7 @@ private static void AppendTextTokens(StringBuilder sb, SyntaxTokenList textToken
spans.Add(new BlockSpan(
isCollapsible: true,
textSpan: span,
type: BlockTypes.Comment,
bannerText: GetBannerText(documentationComment, cancellationToken),
autoCollapse: true));
}
......
......@@ -35,6 +35,7 @@ internal abstract class AbstractMetadataAsSourceStructureProvider<TSyntaxNode> :
spans.Add(new BlockSpan(
isCollapsible: true,
type: BlockTypes.Comment,
textSpan: TextSpan.FromBounds(startPosition, endPosition),
hintSpan: TextSpan.FromBounds(startPosition, hintTextEndToken.Span.End),
bannerText: CSharpStructureHelpers.Ellipsis,
......
......@@ -38,6 +38,7 @@ private static string GetBannerText(DirectiveTriviaSyntax simpleDirective)
spans.Add(new BlockSpan(
isCollapsible: true,
textSpan: TextSpan.FromBounds(regionDirective.SpanStart, match.Span.End),
type: BlockTypes.PreprocessorRegion,
bannerText: GetBannerText(regionDirective),
autoCollapse: true));
}
......
......@@ -42,7 +42,7 @@ internal class NamespaceDeclarationStructureProvider : AbstractSyntaxNodeStructu
spans.Add(CSharpStructureHelpers.CreateBlockSpan(
externsAndUsings, autoCollapse: true,
type: BlockTypes.Nonstructural, isCollapsible: true));
type: BlockTypes.Imports, isCollapsible: true));
// finally, add any leading comments before the end of the namespace block
if (!namespaceDeclaration.CloseBraceToken.IsMissing)
......
......@@ -38,6 +38,7 @@ private static string GetBannerText(DirectiveTriviaSyntax simpleDirective)
spans.Add(new BlockSpan(
isCollapsible: true,
textSpan: TextSpan.FromBounds(regionDirective.SpanStart, match.Span.End),
type: BlockTypes.PreprocessorRegion,
bannerText: GetBannerText(regionDirective),
autoCollapse: true,
isDefaultCollapsed: true));
......
......@@ -109,6 +109,7 @@
<Compile Include="Navigation\NavigableItemFactory.DeclaredSymbolNavigableItem.cs" />
<Compile Include="Navigation\NavigableItemFactory.SymbolLocationNavigableItem.cs" />
<Compile Include="Remote\RemoteArguments.cs" />
<Compile Include="Structure\BlockStructureOptions.cs" />
<Compile Include="UseThrowExpression\AbstractUseThrowExpressionDiagnosticAnalyzer.cs" />
<Compile Include="UseThrowExpression\UseThrowExpressionCodeFixProvider.cs" />
<Compile Include="UseThrowExpression\UseThrowExpressionCodeFixProvider.FixAllProvider.cs" />
......
......@@ -52,9 +52,9 @@ internal class BlockSpan
TextSpan = textSpan;
BannerText = bannerText;
HintSpan = hintSpan;
IsCollapsible = isCollapsible;
AutoCollapse = autoCollapse;
IsDefaultCollapsed = isDefaultCollapsed;
IsCollapsible = isCollapsible;
Type = type ?? BlockTypes.Nonstructural;
}
......@@ -64,5 +64,32 @@ public override string ToString()
? $"{{Span={TextSpan}, HintSpan={HintSpan}, BannerText=\"{BannerText}\", AutoCollapse={AutoCollapse}, IsDefaultCollapsed={IsDefaultCollapsed}}}"
: $"{{Span={TextSpan}, BannerText=\"{BannerText}\", AutoCollapse={AutoCollapse}, IsDefaultCollapsed={IsDefaultCollapsed}}}";
}
internal BlockSpan WithType(string type)
=> With(type: type);
internal BlockSpan WithIsCollapsible(bool isCollapsible)
=> With(isCollapsible: isCollapsible);
internal BlockSpan With(
Optional<bool> isCollapsible = default(Optional<bool>),
Optional<TextSpan> textSpan = default(Optional<TextSpan>),
Optional<TextSpan> hintSpan = default(Optional<TextSpan>),
Optional<string> type = default(Optional<string>),
Optional<string> bannerText = default(Optional<string>),
Optional<bool> autoCollapse = default(Optional<bool>),
Optional<bool> isDefaultCollapsed = default(Optional<bool>))
{
var newIsCollapsible = isCollapsible.HasValue ? isCollapsible.Value : IsCollapsible;
var newTextSpan = textSpan.HasValue ? textSpan.Value : TextSpan;
var newHintSpan = hintSpan.HasValue ? hintSpan.Value : HintSpan;
var newType = type.HasValue ? type.Value : Type;
var newBannerText = bannerText.HasValue ? bannerText.Value : BannerText;
var newAutoCollapse = autoCollapse.HasValue ? autoCollapse.Value : AutoCollapse;
var newIsDefaultCollapsed = isDefaultCollapsed.HasValue ? isDefaultCollapsed.Value : IsDefaultCollapsed;
return new BlockSpan(
newIsCollapsible, newTextSpan, newHintSpan, newType, newBannerText, newAutoCollapse, newIsDefaultCollapsed);
}
}
}
\ No newline at end of file
// 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 Microsoft.CodeAnalysis.Options;
namespace Microsoft.CodeAnalysis.Structure
{
internal static class BlockStructureOptions
{
public static readonly PerLanguageOption<bool> ShowBlockStructureGuidesForCommentsAndPreprocessorRegions = new PerLanguageOption<bool>(
nameof(BlockStructureOptions), nameof(ShowBlockStructureGuidesForCommentsAndPreprocessorRegions), defaultValue: false);
public static readonly PerLanguageOption<bool> ShowBlockStructureGuidesForDeclarationLevelConstructs = new PerLanguageOption<bool>(
nameof(BlockStructureOptions), nameof(ShowBlockStructureGuidesForDeclarationLevelConstructs), defaultValue: true);
public static readonly PerLanguageOption<bool> ShowBlockStructureGuidesForCodeLevelConstructs = new PerLanguageOption<bool>(
nameof(BlockStructureOptions), nameof(ShowBlockStructureGuidesForCodeLevelConstructs), defaultValue: true);
public static readonly PerLanguageOption<bool> ShowOutliningForCommentsAndPreprocessorRegions = new PerLanguageOption<bool>(
nameof(BlockStructureOptions), nameof(ShowOutliningForCommentsAndPreprocessorRegions), defaultValue: true);
public static readonly PerLanguageOption<bool> ShowOutliningForDeclarationLevelConstructs = new PerLanguageOption<bool>(
nameof(BlockStructureOptions), nameof(ShowOutliningForDeclarationLevelConstructs), defaultValue: true);
public static readonly PerLanguageOption<bool> ShowOutliningForCodeLevelConstructs = new PerLanguageOption<bool>(
nameof(BlockStructureOptions), nameof(ShowOutliningForCodeLevelConstructs), defaultValue: true);
}
}
\ No newline at end of file
......@@ -5,10 +5,18 @@ namespace Microsoft.CodeAnalysis.Structure
internal static class BlockTypes
{
// Basic types.
public const string Structural = nameof(Structural);
//public const string Structural = nameof(Structural);
//public const string Nonstructural = nameof(Nonstructural);
public const string Nonstructural = nameof(Nonstructural);
// Trivia
public const string Comment = nameof(Comment);
// public const string Region = nameof(Region);
public const string PreprocessorRegion = nameof(PreprocessorRegion);
// Top level declarations.
public const string Imports = nameof(Imports);
public const string Namespace = nameof(Namespace);
public const string Class = nameof(Class);
public const string Enum = nameof(Enum);
......@@ -41,6 +49,6 @@ internal static class BlockTypes
public const string AnonymousMethod = nameof(AnonymousMethod);
public const string Xml = nameof(Xml);
public const string Other = nameof(Other);
// public const string Other = nameof(Other);
}
}
\ No newline at end of file
......@@ -5,6 +5,7 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Options;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Structure
......@@ -33,8 +34,29 @@ public override void ProvideBlockStructure(BlockStructureContext context)
{
try
{
var syntaxRoot = context.Document.GetSyntaxRootSynchronously(context.CancellationToken);
ProvideBlockStructureWorker(context, syntaxRoot);
var cancellationToken = context.CancellationToken;
var syntaxRoot = context.Document.GetSyntaxRootSynchronously(cancellationToken);
var options = context.Document.GetOptionsAsync(cancellationToken).WaitAndGetResult(cancellationToken);
ProvideBlockStructureWorker(context, syntaxRoot, options);
}
catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
{
throw ExceptionUtilities.Unreachable;
}
}
/// <summary>
/// Keep in sync with <see cref="ProvideBlockStructure"/>
/// </summary>
public override async Task ProvideBlockStructureAsync(BlockStructureContext context)
{
try
{
var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
var options = await context.Document.GetOptionsAsync(context.CancellationToken).ConfigureAwait(false);
ProvideBlockStructureWorker(context, syntaxRoot, options);
}
catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
{
......@@ -43,34 +65,110 @@ public override void ProvideBlockStructure(BlockStructureContext context)
}
private void ProvideBlockStructureWorker(
BlockStructureContext context, SyntaxNode syntaxRoot)
BlockStructureContext context, SyntaxNode syntaxRoot, DocumentOptionSet options)
{
var spans = ArrayBuilder<BlockSpan>.GetInstance();
BlockSpanCollector.CollectBlockSpans(
context.Document, syntaxRoot, _nodeProviderMap, _triviaProviderMap, spans, context.CancellationToken);
foreach (var region in spans)
var showIndentGuidesForCodeLevelConstructs = options.GetOption(BlockStructureOptions.ShowBlockStructureGuidesForCodeLevelConstructs);
var showIndentGuidesForDeclarationLevelConstructs = options.GetOption(BlockStructureOptions.ShowBlockStructureGuidesForDeclarationLevelConstructs);
var showIndentGuidesForCommentsAndPreprocessorRegions = options.GetOption(BlockStructureOptions.ShowBlockStructureGuidesForCommentsAndPreprocessorRegions);
var showOutliningForCodeLevelConstructs = options.GetOption(BlockStructureOptions.ShowOutliningForCodeLevelConstructs);
var showOutliningForDeclarationLevelConstructs = options.GetOption(BlockStructureOptions.ShowOutliningForDeclarationLevelConstructs);
var showOutliningForCommentsAndPreprocessorRegions = options.GetOption(BlockStructureOptions.ShowOutliningForCommentsAndPreprocessorRegions);
foreach (var span in spans)
{
context.AddBlockSpan(region);
var updatedSpan = UpdateBlockSpan(span,
showIndentGuidesForCodeLevelConstructs,
showIndentGuidesForDeclarationLevelConstructs,
showIndentGuidesForCommentsAndPreprocessorRegions,
showOutliningForCodeLevelConstructs,
showOutliningForDeclarationLevelConstructs,
showOutliningForCommentsAndPreprocessorRegions);
context.AddBlockSpan(updatedSpan);
}
spans.Free();
}
/// <summary>
/// Keep in sync with <see cref="ProvideBlockStructure"/>
/// </summary>
public override async Task ProvideBlockStructureAsync(BlockStructureContext context)
private BlockSpan UpdateBlockSpan(BlockSpan blockSpan,
bool showIndentGuidesForCodeLevelConstructs,
bool showIndentGuidesForDeclarationLevelConstructs,
bool showIndentGuidesForCommentsAndPreprocessorRegions,
bool showOutliningForCodeLevelConstructs,
bool showOutliningForDeclarationLevelConstructs,
bool showOutliningForCommentsAndPreprocessorRegions)
{
try
var type = blockSpan.Type;
var isTopLevel = IsDeclarationLevelConstruct(type);
var isMemberLevel = IsCodeLevelConstruct(type);
var isComment = IsCommentOrPreprocessorRegion(type);
if (!showIndentGuidesForDeclarationLevelConstructs && isTopLevel)
{
var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
ProvideBlockStructureWorker(context, syntaxRoot);
type = BlockTypes.Nonstructural;
}
catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
else if (!showIndentGuidesForCodeLevelConstructs && isMemberLevel)
{
throw ExceptionUtilities.Unreachable;
type = BlockTypes.Nonstructural;
}
else if (!showIndentGuidesForCommentsAndPreprocessorRegions && isComment)
{
type = BlockTypes.Nonstructural;
}
var isCollapsible = blockSpan.IsCollapsible;
if (isCollapsible)
{
if (!showOutliningForDeclarationLevelConstructs && isTopLevel)
{
isCollapsible = false;
}
else if (!showOutliningForCodeLevelConstructs && isMemberLevel)
{
isCollapsible = false;
}
else if (!showOutliningForCommentsAndPreprocessorRegions && isComment)
{
isCollapsible = false;
}
}
return blockSpan.With(type: type, isCollapsible: isCollapsible);
}
private static bool IsCommentOrPreprocessorRegion(string type)
{
return type == BlockTypes.Comment || type == BlockTypes.PreprocessorRegion;
}
protected bool IsCodeLevelConstruct(string type)
{
switch (type)
{
case BlockTypes.Case:
case BlockTypes.Conditional:
case BlockTypes.LocalFunction:
case BlockTypes.Lock:
case BlockTypes.Loop:
case BlockTypes.TryCatchFinally:
case BlockTypes.Using:
case BlockTypes.Standalone:
case BlockTypes.Switch:
case BlockTypes.AnonymousMethod:
case BlockTypes.Xml:
return true;
}
return false;
}
protected bool IsDeclarationLevelConstruct(string type)
{
return !IsCodeLevelConstruct(type) && !IsCommentOrPreprocessorRegion(type);
}
}
}
\ No newline at end of file
......@@ -30,6 +30,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Structure.MetadataAsSource
spans.Add(New BlockSpan(
isCollapsible:=True,
type:=BlockTypes.Comment,
textSpan:=TextSpan.FromBounds(startPosition, endPosition),
hintSpan:=TextSpan.FromBounds(startPosition, hintTextEndToken.Span.End),
bannerText:=Ellipsis,
......
......@@ -663,15 +663,6 @@ internal class CSharpVSResources {
}
}
/// <summary>
/// Looks up a localized string similar to Outlining.
/// </summary>
internal static string Outlining {
get {
return ResourceManager.GetString("Outlining", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Performance.
/// </summary>
......
......@@ -363,9 +363,6 @@
<data name="Using_Directives" xml:space="preserve">
<value>Using Directives</value>
</data>
<data name="Outlining" xml:space="preserve">
<value>Outlining</value>
</data>
<data name="Performance" xml:space="preserve">
<value>Performance</value>
</data>
......
......@@ -41,6 +41,21 @@
Content="{x:Static local:AdvancedOptionPageStrings.Option_EnterOutliningMode}" />
<CheckBox x:Name="DisplayLineSeparators"
Content="{x:Static local:AdvancedOptionPageStrings.Option_DisplayLineSeparators}" />
<CheckBox x:Name="Show_outlining_for_declaration_level_constructs"
Content="{x:Static local:AdvancedOptionPageStrings.Option_Show_outlining_for_declaration_level_constructs}" />
<CheckBox x:Name="Show_outlining_for_code_level_constructs"
Content="{x:Static local:AdvancedOptionPageStrings.Option_Show_outlining_for_code_level_constructs}" />
<CheckBox x:Name="Show_outlining_for_comments_and_preprocessor_regions"
Content="{x:Static local:AdvancedOptionPageStrings.Option_Show_outlining_for_comments_and_preprocessor_regions}" />
</StackPanel>
</GroupBox>
<GroupBox x:Uid="BlockStructureGuidesGroupBox"
Header="{x:Static local:AdvancedOptionPageStrings.Option_Block_Structure_Guides}">
<StackPanel>
<CheckBox x:Name="Show_guides_for_declaration_level_constructs"
Content="{x:Static local:AdvancedOptionPageStrings.Option_Show_guides_for_declaration_level_constructs}" />
<CheckBox x:Name="Show_guides_for_code_level_constructs"
Content="{x:Static local:AdvancedOptionPageStrings.Option_Show_guides_for_code_level_constructs}" />
</StackPanel>
</GroupBox>
<GroupBox x:Uid="EditorHelpGroupBox"
......
......@@ -7,6 +7,7 @@
using Microsoft.CodeAnalysis.Editor.Shared.Options;
using Microsoft.CodeAnalysis.ExtractMethod;
using Microsoft.CodeAnalysis.Shared.Options;
using Microsoft.CodeAnalysis.Structure;
using Microsoft.CodeAnalysis.SymbolSearch;
using Microsoft.VisualStudio.LanguageServices.Implementation;
using Microsoft.VisualStudio.LanguageServices.Implementation.Options;
......@@ -25,6 +26,13 @@ public AdvancedOptionPageControl(IServiceProvider serviceProvider) : base(servic
BindToOption(Split_string_literals_on_enter, SplitStringLiteralOptions.Enabled, LanguageNames.CSharp);
BindToOption(EnterOutliningMode, FeatureOnOffOptions.Outlining, LanguageNames.CSharp);
BindToOption(Show_outlining_for_declaration_level_constructs, BlockStructureOptions.ShowOutliningForDeclarationLevelConstructs, LanguageNames.CSharp);
BindToOption(Show_outlining_for_code_level_constructs, BlockStructureOptions.ShowOutliningForCodeLevelConstructs, LanguageNames.CSharp);
BindToOption(Show_outlining_for_comments_and_preprocessor_regions, BlockStructureOptions.ShowOutliningForCommentsAndPreprocessorRegions, LanguageNames.CSharp);
BindToOption(Show_guides_for_declaration_level_constructs, BlockStructureOptions.ShowBlockStructureGuidesForDeclarationLevelConstructs, LanguageNames.CSharp);
BindToOption(Show_guides_for_code_level_constructs, BlockStructureOptions.ShowBlockStructureGuidesForCodeLevelConstructs, LanguageNames.CSharp);
BindToOption(GenerateXmlDocCommentsForTripleSlash, FeatureOnOffOptions.AutoXmlDocCommentGeneration, LanguageNames.CSharp);
BindToOption(InsertAsteriskAtTheStartOfNewLinesWhenWritingBlockComments, FeatureOnOffOptions.AutoInsertBlockCommentStartString, LanguageNames.CSharp);
BindToOption(DisplayLineSeparators, FeatureOnOffOptions.LineSeparator, LanguageNames.CSharp);
......
......@@ -88,9 +88,25 @@ public static string Option_OptimizeForSolutionSize_Small
}
public static string Option_Outlining
{
get { return CSharpVSResources.Outlining; }
}
=> ServicesVSResources.Outlining;
public static string Option_Show_outlining_for_declaration_level_constructs
=> ServicesVSResources.Show_outlining_for_declaration_level_constructs;
public static string Option_Show_outlining_for_code_level_constructs
=> ServicesVSResources.Show_outlining_for_code_level_constructs;
public static string Option_Show_outlining_for_comments_and_preprocessor_regions
=> ServicesVSResources.Show_outlining_for_comments_and_preprocessor_regions;
public static string Option_Block_Structure_Guides
=> ServicesVSResources.Block_Structure_Guides;
public static string Option_Show_guides_for_declaration_level_constructs
=> ServicesVSResources.Show_guides_for_declaration_level_constructs;
public static string Option_Show_guides_for_code_level_constructs
=> ServicesVSResources.Show_guides_for_code_level_constructs;
public static string Option_Performance
{
......
......@@ -253,6 +253,15 @@ internal class ServicesVSResources {
}
}
/// <summary>
/// Looks up a localized string similar to Block Structure Guides.
/// </summary>
internal static string Block_Structure_Guides {
get {
return ResourceManager.GetString("Block_Structure_Guides", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to [-] .
/// </summary>
......@@ -1185,6 +1194,15 @@ internal class ServicesVSResources {
}
}
/// <summary>
/// Looks up a localized string similar to Outlining.
/// </summary>
internal static string Outlining {
get {
return ResourceManager.GetString("Outlining", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Overridden By.
/// </summary>
......@@ -1551,6 +1569,60 @@ internal class ServicesVSResources {
}
}
/// <summary>
/// Looks up a localized string similar to Show guides for code level constructs.
/// </summary>
internal static string Show_guides_for_code_level_constructs {
get {
return ResourceManager.GetString("Show_guides_for_code_level_constructs", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show guides for comments and preprocessor regions.
/// </summary>
internal static string Show_guides_for_comments_and_preprocessor_regions {
get {
return ResourceManager.GetString("Show_guides_for_comments_and_preprocessor_regions", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show guides for declaration level constructs.
/// </summary>
internal static string Show_guides_for_declaration_level_constructs {
get {
return ResourceManager.GetString("Show_guides_for_declaration_level_constructs", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show outlining for code level constructs.
/// </summary>
internal static string Show_outlining_for_code_level_constructs {
get {
return ResourceManager.GetString("Show_outlining_for_code_level_constructs", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show outlining for comments and preprocessor regions.
/// </summary>
internal static string Show_outlining_for_comments_and_preprocessor_regions {
get {
return ResourceManager.GetString("Show_outlining_for_comments_and_preprocessor_regions", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show outlining for declaration level constructs.
/// </summary>
internal static string Show_outlining_for_declaration_level_constructs {
get {
return ResourceManager.GetString("Show_outlining_for_declaration_level_constructs", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Summary:.
/// </summary>
......
......@@ -732,4 +732,28 @@ Additional information: {1}</value>
<data name="Expression_preferences_colon" xml:space="preserve">
<value>Expression preferences:</value>
</data>
<data name="Block_Structure_Guides" xml:space="preserve">
<value>Block Structure Guides</value>
</data>
<data name="Outlining" xml:space="preserve">
<value>Outlining</value>
</data>
<data name="Show_guides_for_code_level_constructs" xml:space="preserve">
<value>Show guides for code level constructs</value>
</data>
<data name="Show_guides_for_comments_and_preprocessor_regions" xml:space="preserve">
<value>Show guides for comments and preprocessor regions</value>
</data>
<data name="Show_guides_for_declaration_level_constructs" xml:space="preserve">
<value>Show guides for declaration level constructs</value>
</data>
<data name="Show_outlining_for_code_level_constructs" xml:space="preserve">
<value>Show outlining for code level constructs</value>
</data>
<data name="Show_outlining_for_comments_and_preprocessor_regions" xml:space="preserve">
<value>Show outlining for comments and preprocessor regions</value>
</data>
<data name="Show_outlining_for_declaration_level_constructs" xml:space="preserve">
<value>Show outlining for declaration level constructs</value>
</data>
</root>
\ No newline at end of file
......@@ -343,15 +343,6 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Outlining.
'''</summary>
Friend Shared ReadOnly Property Outlining() As String
Get
Return ResourceManager.GetString("Outlining", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Performance.
'''</summary>
......@@ -369,7 +360,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic
Return ResourceManager.GetString("Place_System_directives_first_when_sorting_imports", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Predefined type preferences:.
'''</summary>
......
......@@ -180,9 +180,6 @@
<data name="Small" xml:space="preserve">
<value>Small</value>
</data>
<data name="Outlining" xml:space="preserve">
<value>Outlining</value>
</data>
<data name="Performance" xml:space="preserve">
<value>Performance</value>
</data>
......
......@@ -42,6 +42,21 @@
Content="{x:Static local:AdvancedOptionPageStrings.Option_EnableOutlining}" />
<CheckBox x:Name="DisplayLineSeparators"
Content="{x:Static local:AdvancedOptionPageStrings.Option_DisplayLineSeparators}" />
<CheckBox x:Name="Show_outlining_for_declaration_level_constructs"
Content="{x:Static local:AdvancedOptionPageStrings.Option_Show_outlining_for_declaration_level_constructs}" />
<CheckBox x:Name="Show_outlining_for_code_level_constructs"
Content="{x:Static local:AdvancedOptionPageStrings.Option_Show_outlining_for_code_level_constructs}" />
<CheckBox x:Name="Show_outlining_for_comments_and_preprocessor_regions"
Content="{x:Static local:AdvancedOptionPageStrings.Option_Show_outlining_for_comments_and_preprocessor_regions}" />
</StackPanel>
</GroupBox>
<GroupBox x:Uid="BlockStructureGuidesGroupBox"
Header="{x:Static local:AdvancedOptionPageStrings.Option_Block_Structure_Guides}">
<StackPanel>
<CheckBox x:Name="Show_guides_for_declaration_level_constructs"
Content="{x:Static local:AdvancedOptionPageStrings.Option_Show_guides_for_declaration_level_constructs}" />
<CheckBox x:Name="Show_guides_for_code_level_constructs"
Content="{x:Static local:AdvancedOptionPageStrings.Option_Show_guides_for_code_level_constructs}" />
</StackPanel>
</GroupBox>
<GroupBox x:Uid="EditorHelpGroupBox"
......
......@@ -5,6 +5,7 @@ Imports Microsoft.CodeAnalysis.Editing
Imports Microsoft.CodeAnalysis.Editor.Shared.Options
Imports Microsoft.CodeAnalysis.ExtractMethod
Imports Microsoft.CodeAnalysis.Shared.Options
Imports Microsoft.CodeAnalysis.Structure
Imports Microsoft.CodeAnalysis.SymbolSearch
Imports Microsoft.VisualStudio.LanguageServices.Implementation
......@@ -19,8 +20,15 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options
BindToOption(SuggestForTypesInReferenceAssemblies, SymbolSearchOptions.SuggestForTypesInReferenceAssemblies, LanguageNames.VisualBasic)
BindToOption(SuggestForTypesInNuGetPackages, SymbolSearchOptions.SuggestForTypesInNuGetPackages, LanguageNames.VisualBasic)
BindToOption(EnableEndConstruct, FeatureOnOffOptions.EndConstruct, LanguageNames.VisualBasic)
BindToOption(EnableOutlining, FeatureOnOffOptions.Outlining, LanguageNames.VisualBasic)
BindToOption(Show_outlining_for_declaration_level_constructs, BlockStructureOptions.ShowOutliningForDeclarationLevelConstructs, LanguageNames.VisualBasic)
BindToOption(Show_outlining_for_code_level_constructs, BlockStructureOptions.ShowOutliningForCodeLevelConstructs, LanguageNames.VisualBasic)
BindToOption(Show_outlining_for_comments_and_preprocessor_regions, BlockStructureOptions.ShowOutliningForCommentsAndPreprocessorRegions, LanguageNames.VisualBasic)
BindToOption(Show_guides_for_declaration_level_constructs, BlockStructureOptions.ShowBlockStructureGuidesForDeclarationLevelConstructs, LanguageNames.VisualBasic)
BindToOption(Show_guides_for_code_level_constructs, BlockStructureOptions.ShowBlockStructureGuidesForCodeLevelConstructs, LanguageNames.VisualBasic)
BindToOption(EnableEndConstruct, FeatureOnOffOptions.EndConstruct, LanguageNames.VisualBasic)
BindToOption(EnableLineCommit, FeatureOnOffOptions.PrettyListing, LanguageNames.VisualBasic)
BindToOption(AutomaticInsertionOfInterfaceAndMustOverrideMembers, FeatureOnOffOptions.AutomaticInsertionOfAbstractOrInterfaceMembers, LanguageNames.VisualBasic)
BindToOption(DisplayLineSeparators, FeatureOnOffOptions.LineSeparator, LanguageNames.VisualBasic)
......
......@@ -123,11 +123,25 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options
End Get
End Property
Public ReadOnly Property Option_Outlining As String
Get
Return BasicVSResources.Outlining
End Get
End Property
Public ReadOnly Property Option_Outlining As String = ServicesVSResources.Outlining
Public ReadOnly Property Option_Show_outlining_for_declaration_level_constructs As String =
ServicesVSResources.Show_outlining_for_declaration_level_constructs
Public ReadOnly Property Option_Show_outlining_for_code_level_constructs As String =
ServicesVSResources.Show_outlining_for_code_level_constructs
Public ReadOnly Property Option_Show_outlining_for_comments_and_preprocessor_regions As String =
ServicesVSResources.Show_outlining_for_comments_and_preprocessor_regions
Public ReadOnly Property Option_Block_Structure_Guides As String =
ServicesVSResources.Block_Structure_Guides
Public ReadOnly Property Option_Show_guides_for_declaration_level_constructs As String =
ServicesVSResources.Show_guides_for_declaration_level_constructs
Public ReadOnly Property Option_Show_guides_for_code_level_constructs As String =
ServicesVSResources.Show_guides_for_code_level_constructs
Public ReadOnly Property Option_Performance As String
Get
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册