From b07f230f3f4e9d01a71402e37106dd18ad0735ce Mon Sep 17 00:00:00 2001 From: Mads Kristensen Date: Mon, 10 Jan 2022 10:21:32 -0800 Subject: [PATCH] Intercepted the formatting command [release] --- src/Commands/FormatDocumentCommand.cs | 49 ++++++++++++++------------ src/Commands/FormatSelectionCommand.cs | 39 -------------------- src/Editor/EditorFeatures.cs | 2 -- src/PkgdefLanguage.csproj | 3 +- src/PkgdefPackage.cs | 5 ++- test/PkgdefLanguage.Test.csproj | 2 +- 6 files changed, 32 insertions(+), 68 deletions(-) delete mode 100644 src/Commands/FormatSelectionCommand.cs diff --git a/src/Commands/FormatDocumentCommand.cs b/src/Commands/FormatDocumentCommand.cs index bd17190..48a664c 100644 --- a/src/Commands/FormatDocumentCommand.cs +++ b/src/Commands/FormatDocumentCommand.cs @@ -1,26 +1,36 @@ using System; -using System.ComponentModel.Composition; using System.Linq; using System.Text; -using Microsoft.VisualStudio.Commanding; +using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Text; -using Microsoft.VisualStudio.Text.Editor; -using Microsoft.VisualStudio.Text.Editor.Commanding.Commands; -using Microsoft.VisualStudio.Utilities; namespace PkgdefLanguage { - [Export(typeof(ICommandHandler))] - [Name(nameof(FormatDocumentCommand))] - [ContentType(Constants.LanguageName)] - [TextViewRole(PredefinedTextViewRoles.PrimaryDocument)] - public class FormatDocumentCommand : ICommandHandler + public class FormatDocumentCommand { - public string DisplayName => nameof(CommentCommand); + public static async Task InitializeAsync() + { + // We need to manually intercept the FormatDocument command, because language services swallow formatting commands. + await VS.Commands.InterceptAsync(Microsoft.VisualStudio.VSConstants.VSStd2KCmdID.FORMATDOCUMENT, () => + { + return ThreadHelper.JoinableTaskFactory.Run(async () => + { + DocumentView doc = await VS.Documents.GetActiveDocumentViewAsync(); + + if (doc?.TextBuffer != null && doc.TextBuffer.ContentType.IsOfType(Constants.LanguageName)) + { + Format(doc.TextBuffer); + return CommandProgression.Stop; + } - public bool ExecuteCommand(FormatDocumentCommandArgs args, CommandExecutionContext executionContext) + return CommandProgression.Continue; + }); + }); + } + + private static void Format(ITextBuffer buffer) { - Document doc = args.SubjectBuffer.GetDocument(); + Document doc = buffer.GetDocument(); var sb = new StringBuilder(); foreach (ParseItem item in doc.Items) @@ -58,22 +68,15 @@ public bool ExecuteCommand(FormatDocumentCommandArgs args, CommandExecutionConte } } - var wholeDocSpan = new Span(0, args.SubjectBuffer.CurrentSnapshot.Length); - args.SubjectBuffer.Replace(wholeDocSpan, sb.ToString().Trim()); - - return true; + var wholeDocSpan = new Span(0, buffer.CurrentSnapshot.Length); + buffer.Replace(wholeDocSpan, sb.ToString().Trim()); } - private Entry NextEntry(Entry current) + private static Entry NextEntry(Entry current) { return current.Document.Items .OfType() .FirstOrDefault(e => e.Span.Start >= current.Span.End); } - - public CommandState GetCommandState(FormatDocumentCommandArgs args) - { - return CommandState.Available; - } } } \ No newline at end of file diff --git a/src/Commands/FormatSelectionCommand.cs b/src/Commands/FormatSelectionCommand.cs deleted file mode 100644 index c5f694f..0000000 --- a/src/Commands/FormatSelectionCommand.cs +++ /dev/null @@ -1,39 +0,0 @@ - -using System.ComponentModel.Composition; -using System.Linq; -using Microsoft.VisualStudio.Commanding; -using Microsoft.VisualStudio.Text; -using Microsoft.VisualStudio.Text.Editor; -using Microsoft.VisualStudio.Text.Editor.Commanding.Commands; -using Microsoft.VisualStudio.Utilities; - -namespace PkgdefLanguage -{ - [Export(typeof(ICommandHandler))] - [Name(nameof(FormatSelectionCommand))] - [ContentType(Constants.LanguageName)] - [TextViewRole(PredefinedTextViewRoles.PrimaryDocument)] - public class FormatSelectionCommand : ICommandHandler - { - public string DisplayName => nameof(CommentCommand); - - public bool ExecuteCommand(FormatSelectionCommandArgs args, CommandExecutionContext executionContext) - { - Document doc = args.SubjectBuffer.GetDocument(); - SnapshotPoint position = args.TextView.Selection.Start.Position; - ParseItem item = doc.Items.FirstOrDefault(i => i.Type == ItemType.Entry && i.Span.Contains(position)); - - if (item is Entry entry) - { - args.SubjectBuffer.Replace(entry, entry.GetFormattedText()); - } - - return true; - } - - public CommandState GetCommandState(FormatSelectionCommandArgs args) - { - return CommandState.Available; - } - } -} \ No newline at end of file diff --git a/src/Editor/EditorFeatures.cs b/src/Editor/EditorFeatures.cs index 6e07865..b43a718 100644 --- a/src/Editor/EditorFeatures.cs +++ b/src/Editor/EditorFeatures.cs @@ -3,9 +3,7 @@ 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; diff --git a/src/PkgdefLanguage.csproj b/src/PkgdefLanguage.csproj index 0a7f5cf..10ade73 100644 --- a/src/PkgdefLanguage.csproj +++ b/src/PkgdefLanguage.csproj @@ -70,7 +70,7 @@ - + compile; build; native; contentfiles; analyzers; buildtransitive @@ -80,7 +80,6 @@ - diff --git a/src/PkgdefPackage.cs b/src/PkgdefPackage.cs index d1ecc2b..ca3f11a 100644 --- a/src/PkgdefPackage.cs +++ b/src/PkgdefPackage.cs @@ -15,7 +15,7 @@ namespace PkgdefLanguage [Guid(PackageGuids.PkgdefLanguageString)] [ProvideMenuResource("Menus.ctmenu", 1)] - [ProvideLanguageService(typeof(LanguageFactory), Constants.LanguageName, 0, EnableLineNumbers = true, EnableAsyncCompletion = true, ShowCompletion = true, EnableFormatSelection = true, ShowDropDownOptions = true)] + [ProvideLanguageService(typeof(LanguageFactory), Constants.LanguageName, 0, EnableLineNumbers = true, EnableAsyncCompletion = true, ShowCompletion = true, EnableFormatSelection = false, ShowDropDownOptions = true)] [ProvideLanguageExtension(typeof(LanguageFactory), Constants.PkgDefExt)] [ProvideLanguageExtension(typeof(LanguageFactory), Constants.PkgUndefExt)] @@ -31,9 +31,12 @@ public sealed class PkgdefPackage : ToolkitPackage protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress progress) { await JoinableTaskFactory.SwitchToMainThreadAsync(); + var language = new LanguageFactory(this); RegisterEditorFactory(language); ((IServiceContainer)this).AddService(typeof(LanguageFactory), language, true); + + await FormatDocumentCommand.InitializeAsync(); } } } diff --git a/test/PkgdefLanguage.Test.csproj b/test/PkgdefLanguage.Test.csproj index 9253145..d50d5c1 100644 --- a/test/PkgdefLanguage.Test.csproj +++ b/test/PkgdefLanguage.Test.csproj @@ -7,7 +7,7 @@ - +