Permalink
Browse files

Refactor code to make AutoLoading of VS package no longer needed. Rel…

…ated to #236
  • Loading branch information...
tomasr committed Jun 3, 2018
2 parents 927f790 + 994c684 commit 975524186044ce5ef07b3755f5114476f55d6255
Showing with 565 additions and 499 deletions.
  1. +52 −54 src/{Viasfora → Viasfora.Core}/Commands/AddOutliningCommand.cs
  2. +33 −0 src/Viasfora.Core/Commands/ClearOutliningCommand.cs
  3. +11 −0 src/Viasfora.Core/Commands/ITextViewCommandHandler.cs
  4. +45 −0 src/Viasfora.Core/Commands/RemoveOutliningCommand.cs
  5. +67 −0 src/Viasfora.Core/Commands/SelectionOutliningCommand.cs
  6. +105 −0 src/Viasfora.Core/Commands/TextViewCommandListener.cs
  7. +3 −3 src/Viasfora.Core/Compatibility/SComponentModel.cs
  8. 0 src/{Viasfora.Settings → Viasfora.Core}/Contracts/ILogger.cs
  9. +21 −0 src/Viasfora.Core/PkgSource.cs
  10. +46 −0 src/Viasfora.Core/Util/VsActivityLogger.cs
  11. +1 −6 src/Viasfora.Core/Util/VsColors.cs
  12. +9 −0 src/Viasfora.Core/Viasfora.Core.csproj
  13. +3 −1 src/Viasfora.Core/VsSolution.cs
  14. +0 −25 src/Viasfora.Settings/PkgSource.cs
  15. +10 −15 src/Viasfora.Settings/Settings/GlobalXmlSettingsStore.cs
  16. +1 −2 src/Viasfora.Settings/Settings/SolutionUserSettings.cs
  17. +2 −2 src/Viasfora.Settings/Settings/SuoPersistUserSettings.cs
  18. +0 −2 src/Viasfora.Settings/Viasfora.Settings.csproj
  19. +0 −40 src/Viasfora/Commands/ClearOutliningCommand.cs
  20. +0 −20 src/Viasfora/Commands/CompleteWordCommand.cs
  21. +7 −1 src/Viasfora/Commands/ObfuscateTextCommand.cs
  22. +3 −3 src/Viasfora/Commands/PresentationModeCommand.cs
  23. +0 −48 src/Viasfora/Commands/RemoveOutliningCommand.cs
  24. +0 −77 src/Viasfora/Commands/SelectionOutliningCommand.cs
  25. +32 −31 src/Viasfora/Telemetry.cs
  26. +19 −5 src/Viasfora/TelemetryService.cs
  27. +0 −5 src/Viasfora/Viasfora.csproj
  28. +93 −157 src/Viasfora/VsfPackage.cs
  29. +2 −2 tests/Viasfora.Tests/VsfVsTestBase.cs
