Skip to content

Commit

Permalink
Fixed editor factory registration
Browse files Browse the repository at this point in the history
  • Loading branch information
madskristensen committed Jan 9, 2022
1 parent be28d09 commit 7eec395
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 154 deletions.
2 changes: 2 additions & 0 deletions src/Editor/EditorFeatures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion;
using Microsoft.VisualStudio.Language.StandardClassification;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Text.BraceCompletion;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.Utilities;

Expand Down
282 changes: 141 additions & 141 deletions src/Editor/IntelliSense.cs
Original file line number Diff line number Diff line change
@@ -1,141 +1,141 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel.Composition;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Core.Imaging;
using Microsoft.VisualStudio.Imaging;
using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion;
using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion.Data;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Adornments;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Utilities;
using Microsoft.Win32;

namespace PkgdefLanguage
{
[Export(typeof(IAsyncCompletionSourceProvider))]
[ContentType(Constants.LanguageName)]
[Name(Constants.LanguageName)]
public class IntelliSense : IAsyncCompletionSourceProvider
{
public IAsyncCompletionSource GetOrCreate(ITextView textView) =>
textView.Properties.GetOrCreateSingletonProperty(() => new AsyncCompletionSource());
}

public class AsyncCompletionSource : IAsyncCompletionSource
{
private static readonly ImageElement _referenceIcon = new(KnownMonikers.LocalVariable.ToImageId(), "Variable");

public Task<CompletionContext> GetCompletionContextAsync(IAsyncCompletionSession session, CompletionTrigger trigger, SnapshotPoint triggerLocation, SnapshotSpan applicableToSpan, CancellationToken cancellationToken)
{
Document document = session.TextView.TextBuffer.GetDocument();
ParseItem item = document.FindItemFromPosition(triggerLocation.Position);
IEnumerable<CompletionItem> items = null;

if (item?.Type == ItemType.Reference)
{
items = GetReferenceCompletion();
}
else if (item?.Type == ItemType.RegistryKey)
{
items = GetRegistryKeyCompletion(item, triggerLocation);
}

return Task.FromResult(items == null ? null : new CompletionContext(items.ToImmutableArray()));
}

private IEnumerable<CompletionItem> GetRegistryKeyCompletion(ParseItem item, SnapshotPoint triggerLocation)
{
ITextSnapshotLine line = triggerLocation.GetContainingLine();
var column = triggerLocation.Position - line.Start - 1;
var previousKey = item.Text.LastIndexOf('\\', column);

if (previousKey > -1)
{
IEnumerable<string> prevKeys = item.Text.Substring(0, previousKey).Split('\\').Skip(1);
RegistryKey root = VSRegistry.RegistryRoot(__VsLocalRegistryType.RegType_Configuration);
RegistryKey parent = root;

foreach (var subKey in prevKeys)
{
parent = parent.OpenSubKey(subKey);
}

return parent?.GetSubKeyNames()?.Select(s => new CompletionItem(s, this, _referenceIcon));
}

return null;
}

private IEnumerable<CompletionItem> GetReferenceCompletion()
{
foreach (var key in PredefinedVariables.Variables.Keys)
{
var completion = new CompletionItem(key, this, _referenceIcon, ImmutableArray<CompletionFilter>.Empty, "", $"${key}$", key, key, ImmutableArray<ImageElement>.Empty);
completion.Properties.AddProperty("description", PredefinedVariables.Variables[key]);
yield return completion;
}
}

public Task<object> GetDescriptionAsync(IAsyncCompletionSession session, CompletionItem item, CancellationToken token)
{
if (item.Properties.TryGetProperty("description", out string description))
{
return Task.FromResult<object>(description);
}

return Task.FromResult<object>(null);
}

public CompletionStartData InitializeCompletion(CompletionTrigger trigger, SnapshotPoint triggerLocation, CancellationToken token)
{
if (trigger.Character == '\n' || trigger.Character == ']' || trigger.Reason == CompletionTriggerReason.Deletion)
{
return CompletionStartData.DoesNotParticipateInCompletion;
}

Document document = triggerLocation.Snapshot.TextBuffer.GetDocument();
ParseItem item = document?.FindItemFromPosition(triggerLocation.Position);

if (item?.Type == ItemType.Reference)
{
var tokenSpan = new SnapshotSpan(triggerLocation.Snapshot, item);
return new CompletionStartData(CompletionParticipation.ProvidesItems, tokenSpan);
}
else if (item?.Type == ItemType.RegistryKey && item.Text.IndexOf("$rootkey$", StringComparison.OrdinalIgnoreCase) > -1)
{
var column = triggerLocation.Position - item.Span.Start;

if (column < 1)
{
return CompletionStartData.DoesNotParticipateInCompletion; ;
}

var start = item.Text.LastIndexOf('\\', column - 1) + 1;
var end = item.Text.IndexOf('\\', column);
var close = item.Text.IndexOf(']', column);
var textEnd = item.Text.IndexOf(']', column);
end = end >= start ? end : close;
end = end >= start ? end : textEnd;
end = end >= start ? end : item.Text.TrimEnd().Length;

if (end >= start)
{
if (close == -1 || column <= close)
{
var span = new SnapshotSpan(triggerLocation.Snapshot, item.Span.Start + start, end - start);
return new CompletionStartData(CompletionParticipation.ProvidesItems, span);
}
}
}

return CompletionStartData.DoesNotParticipateInCompletion;
}
}
}
//using System;
//using System.Collections.Generic;
//using System.Collections.Immutable;
//using System.ComponentModel.Composition;
//using System.Linq;
//using System.Threading;
//using System.Threading.Tasks;
//using Microsoft.VisualStudio.Core.Imaging;
//using Microsoft.VisualStudio.Imaging;
//using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion;
//using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion.Data;
//using Microsoft.VisualStudio.Shell;
//using Microsoft.VisualStudio.Shell.Interop;
//using Microsoft.VisualStudio.Text;
//using Microsoft.VisualStudio.Text.Adornments;
//using Microsoft.VisualStudio.Text.Editor;
//using Microsoft.VisualStudio.Utilities;
//using Microsoft.Win32;

