Repository: microsoft/terminal (language: cpp)

Issue:
Command palette  goes to the top when you go back (<) from a submenu
As the subject says, if I open a submenu of the command palette (e.g., "New tab") and go back via the <-button, I'm back at the top of the command palette.  I'd prefer to be back where I was.  It's not a bug, but the bahavior could be made more friendly.



Discussion / hints:
Hmm this is in #5400, I'm pretty sure it's a full issue somewhere too

> The "go back" button should pop only one layer of the stack, not go all the way back to the root (https://github.com/microsoft/terminal/pull/8051#issuecomment-722045813)
I guess that's a matter of terminology.  The actual behavior and my desired behavior both go back to the command palette.  It's the position in the command palette after going back that concerns me ... back to the beginning of the command palette or back to where I was.
@zadjii-msft, I would be happy to work on this as my first contribution to this repo (if possible). I assume the desired result is to focus the filtered view to the previously selected item when returning from a nested collection?

![image](https://user-images.githubusercontent.com/27634653/178750016-6adf00ba-6cc2-4558-b9ba-4ccfcce37115.png)

That's what I would do, yea! Lemme know if you have any questions. This line: https://github.com/microsoft/terminal/blob/574a72b505a682a09ea9d533295d3d576556e6c0/src/cascadia/TerminalApp/CommandPalette.cpp#L539 is where I'd start ☺️ 

Fix patch:
diff --git a/src/cascadia/TerminalApp/CommandPalette.cpp b/src/cascadia/TerminalApp/CommandPalette.cpp
index 1bc72516d66..1b2089b642d 100644
--- a/src/cascadia/TerminalApp/CommandPalette.cpp
+++ b/src/cascadia/TerminalApp/CommandPalette.cpp
@@ -525,9 +525,9 @@ namespace winrt::TerminalApp::implementation
     }
 
     // Method Description:
-    // This event is called when the user clicks on an ChevronLeft button right
+    // This event is called when the user clicks on a ChevronLeft button right
     // next to the ParentCommandName (e.g. New Tab...) above the subcommands list.
-    // It'll go up a level when the users click the button.
+    // It'll go up a single level when the user clicks the button.
     // Arguments:
     // - sender: the button that got clicked
     // Return Value:
@@ -536,12 +536,32 @@ namespace winrt::TerminalApp::implementation
                                                 const Windows::UI::Xaml::RoutedEventArgs&)
     {
         _PreviewActionHandlers(*this, nullptr);
-        _nestedActionStack.Clear();
-        ParentCommandName(L"");
-        _currentNestedCommands.Clear();
         _searchBox().Focus(FocusState::Programmatic);
+
+        const auto previousAction{ _nestedActionStack.GetAt(_nestedActionStack.Size() - 1) };
+        _nestedActionStack.RemoveAtEnd();
+
+        // Repopulate nested commands when the root has not been reached yet
+        if (_nestedActionStack.Size() > 0)
+        {
+            const auto newPreviousAction{ _nestedActionStack.GetAt(_nestedActionStack.Size() - 1) };
+            const auto actionPaletteItem{ newPreviousAction.Item().try_as<winrt::TerminalApp::ActionPaletteItem>() };
+
+            ParentCommandName(actionPaletteItem.Command().Name());
+            _updateCurrentNestedCommands(actionPaletteItem.Command());
+        }
+        else
+        {
+            ParentCommandName(L"");
+            _currentNestedCommands.Clear();
+        }
         _updateFilteredActions();
-        _filteredActionsView().SelectedIndex(0);
+
+        const auto lastSelectedIt = std::find_if(begin(_filteredActions), end(_filteredActions), [&](const auto& filteredCommand) {
+            return filteredCommand.Item().Name() == previousAction.Item().Name();
+        });
+        const auto lastSelectedIndex = static_cast<int32_t>(std::distance(begin(_filteredActions), lastSelectedIt));
+        _scrollToIndex(lastSelectedIt != end(_filteredActions) ? lastSelectedIndex : 0);
     }
 
     // Method Description:
@@ -639,14 +659,7 @@ namespace winrt::TerminalApp::implementation
                     // to pick from.
                     _nestedActionStack.Append(filteredCommand);
                     ParentCommandName(actionPaletteItem.Command().Name());
-                    _currentNestedCommands.Clear();
-                    for (const auto& nameAndCommand : actionPaletteItem.Command().NestedCommands())
-                    {
-                        const auto action = nameAndCommand.Value();
-                        auto nestedActionPaletteItem{ winrt::make<winrt::TerminalApp::implementation::ActionPaletteItem>(action) };
-                        auto nestedFilteredCommand{ winrt::make<FilteredCommand>(nestedActionPaletteItem) };
-                        _currentNestedCommands.Append(nestedFilteredCommand);
-                    }
+                    _updateCurrentNestedCommands(actionPaletteItem.Command());
 
                     _updateUIForStackChange();
                 }
@@ -1108,6 +1121,25 @@ namespace winrt::TerminalApp::implementation
         }
     }
 
+    // Method Description:
+    // - Update the list of current nested commands to match that of the
+    //   given parent command.
+    // Arguments:
+    // - parentCommand: the command with an optional list of nested commands.
+    // Return Value:
+    // - <none>
+    void CommandPalette::_updateCurrentNestedCommands(const winrt::Microsoft::Terminal::Settings::Model::Command& parentCommand)
+    {
+        _currentNestedCommands.Clear();
+        for (const auto& nameAndCommand : parentCommand.NestedCommands())
+        {
+            const auto action = nameAndCommand.Value();
+            auto nestedActionPaletteItem{ winrt::make<winrt::TerminalApp::implementation::ActionPaletteItem>(action) };
+            auto nestedFilteredCommand{ winrt::make<FilteredCommand>(nestedActionPaletteItem) };
+            _currentNestedCommands.Append(nestedFilteredCommand);
+        }
+    }
+
     // Method Description:
     // - Dismiss the command palette. This will:
     //   * select all the current text in the input box
diff --git a/src/cascadia/TerminalApp/CommandPalette.h b/src/cascadia/TerminalApp/CommandPalette.h
index ebf32d3594b..bf30258d74f 100644
--- a/src/cascadia/TerminalApp/CommandPalette.h
+++ b/src/cascadia/TerminalApp/CommandPalette.h
@@ -96,6 +96,8 @@ namespace winrt::TerminalApp::implementation
 
         void _updateFilteredActions();
 
+        void _updateCurrentNestedCommands(const winrt::Microsoft::Terminal::Settings::Model::Command& parentCommand);
+
         std::vector<winrt::TerminalApp::FilteredCommand> _collectFilteredActions();
 
         void _close();


Test patch: