diff --git a/src/config.cpp b/src/config.cpp index 7ee367f..ca61308 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -276,21 +276,32 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std:: if (VALUEIT == impl->values.end()) { // it might be in a special category bool found = false; - for (auto& sc : impl->specialCategories) { - if (!valueName.starts_with(sc->name)) - continue; - if (!sc->isStatic && std::string{std::any_cast(sc->values[sc->key].getValue())} != impl->currentSpecialKey) - continue; + if (impl->currentSpecialCategory && valueName.starts_with(impl->currentSpecialCategory->name)) { + VALUEIT = impl->currentSpecialCategory->values.find(valueName.substr(impl->currentSpecialCategory->name.length() + 1)); - VALUEIT = sc->values.find(valueName.substr(sc->name.length() + 1)); - - if (VALUEIT != sc->values.end()) + if (VALUEIT != impl->currentSpecialCategory->values.end()) found = true; - else if (sc->descriptor->dontErrorOnMissing) - return result; // will return a success, cuz we want to ignore missing + } - break; + if (!found) { + for (auto& sc : impl->specialCategories) { + if (!valueName.starts_with(sc->name)) + continue; + + if (!sc->isStatic && std::string{std::any_cast(sc->values[sc->key].getValue())} != impl->currentSpecialKey) + continue; + + VALUEIT = sc->values.find(valueName.substr(sc->name.length() + 1)); + impl->currentSpecialCategory = sc.get(); + + if (VALUEIT != sc->values.end()) + found = true; + else if (sc->descriptor->dontErrorOnMissing) + return result; // will return a success, cuz we want to ignore missing + + break; + } } if (!found) { @@ -312,7 +323,8 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std:: applyDefaultsToCat(*PCAT); - VALUEIT = PCAT->values.find(valueName.substr(sc->name.length() + 1)); + VALUEIT = PCAT->values.find(valueName.substr(sc->name.length() + 1)); + impl->currentSpecialCategory = PCAT; if (VALUEIT != PCAT->values.end()) found = true; @@ -421,8 +433,12 @@ CParseResult CConfig::parseVariable(const std::string& lhs, const std::string& r if (dynamic) { for (auto& l : IT->linesContainingVar) { - parseLine(l, true); + impl->categories = l.categories; + impl->currentSpecialCategory = l.specialCategory; + parseLine(l.line, true); } + + impl->categories = {}; } CParseResult result; @@ -492,7 +508,7 @@ CParseResult CConfig::parseLine(std::string line, bool dynamic) { if (RHSIT == std::string::npos && LHSIT == std::string::npos) continue; else - var.linesContainingVar.push_back(line); + var.linesContainingVar.push_back({line, impl->categories, impl->currentSpecialCategory}); anyMatch = true; } @@ -537,7 +553,8 @@ CParseResult CConfig::parseLine(std::string line, bool dynamic) { return result; } - impl->currentSpecialKey = ""; + impl->currentSpecialKey = ""; + impl->currentSpecialCategory = nullptr; impl->categories.pop_back(); } else { // open a category. diff --git a/src/config.hpp b/src/config.hpp index 3e72791..dbca25c 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -11,9 +11,16 @@ struct SHandler { }; struct SVariable { - std::string name = ""; - std::string value = ""; - std::vector linesContainingVar; // for dynamic updates + std::string name = ""; + std::string value = ""; + + struct SVarLine { + std::string line; + std::vector categories; + SSpecialCategory* specialCategory = nullptr; // if applicable + }; + + std::vector linesContainingVar; // for dynamic updates }; // remember to also edit CConfigValue if editing @@ -71,7 +78,8 @@ class CConfigImpl { std::vector> specialCategoryDescriptors; std::vector categories; - std::string currentSpecialKey = ""; + std::string currentSpecialKey = ""; + SSpecialCategory* currentSpecialCategory = nullptr; // if applicable std::string parseError = ""; diff --git a/tests/config/config.conf b/tests/config/config.conf index e68c46e..3dbe429 100644 --- a/tests/config/config.conf +++ b/tests/config/config.conf @@ -31,9 +31,11 @@ testCategory { } } +$SPECIALVAL1 = 1 + special { key = a - value = 1 + value = $SPECIALVAL1 } special { diff --git a/tests/parse/main.cpp b/tests/parse/main.cpp index c11c4ae..ccbad97 100644 --- a/tests/parse/main.cpp +++ b/tests/parse/main.cpp @@ -191,6 +191,10 @@ int main(int argc, char** argv, char** envp) { EXPECT(std::any_cast(config.getSpecialConfigValue("specialGeneric:one", "value")), 1); EXPECT(std::any_cast(config.getSpecialConfigValue("specialGeneric:two", "value")), 2); + // test dynamic special variable + EXPECT(config.parseDynamic("$SPECIALVAL1 = 2").error, false); + EXPECT(std::any_cast(config.getSpecialConfigValue("special", "value", "a")), (Hyprlang::INT)2); + // test copying EXPECT(std::any_cast(config.getSpecialConfigValue("specialGeneric:one", "copyTest")), 2);