diff --git a/AvaloniaVS.Shared/AvaloniaVS.Shared.projitems b/AvaloniaVS.Shared/AvaloniaVS.Shared.projitems
index c120acde..4b375241 100644
--- a/AvaloniaVS.Shared/AvaloniaVS.Shared.projitems
+++ b/AvaloniaVS.Shared/AvaloniaVS.Shared.projitems
@@ -14,6 +14,7 @@
+
@@ -39,6 +40,13 @@
+
+
+
+
+
+
+
@@ -94,5 +102,6 @@
+
\ No newline at end of file
diff --git a/AvaloniaVS.Shared/IntelliSense/CompletionEngineSource.cs b/AvaloniaVS.Shared/IntelliSense/CompletionEngineSource.cs
new file mode 100644
index 00000000..a77bd64a
--- /dev/null
+++ b/AvaloniaVS.Shared/IntelliSense/CompletionEngineSource.cs
@@ -0,0 +1,15 @@
+using System.ComponentModel.Composition;
+using Avalonia.Ide.CompletionEngine;
+
+namespace AvaloniaVS.Shared.IntelliSense
+{
+ [Export]
+ public class CompletionEngineSource
+ {
+ public CompletionEngineSource()
+ {
+ CompletionEngine = new CompletionEngine();
+ }
+ public CompletionEngine CompletionEngine { get; }
+ }
+}
diff --git a/AvaloniaVS.Shared/IntelliSense/XamlCompletionCommandHandler.cs b/AvaloniaVS.Shared/IntelliSense/XamlCompletionCommandHandler.cs
index f8998fea..96e81770 100644
--- a/AvaloniaVS.Shared/IntelliSense/XamlCompletionCommandHandler.cs
+++ b/AvaloniaVS.Shared/IntelliSense/XamlCompletionCommandHandler.cs
@@ -37,24 +37,25 @@ internal class XamlCompletionCommandHandler : IOleCommandTarget
private readonly ICompletionBroker _completionBroker;
private readonly IOleCommandTarget _nextCommandHandler;
private readonly ITextView _textView;
+ private readonly CompletionEngine _engine;
private ICompletionSession _session;
public XamlCompletionCommandHandler(
IServiceProvider serviceProvider,
ICompletionBroker completionBroker,
ITextView textView,
- IVsTextView textViewAdapter)
+ IVsTextView textViewAdapter,
+ CompletionEngine completionEngine)
{
_serviceProvider = serviceProvider;
_completionBroker = completionBroker;
_textView = textView;
+ _engine = completionEngine;
// Add ourselves as a command to the text view.
textViewAdapter.AddCommandFilter(this, out _nextCommandHandler);
}
- public CompletionEngine Engine { get; set; }
-
public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
{
ThreadHelper.ThrowIfNotOnUIThread();
@@ -255,7 +256,7 @@ private bool HandleSessionCompletion(char c)
if (state == XmlParser.ParserState.AttributeValue ||
state == XmlParser.ParserState.AfterAttributeValue)
{
- var type = Engine.Helper.LookupType(parser.TagName);
+ var type = _engine.Helper.LookupType(parser.TagName);
if (type != null && type.Events.FirstOrDefault(x => x.Name == parser.AttributeName) != null)
{
GenerateEventHandler(type.FullName, parser.AttributeName, selected.InsertionText);
diff --git a/AvaloniaVS.Shared/IntelliSense/XamlCompletionHandlerProvider.cs b/AvaloniaVS.Shared/IntelliSense/XamlCompletionHandlerProvider.cs
index 9b31aeb2..e92782bc 100644
--- a/AvaloniaVS.Shared/IntelliSense/XamlCompletionHandlerProvider.cs
+++ b/AvaloniaVS.Shared/IntelliSense/XamlCompletionHandlerProvider.cs
@@ -1,6 +1,7 @@
using System;
using System.ComponentModel.Composition;
using AvaloniaVS.Models;
+using AvaloniaVS.Shared.IntelliSense;
using Microsoft.VisualStudio.Editor;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Shell;
@@ -22,16 +23,19 @@ internal class XamlCompletionHandlerProvider : IVsTextViewCreationListener
private readonly IServiceProvider _serviceProvider;
private readonly IVsEditorAdaptersFactoryService _adapterService;
private readonly ICompletionBroker _completionBroker;
+ private readonly CompletionEngineSource _completionEngineSource;
[ImportingConstructor]
public XamlCompletionHandlerProvider(
[Import(typeof(SVsServiceProvider))] IServiceProvider serviceProvider,
IVsEditorAdaptersFactoryService adapterService,
- ICompletionBroker completionBroker)
+ ICompletionBroker completionBroker,
+ CompletionEngineSource completionEngineSource)
{
_serviceProvider = serviceProvider;
_adapterService = adapterService;
_completionBroker = completionBroker;
+ _completionEngineSource = completionEngineSource;
}
public void VsTextViewCreated(IVsTextView textViewAdapter)
@@ -46,7 +50,8 @@ public void VsTextViewCreated(IVsTextView textViewAdapter)
_serviceProvider,
_completionBroker,
textView,
- textViewAdapter));
+ textViewAdapter,
+ _completionEngineSource.CompletionEngine));
}
}
}
diff --git a/AvaloniaVS.Shared/IntelliSense/XamlCompletionSource.cs b/AvaloniaVS.Shared/IntelliSense/XamlCompletionSource.cs
index 469b42dc..f4e45c52 100644
--- a/AvaloniaVS.Shared/IntelliSense/XamlCompletionSource.cs
+++ b/AvaloniaVS.Shared/IntelliSense/XamlCompletionSource.cs
@@ -1,25 +1,24 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using AvaloniaVS.Models;
+using AvaloniaVS.Shared.IntelliSense;
using Microsoft.CodeAnalysis;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Text;
using Serilog;
-using CompletionEngine = Avalonia.Ide.CompletionEngine.CompletionEngine;
namespace AvaloniaVS.IntelliSense
{
internal class XamlCompletionSource : ICompletionSource
{
private readonly ITextBuffer _buffer;
- private readonly CompletionEngine _engine;
+ private readonly CompletionEngineSource _engine;
- public XamlCompletionSource(ITextBuffer textBuffer)
+ public XamlCompletionSource(ITextBuffer textBuffer, CompletionEngineSource completionEngineSource)
{
_buffer = textBuffer;
- _engine = new CompletionEngine();
+ _engine = completionEngineSource;
}
public void AugmentCompletionSession(ICompletionSession session, IList completionSets)
@@ -27,13 +26,11 @@ public void AugmentCompletionSession(ICompletionSession session, IList(typeof(XamlBufferMetadata), out var metadata) &&
metadata.CompletionMetadata != null)
{
- session.TextView.Properties.TryGetProperty(typeof(XamlCompletionCommandHandler), out var property);
- property.Engine = _engine;
var sw = Stopwatch.StartNew();
var pos = session.TextView.Caret.Position.BufferPosition;
var text = pos.Snapshot.GetText();
_buffer.Properties.TryGetProperty("AssemblyName", out string assemblyName);
- var completions = _engine.GetCompletions(metadata.CompletionMetadata, text, pos, assemblyName);
+ var completions = _engine.CompletionEngine.GetCompletions(metadata.CompletionMetadata, text, pos, assemblyName);
if (completions?.Completions.Count > 0)
{
diff --git a/AvaloniaVS.Shared/IntelliSense/XamlCompletionSourceProvider.cs b/AvaloniaVS.Shared/IntelliSense/XamlCompletionSourceProvider.cs
index 1a4071a9..e5b3ffa7 100644
--- a/AvaloniaVS.Shared/IntelliSense/XamlCompletionSourceProvider.cs
+++ b/AvaloniaVS.Shared/IntelliSense/XamlCompletionSourceProvider.cs
@@ -1,9 +1,7 @@
-using System;
-using System.ComponentModel.Composition;
+using System.ComponentModel.Composition;
using AvaloniaVS.Models;
+using AvaloniaVS.Shared.IntelliSense;
using Microsoft.VisualStudio.Language.Intellisense;
-using Microsoft.VisualStudio.Shell;
-using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Utilities;
@@ -14,11 +12,17 @@ namespace AvaloniaVS.IntelliSense
[Name("Avalonia XAML Completion")]
internal class XamlCompletionSourceProvider : ICompletionSourceProvider
{
+ [ImportingConstructor]
+ public XamlCompletionSourceProvider([Import] CompletionEngineSource completionEngineSource)
+ {
+ _completionEngineSource = completionEngineSource;
+ }
+ private readonly CompletionEngineSource _completionEngineSource;
public ICompletionSource TryCreateCompletionSource(ITextBuffer textBuffer)
{
if (textBuffer.Properties.ContainsProperty(typeof(XamlBufferMetadata)))
{
- return new XamlCompletionSource(textBuffer);
+ return new XamlCompletionSource(textBuffer, _completionEngineSource);
}
return null;
diff --git a/AvaloniaVS.Shared/SuggestedActions/Actions/Base/BaseSuggestedAction.cs b/AvaloniaVS.Shared/SuggestedActions/Actions/Base/BaseSuggestedAction.cs
new file mode 100644
index 00000000..6a87c820
--- /dev/null
+++ b/AvaloniaVS.Shared/SuggestedActions/Actions/Base/BaseSuggestedAction.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.VisualStudio.Imaging.Interop;
+using Microsoft.VisualStudio.Language.Intellisense;
+
+namespace AvaloniaVS.Shared.SuggestedActions.Actions.Base
+{
+ internal class BaseSuggestedAction
+ {
+ public bool HasActionSets { get; }
+
+ public ImageMoniker IconMoniker { get; }
+
+ public string IconAutomationText { get; }
+
+ public string InputGestureText { get; }
+
+ public bool HasPreview => true;
+
+ public void Dispose()
+ {
+ }
+
+ public bool TryGetTelemetryId(out Guid telemetryId)
+ {
+ telemetryId = Guid.Empty;
+ return false;
+ }
+
+ public Task> GetActionSetsAsync(CancellationToken cancellationToken)
+ {
+ return Task.FromResult>(null);
+ }
+ }
+}
diff --git a/AvaloniaVS.Shared/SuggestedActions/Actions/MissingAliasSuggestedAction.cs b/AvaloniaVS.Shared/SuggestedActions/Actions/MissingAliasSuggestedAction.cs
new file mode 100644
index 00000000..149fb880
--- /dev/null
+++ b/AvaloniaVS.Shared/SuggestedActions/Actions/MissingAliasSuggestedAction.cs
@@ -0,0 +1,56 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using AvaloniaVS.Shared.SuggestedActions.Actions.Base;
+using AvaloniaVS.Shared.SuggestedActions.Helpers;
+using Microsoft.VisualStudio.Language.Intellisense;
+using Microsoft.VisualStudio.Text;
+using Microsoft.VisualStudio.Text.Differencing;
+using Microsoft.VisualStudio.Text.Editor;
+
+namespace AvaloniaVS.Shared.SuggestedActions.Actions
+{
+ internal class MissingAliasSuggestedAction : BaseSuggestedAction, ISuggestedAction
+ {
+ private readonly ITrackingSpan _span;
+ private readonly ITextSnapshot _snapshot;
+ private readonly string _targetClassName;
+ private readonly string _namespaceAlias;
+ private readonly IWpfDifferenceViewerFactoryService _diffFactory;
+ private readonly IDifferenceBufferFactoryService _diffBufferFactory;
+ private readonly ITextBufferFactoryService _bufferFactory;
+ private readonly ITextViewRoleSet _previewRoleSet;
+
+ public MissingAliasSuggestedAction(ITrackingSpan span, IWpfDifferenceViewerFactoryService diffFactory, IDifferenceBufferFactoryService diffBufferFactory, ITextBufferFactoryService bufferFactory, ITextEditorFactoryService textEditorFactoryService, IReadOnlyDictionary inverseNamespaces)
+ {
+ _span = span;
+ _snapshot = _span.TextBuffer.CurrentSnapshot;
+ _targetClassName = _span.GetText(_snapshot);
+ var targetClassMetadata = inverseNamespaces.FirstOrDefault(x => x.Key.Split('.').Last() == _targetClassName);
+ _namespaceAlias = targetClassMetadata.Value.Split(':').Last().Split('.').Last();
+ _diffFactory = diffFactory;
+ _diffBufferFactory = diffBufferFactory;
+ _bufferFactory = bufferFactory;
+ _previewRoleSet = textEditorFactoryService.CreateTextViewRoleSet(PredefinedTextViewRoles.Analyzable);
+ DisplayText = $"Use {_namespaceAlias.ToLower()} ({targetClassMetadata.Value})";
+ }
+
+ public string DisplayText { get; }
+
+ public Task