diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs b/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs index 2fab48259c61d..5189907a8e71a 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/CommandHandlers/RenameCommandHandler.cs @@ -38,6 +38,14 @@ internal partial class RenameCommandHandler( IAsynchronousOperationListenerProvider asynchronousOperationListenerProvider) : AbstractRenameCommandHandler(threadingContext, renameService, globalOptionService, asynchronousOperationListenerProvider.GetListener(FeatureAttribute.Rename)) { + protected override bool AdornmentShouldReceiveKeyboardNavigation(ITextView textView) + => GetAdornment(textView) switch + { + RenameDashboard dashboard => dashboard.ShouldReceiveKeyboardNavigation, + RenameFlyout => true, // Always receive keyboard navigation for the inline adornment + _ => false + }; + protected override void SetFocusToTextView(ITextView textView) { (textView as IWpfTextView)?.VisualElement.Focus(); @@ -51,6 +59,22 @@ protected override void SetFocusToAdornment(ITextView textView) } } + protected override void SetAdornmentFocusToNextElement(ITextView textView) + { + if (GetAdornment(textView) is RenameDashboard dashboard) + { + dashboard.FocusNextElement(); + } + } + + protected override void SetAdornmentFocusToPreviousElement(ITextView textView) + { + if (GetAdornment(textView) is RenameDashboard dashboard) + { + dashboard.FocusNextElement(); + } + } + private static InlineRenameAdornment? GetAdornment(ITextView textView) { // If our adornment layer somehow didn't get composed, GetAdornmentLayer will throw. diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/UI/InlineRenameAdornmentManager.cs b/src/EditorFeatures/Core.Wpf/InlineRename/UI/InlineRenameAdornmentManager.cs index 30c28fdd836ce..c0b3678fa7ec9 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/UI/InlineRenameAdornmentManager.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/UI/InlineRenameAdornmentManager.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Runtime.CompilerServices; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.InlineRename; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.EditorFeatures.Lightup; using Microsoft.CodeAnalysis.Internal.Log; @@ -19,7 +20,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename { - internal sealed class InlineRenameAdornmentManager : IDisposable + internal class InlineRenameAdornmentManager : IDisposable { private readonly IWpfTextView _textView; private readonly IGlobalOptionService _globalOptionService; @@ -117,45 +118,59 @@ private void UpdateAdornments() return null; } - if (!_textView.HasAggregateFocus) + var useInlineAdornment = _globalOptionService.GetOption(InlineRenameUIOptionsStorage.UseInlineAdornment); + LogAdornmentChoice(useInlineAdornment); + if (useInlineAdornment) { - // For the rename flyout, the adornment is dismissed on focus lost. There's - // no need to keep an adornment on every textview for show/hide behaviors - return null; + if (!_textView.HasAggregateFocus) + { + // For the rename flyout, the adornment is dismissed on focus lost. There's + // no need to keep an adornment on every textview for show/hide behaviors + return null; + } + + // Get the active selection to make sure the rename text is selected in the same way + var originalSpan = _renameService.ActiveSession.TriggerSpan; + var selectionSpan = _textView.Selection.SelectedSpans.First(); + + var start = selectionSpan.IsEmpty + ? 0 + : selectionSpan.Start - originalSpan.Start; // The length from the identifier to the start of selection + + var length = selectionSpan.IsEmpty + ? originalSpan.Length + : selectionSpan.Length; + + var identifierSelection = new TextSpan(start, length); + + var adornment = new RenameFlyout( + (RenameFlyoutViewModel)s_createdViewModels.GetValue( + _renameService.ActiveSession, + session => new RenameFlyoutViewModel(session, + identifierSelection, + registerOleComponent: true, + _globalOptionService, + _threadingContext, + _listenerProvider, + _smartRenameSessionFactory)), + _textView, + _themeService, + _asyncQuickInfoBroker, + _editorFormatMapService, + _threadingContext, + _listenerProvider); + + return adornment; } + else + { + var newAdornment = new RenameDashboard( + (RenameDashboardViewModel)s_createdViewModels.GetValue(_renameService.ActiveSession, session => new RenameDashboardViewModel(session, _threadingContext, _textView)), + _editorFormatMapService, + _textView); - // Get the active selection to make sure the rename text is selected in the same way - var originalSpan = _renameService.ActiveSession.TriggerSpan; - var selectionSpan = _textView.Selection.SelectedSpans.First(); - - var start = selectionSpan.IsEmpty - ? 0 - : selectionSpan.Start - originalSpan.Start; // The length from the identifier to the start of selection - - var length = selectionSpan.IsEmpty - ? originalSpan.Length - : selectionSpan.Length; - - var identifierSelection = new TextSpan(start, length); - - var adornment = new RenameFlyout( - (RenameFlyoutViewModel)s_createdViewModels.GetValue( - _renameService.ActiveSession, - session => new RenameFlyoutViewModel(session, - identifierSelection, - registerOleComponent: true, - _globalOptionService, - _threadingContext, - _listenerProvider, - _smartRenameSessionFactory)), - _textView, - _themeService, - _asyncQuickInfoBroker, - _editorFormatMapService, - _threadingContext, - _listenerProvider); - - return adornment; + return newAdornment; + } } private static bool ViewIncludesBufferFromWorkspace(IWpfTextView textView, Workspace workspace) @@ -169,5 +184,13 @@ private static bool ViewIncludesBufferFromWorkspace(IWpfTextView textView, Works Workspace.TryGetWorkspace(textContainer, out var workspace); return workspace; } + + private static void LogAdornmentChoice(bool useInlineAdornment) + { + TelemetryLogging.Log(FunctionId.InlineRenameAdornmentChoice, KeyValueLogMessage.Create(m => + { + m[nameof(useInlineAdornment)] = useInlineAdornment; + })); + } } } diff --git a/src/EditorFeatures/Core/InlineRename/AbstractInlineRenameUndoManager.cs b/src/EditorFeatures/Core/InlineRename/AbstractInlineRenameUndoManager.cs index 7e9a0a0b094a1..a3b5a85a22018 100644 --- a/src/EditorFeatures/Core/InlineRename/AbstractInlineRenameUndoManager.cs +++ b/src/EditorFeatures/Core/InlineRename/AbstractInlineRenameUndoManager.cs @@ -29,6 +29,7 @@ protected class ActiveSpanState } protected readonly InlineRenameService InlineRenameService; + private readonly IGlobalOptionService _globalOptionService; protected readonly Dictionary UndoManagers = []; protected readonly Stack UndoStack = new Stack(); protected readonly Stack RedoStack = new Stack(); @@ -38,9 +39,10 @@ protected class ActiveSpanState private InlineRenameSession _trackedSession; - public AbstractInlineRenameUndoManager(InlineRenameService inlineRenameService) + public AbstractInlineRenameUndoManager(InlineRenameService inlineRenameService, IGlobalOptionService globalOptionService) { this.InlineRenameService = inlineRenameService; + _globalOptionService = globalOptionService; InlineRenameService.ActiveSessionChanged += InlineRenameService_ActiveSessionChanged; } @@ -52,6 +54,17 @@ private void InlineRenameService_ActiveSessionChanged(object sender, InlineRenam _trackedSession.ReplacementTextChanged -= InlineRenameSession_ReplacementTextChanged; } + if (!_globalOptionService.GetOption(InlineRenameUIOptionsStorage.UseInlineAdornment)) + { + // If the user is typing directly into the editor as the only way to change + // the replacement text then we don't need to respond to text changes. The + // listener on the textview that calls UpdateCurrentState will handle + // this correctly. This option cannot change when we are currently in a session, so + // only hook up as needed + _trackedSession = null; + return; + } + _trackedSession = InlineRenameService.ActiveSession; if (_trackedSession is not null) diff --git a/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler.cs b/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler.cs index 923c015b056ff..6de72e939503b 100644 --- a/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler.cs +++ b/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler.cs @@ -26,10 +26,16 @@ internal abstract partial class AbstractRenameCommandHandler( { public string DisplayName => EditorFeaturesResources.Rename; + protected abstract bool AdornmentShouldReceiveKeyboardNavigation(ITextView textView); + protected abstract void SetFocusToTextView(ITextView textView); protected abstract void SetFocusToAdornment(ITextView textView); + protected abstract void SetAdornmentFocusToPreviousElement(ITextView textView); + + protected abstract void SetAdornmentFocusToNextElement(ITextView textView); + private CommandState GetCommandState(Func nextHandler) { if (renameService.ActiveSession != null) diff --git a/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler_TabHandler.cs b/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler_TabHandler.cs new file mode 100644 index 0000000000000..9846afad5f315 --- /dev/null +++ b/src/EditorFeatures/Core/InlineRename/CommandHandlers/AbstractRenameCommandHandler_TabHandler.cs @@ -0,0 +1,65 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.CodeAnalysis.Editor.Shared.Extensions; +using Microsoft.VisualStudio.Commanding; +using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Text.Editor.Commanding.Commands; + +namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename; + +internal abstract partial class AbstractRenameCommandHandler : + IChainedCommandHandler, + IChainedCommandHandler +{ + public CommandState GetCommandState(TabKeyCommandArgs args, Func nextHandler) + => GetCommandState(nextHandler); + + public void ExecuteCommand(TabKeyCommandArgs args, Action nextHandler, CommandExecutionContext context) + { + // If the Dashboard is focused, just navigate through its UI. + if (AdornmentShouldReceiveKeyboardNavigation(args.TextView)) + { + SetAdornmentFocusToNextElement(args.TextView); + return; + } + + HandlePossibleTypingCommand(args, nextHandler, context.OperationContext, (activeSession, _, span) => + { + var spans = new NormalizedSnapshotSpanCollection( + activeSession.GetBufferManager(args.SubjectBuffer) + .GetEditableSpansForSnapshot(args.SubjectBuffer.CurrentSnapshot)); + + for (var i = 0; i < spans.Count; i++) + { + if (span == spans[i]) + { + var selectNext = i < spans.Count - 1 ? i + 1 : 0; + var newSelection = spans[selectNext]; + args.TextView.TryMoveCaretToAndEnsureVisible(newSelection.Start); + args.TextView.SetSelection(newSelection); + break; + } + } + }); + } + + public CommandState GetCommandState(BackTabKeyCommandArgs args, Func nextHandler) + => GetCommandState(nextHandler); + + public void ExecuteCommand(BackTabKeyCommandArgs args, Action nextHandler, CommandExecutionContext context) + { + // If the Dashboard is focused, just navigate through its UI. + if (AdornmentShouldReceiveKeyboardNavigation(args.TextView)) + { + SetAdornmentFocusToPreviousElement(args.TextView); + return; + } + else + { + nextHandler(); + } + } +} diff --git a/src/EditorFeatures/Core/InlineRename/InlineRenameUIOptionsStorage.cs b/src/EditorFeatures/Core/InlineRename/InlineRenameUIOptionsStorage.cs index c91d0ce159cec..7ec8df35832b9 100644 --- a/src/EditorFeatures/Core/InlineRename/InlineRenameUIOptionsStorage.cs +++ b/src/EditorFeatures/Core/InlineRename/InlineRenameUIOptionsStorage.cs @@ -8,6 +8,7 @@ namespace Microsoft.CodeAnalysis.Editor.InlineRename; internal sealed class InlineRenameUIOptionsStorage { + public static readonly Option2 UseInlineAdornment = new("dotnet_rename_use_inline_adornment", defaultValue: true); public static readonly Option2 CollapseUI = new("dotnet_collapse_inline_rename_ui", defaultValue: false); public static readonly Option2 CollapseSuggestionsPanel = new("dotnet_collapse_suggestions_in_inline_rename_ui", defaultValue: false); public static readonly Option2 GetSuggestionsAutomatically = new("dotnet_rename_get_suggestions_automatically", defaultValue: false); diff --git a/src/EditorFeatures/Core/InlineRename/UndoManagerServiceFactory.cs b/src/EditorFeatures/Core/InlineRename/UndoManagerServiceFactory.cs index b02fe9f6c8f37..7bdb7f84c4d01 100644 --- a/src/EditorFeatures/Core/InlineRename/UndoManagerServiceFactory.cs +++ b/src/EditorFeatures/Core/InlineRename/UndoManagerServiceFactory.cs @@ -21,13 +21,15 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename; [ExportWorkspaceServiceFactory(typeof(IInlineRenameUndoManager), ServiceLayer.Default), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class UndoManagerServiceFactory(InlineRenameService inlineRenameService) : IWorkspaceServiceFactory +internal class UndoManagerServiceFactory(InlineRenameService inlineRenameService, IGlobalOptionService globalOptionService) : IWorkspaceServiceFactory { + private readonly InlineRenameService _inlineRenameService = inlineRenameService; + private readonly IGlobalOptionService _globalOptionService = globalOptionService; + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) - => new InlineRenameUndoManager(inlineRenameService); + => new InlineRenameUndoManager(_inlineRenameService, _globalOptionService); - internal sealed class InlineRenameUndoManager(InlineRenameService inlineRenameService) - : AbstractInlineRenameUndoManager(inlineRenameService), IInlineRenameUndoManager + internal class InlineRenameUndoManager(InlineRenameService inlineRenameService, IGlobalOptionService globalOptionService) : AbstractInlineRenameUndoManager(inlineRenameService, globalOptionService), IInlineRenameUndoManager { internal class BufferUndoState { diff --git a/src/EditorFeatures/Core/IntelliSense/QuickInfo/QuickInfoSourceProvider.QuickInfoSource.cs b/src/EditorFeatures/Core/IntelliSense/QuickInfo/QuickInfoSourceProvider.QuickInfoSource.cs index a9f81429bb583..57019ea4d2bac 100644 --- a/src/EditorFeatures/Core/IntelliSense/QuickInfo/QuickInfoSourceProvider.QuickInfoSource.cs +++ b/src/EditorFeatures/Core/IntelliSense/QuickInfo/QuickInfoSourceProvider.QuickInfoSource.cs @@ -24,6 +24,7 @@ using Microsoft.VisualStudio.Utilities; using IntellisenseQuickInfoItem = Microsoft.VisualStudio.Language.Intellisense.QuickInfoItem; +using Microsoft.CodeAnalysis.Editor.InlineRename; namespace Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.QuickInfo; @@ -51,7 +52,7 @@ public async Task GetQuickInfoItemAsync(IAsyncQuickIn // Until https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1611398 is resolved we can't disable // quickinfo in InlineRename. Instead, we return no quickinfo information while the adornment // is being shown. This can be removed after IFeaturesService supports disabling quickinfo - if (_inlineRenameService.ActiveSession is not null) + if (_editorOptionsService.GlobalOptions.GetOption(InlineRenameUIOptionsStorage.UseInlineAdornment) && _inlineRenameService.ActiveSession is not null) return null; var triggerPoint = session.GetTriggerPoint(_subjectBuffer.CurrentSnapshot); diff --git a/src/EditorFeatures/Test2/Rename/RenameCommandHandlerTests.vb b/src/EditorFeatures/Test2/Rename/RenameCommandHandlerTests.vb index 472194cbdf9f0..5743c6ceae7db 100644 --- a/src/EditorFeatures/Test2/Rename/RenameCommandHandlerTests.vb +++ b/src/EditorFeatures/Test2/Rename/RenameCommandHandlerTests.vb @@ -218,6 +218,50 @@ End Class End Using End Sub + + + Public Async Function TypingTabDuringRename(host As RenameTestHost) As Task + Using workspace = CreateWorkspaceWithWaiter( + + + + class $$Goo + { + Goo f; + } + + + , host) + + ' This test specifically matters for the case where a user is typing in the editor + ' and is not intended to test the rename flyout tab behavior + Dim optionsService = workspace.GetService(Of IGlobalOptionService)() + optionsService.SetGlobalOption(InlineRenameUIOptionsStorage.UseInlineAdornment, False) + + Dim view = workspace.Documents.Single().GetTextView() + view.Caret.MoveTo(New SnapshotPoint(view.TextBuffer.CurrentSnapshot, workspace.Documents.Single(Function(d) d.CursorPosition.HasValue).CursorPosition.Value)) + + Dim commandHandler = CreateCommandHandler(workspace) + + Dim session = StartSession(workspace) + + ' TODO: should we make tab wait instead? + Await WaitForRename(workspace) + + ' Unfocus the dashboard + Dim dashboard = DirectCast(view.GetAdornmentLayer("RoslynRenameDashboard").Elements(0).Adornment, RenameDashboard) + dashboard.ShouldReceiveKeyboardNavigation = False + + commandHandler.ExecuteCommand(New TabKeyCommandArgs(view, view.TextBuffer), + Sub() AssertEx.Fail("Tab should not have been passed to the editor."), + Utilities.TestCommandExecutionContext.Create()) + + Assert.Equal(3, view.Caret.Position.BufferPosition.GetContainingLineNumber()) + + session.Cancel() + End Using + End Function + Public Async Function SelectAllDuringRename(host As RenameTestHost) As Task diff --git a/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml b/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml index f656217d8d886..24b834f2613be 100644 --- a/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml +++ b/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml @@ -103,6 +103,16 @@ + + diff --git a/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml.cs b/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml.cs index 350f05c4f3c99..7b05d1dec46e3 100644 --- a/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml.cs +++ b/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml.cs @@ -77,6 +77,7 @@ public AdvancedOptionPageControl(OptionStore optionStore) : base(optionStore) // Rename BindToOption(Rename_asynchronously_exerimental, InlineRenameSessionOptionsStorage.CommitRenameAsynchronously); + BindToOption(Rename_UI_setting, InlineRenameUIOptionsStorage.UseInlineAdornment, label: Rename_UI_setting_label); // Using Directives BindToOption(PlaceSystemNamespaceFirst, GenerationOptions.PlaceSystemNamespaceFirst, LanguageNames.CSharp); diff --git a/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageStrings.cs b/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageStrings.cs index dbd71053d7fe8..a876aede7e26e 100644 --- a/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageStrings.cs +++ b/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageStrings.cs @@ -376,6 +376,15 @@ public static string Option_Rename public static string Option_Rename_asynchronously_experimental => ServicesVSResources.Rename_asynchronously_experimental; + public static string Where_should_the_rename_UI_be_shown + => ServicesVSResources.Where_should_the_rename_UI_be_shown; + + public static string Option_Show_UI_inline + => ServicesVSResources.Show_UI_inline; + + public static string Option_Show_UI_as_dashboard_in_top_right + => ServicesVSResources.Show_UI_as_dashboard_in_top_right; + public static string Document_Outline => ServicesVSResources.Document_Outline; diff --git a/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs b/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs index a629930c5c2e3..aaec75d39251e 100644 --- a/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs +++ b/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs @@ -15,6 +15,7 @@ using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Options; using Microsoft.VisualStudio.Editor; using Microsoft.VisualStudio.OLE.Interop; using Microsoft.VisualStudio.Text; @@ -27,16 +28,28 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.InlineRename; using Workspace = Microsoft.CodeAnalysis.Workspace; [ExportWorkspaceServiceFactory(typeof(IInlineRenameUndoManager), ServiceLayer.Host), Shared] -[method: ImportingConstructor] -[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class VisualStudioInlineRenameUndoManagerServiceFactory( - InlineRenameService inlineRenameService, - IVsEditorAdaptersFactoryService editorAdaptersFactoryService) : IWorkspaceServiceFactory +internal sealed class VisualStudioInlineRenameUndoManagerServiceFactory : IWorkspaceServiceFactory { + private readonly InlineRenameService _inlineRenameService; + private readonly IVsEditorAdaptersFactoryService _editorAdaptersFactoryService; + private readonly IGlobalOptionService _globalOptionService; + + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public VisualStudioInlineRenameUndoManagerServiceFactory( + InlineRenameService inlineRenameService, + IVsEditorAdaptersFactoryService editorAdaptersFactoryService, + IGlobalOptionService globalOptionService) + { + _inlineRenameService = inlineRenameService; + _editorAdaptersFactoryService = editorAdaptersFactoryService; + _globalOptionService = globalOptionService; + } + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) - => new InlineRenameUndoManager(inlineRenameService, editorAdaptersFactoryService); + => new InlineRenameUndoManager(_inlineRenameService, _editorAdaptersFactoryService, _globalOptionService); - internal sealed class InlineRenameUndoManager(InlineRenameService inlineRenameService, IVsEditorAdaptersFactoryService editorAdaptersFactoryService) : AbstractInlineRenameUndoManager(inlineRenameService), IInlineRenameUndoManager + internal class InlineRenameUndoManager : AbstractInlineRenameUndoManager, IInlineRenameUndoManager { private class RenameUndoPrimitive : IOleUndoUnit { @@ -81,7 +94,10 @@ internal class BufferUndoState public ITextBuffer UndoHistoryBuffer { get; set; } } - private readonly IVsEditorAdaptersFactoryService _editorAdaptersFactoryService = editorAdaptersFactoryService; + private readonly IVsEditorAdaptersFactoryService _editorAdaptersFactoryService; + + public InlineRenameUndoManager(InlineRenameService inlineRenameService, IVsEditorAdaptersFactoryService editorAdaptersFactoryService, IGlobalOptionService globalOptionService) : base(inlineRenameService, globalOptionService) + => _editorAdaptersFactoryService = editorAdaptersFactoryService; public void CreateStartRenameUndoTransaction(Workspace workspace, ITextBuffer subjectBuffer, IInlineRenameSession inlineRenameSession) { diff --git a/src/VisualStudio/Core/Def/Options/VisualStudioOptionStorage.cs b/src/VisualStudio/Core/Def/Options/VisualStudioOptionStorage.cs index 79e618b1f14e1..63aab8f719204 100644 --- a/src/VisualStudio/Core/Def/Options/VisualStudioOptionStorage.cs +++ b/src/VisualStudio/Core/Def/Options/VisualStudioOptionStorage.cs @@ -337,6 +337,7 @@ public bool TryFetch(LocalUserRegistryOptionPersister persister, OptionKey2 opti {"dotnet_suppress_inlay_hints_for_parameters_that_match_argument_name", new RoamingProfileStorage("TextEditor.%LANGUAGE%.Specific.InlineParameterNameHints.SuppressForParametersThatMatchArgumentName")}, {"dotnet_suppress_inlay_hints_for_parameters_that_match_method_intent", new RoamingProfileStorage("TextEditor.%LANGUAGE%.Specific.InlineParameterNameHints.SuppressForParametersThatMatchMethodIntent")}, {"dotnet_collapse_inline_rename_ui", new RoamingProfileStorage("TextEditor.CollapseRenameUI")}, + {"dotnet_rename_use_inline_adornment", new RoamingProfileStorage("TextEditor.RenameUseInlineAdornment")}, {"dotnet_preview_inline_rename_changes", new RoamingProfileStorage("TextEditor.Specific.PreviewRename")}, {"dotnet_collapse_suggestions_in_inline_rename_ui", new RoamingProfileStorage("TextEditor.CollapseRenameSuggestionsUI")}, {"dotnet_commit_rename_asynchronously", new RoamingProfileStorage("TextEditor.Specific.CommitRenameAsynchronously")}, diff --git a/src/VisualStudio/Core/Def/ServicesVSResources.resx b/src/VisualStudio/Core/Def/ServicesVSResources.resx index 7da15a9e6f316..e009d3c6c76bf 100644 --- a/src/VisualStudio/Core/Def/ServicesVSResources.resx +++ b/src/VisualStudio/Core/Def/ServicesVSResources.resx @@ -1721,6 +1721,18 @@ Additional information: {1} Extract Base Record {Locked="Record"} "Record" is a language construct for C# and should not be localized + + Show UI as a dashboard in top right + "UI" is an acronym for "User Interface" + + + Show UI Inline + "UI" is an acronym for "User Interface" + + + Where should the rename UI be shown? + "UI" is an acronym for "User Interface" + Prefer read-only struct diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf index 62a46a9974372..8a62f08c81a55 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf @@ -1342,6 +1342,16 @@ Zobrazit příkaz Odebrat nepoužívané odkazy v Průzkumníkovi řešení + + Show UI as a dashboard in top right + Zobrazit uživatelské rozhraní jako řídicí panel v pravém horním rohu + "UI" is an acronym for "User Interface" + + + Show UI Inline + Zobrazit vložené uživatelské rozhraní + "UI" is an acronym for "User Interface" + Show compiler errors and warnings for: Zobrazit chyby a upozornění kompilátoru pro: @@ -1717,6 +1727,11 @@ Když se typy volně shodují + + Where should the rename UI be shown? + Kde by se mělo zobrazit uživatelské rozhraní pro přejmenování? + "UI" is an acronym for "User Interface" + Whitespace Prázdné znaky diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf index bab6218f62608..8fe62267bb4ae 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf @@ -1342,6 +1342,16 @@ Befehl „Nicht verwendete Verweise entfernen“ in Projektmappen-Explorer anzeigen + + Show UI as a dashboard in top right + Benutzeroberfläche als Dashboard oben rechts anzeigen + "UI" is an acronym for "User Interface" + + + Show UI Inline + Inline der Benutzeroberfläche anzeigen + "UI" is an acronym for "User Interface" + Show compiler errors and warnings for: Compilerfehler und -warnungen anzeigen für: @@ -1717,6 +1727,11 @@ Wenn Typen lose übereinstimmen + + Where should the rename UI be shown? + Wo sollte die Benutzeroberfläche zum Umbenennen angezeigt werden? + "UI" is an acronym for "User Interface" + Whitespace Leerstelle diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf index 9a14f3acea492..ca9cb1ad5a59d 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf @@ -1342,6 +1342,16 @@ Mostrar el comando "Quitar referencias sin usar" en Explorador de soluciones + + Show UI as a dashboard in top right + Mostrar la interfaz de usuario como un panel en la parte superior derecha + "UI" is an acronym for "User Interface" + + + Show UI Inline + Mostrar interfaz de usuario insertada + "UI" is an acronym for "User Interface" + Show compiler errors and warnings for: Mostrar errores y advertencias del compilador para: @@ -1717,6 +1727,11 @@ Cuando los tipos coinciden ligeramente + + Where should the rename UI be shown? + ¿Dónde se debe mostrar la interfaz de usuario de cambio de nombre? + "UI" is an acronym for "User Interface" + Whitespace Espacio en blanco diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf index 974900d486a24..31bba5a18c10d 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf @@ -1342,6 +1342,16 @@ Afficher la commande « Supprimer les références inutilisées » dans l’Explorateur de solutions + + Show UI as a dashboard in top right + Afficher l’interface utilisateur en tant que tableau de bord en haut à droite + "UI" is an acronym for "User Interface" + + + Show UI Inline + Afficher l’interface utilisateur inline + "UI" is an acronym for "User Interface" + Show compiler errors and warnings for: Afficher les erreurs et avertissements du compilateur pour : @@ -1717,6 +1727,11 @@ Lorsque les types correspondent peu + + Where should the rename UI be shown? + Où l’interface utilisateur de changement de nom doit-elle être affichée? + "UI" is an acronym for "User Interface" + Whitespace Espaces blancs diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf index 0751d9cebeb34..9f04c08e77dc5 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf @@ -1342,6 +1342,16 @@ Mostra il comando "Rimuovi riferimenti inutilizzati" in Esplora soluzioni + + Show UI as a dashboard in top right + Mostra l'interfaccia utente come dashboard in alto a destra + "UI" is an acronym for "User Interface" + + + Show UI Inline + Mostra interfaccia utente inline + "UI" is an acronym for "User Interface" + Show compiler errors and warnings for: Mostra errori e avvisi del compilatore per: @@ -1717,6 +1727,11 @@ Quando i tipi corrispondono liberamente + + Where should the rename UI be shown? + Dove deve essere visualizzata l'interfaccia utente di ridenominazione? + "UI" is an acronym for "User Interface" + Whitespace Spazio vuoto diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf index 593f144483109..ae2fac8026e92 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf @@ -1342,6 +1342,16 @@ ソリューション エクスプローラーで [未使用の参照を削除する] コマンドを表示する + + Show UI as a dashboard in top right + 右上にダッシュボードとして UI を表示する + "UI" is an acronym for "User Interface" + + + Show UI Inline + UI インラインの表示 + "UI" is an acronym for "User Interface" + Show compiler errors and warnings for: 次のコンパイラ エラーと警告を表示する: @@ -1717,6 +1727,11 @@ 型が緩やかに一致する場合 + + Where should the rename UI be shown? + 名前変更 UI はどこに表示されますか? + "UI" is an acronym for "User Interface" + Whitespace 空白 diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf index 4acc19784266d..5d8f3512f31bf 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf @@ -1342,6 +1342,16 @@ 솔루션 탐색기에서 "사용하지 않는 참조 제거" 명령 표시 + + Show UI as a dashboard in top right + 오른쪽 위에 대시보드로 UI 표시 + "UI" is an acronym for "User Interface" + + + Show UI Inline + UI 인라인 표시 + "UI" is an acronym for "User Interface" + Show compiler errors and warnings for: 다음에 대한 컴파일러 오류 및 경고 표시: @@ -1717,6 +1727,11 @@ 형식이 느슨하게 일치하는 경우 + + Where should the rename UI be shown? + 이름 바꾸기 UI는 어디에 표시되어야 하나요? + "UI" is an acronym for "User Interface" + Whitespace 공백 diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf index a425bb31b397e..230d97c2499e1 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf @@ -1342,6 +1342,16 @@ Pokaż polecenie „Usuń nieużywane odwołania” w Eksploratorze rozwiązań + + Show UI as a dashboard in top right + Pokaż interfejs użytkownika jako pulpit nawigacyjny w prawym górnym rogu + "UI" is an acronym for "User Interface" + + + Show UI Inline + Pokaż wbudowany interfejs użytkownika + "UI" is an acronym for "User Interface" + Show compiler errors and warnings for: Pokaż błędy i ostrzeżenia kompilatora dla: @@ -1717,6 +1727,11 @@ Gdy typy są luźno zgodne + + Where should the rename UI be shown? + Gdzie powinien być wyświetlany interfejs użytkownika zmiany nazwy? + "UI" is an acronym for "User Interface" + Whitespace Odstępy diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf index c39020eb0283b..03a4c8c8b5108 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf @@ -1342,6 +1342,16 @@ Mostrar o comando "Remover Referências Não Utilizadas" no Gerenciador de Soluções + + Show UI as a dashboard in top right + Mostrar interface do usuário como um painel no canto superior direito + "UI" is an acronym for "User Interface" + + + Show UI Inline + Mostrar IU Embutida + "UI" is an acronym for "User Interface" + Show compiler errors and warnings for: Mostrar erros e alertas do compilador para: @@ -1717,6 +1727,11 @@ Quando os tipos correspondem vagamente + + Where should the rename UI be shown? + Onde a interface do usuário de renomeação deve ser mostrada? + "UI" is an acronym for "User Interface" + Whitespace Espaço em branco diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf index 028127470ae75..0134d57fa3e6e 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf @@ -1342,6 +1342,16 @@ Показывать команду "Удалить неиспользуемые ссылки" в Обозревателе решений + + Show UI as a dashboard in top right + Показывать пользовательский интерфейс как информационную панель в правом верхнем углу + "UI" is an acronym for "User Interface" + + + Show UI Inline + Показывать встроенный пользовательский интерфейс + "UI" is an acronym for "User Interface" + Show compiler errors and warnings for: Показывать ошибки и предупреждения компилятора для: @@ -1717,6 +1727,11 @@ При слабом совпадении типов + + Where should the rename UI be shown? + Где следует показывать пользовательский интерфейс переименования? + "UI" is an acronym for "User Interface" + Whitespace Пустое пространство diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf index e714666534bb4..3091e2a0b5925 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf @@ -1342,6 +1342,16 @@ Çözüm Gezgini'nde "Kullanılmayan Başvuruları Kaldır" komutunu göster + + Show UI as a dashboard in top right + UI öğesini sağ üstte pano olarak göster + "UI" is an acronym for "User Interface" + + + Show UI Inline + UI Satır İçini Göster + "UI" is an acronym for "User Interface" + Show compiler errors and warnings for: Şunun için derleyici hatalarını ve uyarılarını göster: @@ -1717,6 +1727,11 @@ Türler yaklaşık olarak eşleştiğinde + + Where should the rename UI be shown? + Yeniden adlandırma UI öğesi nerede gösterilmeli? + "UI" is an acronym for "User Interface" + Whitespace Boşluk diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf index edf3a98da79ae..4e03a034e1223 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf @@ -1342,6 +1342,16 @@ 在解决方案资源管理器中显示“删除未使用的引用”命令 + + Show UI as a dashboard in top right + 将 UI 显示为右上角的仪表板 + "UI" is an acronym for "User Interface" + + + Show UI Inline + 显示 UI 内联 + "UI" is an acronym for "User Interface" + Show compiler errors and warnings for: 显示以下的编译器错误和警告: @@ -1717,6 +1727,11 @@ 当类型宽松匹配时 + + Where should the rename UI be shown? + 重命名 UI 应显示在何处? + "UI" is an acronym for "User Interface" + Whitespace 空格 diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf index a974c700370b7..1b04c7be7a707 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf @@ -1342,6 +1342,16 @@ 在方案總管中顯示「移除未使用的參考」命令 + + Show UI as a dashboard in top right + 將 UI 顯示為右上方的儀表板 + "UI" is an acronym for "User Interface" + + + Show UI Inline + 顯示 UI 內嵌 + "UI" is an acronym for "User Interface" + Show compiler errors and warnings for: 顯示編譯器錯誤和警告: @@ -1717,6 +1727,11 @@ 當類型鬆散相符時 + + Where should the rename UI be shown? + 重新命名 UI 應該顯示在何處? + "UI" is an acronym for "User Interface" + Whitespace 空白 diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpAutomaticBraceCompletion.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpAutomaticBraceCompletion.cs index aa4636b489ee9..6e9b9c57730d9 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpAutomaticBraceCompletion.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpAutomaticBraceCompletion.cs @@ -24,7 +24,7 @@ public CSharpAutomaticBraceCompletion() { } - [IdeTheory(Skip = "https://github.com/dotnet/roslyn/issues/63576"), CombinatorialData] + [IdeTheory, CombinatorialData] public async Task Braces_InsertionAndTabCompleting(bool showCompletionInArgumentLists) { await SetUpEditorAsync(@" @@ -376,7 +376,7 @@ void M() await TestServices.EditorVerifier.CurrentLineTextAsync(" var v = @$\"$$", assertCaretPosition: true, HangMitigatingCancellationToken); } - [IdeTheory(Skip = "https://github.com/dotnet/roslyn/issues/63576"), CombinatorialData] + [IdeTheory, CombinatorialData] public async Task AngleBracket_PossibleGenerics_InsertionAndCompletion(bool showCompletionInArgumentLists) { await SetUpEditorAsync(@" @@ -385,6 +385,11 @@ class C { $$ }", HangMitigatingCancellationToken); + // Disable new rename UI for now, it's causing these tests to fail. + // https://github.com/dotnet/roslyn/issues/63576 + var globalOptions = await TestServices.Shell.GetComponentModelServiceAsync(HangMitigatingCancellationToken); + globalOptions.SetGlobalOption(InlineRenameUIOptionsStorage.UseInlineAdornment, false); + await TestServices.Workspace.SetTriggerCompletionInArgumentListsAsync(LanguageNames.CSharp, showCompletionInArgumentLists, HangMitigatingCancellationToken); await TestServices.Input.SendWithoutActivateAsync(["System.Action<", VirtualKeyCode.TAB], HangMitigatingCancellationToken); diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpRename.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpRename.cs index 50e3b2a8fa59d..edd87ecde682c 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpRename.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpRename.cs @@ -36,6 +36,7 @@ public override async Task InitializeAsync() // reset relevant global options to default values: var globalOptions = await TestServices.Shell.GetComponentModelServiceAsync(HangMitigatingCancellationToken); + globalOptions.SetGlobalOption(InlineRenameUIOptionsStorage.UseInlineAdornment, false); globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.RenameInComments, false); globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.RenameInStrings, false); globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.RenameOverloads, false); @@ -668,6 +669,8 @@ static void Main(string[] args) [IdeFact] public async Task VerifyTextSync() { + var globalOptions = await TestServices.Shell.GetComponentModelServiceAsync(HangMitigatingCancellationToken); + globalOptions.SetGlobalOption(InlineRenameUIOptionsStorage.UseInlineAdornment, true); await TestServices.SolutionExplorer.AddFileAsync(ProjectName, "Program.cs", """ public class Class2 @@ -706,6 +709,8 @@ public class Class2 [IdeFact, WorkItem("https://github.com/dotnet/roslyn/issues/68374")] public async Task VerifySelectionAsync() { + var globalOptions = await TestServices.Shell.GetComponentModelServiceAsync(HangMitigatingCancellationToken); + globalOptions.SetGlobalOption(InlineRenameUIOptionsStorage.UseInlineAdornment, true); var startCode = """ public class Class2 { @@ -746,6 +751,8 @@ public class Class2 [IdeFact(Skip = "https://github.com/dotnet/roslyn/issues/73630"), WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1903953/")] public async Task VerifyRenameLinkedDocumentsAsync() { + var globalOptions = await TestServices.Shell.GetComponentModelServiceAsync(HangMitigatingCancellationToken); + globalOptions.SetGlobalOption(InlineRenameUIOptionsStorage.UseInlineAdornment, true); var projectName = "MultiTFMProject"; await TestServices.SolutionExplorer.AddCustomProjectAsync(projectName, ".csproj", """ @@ -799,12 +806,16 @@ void Method() await TestServices.SolutionExplorer.GetProjectItemAsync(projectName, "MyTestClass.cs", HangMitigatingCancellationToken); } - [IdeFact] - public async Task VerifyAsyncRename() + [CombinatorialData] + [IdeTheory] + public async Task VerifyAsyncRename(bool useInlineRename) { var globalOptions = await TestServices.Shell.GetComponentModelServiceAsync(HangMitigatingCancellationToken); globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.CommitRenameAsynchronously, true); + if (!useInlineRename) + globalOptions.SetGlobalOption(InlineRenameUIOptionsStorage.UseInlineAdornment, false); + var markup = """ class Program { diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/InlineRenameInProcess.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/InlineRenameInProcess.cs index bf0576e39f6e4..94712072f37ef 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/InlineRenameInProcess.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/InlineRenameInProcess.cs @@ -46,6 +46,14 @@ public async Task ToggleIncludeOverloadsAsync(CancellationToken cancellationToke public async Task VerifyStringInFlyout(string expected, CancellationToken cancellationToken) { + var optionService = await GetComponentModelServiceAsync(cancellationToken); + var isRenameFlyoutEnabled = optionService.GetOption(InlineRenameUIOptionsStorage.UseInlineAdornment); + if (!isRenameFlyoutEnabled) + { + Contract.Fail("Inline rename flyout is disabled"); + return; + } + var vsTextManager = await GetRequiredGlobalServiceAsync(cancellationToken); var vsTextView = await vsTextManager.GetActiveViewAsync(JoinableTaskFactory, cancellationToken); var testViewHost = await vsTextView.GetTextViewHostAsync(JoinableTaskFactory, cancellationToken); diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/StateResetInProcess.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/StateResetInProcess.cs index 2e88952748a4b..e1335433d99be 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/StateResetInProcess.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/StateResetInProcess.cs @@ -62,6 +62,7 @@ public async Task ResetGlobalOptionsAsync(CancellationToken cancellationToken) ResetOption(globalOptions, InlineRenameSessionOptionsStorage.RenameInComments); ResetOption(globalOptions, InlineRenameSessionOptionsStorage.RenameInStrings); ResetOption(globalOptions, InlineRenameSessionOptionsStorage.RenameOverloads); + ResetOption(globalOptions, InlineRenameUIOptionsStorage.UseInlineAdornment); ResetOption(globalOptions, MetadataAsSourceOptionsStorage.NavigateToDecompiledSources); ResetOption(globalOptions, WorkspaceConfigurationOptionsStorage.SourceGeneratorExecution); ResetPerLanguageOption(globalOptions, FormattingOptions2.IndentationSize); diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicAutomaticBraceCompletion.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicAutomaticBraceCompletion.cs index 39a1d5d27cdb5..9efb2d4c46f0a 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicAutomaticBraceCompletion.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicAutomaticBraceCompletion.cs @@ -32,6 +32,10 @@ public async Task Braces_InsertionAndTabCompleting(bool argumentCompletion) var globalOptions = await TestServices.Shell.GetComponentModelServiceAsync(HangMitigatingCancellationToken); globalOptions.SetGlobalOption(CompletionViewOptionsStorage.EnableArgumentCompletionSnippets, LanguageNames.VisualBasic, argumentCompletion); + // Disable new rename UI for now, it's causing these tests to fail. + // https://github.com/dotnet/roslyn/issues/63576 + globalOptions.SetGlobalOption(InlineRenameUIOptionsStorage.UseInlineAdornment, false); + await SetUpEditorAsync(@" Class C Sub Goo() @@ -193,9 +197,14 @@ End Sub await TestServices.EditorVerifier.CurrentLineTextAsync(" Dim [Dim] As Long$$", assertCaretPosition: true, HangMitigatingCancellationToken); } - [IdeFact(Skip = "https://github.com/dotnet/roslyn/issues/63576")] + [IdeFact] public async Task DoubleQuote_InsertionAndTabCompletion() { + // Disable new rename UI for now, it's causing these tests to fail. + // https://github.com/dotnet/roslyn/issues/63576 + var globalOptions = await TestServices.Shell.GetComponentModelServiceAsync(HangMitigatingCancellationToken); + globalOptions.SetGlobalOption(InlineRenameUIOptionsStorage.UseInlineAdornment, false); + await SetUpEditorAsync(@" Class C Sub Goo() diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicRename.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicRename.cs index a32e145260389..44b774df38703 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicRename.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicRename.cs @@ -33,6 +33,7 @@ public override async Task InitializeAsync() // reset relevant global options to default values: var globalOptions = await TestServices.Shell.GetComponentModelServiceAsync(HangMitigatingCancellationToken); + globalOptions.SetGlobalOption(InlineRenameUIOptionsStorage.UseInlineAdornment, false); globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.RenameInComments, false); globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.RenameInStrings, false); globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.RenameOverloads, false); diff --git a/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml b/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml index 8cffe98344eaa..816f045c59e68 100644 --- a/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml +++ b/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml @@ -91,6 +91,16 @@ + + diff --git a/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml.vb b/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml.vb index 74fdd6797b2a7..289fd7463d7f8 100644 --- a/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml.vb +++ b/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml.vb @@ -77,6 +77,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options ' Rename BindToOption(Rename_asynchronously_exerimental, InlineRenameSessionOptionsStorage.CommitRenameAsynchronously) + BindToOption(Rename_UI_setting, InlineRenameUIOptionsStorage.UseInlineAdornment, label:=Rename_UI_setting_label) ' Import directives BindToOption(PlaceSystemNamespaceFirst, GenerationOptions.PlaceSystemNamespaceFirst, LanguageNames.VisualBasic) diff --git a/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageStrings.vb b/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageStrings.vb index 20a7a1ef70176..bf6c8ac4a0085 100644 --- a/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageStrings.vb +++ b/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageStrings.vb @@ -349,6 +349,15 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options Public ReadOnly Property Option_Rename_asynchronously_experimental As String = ServicesVSResources.Rename_asynchronously_experimental + Public ReadOnly Property Where_should_the_rename_UI_be_shown As String = + ServicesVSResources.Where_should_the_rename_UI_be_shown + + Public ReadOnly Property Option_Show_UI_inline As String = + ServicesVSResources.Show_UI_inline + + Public ReadOnly Property Option_Show_UI_as_dashboard_in_top_right As String = + ServicesVSResources.Show_UI_as_dashboard_in_top_right + Public ReadOnly Property Document_Outline As String = ServicesVSResources.Document_Outline