Skip to content

Commit

Permalink
+ Added Smart Bar for interactive windows
Browse files Browse the repository at this point in the history
  • Loading branch information
wmjordan committed Dec 12, 2018
1 parent 14bf718 commit 92e3502
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 16 deletions.
1 change: 1 addition & 0 deletions Codist/Codist.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@
<Compile Include="Helpers\SymbolFormatter.cs" />
<Compile Include="Helpers\XmlDocRenderer.cs" />
<Compile Include="SmartBars\CSharpSmartBar.cs" />
<Compile Include="SmartBars\OutputSmartBar.cs" />
<Compile Include="SmartBars\MarkdownSmartBar.cs" />
<Compile Include="SmartBars\SmartBar.CommonEdit.cs" />
<Compile Include="SmartBars\SmartBar.cs" />
Expand Down
20 changes: 18 additions & 2 deletions Codist/Helpers/TextEditorHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,17 @@ public static void ExpandSelectionToLine(this IWpfTextView view, bool includeLin
}
view.Selection.Select(new SnapshotSpan(start, end), false);
}
public static bool TryGetFirstSelectionSpan(this ITextView view, out SnapshotSpan span) {
if (view.Selection.IsEmpty || view.Selection.SelectedSpans.Count < 1) {
span = new SnapshotSpan();
return false;
}
else {
span = view.Selection.SelectedSpans[0];
return true;
}
}

