Installed product versions
- Visual Studio 2022 CE
- CollapseComments v 2.5.1
Description
If I do:
Ctrl + M, Ctrl + M
(collapsing everything)
I see only one entry in the Undo history
Ctrl + M, Ctrl + L
(expanding everything)
this correctly adds only one entry in the Undo history
Ctrl + M, Ctrl + C
(collapsing only the comments)
this correctly adds 100 entries in the Undo history if I have 100 functions in the code.
CollapseComments works very nicely, thanks a lot for that!,
but then every comments section that is collapsed adds one entry in the undo/redo history.
This not only is annoying and it makes the undo redo history useless, but also it makes VS unusable too, or very slow to say the least, if you try to undo like 20 of those undo entries.
There are two solutions for that.
### SOLUTION 1:
The simple workaround I used was to use this extension by Sergey Vlasov:
Disable Outlining Undo
reported in ide - Visual Studio _ exclude outlining from undo_redo stack - Stack Overflow
To have had the outlining actions go into the undo/redo history has always been a strong nuisance of Visual Studio for me (and clearly not only me).
In this extension the value of DefaultTextViewOptions.OutliningUndoOptionId
is simply set to false.
Here is roughly a possible code equivalent to that of the 'Disable Outlining Undo' extension (using ChatGPT)
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Formatting;
public class MyTextViewCreationListener : TextViewCreationListener
{
public override void TextViewCreated(ITextView textView)
{
if (textView.Options is IEditorOptions editorOptions)
{
//getting the value
object outliningUndoOptionId = textView.Options.GetOptionValue(DefaultTextViewOptions.OutliningUndoOptionId);
int outliningUndoOptionIdValue = (int)outliningUndoOptionId;
//setting the value to disable undo for outlines
editorOptions.SetOptionValue(DefaultTextViewOptions.OutliningUndoOptionId, false);
}
}
}
Registering the TextViewCreationListener listener:
using Microsoft.VisualStudio.Shell;
protected override void Initialize()
{
base.Initialize();
var textViewCreationListener = new MyTextViewCreationListener();
var textViewCreationService = GetService(typeof(ITextViewCreationListener)) as ITextViewCreationListener;
if (textViewCreationService != null)
{
textViewCreationService.TextViewCreated += textViewCreationListener.TextViewCreated;
}
}
A different implementation of this could be to simply to derive from
as explained in here and by MS here
Something on the line of (didn't test it):
using System;
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Utilities;
[Export(typeof(IWpfTextViewCreationListener))]
[ContentType("text")]
[TextViewRole(PredefinedTextViewRoles.PrimaryDocument)]
internal sealed class MyWpfTextViewCreationListener : IWpfTextViewCreationListener
{
public void TextViewCreated(IWpfTextView textView)
{
try
{
if (textView.Options.IsOptionDefined<bool>(DefaultTextViewOptions.OutliningUndoOptionId, false))
{
textView.Options.SetOptionValue<bool>(DefaultTextViewOptions.OutliningUndoOptionId, false);
}
}
catch (Exception)
{
}
}
}
If this idea would be integrated in the 'Collapse Comments' extension then it would be a good idea to re-enable the undo/redo stack after the outlining were concluded, or even better to restore the value of 'DefaultTextViewOptions.OutliningUndoOptionId' to the one it had before the collapsing operation was started.
### SOLUTION 2:
Even better would probably be to gather the entire action in a single undo/redo entry in the undo/redo history.
The raw code for this is (again using ChatGPT):
# References to add:
# Microsoft.VisualStudio.Shell.17.0.dll
# Microsoft.VisualStudio.Text.Data.17.0.dll
# Microsoft.VisualStudio.Text.Logic.17.0.dll
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Operations;
using Microsoft.VisualStudio.TextManager.Interop;
public class GroupUndoRedoExtension
{
private IWpfTextView _textView;
private IEditorOperations _editorOperations;
public GroupUndoRedoExtension(IWpfTextView textView, IEditorOperationsFactoryService editorOperationsFactory)
{
_textView = textView;
_editorOperations = editorOperationsFactory.GetEditorOperations(_textView);
}
public void GroupActions()
{
// Start a compound action to group multiple actions
_editorOperations.BeginCompositeUndo();
// Perform the individual actions
// Example: Insert text at the current caret position
_editorOperations.InsertText("Hello, World!");
// End the compound action to group the actions
_editorOperations.EndCompositeUndo();
}
}
Sorry for using ChatGPT actually.
I hope this helps, and maybe it will be integrated one day in this extension.