//namespace PkgdefLanguage
//{
// [Export(typeof(IAsyncCompletionSourceProvider))]
// [ContentType(Constants.LanguageName)]
// [Name(Constants.LanguageName)]
// public class IntelliSense : IAsyncCompletionSourceProvider
// {
// public IAsyncCompletionSource GetOrCreate(ITextView textView) =>
// textView.Properties.GetOrCreateSingletonProperty(() => new AsyncCompletionSource());
// }

// public class AsyncCompletionSource : IAsyncCompletionSource
// {
// private static readonly ImageElement _referenceIcon = new(KnownMonikers.LocalVariable.ToImageId(), "Variable");

// public Task<CompletionContext> GetCompletionContextAsync(IAsyncCompletionSession session, CompletionTrigger trigger, SnapshotPoint triggerLocation, SnapshotSpan applicableToSpan, CancellationToken cancellationToken)
// {
// Document document = session.TextView.TextBuffer.GetDocument();
// ParseItem item = document.FindItemFromPosition(triggerLocation.Position);
// IEnumerable<CompletionItem> items = null;

// if (item?.Type == ItemType.Reference)
// {
// items = GetReferenceCompletion();
// }
// else if (item?.Type == ItemType.RegistryKey)
// {
// items = GetRegistryKeyCompletion(item, triggerLocation);
// }

// return Task.FromResult(items == null ? null : new CompletionContext(items.ToImmutableArray()));
// }

// private IEnumerable<CompletionItem> GetRegistryKeyCompletion(ParseItem item, SnapshotPoint triggerLocation)
// {
// ITextSnapshotLine line = triggerLocation.GetContainingLine();
// var column = triggerLocation.Position - line.Start - 1;
// var previousKey = item.Text.LastIndexOf('\\', column);

// if (previousKey > -1)
// {
// IEnumerable<string> prevKeys = item.Text.Substring(0, previousKey).Split('\\').Skip(1);
// RegistryKey root = VSRegistry.RegistryRoot(__VsLocalRegistryType.RegType_Configuration);
// RegistryKey parent = root;

// foreach (var subKey in prevKeys)
// {
// parent = parent.OpenSubKey(subKey);
// }

// return parent?.GetSubKeyNames()?.Select(s => new CompletionItem(s, this, _referenceIcon));
// }

// return null;
// }

// private IEnumerable<CompletionItem> GetReferenceCompletion()
// {
// foreach (var key in PredefinedVariables.Variables.Keys)
// {
// var completion = new CompletionItem(key, this, _referenceIcon, ImmutableArray<CompletionFilter>.Empty, "", $"${key}$", key, key, ImmutableArray<ImageElement>.Empty);
// completion.Properties.AddProperty("description", PredefinedVariables.Variables[key]);
// yield return completion;
// }
// }

