Skip to content

Commit

Permalink
generate IDs for user commands
Browse files Browse the repository at this point in the history
  • Loading branch information
PankajBhojwani committed Mar 26, 2024
1 parent be193b2 commit db528c9
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 4 deletions.
69 changes: 67 additions & 2 deletions src/cascadia/TerminalSettingsModel/Command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "KeyChordSerialization.h"
#include <LibraryResources.h>
#include "TerminalSettingsSerializationHelpers.h"
#include "CascadiaSettings.h"

using namespace winrt::Microsoft::Terminal::Settings::Model;
using namespace winrt::Windows::Foundation::Collections;
Expand All @@ -21,6 +22,7 @@ namespace winrt
}

static constexpr std::string_view NameKey{ "name" };
static constexpr std::string_view IDKey{ "id" };
static constexpr std::string_view IconKey{ "icon" };
static constexpr std::string_view ActionKey{ "command" };
static constexpr std::string_view ArgsKey{ "args" };
Expand All @@ -40,7 +42,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
auto command{ winrt::make_self<Command>() };
command->_name = _name;
command->_Origin = OriginTag::User;
command->_Origin = _Origin;
command->_ID = _ID;
command->_ActionAndArgs = *get_self<implementation::ActionAndArgs>(_ActionAndArgs)->Copy();
command->_keyMappings = _keyMappings;
command->_iconPath = _iconPath;
Expand All @@ -57,6 +60,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
command->_subcommands.Insert(kv.Key(), *subCmd->Copy());
}
}

return command;
}

Expand Down Expand Up @@ -115,6 +119,44 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
}

hstring Command::ID() const noexcept
{
return hstring{ _ID };
}

// Function Description:
// - generate an ID for this command and populate the _ID field
// - this function _will_ overwrite an existing ID if there is one, it is
// on the caller to make sure that either there was no ID or the overwrite is okay
// - this function should only be called to generate IDs for user-created commands
void Command::_generateID()
{
if (_ActionAndArgs)
{
// lambda function to remove whitespace and capitalize each letter after a removed space
auto removeWhitespaceAndCapitalize = [](wchar_t& x, bool& capitalizeNext) {
if (std::iswspace(x))
{
capitalizeNext = true; // Capitalize the next character
return true; // Remove the whitespace
}
else if (capitalizeNext)
{
x = std::towupper(x); // Capitalize the letter
capitalizeNext = false; // Reset flag
}
return false; // Keep the character
};

std::wstring noWhitespaceName{ get_self<implementation::ActionAndArgs>(_ActionAndArgs)->GenerateName() };
bool capitalizeNext;
noWhitespaceName.erase(std::remove_if(noWhitespaceName.begin(), noWhitespaceName.end(), [&capitalizeNext, removeWhitespaceAndCapitalize](wchar_t& x) {
return removeWhitespaceAndCapitalize(x, capitalizeNext);
}), noWhitespaceName.end());
_ID = RS_(L"OriginTagUser") + L"." + noWhitespaceName;
}
}

void Command::Name(const hstring& value)
{
if (!_name.has_value() || _name.value() != value)
Expand Down Expand Up @@ -307,6 +349,22 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
if (const auto actionJson{ json[JsonKey(ActionKey)] })
{
result->_ActionAndArgs = *ActionAndArgs::FromJson(actionJson, warnings);

// we might need to generate an ID, check these:
// 1. the action is valid
// 2. there isn't already an ID
// 3. the origin is User
if (result->_ActionAndArgs.Action() != ShortcutAction::Invalid)
{
if (const auto id{ json[JsonKey("id")] })
{
result->_ID = JsonUtils::GetValue<std::wstring>(id);
}
else if (origin == OriginTag::User)
{
result->_generateID();
}
}
}
else
{
Expand Down Expand Up @@ -424,6 +482,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
Json::Value cmdJson{ Json::ValueType::objectValue };
JsonUtils::SetValueForKey(cmdJson, IconKey, _iconPath);
JsonUtils::SetValueForKey(cmdJson, NameKey, _name);
if (!_ID.empty())
{
JsonUtils::SetValueForKey(cmdJson, IDKey, _ID);
}

if (_ActionAndArgs)
{
Expand All @@ -444,6 +506,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// First iteration also writes icon and name
JsonUtils::SetValueForKey(cmdJson, IconKey, _iconPath);
JsonUtils::SetValueForKey(cmdJson, NameKey, _name);
if (!_ID.empty())
{
JsonUtils::SetValueForKey(cmdJson, IDKey, _ID);
}
}

if (_ActionAndArgs)
Expand All @@ -455,7 +521,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
cmdList.append(cmdJson);
}
}

return cmdList;
}

Expand Down
6 changes: 5 additions & 1 deletion src/cascadia/TerminalSettingsModel/Command.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
hstring Name() const noexcept;
void Name(const hstring& name);

hstring ID() const noexcept;

Control::KeyChord Keys() const noexcept;
hstring KeyChordText() const noexcept;
std::vector<Control::KeyChord> KeyMappings() const noexcept;
Expand All @@ -78,16 +80,18 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
WINRT_PROPERTY(ExpandCommandType, IterateOn, ExpandCommandType::None);
WINRT_PROPERTY(Model::ActionAndArgs, ActionAndArgs);
WINRT_PROPERTY(OriginTag, Origin);
WINRT_PROPERTY(hstring, ID);

private:
Json::Value _originalJson;
Windows::Foundation::Collections::IMap<winrt::hstring, Model::Command> _subcommands{ nullptr };
std::vector<Control::KeyChord> _keyMappings;
std::optional<std::wstring> _name;
std::wstring _ID;
std::optional<std::wstring> _iconPath;
bool _nestedCommand{ false };

void _generateID();

static std::vector<Model::Command> _expandCommand(Command* const expandable,
Windows::Foundation::Collections::IVectorView<Model::Profile> profiles,
Windows::Foundation::Collections::IVectorView<Model::ColorScheme> schemes);
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalSettingsModel/Command.idl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ namespace Microsoft.Terminal.Settings.Model
Command();

String Name { get; };
String ID;
String ID { get; };
ActionAndArgs ActionAndArgs { get; };
Microsoft.Terminal.Control.KeyChord Keys { get; };
void RegisterKey(Microsoft.Terminal.Control.KeyChord keys);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@
<data name="OpenSystemMenuCommandKey" xml:space="preserve">
<value>Open system menu</value>
</data>
<data name="OriginTagUser" xml:space="preserve">
<value>User</value>
</data>
<data name="CommandPromptDisplayName" xml:space="preserve">
<value>Command Prompt</value>
<comment>This is the name of "Command Prompt", as localized in Windows. The localization here should match the one in the Windows product for "Command Prompt"</comment>
Expand Down

0 comments on commit db528c9

Please sign in to comment.