This entirely removes `KeyMapping` from the settings model, and builds on the work done in #9543 to consolidate all actions (key bindings and commands) into a unified data structure (`ActionMap`).
## References
#9428 - Spec
#6900 - Actions page
Closes#7441
## Detailed Description of the Pull Request / Additional comments
The important thing here is to remember that we're shifting our philosophy of how to interact/represent actions. Prior to this, the actions arrays in the JSON would be deserialized twice: once for key bindings, and again for commands. By thinking of every entry in the relevant JSON as a `Command`, we can remove a lot of the context switching between working with a key binding vs a command palette item.
#9543 allows us to make that shift. Given the work in that PR, we can now deserialize all of the relevant information from each JSON action item. This allows us to simplify `ActionMap::FromJson` to simply iterate over each JSON action item, deserialize it, and add it to our `ActionMap`.
Internally, our `ActionMap` operates as discussed in #9428 by maintaining a `_KeyMap` that points to an action ID, and using that action ID to retrieve the `Command` from the `_ActionMap`. Adding actions to the `ActionMap` automatically accounts for name/key-chord collisions. A `NameMap` can be constructed when requested; this is for the Command Palette.
Querying the `ActionMap` is fairly straightforward. Helper functions were needed to be able to distinguish an explicit unbinding vs the command not being found in the current layer. Internally, we store explicitly unbound names/key-chords as `ShortcutAction::Invalid` commands. However, we return `nullptr` when a query points to an unbound command. This is done to hide this complexity away from any caller.
The command palette still needs special handling for nested and iterable commands. Thankfully, the expansion of iterable commands is performed on an `IMapView`, so we can just expose `NameMap` as a consolidation of `ActionMap`'s `NameMap` with its parents. The same can be said for exposing key chords in nested commands.
## Validation Steps Performed
All local tests pass.
## Summary of the Pull Request
Allow schemes to be previewed as the user hovers over them in the Command Palette.
![preview-set-color-scheme](https://user-images.githubusercontent.com/18356694/114557761-9a3cbd80-9c2f-11eb-987f-eb0c89ee1fa6.gif)
## References
* Branched off of #8392, which is why the commit history is so polluted. 330a8e8 : 544b2fd has the interesting commits
* #5400: cmdpal megathread
### Potential follow-ups
* changing the font size
* changing the font face
* changing the opacity of acrylic
## PR Checklist
* [x] Closes#6689, a last straggling FHL PR
* [x] I work here
* [ ] Tests added/passed
* [n/a] Requires documentation to be updated - I don't think so
## Detailed Description of the Pull Request / Additional comments
This works by inserting a "preview" `TerminalSettings` into the settings hierarchy, before the `TermControl`'s runtime settings, and after the ones from the actual `CascadiaSettings`. This allows us to modify that preview settings object, then discard it when we're done with the preview.
This could also be used for other settings in the future - I built it to be extensible to other `ShortcutAction`s, though I haven't implemented those yet.
## Validation Steps Performed
* Select a colorscheme - it becomes the active one
* `colortool -x <scheme>` after selecting a scheme - colortool overrides the selected scheme
* Select a colorscheme after a `colortool -x <scheme>` after selecting a scheme - the scheme in the palette becomes the active one
* Pressing <kbd>esc</kbd> at any point to dismiss the command palette - scheme returns to the previous one
* reloading the settings - returns to the scheme in the settings
There seems to be a bug in WinUI (see microsoft/microsoft-ui-xaml#2121)
that results in heterogeneous `ModernCollectionBasePanel` configured
with `DataTemplateSelector` and virtualization enabled to recycle a
container even if its `ContentTemplate` is wrong.
I considered few options of handling this:
* Disabling virtualization (by replacing item container template with
some non-virtualizing panel (e.g., `StackPanel`,
`VirtualizingStackPanel` with `VirtualizationMode`=`Standard`)
* Replacing `DataTemplateSelector` approach with `ChoosingItemContainer`
event handling approach, which allows you to manage the item container
(`ListViewItem`) allocation process.
I have chosen the last one, as it should limit the amount of
allocations, and might allow optimizations in the future.
The solution introduces:
* A container for `ListViewItem`s in the form of a map of sets:
* The key of this map is a data template (e.g., `TabItemDataTemplate`)
* The value in the set is the container
* `ChoosingItemContainer` event handler that looks for available item in
the container or creates a new one
* `ContainerContentChanging` event handler that returns the recycled
item to the container
Closes#9288
As mentioned in https://github.com/microsoft/terminal/issues/9354#issuecomment-790034728
`GETSET_SETTING` is too visually similar to `GETSET_PROPERTY`, but with a _VERY_ different meaning. I think that merely changing the name of the macro would make it harder for us to make this mistake again.
* Currently TerminalPage registers on CmdPal key events:
* To invoke bindings when the palette is open
* Since some key combinations are not triggered by KeyDown
it registers for PreviewKeyDown
* As a result bindings might be preferred over navigation
(e.g., ctrl+v will paste into Terminal rather than into search box)
* To fix this, I moved all interactions inside the CmdPal into
PreviewKeyDown as well
* In addition, added specific handling for copy/paste
which now allow to interact with search box even if not focused
Closes#9044
A part of the #8415.
Includes:
* Moving `TabSwitcherMode` related decisions into `CommandPalette`
(simplifying the logic of `TerminalPage::SelectNextTab`)
* Fix a bug where the index of first tab switch is incorrect
(since bindings are not updated)
* Removing redundant `CommandPalette` updates
* Preparations for tabs binding
Following up https://github.com/microsoft/terminal/pull/8586 by @Hegunumo,
fully remove the command dispatching logic from Command Palette.
Currently Command Palette might dispatch command in Tab Switcher mode.
This leads to several inconsistencies:
* Only the commands with the same key modifier as an ATS anchor will be issued
* This command will not close the TabSwitcher
(while commands issued from TerminalPage do).
Implementation details:
* Pass KeyMapping rather than binding to CommandPalette
* Use this mapping inside previewKeyDownHandler of ATS to detect
if previous tab or next tab bindings were engaged.
No need to handle Ctrl+Tab explicitly anymore -
it is handled as any other binding.
* Cleanup the logic in TerminalPage::_SelectNextTab
that checks if CommandPalette is visible.
It is not required anymore, as visible palette would intercept the call.
* Remove dependency of TerminalPage on AppLogic
that was introduced lately .
This commit introduces another optional text block in palette that will
be shown in the command line mode (above the history). This text block
will either contain a list of parsed command lines or a description why
the parsing failed
Closes#8344Closes#7284
First step towards #8415:
* Introduce `PaletteItem` and derive from it to provide native support
for tabs and command lines (`ActionPaletteItem` / `TabPaletteItem`,
`CommandLinePaltteItem`)
* Remove business logic behind PaletteItem from palette (aka dispatch
commands and preview tabs externally)
So the implementation is somewhat dirty.
The ideas was nice - add lostFocusHandler
However it broke few things:
* In the TabSwitcher the ListItem must be focusable since otherwise
the SingleSelectionMode behavior breaks.
To address this I had to put the lostFocusHandler on the items as well
* When you click the flyout, the palette loses focus,
which makes the terminal page to set the focus on the tab, closing the flyout.
To address this I had to ensure the tab won't get focused once the flyout is open.
In addition, flyout should fix the focus before opening,
otherwise alt+tab will put a focus on a tab row rather than on tab
* I also had to close the palette if the tab order changes.
To prevent inconsistencies.
Closes#8355
## Summary of the Pull Request
Add a history to command palette in the command line mode.
Few considerations/limitations
1. In-memory, 10 entries hard-coded
2. MRU
3. List rather than set
4. The user needs explicitly select command from the history
## PR Checklist
* [x] Closes https://github.com/microsoft/terminal/issues/8296
* [x] CLA signed.
* [x] Tests added/passed
* [ ] Documentation updated - irrelevant
* [ ] Schema updated - irrelevant
* [ ] I've discussed this with core contributors already.
## Validation Steps Performed
* Manual testing
In introduced a bug in #8185, due to which Command Palette sorts items
alphabetically in the tab switcher mode. This PR fixes it.
Validation:
Created tabs with different names and verified that the MRU order is
preserved
Closes#8185
* Created a ViewModel class in the Command Palette called
FilteredCommand, aggregating the Command, the filter and the
highlighted presentation of the command name
* This ListView of the filtered commands is bound to the vector of
FilteredCommands
* Introduced HighlightedTextControl user control with HighlightedText
view model
* Added this control to the ListView Item's grid
* Bound the FilteredCommand's highlighted command name to the user
control
## Validation Steps Performed
* UT for matching algorithm
* Only manual tests
* Searching in CommandLine, SwitchTab and Nested Command modes
* Checking for bot matching an non matching filters
* Dogfooding
Closes#6646
## Summary of the Pull Request
Changes the way the `useTabSwitcher` setting works. It now accepts either a boolean or a string:
* `true`, `"mru"`: Use the tab switcher with MRU tab switching
* `"inOrder"`: Use the tab switcher, with in-order tab switching
* `false`, `"disabled"`: Don't use the tab switcher. Tabs will switch in-order.
This is following the discussion chronicled in #8025, as well as the follow-up investigation in that thread.
## References
* #7952 introduced MRU tab switching
## PR Checklist
* [x] Closes#8025 - there's also discussion of using a parameter in an action to override this setting, but that should get punted to a follow-up task
* [x] I work here
* [x] Tests added/passed - YOU BET THEY WERE
* [ ] Requires documentation to be updated
## Validation Steps Performed
I've been switching tabs all day and all night, with different settings values, and hot-reloading the setting.
I also _ran the test_ I added.
This commit adds functionality so that users can move back from sub menu
whenever they want. As a result, users no longer have to close command
palette and open it again to get all commands again.
Closes#7910
This PR changes the ATS display order to _always_ be in most recently
used (MRU) order. I chose not to give ATS the option to be displayed
in-order because that order is better served through the traditional
left-right TabRow switching.
_Note_: `TabSearch` will stay in-order.
This means that users can only choose one order or another in their
`nextTab/prevTab` bindings. Setting `useTabSwitcher` to true will make
nT/pT open the ATS in MRU order. If it's set to false, the ATS won't
open and nT/pT will simply go left and right on the TabRow.
I'm open to getting rid of the global and making ATS its own keybinding,
but for now I figured I would keep the current behavior and open the PR
to get eyes on the code that doesn't have anything to do with the
settings.
Closes#973
VsCode uses `>` as its "prefix" for the equivalent of their "action
mode". This PR aligns the Terminal with their logic here.
We have to be tricky - if we use the `>` in the actual input as the
indicator for action mode, we can't display any placeholder text in the
input to tell users to type a command. This wasn't an issue for the
commandline mode previously, because we'd stick the "prompt" in the "no
matches text" space. However, we can't do that for action mode. Instead,
we'll stick a floating text block over the input box, and when the
user's in action mode, we'll manually place a `>` into that space. When
the user backspaces the `>`, we'll remove it from that block, and switch
into commandline mode.
## Validation Steps Performed
Played with the cmdpal in lots of different modes, this finally feels
good
Closes#7736
## Summary of the Pull Request
![preview-ats-000](https://user-images.githubusercontent.com/18356694/94801728-18302a00-03ac-11eb-851d-760b92ebb46f.gif)
This PR enables the ATS to display the active tab as the user navigates the tab switcher. We do this by dispatching the tab switch actions as the user navigates the menu, and manually _not_ focusing the new tab when the tab switcher is open.
## References
* #6732 - original tab switcher PR
* #6689 - That's a more involved, generic version of this, but this PR will be enough to stop most of the complaints hopefully
## PR Checklist
* [x] Closes#7409
* [x] I work here
* [ ] Tests added/passed
* [n/a] Requires documentation to be updated
## Validation Steps Performed
Opened tabs, tabbed through the menu, verified that it did what I'd expect
Introduces a new TerminalSettingsModel (TSM) project. This project is
responsible for (de)serializing and exposing Windows Terminal's settings
as WinRT objects.
## References
#885: TSM epic
#1564: Settings UI is dependent on this for data binding and settings access
#6904: TSM Spec
In the process of ripping out TSM from TerminalApp, a few other changes
were made to make this possible:
1. AppLogic's `ApplicationDisplayName` and `ApplicationVersion` was
moved to `CascadiaSettings`
- These are defined as static functions. They also no longer check if
`AppLogic::Current()` is nullptr.
2. `enum LaunchMode` was moved from TerminalApp to TSM
3. `AzureConnectionType` and `TelnetConnectionType` were moved from the
profile generators to their respective TerminalConnections
4. CascadiaSettings' `SettingsPath` and `DefaultSettingsPath` are
exposed as `hstring` instead of `std::filesystem::path`
5. `Command::ExpandCommands()` was exposed via the IDL
- This required some of the warnings to be saved to an `IVector`
instead of `std::vector`, among some other small changes.
6. The localization resources had to be split into two halves.
- Resource file linked in init.cpp. Verified at runtime thanks to the
StaticResourceLoader.
7. Added constructors to some `ActionArgs`
8. Utils.h/cpp were moved to `cascadia/inc`. `JsonKey()` was moved to
`JsonUtils`. Both TermApp and TSM need access to Utils.h/cpp.
A large amount of work includes moving to the new namespace
(`TerminalApp` --> `Microsoft::Terminal::Settings::Model`).
Fixing the tests had its own complications. Testing required us to split
up TSM into a DLL and LIB, similar to TermApp. Discussion on creating a
non-local test variant can be found in #7743.
Closes#885
Currently, `CommandPalette` creates and maintains the `SwitchToTab`
commands used for the ATS. When `Command` goes into the
TerminalSettingsModel, the palette won't be able to access `Command`'s
implementation type, making it difficult for `CommandPalette` to tell
`Command` to listen to `Tab` for changes.
This PR changes the relationship up so `Tab` now manages its
`SwitchToTab` command, and `CommandPalette` just plops the command from
`Tab` into its list.
## Summary of the Pull Request
Adds support for "commandline mode" to the command palette.
![cmdpal-commandline-mode](https://user-images.githubusercontent.com/18356694/90263053-bbd17500-de14-11ea-8726-fee48fec5888.gif)
This allows the user to start typing a `wt.exe` commandline directly in the command palette, to run that commandline directly in the current window. This allows the user input something like `> nt -p Ubuntu ; sp -p ssh` and open up a new tab and split it _in the current window_.
## References
* cmdpal megathread: #5400
* Kinda related to #4472
* built with the `wt` action from #6537
## PR Checklist
* [x] Closes#6677
* [x] I work here
* [ ] Tests added/passed
* [ ] Requires documentation to be updated - sure does, when the cmdpal docs are written in the first place :P
## Validation Steps Performed
Tested manually
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
This PR splits the anchored and unanchored tab switcher into two. The anchored tab switcher is now baked into `nextTab`/`prevTab`, and the unanchored tab switcher command is just named `tabSearch`. `tabSearch` takes no arguments. To reflect this distinction, `CommandPalette.cpp` now refers to one as `TabSwitchMode` and the other as `TabSearchMode`.
I've added a global setting named `useTabSwitcher` (name up for debate) that makes the Terminal use the anchored tab switcher experience for `nextTab` and `prevTab`.
I've also given the control the ability to detect <kbd>Alt</kbd> KeyUp events and to dispatch keybinding events. By listening for keybindings, the ATS can react to `nextTab`/`prevTab` invocations for navigation in addition to listening for <kbd>tab</kbd> and the arrow keys.
Closes#7178
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] CLA signed.
* [x] Documentation updates: microsoftdocs/terminal#107
* [x] Schema updated.
## Summary of the Pull Request
![cmdpal-nested-command-polish](https://user-images.githubusercontent.com/18356694/90293616-1f29ca00-de4a-11ea-8942-00d255de929a.gif)
* Add a chevron for nested commands
* Add the text of the parent command when entering a child command
## References
## PR Checklist
* [x] Closes#7265
* [x] I work here
* [n/a] Tests added/passed
* [n/a] Requires documentation to be updated
## Validation Steps Performed
_look at that gif_
## Summary of the Pull Request
This PR adds support for both _nested_ and _iterable_ commands in the Command palette.
![nested-commands-000](https://user-images.githubusercontent.com/18356694/87072916-2d991c00-c1e2-11ea-8917-a70e8b8b9803.gif)
* **Nested commands**: These are commands that include additional sub-commands. When the user selects on of these, the palette will update to only show the nested commands.
* **Iterable commands**: These are commands what allow the user to define only a single command, which is repeated once for every profile. (in the future, also repeated for color schemes, themes, etc.)
The above gif uses the following json:
```json
{
"name": "Split Pane...",
"commands": [
{
"iterateOn": "profiles",
"name": "Split with ${profile.name}...",
"commands": [
{ "command": { "action": "splitPane", "profile": "${profile.name}", "split": "automatic" } },
{ "command": { "action": "splitPane", "profile": "${profile.name}", "split": "vertical" } },
{ "command": { "action": "splitPane", "profile": "${profile.name}", "split": "horizontal" } }
]
}
]
},
```
## References
## PR Checklist
* [x] Closes#3994
* [x] I work here
* [x] Tests added/passed
* [ ] Requires documentation to be updated - Sure does, but we'll finish polishing this first.
## Detailed Description of the Pull Request / Additional comments
We've now gotta keep the original json for a command around, so that once we know what all the profiles will be, we can expand the commands that need it.
We've also got to parse commands recursively, because they might have any number of child commands.
These together made the command parsing a _lot_ more complicated, but it feels good so far.
## Validation Steps Performed
* wrote a bunch of tests
* Played with it a bunch
![TabSwitchingv2](https://user-images.githubusercontent.com/57155886/88237962-5505d500-cc35-11ea-8384-d91699155067.gif)
## Summary of the Pull Request
This PR adds the Advanced Tab Switcher (ATS) to Terminal. It'll work
similarly to VSCode's tab switcher. Because this implementation rides
off a lot of the Command Palette's XAML code, it'll look just like the
Command Palette, and also have support for tab title search.
## References
#3753 - ATS Spec
Closes#1502
The command palette is a ListView of commands. As you type into the
search box, commands are added or removed from the ListView. Currently,
each update is done by completely clearing the backing list, then adding
back any items that should be displayed. However, this defeats the
ListView's built-in animations: upon every keystroke, ListView displays
its list-clearing animation, then animates the insertion of every item
that wasn't deleted. This results in noticeable flickering.
This PR changes the update logic so that it updates the list using
(roughly) the minimum number of Insert and Remove calls, so the ListView
makes smoother transitions as you type.
I implemented it by keeping the existing code that builds the filtered
list, but I changed it to build into a scratch list. Then I grafted on
a generic delta algorithm to make the real list look like the scratch
list.
To verify the delta algorithm, I tested all 360,000 permutations of
pairs of up to 5 element lists in a toy C# app.
## Validation
I'm not sure if my screen capture tool really caught all the flickering
here, but the screencasts below should give a rough idea of the
difference. (All the flickering was becoming a nuisance while I was
testing out the HC changes.)
See the images in #6939 for more info.
Co-authored-by: Jeffrey Tippet <jtippet@microsoft.com>
## Summary of the Pull Request
Pretty straightforward. Logs three scenarios:
* The user opened the command palette (and which mode it was opened in)
* The user ran a command from the palette
* The user dismissed the palette without running an action.
We discussed this in team sync yesterday.
## PR Checklist
* [x] I work here
* [n/a] Requires documentation to be updated
## Summary of the Pull Request
![command-palette-001](https://user-images.githubusercontent.com/18356694/85313480-b6dbef00-b47d-11ea-8a8f-a802d26c2f9b.gif)
This adds a first iteration on the command palette. Notable missing features are:
* Commandline mode: This will be a follow-up PR, following the merge of #6537
* nested and iterable commands: These will additionally be a follow-up PR.
This is also additionally based off the addenda in #6532.
This does not bind a key for the palette by default. That will be done when the above follow-ups are completed.
## References
* #2046 - The original command palette thread
* #5400 - This is the megathread for all command palette issues, which is tracking a bunch of additional follow up work
* #5674 and #6532 - specs
* #6537 - related
## PR Checklist
* [x] Closes#2046
- incidentally also closes#6645
* [x] I work here
* [x] Tests added/passed
* [ ] Requires documentation to be updated - delaying this until it's more polished.
## Detailed Description of the Pull Request / Additional comments
* There's a lot of code for autogenerating command names. That's all in `ActionArgs.cpp`, because each case is so _not_ boilerplate, unlike the rest of the code in `ActionArgs.h`.
## Validation Steps Performed
* I've been playing with this for months.
* Tests
* Selfhost with the team