// public Task<object> GetDescriptionAsync(IAsyncCompletionSession session, CompletionItem item, CancellationToken token)
// {
// if (item.Properties.TryGetProperty("description", out string description))
// {
// return Task.FromResult<object>(description);
// }

// return Task.FromResult<object>(null);
// }

// public CompletionStartData InitializeCompletion(CompletionTrigger trigger, SnapshotPoint triggerLocation, CancellationToken token)
// {
// if (trigger.Character == '\n' || trigger.Character == ']' || trigger.Reason == CompletionTriggerReason.Deletion)
// {
// return CompletionStartData.DoesNotParticipateInCompletion;
// }

// Document document = triggerLocation.Snapshot.TextBuffer.GetDocument();
// ParseItem item = document?.FindItemFromPosition(triggerLocation.Position);

// if (item?.Type == ItemType.Reference)
// {
// var tokenSpan = new SnapshotSpan(triggerLocation.Snapshot, item);
// return new CompletionStartData(CompletionParticipation.ProvidesItems, tokenSpan);
// }
// else if (item?.Type == ItemType.RegistryKey && item.Text.IndexOf("$rootkey$", StringComparison.OrdinalIgnoreCase) > -1)
// {
// var column = triggerLocation.Position - item.Span.Start;

// if (column < 1)
// {
// return CompletionStartData.DoesNotParticipateInCompletion; ;
// }

// var start = item.Text.LastIndexOf('\\', column - 1) + 1;
// var end = item.Text.IndexOf('\\', column);
// var close = item.Text.IndexOf(']', column);
// var textEnd = item.Text.IndexOf(']', column);
// end = end >= start ? end : close;
// end = end >= start ? end : textEnd;
// end = end >= start ? end : item.Text.TrimEnd().Length;

// if (end >= start)
// {
// if (close == -1 || column <= close)
// {
// var span = new SnapshotSpan(triggerLocation.Snapshot, item.Span.Start + start, end - start);
// return new CompletionStartData(CompletionParticipation.ProvidesItems, span);
// }
// }
// }

// return CompletionStartData.DoesNotParticipateInCompletion;
// }
// }
//}
2 changes: 2 additions & 0 deletions src/Editor/LanguageFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

