Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
d973836
settings model reflection
PankajBhojwani May 14, 2025
ce8b31b
use x-macro here instead
PankajBhojwani May 14, 2025
72e9b64
format
PankajBhojwani May 15, 2025
9618831
first nits
PankajBhojwani May 16, 2025
6557d17
Merge branch 'main' of https://github.com/microsoft/terminal into dev…
PankajBhojwani May 29, 2025
d62ede4
init as nullptr
PankajBhojwani May 29, 2025
18830be
change this back
PankajBhojwani May 29, 2025
035b341
static actionargfactory class
PankajBhojwani May 30, 2025
80924f2
rename and separate interface
PankajBhojwani May 30, 2025
46b036b
folder path, only capitalize first letter
PankajBhojwani May 30, 2025
b0ba0df
deduplicate resource strings
PankajBhojwani Jun 2, 2025
e2b2d46
new tab menu updates with id changes
PankajBhojwani Jun 2, 2025
cdb9599
name fix
PankajBhojwani Jun 2, 2025
0227969
undef the correct thing
PankajBhojwani Jun 3, 2025
0cb802e
format
PankajBhojwani Jun 3, 2025
a611189
move to action map
PankajBhojwani Jun 13, 2025
67a1b4e
alphabetical
PankajBhojwani Jun 13, 2025
54681b4
localized arg names
PankajBhojwani Jun 20, 2025
10b8475
rename
PankajBhojwani Jun 20, 2025
2f4a0c9
Arg_desc
PankajBhojwani Jun 23, 2025
da0a7a0
conflict
PankajBhojwani Aug 12, 2025
c5dd430
const vectors, rename to typeHint
PankajBhojwani Aug 13, 2025
2b1ffd4
__COUNTER__, lazy init static arg descriptors
PankajBhojwani Aug 14, 2025
ccfb4bd
format
PankajBhojwani Aug 14, 2025
06c051b
+1
PankajBhojwani Aug 15, 2025
19fb26d
split pane args fix
PankajBhojwani Aug 15, 2025
981a01e
don't need this anymore
PankajBhojwani Aug 15, 2025
892ced6
two cached vectors
PankajBhojwani Aug 18, 2025
75d0a1b
lightweight arg count
PankajBhojwani Aug 18, 2025
e2a758e
first round
PankajBhojwani Aug 20, 2025
e9291ba
init newterminalargs in getemptyargs
PankajBhojwani Aug 21, 2025
ea36019
unnecessary includes
PankajBhojwani Aug 21, 2025
890671a
callback instead
PankajBhojwani Aug 21, 2025
84aaf05
lowercase i
PankajBhojwani Aug 21, 2025
ebee14b
map handles id changes
PankajBhojwani Aug 22, 2025
cde4c03
vector instead
PankajBhojwani Aug 25, 2025
d9a409a
updateid moved to cascadia settings
PankajBhojwani Aug 25, 2025
eddbf7a
make sure to get the new id here
PankajBhojwani Aug 25, 2025
a3ef051
overwrite
PankajBhojwani Aug 25, 2025
f4e58ae
format
PankajBhojwani Aug 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
318 changes: 212 additions & 106 deletions src/cascadia/TerminalSettingsModel/ActionArgs.h

Large diffs are not rendered by default.

29 changes: 27 additions & 2 deletions src/cascadia/TerminalSettingsModel/ActionArgs.idl
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,32 @@ import "Command.idl";

namespace Microsoft.Terminal.Settings.Model
{
enum ArgTag
{
None = 0,
FilePath,
ColorScheme
};

struct ArgDescription
{
String Name;
String Type;
Boolean Required;
ArgTag Tag;
};

interface IActionArgs
{
Boolean Equals(IActionArgs other);
String GenerateName();
IActionArgs Copy();
UInt64 Hash();

UInt32 GetArgCount();
ArgDescription GetArgDescriptionAt(UInt32 index);
IInspectable GetArgAt(UInt32 index);
void SetArgAt(UInt32 index, Object value);
};

interface IActionEventArgs
Expand Down Expand Up @@ -168,6 +188,11 @@ namespace Microsoft.Terminal.Settings.Model
UInt64 ContentId{ get; set; };

String ToCommandline();

UInt32 GetArgCount();
ArgDescription GetArgDescriptionAt(UInt32 index);
IInspectable GetArgAt(UInt32 index);
void SetArgAt(UInt32 index, Object value);
};

[default_interface] runtimeclass ActionEventArgs : IActionEventArgs
Expand Down Expand Up @@ -230,7 +255,7 @@ namespace Microsoft.Terminal.Settings.Model
{
SendInputArgs(String input);

String Input { get; };
String Input;
};

