Skip to content

Commit

Permalink
+ Option to show #region name on Navigation Bar
Browse files Browse the repository at this point in the history
+ Added command for regional directives on Smart Bar
  • Loading branch information
wmjordan committed Dec 29, 2018
1 parent f2aed1b commit 293b968
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 115 deletions.
2 changes: 2 additions & 0 deletions Codist/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,8 @@ public enum NaviBarOptions
SyntaxDetail = 1,
SymbolToolTip = 1 << 1,
RangeHighlight = 1 << 2,
RegionOnBar = 1 << 3,
StripRegionNonLetter = 1 << 4,
ParameterList = 1 << 10,
ParameterListShowParamName = 1 << 11,
FieldValue = 1 << 12,
Expand Down
14 changes: 14 additions & 0 deletions Codist/Helpers/CodeAnalysisHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,20 @@ public static bool IsSyntaxBlock(this SyntaxNode node) {
}
return false;
}

public static bool IsRegionalDirective(this SyntaxNode node) {
switch (node.Kind()) {
case SyntaxKind.IfDirectiveTrivia:
case SyntaxKind.ElifDirectiveTrivia:
case SyntaxKind.ElseDirectiveTrivia:
case SyntaxKind.EndIfDirectiveTrivia:
case SyntaxKind.RegionDirectiveTrivia:
case SyntaxKind.EndRegionDirectiveTrivia:
return true;
}
return false;
}

#endregion

#region Node icon
Expand Down
41 changes: 40 additions & 1 deletion Codist/Helpers/SemanticContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,21 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Outlining;

namespace Codist
{
sealed class SemanticContext
{
VersionStamp _Version;
SyntaxNode _Node, _NodeIncludeTrivia;
readonly IOutliningManager _OutliningManager;

public SemanticContext(IWpfTextView textView) {
View = textView;
_OutliningManager = ServicesHelper.Instance.OutliningManager.GetOutliningManager(textView);
}

public IWpfTextView View { get; }
Expand Down Expand Up @@ -285,7 +289,42 @@ public async Task<bool> UpdateAsync(int position, CancellationToken cancellation
return true;
}

private void ResetNodeInfo() {
public List<SyntaxNode> GetContainingNodes(SnapshotPoint start, bool includeSyntaxDetails, bool includeRegions) {
var node = Node;
var nodes = new List<SyntaxNode>(5);
while (node != null) {
if (node.FullSpan.Contains(View.Selection, true)
&& node.IsKind(SyntaxKind.VariableDeclaration) == false
&& (includeSyntaxDetails && node.IsSyntaxBlock() || node.IsDeclaration() || node.IsKind(SyntaxKind.Attribute))) {
nodes.Add(node);
}
node = node.Parent;
}
nodes.Reverse();
if (includeRegions == false) {
return nodes;
}
foreach (var region in GetRegions(start)) {
node = Compilation.FindTrivia(region.Extent.GetStartPoint(View.TextSnapshot)).GetStructure();
if (node == null || node is DirectiveTriviaSyntax == false) {
continue;
}
for (int i = 0; i < nodes.Count; i++) {
if (node.SpanStart < nodes[i].SpanStart) {
nodes.Insert(i, node);
break;
}
}
}
return nodes;
}

public IEnumerable<ICollapsible> GetRegions(int position) {
return _OutliningManager.GetAllRegions(new SnapshotSpan(View.TextSnapshot, position, 0))
.Where(c => c.CollapsedForm as string != "...");
}

void ResetNodeInfo() {
_Node = _NodeIncludeTrivia = null;
Token = default;
}
Expand Down
4 changes: 4 additions & 0 deletions Codist/Helpers/ServicesHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,14 @@ private ServicesHelper() {
[Import]
public IGlyphService Glyph { get; private set; }

[Import]
public Microsoft.VisualStudio.Text.Outlining.IOutliningManagerService OutliningManager { get; private set; }

[Import]
public ITextStructureNavigatorSelectorService TextStructureNavigator { get; private set; }

[Import]
public IViewTagAggregatorFactoryService ViewTagAggregatorFactory { get; private set; }

}
}
41 changes: 25 additions & 16 deletions Codist/NaviBar/CSharpBar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using AppHelpers;
using Codist.Controls;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.VisualStudio.Imaging;
using Microsoft.VisualStudio.PlatformUI;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Text.Editor;
using Task = System.Threading.Tasks.Task;
using AppHelpers;
using Microsoft.VisualStudio.PlatformUI;

namespace Codist.NaviBar
{
Expand Down Expand Up @@ -188,22 +188,11 @@ void ViewClosed(object sender, EventArgs e) {
}

async Task<List<SyntaxNode>> UpdateModelAsync(CancellationToken token) {
if (await _SemanticContext.UpdateAsync(_View.Selection.Start.Position, token) == false) {
var start = _View.Selection.Start.Position;
if (await _SemanticContext.UpdateAsync(start, token) == false) {
return new List<SyntaxNode>();
}
var node = _SemanticContext.Node;
var nodes = new List<SyntaxNode>(5);
var detail = Config.Instance.NaviBarOptions.MatchFlags(NaviBarOptions.SyntaxDetail);
while (node != null) {
if (node.FullSpan.Contains(_View.Selection, true)
&& node.IsKind(SyntaxKind.VariableDeclaration) == false
&& (detail && node.IsSyntaxBlock() || node.IsDeclaration() || node.IsKind(SyntaxKind.Attribute))) {
nodes.Add(node);
}
node = node.Parent;
}
nodes.Reverse();
return nodes;
return _SemanticContext.GetContainingNodes(start, Config.Instance.NaviBarOptions.MatchFlags(NaviBarOptions.SyntaxDetail), Config.Instance.NaviBarOptions.MatchFlags(NaviBarOptions.RegionOnBar));
}

static string GetParameterListSignature(ParameterListSyntax parameters, bool useParamName) {
Expand Down Expand Up @@ -468,6 +457,9 @@ NaviItem SetHeader(SyntaxNode node, bool includeContainer, bool highlight, bool
if (title == null) {
return this;
}
if (node.IsStructuredTrivia && Config.Instance.NaviBarOptions.MatchFlags(NaviBarOptions.StripRegionNonLetter)) {
title = TrimNonLetterOrDigitCharacters(title);
}
if (includeContainer == false && node.IsTypeDeclaration()) {
var p = node.Parent;
while (p.IsTypeDeclaration()) {
Expand Down Expand Up @@ -505,6 +497,23 @@ NaviItem SetHeader(SyntaxNode node, bool includeContainer, bool highlight, bool
return this;
}

static string TrimNonLetterOrDigitCharacters(string title) {
int s = 0, e = title.Length;
for (int i = 0; i < title.Length; i++) {
if (Char.IsLetterOrDigit(title[i])) {
s = i;
break;
}
}
for (int i = title.Length - 1; i >= s; i--) {
if (Char.IsLetterOrDigit(title[i])) {
e = i + 1;
break;
}
}
return s > 0 || e < title.Length ? title.Substring(s, e - s) : title;
}

NaviItem ShowNodeValue() {
if (Config.Instance.NaviBarOptions.MatchFlags(NaviBarOptions.FieldValue)) {
switch (Node.Kind()) {
Expand Down
Loading

0 comments on commit 293b968

Please sign in to comment.