namespace PkgdefLanguage
{
[ComVisible(true)]
[Guid(PackageGuids.EditorFactoryString)]
internal sealed class LanguageFactory : LanguageBase
{
Expand Down Expand Up @@ -34,6 +35,7 @@ public override void SetDefaultPreferences(LanguagePreferences preferences)
preferences.IndentSize = 2;
preferences.IndentStyle = IndentingStyle.Smart;
preferences.ShowNavigationBar = true;
preferences.EnableFormatSelection = true;

preferences.WordWrap = true;
preferences.WordWrapGlyphs = true;
Expand Down
4 changes: 2 additions & 2 deletions src/PkgdefLanguage.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
<GeneratePkgDefFile>true</GeneratePkgDefFile>
<IncludeAssemblyInVSIXContainer>true</IncludeAssemblyInVSIXContainer>
<IncludeDebugSymbolsInVSIXContainer>true</IncludeDebugSymbolsInVSIXContainer>
<IncludeDebugSymbolsInLocalVSIXDeployment>true</IncludeDebugSymbolsInLocalVSIXDeployment>
<IncludeDebugSymbolsInLocalVSIXDeployment>false</IncludeDebugSymbolsInLocalVSIXDeployment>
<CopyBuildOutputToOutputDirectory>true</CopyBuildOutputToOutputDirectory>
<CopyOutputSymbolsToOutputDirectory>false</CopyOutputSymbolsToOutputDirectory>
<CopyOutputSymbolsToOutputDirectory>true</CopyOutputSymbolsToOutputDirectory>
<StartAction>Program</StartAction>
<StartProgram Condition="'$(DevEnvDir)' != ''">$(DevEnvDir)devenv.exe</StartProgram>
<StartArguments>/rootsuffix Exp</StartArguments>
Expand Down
15 changes: 8 additions & 7 deletions src/PkgdefPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,25 @@ namespace PkgdefLanguage
[Guid(PackageGuids.PkgdefLanguageString)]
[ProvideMenuResource("Menus.ctmenu", 1)]

[ProvideLanguageService(typeof(LanguageFactory), Constants.LanguageName, 0, DefaultToInsertSpaces = true, EnableLineNumbers = true, EnableAsyncCompletion = true, EnableCommenting = true, ShowCompletion = true, ShowDropDownOptions = true)]
[ProvideLanguageService(typeof(LanguageFactory), Constants.LanguageName, 0, EnableLineNumbers = true, EnableAsyncCompletion = true, ShowCompletion = true, EnableFormatSelection = true, ShowDropDownOptions = true)]
[ProvideLanguageExtension(typeof(LanguageFactory), Constants.PkgDefExt)]
[ProvideLanguageExtension(typeof(LanguageFactory), Constants.PkgUndefExt)]
[ProvideEditorExtension(typeof(LanguageFactory), Constants.PkgDefExt, 0x32)]
[ProvideEditorExtension(typeof(LanguageFactory), Constants.PkgUndefExt, 0x32)]
[ProvideEditorFactory(typeof(LanguageFactory), 0, CommonPhysicalViewAttributes = (int)__VSPHYSICALVIEWATTRIBUTES.PVA_SupportsPreview, TrustLevel = __VSEDITORTRUSTLEVEL.ETL_AlwaysTrusted)]

[ProvideEditorFactory(typeof(LanguageFactory), 738, CommonPhysicalViewAttributes = (int)__VSPHYSICALVIEWATTRIBUTES.PVA_SupportsPreview, TrustLevel = __VSEDITORTRUSTLEVEL.ETL_AlwaysTrusted)]
[ProvideEditorExtension(typeof(LanguageFactory), Constants.PkgDefExt, 65535, NameResourceID = 738)]
[ProvideEditorExtension(typeof(LanguageFactory), Constants.PkgUndefExt, 65535, NameResourceID = 738)]
[ProvideEditorLogicalView(typeof(LanguageFactory), VSConstants.LOGVIEWID.TextView_string, IsTrusted = true)]
[ProvideEditorLogicalView(typeof(LanguageFactory), VSConstants.LOGVIEWID.Code_string, IsTrusted = true)]

[ProvideFileIcon(Constants.PkgDefExt, "KnownMonikers.RegistrationScript")]
[ProvideFileIcon(Constants.PkgUndefExt, "KnownMonikers.RegistrationScript")]
public sealed class PkgdefPackage : ToolkitPackage
{
protected override Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
var language = new LanguageFactory(this);
RegisterEditorFactory(language);
((IServiceContainer)this).AddService(typeof(LanguageFactory), language, true);
return Task.CompletedTask;
}
}
}
4 changes: 2 additions & 2 deletions src/VSCommandTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ namespace PkgdefLanguage
/// </summary>
internal sealed partial class PackageGuids
{
public const string EditorFactoryString = "57522df2-e926-4908-8c62-d57afece26e5";
public const string EditorFactoryString = "57522df2-e926-4908-8c62-d57afece26e4";
public static Guid EditorFactory = new Guid(EditorFactoryString);

public const string PkgdefLanguageString = "4ecd0189-a643-49a1-9f2a-6f32e299dd7d";
public const string PkgdefLanguageString = "4ecd0189-a643-49a1-9f2a-6f32e299dd7c";
public static Guid PkgdefLanguage = new Guid(PkgdefLanguageString);
}
/// <summary>
Expand Down
9 changes: 7 additions & 2 deletions src/VSCommandTable.vsct
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@

</Commands>

<UsedCommands>
<UsedCommand guid="guidVSStd97" id="ECMD_FORMATDOCUMENT" />
<UsedCommand guid="guidVSStd97" id="ECMD_FORMATSELECTION" />
</UsedCommands>

<Symbols>
<GuidSymbol name="EditorFactory" value="{57522df2-e926-4908-8c62-d57afece26e5}" />
<GuidSymbol name="PkgdefLanguage" value="{4ecd0189-a643-49a1-9f2a-6f32e299dd7d}" />
<GuidSymbol name="EditorFactory" value="{57522df2-e926-4908-8c62-d57afece26e4}" />
<GuidSymbol name="PkgdefLanguage" value="{4ecd0189-a643-49a1-9f2a-6f32e299dd7c}" />
</Symbols>
</CommandTable>

0 comments on commit 7eec395

Please sign in to comment.