Skip to content

Commit

Permalink
add dynamic profile generators
Browse files Browse the repository at this point in the history
  • Loading branch information
carlos-zamora committed Feb 25, 2025
1 parent f5f6345 commit ec88b32
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 18 deletions.
21 changes: 16 additions & 5 deletions src/cascadia/TerminalSettingsEditor/Extensions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,25 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
_extensionSources.clear();
_CurrentExtensionSource.clear();

std::vector<Editor::FragmentExtensionViewModel> fragmentExtensions;
fragmentExtensions.reserve(settings.FragmentExtensions().Size());
std::vector<Model::FragmentSettings> extensions;
extensions.reserve(settings.FragmentExtensions().Size() + settings.DynamicProfileGenerators().Size());
for (auto ext : settings.FragmentExtensions())
{
extensions.push_back(ext);
}
for (auto ext : settings.DynamicProfileGenerators())
{
extensions.push_back(ext);
}

std::vector<Editor::FragmentExtensionViewModel> extensionVMs;
extensionVMs.reserve(extensions.size());

// these vectors track components all extensions successfully added
std::vector<Editor::FragmentProfileViewModel> profilesModifiedTotal;
std::vector<Editor::FragmentProfileViewModel> profilesAddedTotal;
std::vector<Editor::FragmentColorSchemeViewModel> colorSchemesAddedTotal;
for (const auto&& fragExt : settings.FragmentExtensions())
for (const auto& fragExt : extensions)
{
const auto extensionEnabled = GetExtensionState(fragExt.Source());

Expand Down Expand Up @@ -173,10 +184,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
}

_extensionSources.insert(fragExt.Source());
fragmentExtensions.push_back(winrt::make<FragmentExtensionViewModel>(fragExt, currentProfilesModified, currentProfilesAdded, currentColorSchemesAdded));
extensionVMs.push_back(winrt::make<FragmentExtensionViewModel>(fragExt, currentProfilesModified, currentProfilesAdded, currentColorSchemesAdded));
}

_fragmentExtensions = single_threaded_observable_vector<Editor::FragmentExtensionViewModel>(std::move(fragmentExtensions));
_fragmentExtensions = single_threaded_observable_vector<Editor::FragmentExtensionViewModel>(std::move(extensionVMs));
_profilesModifiedView = single_threaded_observable_vector<Editor::FragmentProfileViewModel>(std::move(profilesModifiedTotal));
_profilesAddedView = single_threaded_observable_vector<Editor::FragmentProfileViewModel>(std::move(profilesAddedTotal));
_colorSchemesAddedView = single_threaded_observable_vector<Editor::FragmentColorSchemeViewModel>(std::move(colorSchemesAddedTotal));
Expand Down
16 changes: 16 additions & 0 deletions src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,17 @@ Model::CascadiaSettings CascadiaSettings::Copy() const
}
settings->_fragmentExtensions = winrt::single_threaded_vector(std::move(fragmentExtensions));
}

// copy dynamic profile generators
{
std::vector<Model::FragmentSettings> dynamicProfileGenerators;
dynamicProfileGenerators.reserve(_dynamicProfileGeneratorExtensions.Size());
for (const auto& fragment : _dynamicProfileGeneratorExtensions)
{
dynamicProfileGenerators.emplace_back(get_self<FragmentSettings>(fragment)->Copy());
}
settings->_dynamicProfileGeneratorExtensions = winrt::single_threaded_vector(std::move(dynamicProfileGenerators));
}
}

// load errors
Expand Down Expand Up @@ -220,6 +231,11 @@ IVectorView<Model::FragmentSettings> CascadiaSettings::FragmentExtensions() cons
return _fragmentExtensions.GetView();
}

IVectorView<Model::FragmentSettings> CascadiaSettings::DynamicProfileGenerators() const noexcept
{
return _dynamicProfileGeneratorExtensions.GetView();
}

// Method Description:
// - Returns the globally configured keybindings
// Arguments:
Expand Down
3 changes: 3 additions & 0 deletions src/cascadia/TerminalSettingsModel/CascadiaSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
ParsedSettings inboxSettings;
ParsedSettings userSettings;
std::vector<Model::FragmentSettings> fragmentExtensions;
std::vector<Model::FragmentSettings> dynamicProfileGeneratorExtensions;
bool duplicateProfile = false;