@@ -1,54 +1,52 @@
using System;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text;
using Winterdom.Viasfora.Outlining;
namespace Winterdom.Viasfora.Commands {
public class AddOutliningCommand : VsCommand {
public AddOutliningCommand(VsfPackage package, OleMenuCommandService omcs)
: base(package, omcs) {
Initialize(new Guid(Guids.guidVsfTextEditorCmdSet), PkgCmdIdList.cmdidAddOutlining);
}
protected override void OnBeforeQueryStatus(object sender, EventArgs e) {
base.OnBeforeQueryStatus(sender, e);
var view = TextEditor.GetCurrentView();
Command.Enabled = view != null
&& TextEditor.SupportsOutlines(view)
&& TextEditor.GetCurrentSelection() != null;
}
protected override void OnInvoke(object sender, EventArgs e) {
base.OnInvoke(sender, e);
ITextSelection selection = TextEditor.GetCurrentSelection();
if ( selection != null ) {
if ( selection.Mode == TextSelectionMode.Box ) {
// not supported, ignore for now;
return;
}
// in many cases, the buffer at the top of the
// buffer graph will be a projection buffer, which
// is problematic for the ASPX editor. Instead
// look for the first, non-projection buffer
// on the graph and project on it.
ITextView view = selection.TextView;
SnapshotSpan? span = TextEditor.MapSelectionToPrimaryBuffer(selection);
//SnapshotSpan? span = selection.StreamSelectionSpan.SnapshotSpan;
if ( span != null ) {
AddOutlining(span.Value.Snapshot.TextBuffer, span.Value);
var oc = OutliningController.Get(view);
if ( oc != null ) {
oc.CollapseRegion(span.Value);
}
}
}
}
private void AddOutlining(ITextBuffer buffer, SnapshotSpan span) {
var outlines = UserOutliningManager.Get(buffer);
outlines.Add(span);
Telemetry.WriteEvent("Add Outlining");
}
}
}
using System;
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Winterdom.Viasfora.Contracts;
using Winterdom.Viasfora.Outlining;
namespace Winterdom.Viasfora.Commands {
[Export(typeof(ITextViewCommandHandler))]
public class AddOutliningCommand : ITextViewCommandHandler {
public Guid CommandGroup => new Guid(Guids.guidVsfTextEditorCmdSet);
public int CommandId => PkgCmdIdList.cmdidAddOutlining;
[Import]
public IVsfTelemetry Telemetry { get; set; }
public bool IsEnabled(ITextView view, ref String commandText) {
return TextEditor.SupportsOutlines(view)
&& !view.Selection.IsEmpty;
}
public bool Handle(ITextView view) {
var selection = view.Selection;
if ( selection != null ) {
if ( selection.Mode == TextSelectionMode.Box ) {
// not supported, ignore for now;
return false;
}
// in many cases, the buffer at the top of the
// buffer graph will be a projection buffer, which
// is problematic for the ASPX editor. Instead
// look for the first, non-projection buffer
// on the graph and project on it.
SnapshotSpan? span = TextEditor.MapSelectionToPrimaryBuffer(selection);
//SnapshotSpan? span = selection.StreamSelectionSpan.SnapshotSpan;
if ( span != null ) {
AddOutlining(span.Value.Snapshot.TextBuffer, span.Value);
var oc = OutliningController.Get(view);
if ( oc != null ) {
oc.CollapseRegion(span.Value);
}
return true;
}
}
return false;
}
private void AddOutlining(ITextBuffer buffer, SnapshotSpan span) {
var outlines = UserOutliningManager.Get(buffer);
outlines.Add(span);
Telemetry.WriteEvent("Add Outlining");
}
}
}
@@ -0,0 +1,33 @@
using System;
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Winterdom.Viasfora.Contracts;
using Winterdom.Viasfora.Outlining;
namespace Winterdom.Viasfora.Commands {
[Export(typeof(ITextViewCommandHandler))]
public class ClearOutliningCommand : ITextViewCommandHandler {
public Guid CommandGroup => new Guid(Guids.guidVsfTextEditorCmdSet);
public int CommandId => PkgCmdIdList.cmdidClearOutlining;
[Import]
public IVsfTelemetry Telemetry { get; set; }
public bool IsEnabled(ITextView view, ref String commandText) {
var outlining = GetOutlining(view, out ITextBuffer buffer);
return outlining != null && outlining.HasUserOutlines();
}
public bool Handle(ITextView view) {
var outlining = GetOutlining(view, out ITextBuffer buffer);
outlining?.RemoveAll(buffer.CurrentSnapshot);
Telemetry.WriteEvent("Clear Outlining");
return true;
}
private IUserOutlining GetOutlining(ITextView view, out ITextBuffer buffer) {
buffer = TextEditor.GetPrimaryBuffer(view);
return UserOutliningManager.Get(buffer);
}
}
}
@@ -0,0 +1,11 @@
using Microsoft.VisualStudio.Text.Editor;
using System;
namespace Winterdom.Viasfora.Commands {
public interface ITextViewCommandHandler {
Guid CommandGroup { get; }
int CommandId { get; }
bool IsEnabled(ITextView view, ref String commandText);
bool Handle(ITextView view);
}
}
@@ -0,0 +1,45 @@
using System;
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Text.Editor;
using Winterdom.Viasfora.Contracts;
using Winterdom.Viasfora.Outlining;
namespace Winterdom.Viasfora.Commands {
[Export(typeof(ITextViewCommandHandler))]
public class RemoveOutliningCommand : ITextViewCommandHandler {
public Guid CommandGroup => new Guid(Guids.guidVsfTextEditorCmdSet);
public int CommandId => PkgCmdIdList.cmdidRemoveOutlining;
[Import]
public IVsfTelemetry Telemetry { get; set; }
public bool IsEnabled(ITextView view, ref String commandText) {
ITextCaret caret = view.Caret;
if ( caret == null ) return false;
var point = TextEditor.MapCaretToPrimaryBuffer(view);
if ( point != null ) {
IUserOutlining outlining =
UserOutliningManager.Get(point.Value.Snapshot.TextBuffer);
return outlining.IsInOutliningRegion(point.Value);
}
return false;
}
public bool Handle(ITextView view) {
ITextCaret caret = view.Caret;
if ( caret == null ) return false;
var point = TextEditor.MapCaretToPrimaryBuffer(view);
//SnapshotPoint? point = caret.Position.BufferPosition;
if ( point != null ) {
IUserOutlining outlining =
UserOutliningManager.Get(point.Value.Snapshot.TextBuffer);
outlining.RemoveAt(point.Value);
Telemetry.WriteEvent("Remove Outlining");
}
return true;
}
}
}
@@ -0,0 +1,67 @@
using System;
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Winterdom.Viasfora.Contracts;
using Winterdom.Viasfora.Outlining;
namespace Winterdom.Viasfora.Commands {
[Export(typeof(ITextViewCommandHandler))]
public class SelectionOutliningCommand : ITextViewCommandHandler {
public Guid CommandGroup => new Guid(Guids.guidVsfTextEditorCmdSet);
public int CommandId => PkgCmdIdList.cmdidSelectionOutlining;
[Import]
public IVsfTelemetry Telemetry { get; set; }
public bool IsEnabled(ITextView view, ref String commandText) {
if ( TextEditor.SupportsOutlines(view) ) {
if ( HasFeatureOutlines(view) ) {
commandText = "Remove Selection Outline";
return true;
} else if ( !view.Selection.IsEmpty ) {
commandText = "Outline Selection";
return true;
}
}
return false;
}
public bool Handle(ITextView view) {
if ( HasFeatureOutlines(view) ) {
ClearOutlines(view);
return true;
}
var selection = view.Selection;
SnapshotSpan? span = selection.StreamSelectionSpan.SnapshotSpan;
if ( span.HasValue ) {
AddOutlining(span.Value.Snapshot.TextBuffer, span.Value);
CollapseOutlines(selection.TextView);
Telemetry.WriteEvent("Outline Selection");
}
return true;
}
private void AddOutlining(ITextBuffer buffer, SnapshotSpan span) {
var outlines = SelectionOutliningManager.Get(buffer);
if ( outlines != null ) {
outlines.CreateRegionsAround(span);
}
}
private void CollapseOutlines(ITextView textView) {
var controller = OutliningController.Get(textView);
if ( controller != null ) {
controller.CollapseSelectionRegions();
}
}
private void ClearOutlines(ITextView view) {
var controller = OutliningController.Get(view);
if ( controller != null ) {
controller.RemoveSelectionRegions();
}
}
private bool HasFeatureOutlines(ITextView view) {
var outlines = SelectionOutliningManager.Get(view.TextBuffer);
return outlines != null && outlines.HasUserOutlines();
}
}
}
@@ -0,0 +1,105 @@
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Editor;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.TextManager.Interop;
using Microsoft.VisualStudio.Utilities;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Runtime.InteropServices;
namespace Winterdom.Viasfora.Commands {
[Export(typeof(IVsTextViewCreationListener))]
[Name("viasfora.command.handler")]
[ContentType(ContentTypes.Text)]
[TextViewRole(PredefinedTextViewRoles.PrimaryDocument)]
public class TextViewCommandListener : IVsTextViewCreationListener {
[Import]
internal IVsEditorAdaptersFactoryService AdapterService { get; set; }
[ImportMany]
public List<ITextViewCommandHandler> CommandHandlers { get; set; }
public void VsTextViewCreated(IVsTextView textViewAdapter) {
ITextView textView = AdapterService.GetWpfTextView(textViewAdapter);
if ( textView == null )
return;
textView.Properties.GetOrCreateSingletonProperty(
() => new TextViewCommandHandler(this, textViewAdapter, textView)
);
}
public ITextViewCommandHandler FindHandler(Guid cmdGroup, int cmdId) {
// TODO: Optimize this
foreach ( var cmd in this.CommandHandlers ) {
if ( cmd.CommandGroup == cmdGroup && cmd.CommandId == cmdId ) {
return cmd;
}
}
return null;
}
}
public class TextViewCommandHandler : IOleCommandTarget {
private TextViewCommandListener provider;
private IOleCommandTarget nextCommandHandler;
private ITextView textView;
public TextViewCommandHandler(TextViewCommandListener provider, IVsTextView viewAdapter, ITextView textView) {
this.provider = provider;
this.textView = textView;
//add the command to the command chain
viewAdapter.AddCommandFilter(this, out this.nextCommandHandler);
}
public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText) {
var cmdId = (int)prgCmds[0].cmdID;
var handler = this.provider.FindHandler(pguidCmdGroup, cmdId);
if ( handler != null ) {
String commandText = "";
bool isEnabled = handler.IsEnabled(this.textView, ref commandText);
if ( isEnabled ) {
prgCmds[0].cmdf = (uint)OLECMDF.OLECMDF_ENABLED | (uint)OLECMDF.OLECMDF_SUPPORTED;
if ( !String.IsNullOrEmpty(commandText) ) {
SetOleCmdText(pCmdText, commandText);
}
return VSConstants.S_OK;
}
}
return this.nextCommandHandler.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);
}
public void SetOleCmdText(IntPtr pCmdText, string text) {
// taken from https://social.msdn.microsoft.com/Forums/vstudio/en-US/e8c9418f-99a8-41d7-bb85-a7db15664abf/how-to-change-menu-controllers-text-dynamically?forum=vsx
OLECMDTEXT CmdText = (OLECMDTEXT)Marshal.PtrToStructure(pCmdText, typeof(OLECMDTEXT));
char[] buffer = text.ToCharArray();
IntPtr pText = (IntPtr)((long)pCmdText + (long)Marshal.OffsetOf(typeof(OLECMDTEXT), "rgwz"));
IntPtr pCwActual = (IntPtr)((long)pCmdText + (long)Marshal.OffsetOf(typeof(OLECMDTEXT), "cwActual"));
// The max chars we copy is our string, or one less than the buffer size,
// since we need a null at the end.
int maxChars = (int)Math.Min(CmdText.cwBuf - 1, buffer.Length);
Marshal.Copy(buffer, 0, pText, maxChars);
// append a null
Marshal.WriteInt16((IntPtr)((long)pText + (long)maxChars * 2), (Int16)0);
// write out the length + null char
Marshal.WriteInt32(pCwActual, maxChars + 1);
}
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) {
int hr = VSConstants.S_OK;
var cmdId = (int)nCmdID;
var handler = this.provider.FindHandler(pguidCmdGroup, cmdId);
bool handled = false;
if ( handler != null ) {
handled = handler.Handle(this.textView);
}
if ( !handled ) {
// let other commands handle it
hr = this.nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
}
return hr;
}
}
}
@@ -15,14 +15,14 @@ public class SComponentModel {
private object sComponentModel;
public SComponentModel() {
sComponentModel =
this.sComponentModel =
ServiceProvider.GlobalProvider.GetService(new Guid(SComponentModelHost));
}
public T GetService<T>() {
MethodInfo generic = sComponentModel.GetType().GetMethod("GetService");
MethodInfo generic = this.sComponentModel.GetType().GetMethod("GetService");
MethodInfo concrete = generic.MakeGenericMethod(typeof(T));
return (T)concrete.Invoke(sComponentModel, null);
return (T)concrete.Invoke(this.sComponentModel, null);
}
}
}
Oops, something went wrong.

0 comments on commit 9755241

Please sign in to comment.