diff --git a/src/Commands/CommentCommand.cs b/src/Commands/CommentCommand.cs deleted file mode 100644 index 1f013d8..0000000 --- a/src/Commands/CommentCommand.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Collections.ObjectModel; -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.Text.Formatting; -using Microsoft.VisualStudio.Utilities; - -namespace PkgdefLanguage -{ - [Export(typeof(ICommandHandler))] - [Name(nameof(CommentCommand))] - [ContentType(Constants.LanguageName)] - [TextViewRole(PredefinedTextViewRoles.PrimaryDocument)] - public class CommentCommand : ICommandHandler - { - public string DisplayName => nameof(CommentCommand); - - public bool ExecuteCommand(CommentSelectionCommandArgs args, CommandExecutionContext executionContext) - { - SnapshotSpan spans = args.TextView.Selection.SelectedSpans.First(); - Collection lines = args.TextView.TextViewLines.GetTextViewLinesIntersectingSpan(spans); - - foreach (ITextViewLine line in lines.Reverse()) - { - args.TextView.TextBuffer.Insert(line.Start.Position, Constants.CommentChars[0]); - } - - return true; - } - - public CommandState GetCommandState(CommentSelectionCommandArgs args) - { - return CommandState.Available; - } - } -} \ No newline at end of file diff --git a/src/Commands/Commenting.cs b/src/Commands/Commenting.cs new file mode 100644 index 0000000..93a82f6 --- /dev/null +++ b/src/Commands/Commenting.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.ObjectModel; +using System.Linq; +using Microsoft.VisualStudio; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Text.Formatting; + +namespace PkgdefLanguage +{ + public class Commenting2 + { + public static async Task InitializeAsync() + { + // We need to manually intercept the commenting command, because language services swallow these commands. + await VS.Commands.InterceptAsync(VSConstants.VSStd2KCmdID.COMMENT_BLOCK, () => Execute(Comment)); + await VS.Commands.InterceptAsync(VSConstants.VSStd2KCmdID.UNCOMMENT_BLOCK, () => Execute(Uncomment)); + } + + private static CommandProgression Execute(Action action) + { + return ThreadHelper.JoinableTaskFactory.Run(async () => + { + DocumentView doc = await VS.Documents.GetActiveDocumentViewAsync(); + + if (doc?.TextBuffer != null && doc.TextBuffer.ContentType.IsOfType(Constants.LanguageName)) + { + action(doc); + return CommandProgression.Stop; + } + + return CommandProgression.Continue; + }); + } + + private static void Comment(DocumentView doc) + { + SnapshotSpan spans = doc.TextView.Selection.SelectedSpans.First(); + Collection lines = doc.TextView.TextViewLines.GetTextViewLinesIntersectingSpan(spans); + + foreach (ITextViewLine line in lines.Reverse()) + { + doc.TextBuffer.Insert(line.Start.Position, Constants.CommentChars[0]); + } + } + + private static void Uncomment(DocumentView doc) + { + SnapshotSpan spans = doc.TextView.Selection.SelectedSpans.First(); + Collection lines = doc.TextView.TextViewLines.GetTextViewLinesIntersectingSpan(spans); + + foreach (ITextViewLine line in lines.Reverse()) + { + var span = Span.FromBounds(line.Start, line.End); + var originalText = doc.TextBuffer.CurrentSnapshot.GetText(span).TrimStart('/', ';'); + Span commentCharSpan = new(span.Start, span.Length - originalText.Length); + + doc.TextBuffer.Delete(commentCharSpan); + } + } + } +} \ No newline at end of file diff --git a/src/Commands/FormatDocumentCommand.cs b/src/Commands/Formatting.cs similarity index 98% rename from src/Commands/FormatDocumentCommand.cs rename to src/Commands/Formatting.cs index 48a664c..60c7def 100644 --- a/src/Commands/FormatDocumentCommand.cs +++ b/src/Commands/Formatting.cs @@ -6,7 +6,7 @@ namespace PkgdefLanguage { - public class FormatDocumentCommand + public class Formatting { public static async Task InitializeAsync() { diff --git a/src/Commands/UncommentCommand.cs b/src/Commands/UncommentCommand.cs deleted file mode 100644 index 6ac39f7..0000000 --- a/src/Commands/UncommentCommand.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Collections.ObjectModel; -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.Text.Formatting; -using Microsoft.VisualStudio.Utilities; - -namespace PkgdefLanguage -{ - [Export(typeof(ICommandHandler))] - [Name(nameof(CommentCommand))] - [ContentType(Constants.LanguageName)] - [TextViewRole(PredefinedTextViewRoles.PrimaryDocument)] - public class UncommentCommand : ICommandHandler - { - public string DisplayName => nameof(UncommentCommand); - - public bool ExecuteCommand(UncommentSelectionCommandArgs args, CommandExecutionContext executionContext) - { - SnapshotSpan spans = args.TextView.Selection.SelectedSpans.First(); - Collection lines = args.TextView.TextViewLines.GetTextViewLinesIntersectingSpan(spans); - - foreach (ITextViewLine line in lines.Reverse()) - { - var span = Span.FromBounds(line.Start, line.End); - var text = args.TextView.TextBuffer.CurrentSnapshot.GetText(span).TrimStart(Constants.CommentChars[0][0]); - args.TextView.TextBuffer.Replace(span, text); - } - - return true; - } - - public CommandState GetCommandState(UncommentSelectionCommandArgs args) - { - return CommandState.Available; - } - } -} \ No newline at end of file diff --git a/src/Editor/LanguageFactory.cs b/src/Editor/LanguageFactory.cs index 44d454b..131971a 100644 --- a/src/Editor/LanguageFactory.cs +++ b/src/Editor/LanguageFactory.cs @@ -19,13 +19,18 @@ public LanguageFactory(object site) : base(site) public override string[] FileExtensions { get; } = new[] { Constants.PkgDefExt, Constants.PkgUndefExt }; + public override ViewFilter CreateViewFilter(CodeWindowManager mgr, IVsTextView newView) + { + return base.CreateViewFilter(mgr, newView); + } + public override void SetDefaultPreferences(LanguagePreferences preferences) { preferences.EnableCodeSense = false; preferences.EnableMatchBraces = true; preferences.EnableMatchBracesAtCaret = true; preferences.EnableShowMatchingBrace = true; - preferences.EnableCommenting = false; + preferences.EnableCommenting = true; preferences.HighlightMatchingBraceFlags = _HighlightMatchingBraceFlags.HMB_USERECTANGLEBRACES; preferences.LineNumbers = true; preferences.MaxErrorMessages = 100; diff --git a/src/PkgdefLanguage.csproj b/src/PkgdefLanguage.csproj index 10ade73..d43b5ae 100644 --- a/src/PkgdefLanguage.csproj +++ b/src/PkgdefLanguage.csproj @@ -80,11 +80,10 @@ - + - - + diff --git a/src/PkgdefPackage.cs b/src/PkgdefPackage.cs index ca3f11a..922173d 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 = false, ShowDropDownOptions = true)] + [ProvideLanguageService(typeof(LanguageFactory), Constants.LanguageName, 0, EnableLineNumbers = true, EnableAsyncCompletion = true, ShowCompletion = true, EnableFormatSelection = false, ShowDropDownOptions = true, EnableCommenting = true)] [ProvideLanguageExtension(typeof(LanguageFactory), Constants.PkgDefExt)] [ProvideLanguageExtension(typeof(LanguageFactory), Constants.PkgUndefExt)] @@ -36,7 +36,8 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke RegisterEditorFactory(language); ((IServiceContainer)this).AddService(typeof(LanguageFactory), language, true); - await FormatDocumentCommand.InitializeAsync(); + await Formatting.InitializeAsync(); + await Commenting2.InitializeAsync(); } } }