[default_interface] runtimeclass SplitPaneArgs : IActionArgs
Expand Down Expand Up @@ -309,7 +334,7 @@ namespace Microsoft.Terminal.Settings.Model
[default_interface] runtimeclass CloseTabArgs : IActionArgs
{
CloseTabArgs(UInt32 tabIndex);
Windows.Foundation.IReference<UInt32> Index { get; };
Windows.Foundation.IReference<UInt32> Index;
};

[default_interface] runtimeclass MoveTabArgs : IActionArgs
Expand Down
210 changes: 149 additions & 61 deletions src/cascadia/TerminalSettingsModel/ActionArgsMagic.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,50 +54,81 @@ struct InitListPlaceholder
// expanded. Pretty critical for tracking down extraneous commas, etc.

// Property definitions, and JSON keys
#define DECLARE_ARGS(type, name, jsonKey, required, ...) \
#define DECLARE_ARGS(type, name, jsonKey, required, tag, ...) \
static constexpr std::string_view name##Key{ jsonKey }; \
ACTION_ARG(type, name, ##__VA_ARGS__);

// Parameters to the non-default ctor
#define CTOR_PARAMS(type, name, jsonKey, required, ...) \
#define CTOR_PARAMS(type, name, jsonKey, required, tag, ...) \
const type &name##Param,

// initializers in the ctor
#define CTOR_INIT(type, name, jsonKey, required, ...) \
#define CTOR_INIT(type, name, jsonKey, required, tag, ...) \
_##name{ name##Param },

// append this argument's description to the internal vector
#define APPEND_ARG_DESCRIPTION(type, name, jsonKey, required, tag, ...) \
_argDescriptions.push_back({ L## #name, L## #type, std::wstring_view(L## #required) != L"false", tag });

// check each property in the Equals() method. You'll note there's a stray
// `true` in the definition of Equals() below, that's to deal with trailing
// commas
#define EQUALS_ARGS(type, name, jsonKey, required, ...) \
#define EQUALS_ARGS(type, name, jsonKey, required, tag, ...) \
&&(otherAsUs->_##name == _##name)

// getter and setter for each property by index
#define GET_ARG_BY_INDEX(type, name, jsonKey, required, tag, ...) \
if (index == curIndex++) \
{ \
if (_##name.has_value()) \
{ \
return winrt::box_value(_##name.value()); \
} \
else \
{ \
return winrt::box_value(static_cast<type>(__VA_ARGS__)); \
} \
}

#define SET_ARG_BY_INDEX(type, name, jsonKey, required, tag, ...) \
if (index == curIndex++) \
{ \
if (value) \
{ \
_##name = winrt::unbox_value<type>(value); \
} \
else \
{ \
_##name = std::nullopt; \
} \
}

// JSON deserialization. If the parameter is required to pass any validation,
// add that as the `required` parameter here, as the body of a conditional
// EX: For the RESIZE_PANE_ARGS
// X(Model::ResizeDirection, ResizeDirection, "direction", args->ResizeDirection() == ResizeDirection::None, Model::ResizeDirection::None)
// the bit
// args->ResizeDirection() == ResizeDirection::None
// is used as the conditional for the validation here.
#define FROM_JSON_ARGS(type, name, jsonKey, required, ...) \
JsonUtils::GetValueForKey(json, jsonKey, args->_##name); \
if (required) \
{ \
return { nullptr, { SettingsLoadWarnings::MissingRequiredParameter } }; \
#define FROM_JSON_ARGS(type, name, jsonKey, required, tag, ...) \
JsonUtils::GetValueForKey(json, jsonKey, args->_##name); \
if (required) \
{ \
return { nullptr, { SettingsLoadWarnings::MissingRequiredParameter } }; \
}

// JSON serialization
#define TO_JSON_ARGS(type, name, jsonKey, required, ...) \
#define TO_JSON_ARGS(type, name, jsonKey, required, tag, ...) \
JsonUtils::SetValueForKey(json, jsonKey, args->_##name);

// Copy each property in the Copy() method
#define COPY_ARGS(type, name, jsonKey, required, ...) \
#define COPY_ARGS(type, name, jsonKey, required, tag, ...) \
copy->_##name = _##name;

// hash each property in Hash(). You'll note there's a stray `0` in the
// definition of Hash() below, that's to deal with trailing commas (or in this
// case, leading.)
#define HASH_ARGS(type, name, jsonKey, required, ...) \
#define HASH_ARGS(type, name, jsonKey, required, tag, ...) \
h.write(name());

// Use ACTION_ARGS_STRUCT when you've got no other customizing to do.
Expand All @@ -111,53 +142,110 @@ struct InitListPlaceholder
// * NewTerminalArgs has a ToCommandline method it needs to additionally declare.
// * GlobalSummonArgs has the QuakeModeFromJson helper

#define ACTION_ARG_BODY(className, argsMacro) \
className() = default; \
className( \
argsMacro(CTOR_PARAMS) InitListPlaceholder = {}) : \
argsMacro(CTOR_INIT) _placeholder{} {}; \
argsMacro(DECLARE_ARGS); \
\
private: \
InitListPlaceholder _placeholder; \
\
public: \
hstring GenerateName() const; \
bool Equals(const IActionArgs& other) \
{ \
auto otherAsUs = other.try_as<className>(); \
if (otherAsUs) \
{ \
return true argsMacro(EQUALS_ARGS); \
} \
return false; \
}; \
static FromJsonResult FromJson(const Json::Value& json) \
{ \
auto args = winrt::make_self<className>(); \
argsMacro(FROM_JSON_ARGS); \
return { *args, {} }; \
} \
static Json::Value ToJson(const IActionArgs& val) \
{ \
if (!val) \
{ \
return {}; \
} \
Json::Value json{ Json::ValueType::objectValue }; \
const auto args{ get_self<className>(val) }; \
argsMacro(TO_JSON_ARGS); \
return json; \
} \
IActionArgs Copy() const \
{ \
auto copy{ winrt::make_self<className>() }; \
argsMacro(COPY_ARGS); \
return *copy; \
} \
size_t Hash() const \
{ \
til::hasher h; \
argsMacro(HASH_ARGS); \
return h.finalize(); \
#define ACTION_ARG_BODY(className, argsMacro) \
className() { argsMacro(APPEND_ARG_DESCRIPTION) }; \
className( \
argsMacro(CTOR_PARAMS) InitListPlaceholder = {}) : \
argsMacro(CTOR_INIT) _placeholder{} { \
argsMacro(APPEND_ARG_DESCRIPTION) \
}; \
argsMacro(DECLARE_ARGS); \
\
private: \
InitListPlaceholder _placeholder; \
std::vector<ArgDescription> _argDescriptions; \
\
public: \
hstring GenerateName() const; \
bool Equals(const IActionArgs& other) \
{ \
auto otherAsUs = other.try_as<className>(); \
if (otherAsUs) \
{ \
return true argsMacro(EQUALS_ARGS); \
} \
return false; \
}; \
static FromJsonResult FromJson(const Json::Value& json) \
{ \
auto args = winrt::make_self<className>(); \
argsMacro(FROM_JSON_ARGS); \
return { *args, {} }; \
} \
static Json::Value ToJson(const IActionArgs& val) \
{ \
if (!val) \
{ \
return {}; \
} \
Json::Value json{ Json::ValueType::objectValue }; \
const auto args{ get_self<className>(val) }; \
argsMacro(TO_JSON_ARGS); \
return json; \
} \
IActionArgs Copy() const \
{ \
auto copy{ winrt::make_self<className>() }; \
argsMacro(COPY_ARGS); \
copy->_argDescriptions = _argDescriptions; \
return *copy; \
} \
size_t Hash() const \
{ \
til::hasher h; \
argsMacro(HASH_ARGS); \
return h.finalize(); \
} \
uint32_t GetArgCount() const \
{ \
return gsl::narrow<uint32_t>(_argDescriptions.size()); \
} \
ArgDescription GetArgDescriptionAt(uint32_t index) const \
{ \
return _argDescriptions.at(index); \
} \
IInspectable GetArgAt(uint32_t index) const \
{ \
uint32_t curIndex{ 0 }; \
argsMacro(GET_ARG_BY_INDEX) \
return nullptr; \
} \
void SetArgAt(uint32_t index, IInspectable value) \
{ \
uint32_t curIndex{ 0 }; \
argsMacro(SET_ARG_BY_INDEX) \
}

#define PARTIAL_ACTION_ARG_BODY(className, argsMacro) \
className(){ argsMacro(APPEND_ARG_DESCRIPTION) }; \
className( \
argsMacro(CTOR_PARAMS) InitListPlaceholder = {}) : \
argsMacro(CTOR_INIT) _placeholder{} { \
argsMacro(APPEND_ARG_DESCRIPTION) \
}; \
argsMacro(DECLARE_ARGS); \
\
private: \
InitListPlaceholder _placeholder; \
std::vector<ArgDescription> _argDescriptions; \
\
public: \
uint32_t GetArgCount() const \
{ \
return gsl::narrow<uint32_t>(_argDescriptions.size()); \
} \
ArgDescription GetArgDescriptionAt(uint32_t index) const \
{ \
return _argDescriptions.at(index); \
} \
IInspectable GetArgAt(uint32_t index) const \
{ \
uint32_t curIndex{ 0 }; \
argsMacro(GET_ARG_BY_INDEX) \
return nullptr; \
} \
void SetArgAt(uint32_t index, IInspectable value) \
{ \
uint32_t curIndex{ 0 }; \
argsMacro(SET_ARG_BY_INDEX) \
}
Loading
Loading