private:
Expand Down Expand Up @@ -132,6 +133,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::Windows::Foundation::Collections::IObservableVector<Model::Profile> ActiveProfiles() const noexcept;
Model::ActionMap ActionMap() const noexcept;
winrt::Windows::Foundation::Collections::IVectorView<Model::FragmentSettings> FragmentExtensions() const noexcept;
winrt::Windows::Foundation::Collections::IVectorView<Model::FragmentSettings> DynamicProfileGenerators() const noexcept;
void WriteSettingsToDisk();
Json::Value ToJson() const;
Model::Profile ProfileDefaults() const;
Expand Down Expand Up @@ -190,6 +192,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::Windows::Foundation::Collections::IObservableVector<Model::Profile> _allProfiles = winrt::single_threaded_observable_vector<Model::Profile>();
winrt::Windows::Foundation::Collections::IObservableVector<Model::Profile> _activeProfiles = winrt::single_threaded_observable_vector<Model::Profile>();
winrt::Windows::Foundation::Collections::IVector<Model::FragmentSettings> _fragmentExtensions = winrt::single_threaded_vector<Model::FragmentSettings>();
winrt::Windows::Foundation::Collections::IVector<Model::FragmentSettings> _dynamicProfileGeneratorExtensions = winrt::single_threaded_vector<Model::FragmentSettings>();
std::set<std::string> _themesChangeLog{};

// load errors
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/CascadiaSettings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ namespace Microsoft.Terminal.Settings.Model

ActionMap ActionMap { get; };
Windows.Foundation.Collections.IVectorView<FragmentSettings> FragmentExtensions { get; };
Windows.Foundation.Collections.IVectorView<FragmentSettings> DynamicProfileGenerators { get; };

IVectorView<SettingsLoadWarnings> Warnings { get; };
Windows.Foundation.IReference<SettingsLoadErrors> GetLoadingError { get; };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -991,31 +991,51 @@ bool SettingsLoader::_addOrMergeUserColorScheme(const winrt::com_ptr<implementat
void SettingsLoader::_executeGenerator(const IDynamicProfileGenerator& generator)
{
const auto generatorNamespace = generator.GetNamespace();
if (_ignoredNamespaces.contains(generatorNamespace))
{
return;
}

const auto previousSize = inboxSettings.profiles.size();

std::vector<winrt::com_ptr<implementation::Profile>> generatedProfiles;
try
{
generator.GenerateProfiles(inboxSettings.profiles);
generator.GenerateProfiles(generatedProfiles);
}
CATCH_LOG_MSG("Dynamic Profile Namespace: \"%.*s\"", gsl::narrow<int>(generatorNamespace.size()), generatorNamespace.data())

// These are needed for the FragmentSettings object
std::vector<Model::FragmentProfileEntry> profileEntries;
Json::Value profilesListJson{ Json::ValueType::arrayValue };
Json::StreamWriterBuilder styledWriter;
styledWriter["indentation"] = " ";

// If the generator produced some profiles we're going to give them default attributes.
// By setting the Origin/Source/etc. here, we deduplicate some code and ensure they aren't missing accidentally.
if (inboxSettings.profiles.size() > previousSize)
const winrt::hstring source{ generatorNamespace };
for (const auto& profile : generatedProfiles)
{
const winrt::hstring source{ generatorNamespace };
profile->Origin(OriginTag::Generated);
profile->Source(source);

const auto profileJson = profile->ToJson();
profilesListJson.append(profileJson);
profileEntries.push_back(winrt::make<FragmentProfileEntry>(profile->Guid(), hstring{ til::u8u16(Json::writeString(styledWriter, profileJson)) }));
}

for (const auto& profile : std::span(inboxSettings.profiles).subspan(previousSize))
if (!_ignoredNamespaces.contains(generatorNamespace))
{
// Add generated profiles to the user settings
for (auto& profile : generatedProfiles)
{
profile->Origin(OriginTag::Generated);
profile->Source(source);
inboxSettings.profiles.push_back(profile);
}
}

// Manually construct the JSON for the FragmentSettings object
Json::Value json{ Json::ValueType::objectValue };
json[JsonKey(ProfilesKey)] = profilesListJson;

auto generatorExtension = winrt::make_self<FragmentSettings>(hstring{ generatorNamespace }, hstring{ til::u8u16(Json::writeString(styledWriter, json)) }, hstring{ L"settings.json" }, FragmentScope::Machine);
for (const auto& entry : profileEntries)
{
generatorExtension->NewProfiles().Append(entry);
}
dynamicProfileGeneratorExtensions.emplace_back(*generatorExtension);
}

// Method Description:
Expand Down Expand Up @@ -1308,6 +1328,7 @@ CascadiaSettings::CascadiaSettings(SettingsLoader&& loader) :
_warnings = winrt::single_threaded_vector(std::move(warnings));
_themesChangeLog = std::move(loader.userSettings.themesChangeLog);
_fragmentExtensions = winrt::single_threaded_vector(std::move(loader.fragmentExtensions));
_dynamicProfileGeneratorExtensions = winrt::single_threaded_vector(std::move(loader.dynamicProfileGeneratorExtensions));

_resolveDefaultProfile();
_resolveNewTabMenuProfiles();
Expand Down

0 comments on commit ec88b32

Please sign in to comment.