public static TokenType GetSelectedTokenType(this ITextView view) {
if (view.Selection.IsEmpty || view.Selection.SelectedSpans.Count > 1) {
return TokenType.None;
Expand Down Expand Up @@ -163,11 +174,16 @@ public static void SelectNode(this IWpfTextView view, Microsoft.CodeAnalysis.Syn
else {
ss = new SnapshotSpan(view.TextSnapshot, span.Start, span.Length);
}
view.Selection.Select(ss, false);
view.ViewScroller.EnsureSpanVisible(ss, EnsureSpanVisibleOptions.ShowStart);
view.SelectSpan(ss);
}
}

public static void SelectSpan(this IWpfTextView view, SnapshotSpan span) {
view.ViewScroller.EnsureSpanVisible(span, EnsureSpanVisibleOptions.ShowStart);
view.Selection.Select(span, false);
view.Caret.MoveTo(span.End);
}

public static void TryExecuteCommand(this EnvDTE.DTE dte, string command, string args = "") {
ThreadHelper.ThrowIfNotOnUIThread();
try {
Expand Down
2 changes: 1 addition & 1 deletion Codist/SmartBars/CSharpSmartBar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ sealed class CSharpSmartBar : SmartBar {
readonly SemanticContext _Context;
ISymbol _Symbol;

public CSharpSmartBar(IWpfTextView view) : base(view) {
public CSharpSmartBar(IWpfTextView view, Microsoft.VisualStudio.Text.Operations.ITextSearchService2 textSearchService) : base(view, textSearchService) {
_Context = view.Properties.GetOrCreateSingletonProperty(() => new SemanticContext(view));
}

Expand Down
2 changes: 1 addition & 1 deletion Codist/SmartBars/MarkDownSmartBar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Codist.SmartBars
{
sealed class MarkdownSmartBar : SmartBar
{
public MarkdownSmartBar(IWpfTextView textView) : base(textView) {
public MarkdownSmartBar(IWpfTextView textView, Microsoft.VisualStudio.Text.Operations.ITextSearchService2 textSearchService) : base(textView, textSearchService) {
}

ToolBar MyToolBar => ToolBar2;
Expand Down
42 changes: 42 additions & 0 deletions Codist/SmartBars/OutputSmartBar.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
using Microsoft.VisualStudio.Imaging;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using System.IO;

namespace Codist.SmartBars
{
sealed class OutputSmartBar : SmartBar
{
public OutputSmartBar(IWpfTextView textView, Microsoft.VisualStudio.Text.Operations.ITextSearchService2 textSearchService) : base(textView, textSearchService) {
}

ToolBar MyToolBar => ToolBar;

protected override void AddCommands(CancellationToken cancellationToken) {
base.AddCommands(cancellationToken);
try {
if (View.TryGetFirstSelectionSpan(out var span) && span.Length < 255) {
var t = View.TextSnapshot.GetText(span);
if (Path.IsPathRooted(t) && (File.Exists(t) || Directory.Exists(t))) {
AddCommand(MyToolBar, KnownImageIds.OpenFolder, "Open file in Windows Explorer", ctx => {
if (ctx.View.TryGetFirstSelectionSpan(out var s) && s.Length < 255) {
var p = View.TextSnapshot.GetText(s);
System.Diagnostics.Process.Start("Explorer.exe", "/select,\"" + t + "\"");
}
});
}
}
}
catch (ArgumentException) {
// ignore
}
}
}
}
19 changes: 13 additions & 6 deletions Codist/SmartBars/SmartBar.CommonEdit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Operations;

namespace Codist.SmartBars
{
Expand Down Expand Up @@ -35,9 +36,12 @@ static void ExecuteAndFind(CommandContext ctx, string command) {
protected static void FindNext(CommandContext ctx, string t) {
ThreadHelper.ThrowIfNotOnUIThread();
if (t != null) {
var p = (CodistPackage.DTE.ActiveDocument.Object() as EnvDTE.TextDocument).Selection;
if (p != null && p.FindText(t, (int)EnvDTE.vsFindOptions.vsFindOptionsMatchCase)) {
ctx.KeepToolBar(true);
var r = ctx.TextSearchService.Find(ctx.View.Selection.StreamSelectionSpan.End.Position, t, FindOptions.MatchCase);
if (r.HasValue) {
ctx.View.SelectSpan(r.Value);
}
else {
ctx.HideToolBar();
}
}
}
Expand Down Expand Up @@ -169,11 +173,14 @@ void AddFindAndReplaceCommands() {
return;
}
ctx.KeepToolBar(false);
var p = (CodistPackage.DTE.ActiveDocument.Object() as EnvDTE.TextDocument).Selection;
var option = Keyboard.Modifiers.MatchFlags(ModifierKeys.Control) ? EnvDTE.vsFindOptions.vsFindOptionsMatchCase : 0;
if (p != null && p.FindText(t, (int)option)) {
var r = ctx.TextSearchService.Find(ctx.View.Selection.StreamSelectionSpan.End.Position, t, Keyboard.Modifiers.MatchFlags(ModifierKeys.Control) ? FindOptions.MatchCase : FindOptions.None);
if (r.HasValue) {
ctx.View.SelectSpan(r.Value);
ctx.KeepToolBar(true);
}
else {
ctx.HideToolBar();
}
}, ctx => __FindAndReplaceCommands);
}

Expand Down
12 changes: 9 additions & 3 deletions Codist/SmartBars/SmartBar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Text.Editor;
using Task = System.Threading.Tasks.Task;
using Microsoft.VisualStudio.Text.Operations;

namespace Codist.SmartBars
{
Expand All @@ -31,8 +32,9 @@ internal partial class SmartBar {
/// Initializes a new instance of the <see cref="SmartBar"/> class.
/// </summary>
/// <param name="view">The <see cref="IWpfTextView"/> upon which the adornment will be drawn</param>
public SmartBar(IWpfTextView view) {
public SmartBar(IWpfTextView view, ITextSearchService2 textSearchService) {
View = view ?? throw new ArgumentNullException(nameof(view));
TextSearchService = textSearchService;
_ToolBarLayer = view.GetAdornmentLayer(nameof(SmartBar));
Config.Updated += ConfigUpdated;
if (Config.Instance.SmartBarOptions.MatchFlags(SmartBarOptions.ShiftToggleDisplay)) {
Expand Down Expand Up @@ -72,6 +74,7 @@ public SmartBar(IWpfTextView view) {
protected ToolBar ToolBar { get; }
protected ToolBar ToolBar2 { get; }
protected IWpfTextView View { get; }
protected ITextSearchService2 TextSearchService { get; }
protected CancellationToken CancellationToken {
get {
var c = _Cancellation;
Expand Down Expand Up @@ -433,7 +436,6 @@ protected sealed class CommandContext
readonly SmartBar _Bar;

public CommandContext(SmartBar bar, Control control, RoutedEventArgs eventArgs) {
View = bar.View;
_Bar = bar;
Sender = control;
EventArgs = eventArgs;
Expand All @@ -445,8 +447,12 @@ public CommandContext(SmartBar bar, Control control, RoutedEventArgs eventArgs,
public bool KeepToolBarOnClick { get; set; }
public bool RightClick { get; }
public Control Sender { get; }
public IWpfTextView View { get; }
public IWpfTextView View => _Bar.View;
public ITextSearchService2 TextSearchService => _Bar.TextSearchService;
public CancellationToken CancellationToken => _Bar._Cancellation.GetToken();
public void HideToolBar() {
_Bar.HideToolBar();
}
public void KeepToolBar(bool refresh) {
_Bar.KeepToolbar();
KeepToolBarOnClick = true;
Expand Down
14 changes: 11 additions & 3 deletions Codist/SmartBars/SmartBarTextViewCreationListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Utilities;
using AppHelpers;
using Microsoft.VisualStudio.Text.Operations;

namespace Codist.SmartBars
{
Expand All @@ -13,6 +14,7 @@ namespace Codist.SmartBars
[Export(typeof(IWpfTextViewCreationListener))]
[ContentType(Constants.CodeTypes.Text)]
[TextViewRole(PredefinedTextViewRoles.Document)]
[TextViewRole(PredefinedTextViewRoles.Interactive)]
internal sealed class SmartBarTextViewCreationListener : IWpfTextViewCreationListener
{
// Disable "Field is never assigned to..." and "Field is never used" compiler's warnings. Justification: the field is used by MEF.
Expand All @@ -27,6 +29,9 @@ internal sealed class SmartBarTextViewCreationListener : IWpfTextViewCreationLis
[Order(After = PredefinedAdornmentLayers.Caret)]
AdornmentLayerDefinition _EditorAdornmentLayer;

[Import(typeof(ITextSearchService2))]
ITextSearchService2 _TextSearchService;

#pragma warning restore 649, 169

/// <summary>
Expand All @@ -42,14 +47,17 @@ public void TextViewCreated(IWpfTextView textView) {
var contentType = textView.TextBuffer.ContentType;
if (String.Equals(Constants.CodeTypes.CSharp, contentType.TypeName, StringComparison.OrdinalIgnoreCase)) {
textView.Properties.GetOrCreateSingletonProperty(() => new SemanticContext(textView));
new CSharpSmartBar(textView);
new CSharpSmartBar(textView, _TextSearchService);
}
else if (contentType.IsOfType("code++.Markdown")
|| contentType.TypeName.IndexOf("Markdown", StringComparison.OrdinalIgnoreCase) != -1) {
new MarkdownSmartBar(textView);
new MarkdownSmartBar(textView, _TextSearchService);
}
else if (contentType.IsOfType("output")) {
new OutputSmartBar(textView, _TextSearchService);
}
else {
new SmartBar(textView);
new SmartBar(textView, _TextSearchService);
}
}

Expand Down

0 comments on commit 92e3502

Please sign in to comment.