terminal/src/cascadia/TerminalApp/AppKeyBindings.h
Mike Griese dd1c7b3e52 Add support for new panes with specifc profiles and other settings overrides (#3825)
## Summary of the Pull Request


This enables the user to set a number of extra settings in the `NewTab` and `SplitPane` `ShortcutAction`s, that enable customizing how a new terminal is created at runtime. The following four properties were added:
* `profile`
* `commandline`
* `tabTitle`
* `startingDirectory`

`profile` can be used with either a GUID or the name of a profile, and the action will launch that profile instead of the default.

`commandline`, `tabTitle`, and `startingDirectory` can all be used to override the profile's values of those settings. This will be more useful for #607.

With this PR, you can make bindings like the following:

```json

{ "keys": ["ctrl+a"], "command": { "action": "splitPane", "split": "vertical" } },
{ "keys": ["ctrl+b"], "command": { "action": "splitPane", "split": "vertical", "profile": "{6239a42c-1111-49a3-80bd-e8fdd045185c}" } },
{ "keys": ["ctrl+c"], "command": { "action": "splitPane", "split": "vertical", "profile": "profile1" } },
{ "keys": ["ctrl+d"], "command": { "action": "splitPane", "split": "vertical", "profile": "profile2" } },
{ "keys": ["ctrl+e"], "command": { "action": "splitPane", "split": "horizontal", "commandline": "foo.exe" } },
{ "keys": ["ctrl+f"], "command": { "action": "splitPane", "split": "horizontal", "profile": "profile1", "commandline": "foo.exe" } },
{ "keys": ["ctrl+g"], "command": { "action": "newTab" } },
{ "keys": ["ctrl+h"], "command": { "action": "newTab", "startingDirectory": "c:\\foo" } },
{ "keys": ["ctrl+i"], "command": { "action": "newTab", "profile": "profile2", "startingDirectory": "c:\\foo" } },
{ "keys": ["ctrl+j"], "command": { "action": "newTab", "tabTitle": "bar" } },
{ "keys": ["ctrl+k"], "command": { "action": "newTab", "profile": "profile2", "tabTitle": "bar" } },
{ "keys": ["ctrl+l"], "command": { "action": "newTab", "profile": "profile1", "tabTitle": "bar", "startingDirectory": "c:\\foo", "commandline":"foo.exe" } }
```

## References

This is a lot of work that was largely started in pursuit of #607. We want people to be able to override these properties straight from the commandline. While they may not make as much sense as keybindings like this, they'll make more sense as commandline arguments.

## PR Checklist
* [x] Closes #998
* [x] I work here
* [x] Tests added/passed
* [x] Requires documentation to be updated

## Validation Steps Performed
There are tests 🎉

Manually added some bindings, they opened the correct profiles in panes/tabs
2019-12-09 13:02:29 +00:00

76 lines
2.6 KiB
C++

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "AppKeyBindings.g.h"
#include "ActionArgs.h"
#include "ShortcutActionDispatch.h"
#include "..\inc\cppwinrt_utils.h"
// fwdecl unittest classes
namespace TerminalAppLocalTests
{
class SettingsTests;
class KeyBindingsTests;
class TestUtils;
}
namespace winrt::TerminalApp::implementation
{
struct KeyChordHash
{
std::size_t operator()(const winrt::Microsoft::Terminal::Settings::KeyChord& key) const
{
std::hash<int32_t> keyHash;
std::hash<winrt::Microsoft::Terminal::Settings::KeyModifiers> modifiersHash;
std::size_t hashedKey = keyHash(key.Vkey());
std::size_t hashedMods = modifiersHash(key.Modifiers());
return hashedKey ^ hashedMods;
}
};
struct KeyChordEquality
{
bool operator()(const winrt::Microsoft::Terminal::Settings::KeyChord& lhs, const winrt::Microsoft::Terminal::Settings::KeyChord& rhs) const
{
return lhs.Modifiers() == rhs.Modifiers() && lhs.Vkey() == rhs.Vkey();
}
};
struct AppKeyBindings : AppKeyBindingsT<AppKeyBindings>
{
AppKeyBindings() = default;
bool TryKeyChord(winrt::Microsoft::Terminal::Settings::KeyChord const& kc);
void SetKeyBinding(TerminalApp::ActionAndArgs const& actionAndArgs,
winrt::Microsoft::Terminal::Settings::KeyChord const& chord);
void ClearKeyBinding(winrt::Microsoft::Terminal::Settings::KeyChord const& chord);
Microsoft::Terminal::Settings::KeyChord GetKeyBindingForAction(TerminalApp::ShortcutAction const& action);
Microsoft::Terminal::Settings::KeyChord GetKeyBindingForActionWithArgs(TerminalApp::ActionAndArgs const& actionAndArgs);
static Windows::System::VirtualKeyModifiers ConvertVKModifiers(winrt::Microsoft::Terminal::Settings::KeyModifiers modifiers);
// Defined in AppKeyBindingsSerialization.cpp
void LayerJson(const Json::Value& json);
Json::Value ToJson();
void SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch);
private:
std::unordered_map<winrt::Microsoft::Terminal::Settings::KeyChord, TerminalApp::ActionAndArgs, KeyChordHash, KeyChordEquality> _keyShortcuts;
winrt::TerminalApp::ShortcutActionDispatch _dispatch{ nullptr };
friend class TerminalAppLocalTests::SettingsTests;
friend class TerminalAppLocalTests::KeyBindingsTests;
friend class TerminalAppLocalTests::TestUtils;
};
}
namespace winrt::TerminalApp::factory_implementation
{
BASIC_FACTORY(AppKeyBindings);
}