mirror of
https://github.com/hyprwm/hyprlang.git
synced 2026-01-04 03:10:12 +01:00
core: support nesting with special categories and fix explicit key + nested (#82)
This commit is contained in:
parent
3d63fb4a42
commit
4dafa28d4f
3 changed files with 75 additions and 14 deletions
|
|
@ -283,17 +283,12 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std::
|
|||
CParseResult result;
|
||||
|
||||
std::string valueName;
|
||||
std::string catPrefix;
|
||||
for (auto& c : impl->categories) {
|
||||
valueName += c + ':';
|
||||
catPrefix += c + ':';
|
||||
}
|
||||
|
||||
valueName += command;
|
||||
|
||||
const auto VALUEONLYNAME = command.starts_with(catPrefix) ? command.substr(catPrefix.length()) : command;
|
||||
|
||||
// FIXME: this will bug with nested.
|
||||
if (valueName.contains('[') && valueName.contains(']')) {
|
||||
const auto L = valueName.find_first_of('[');
|
||||
const auto R = valueName.find_last_of(']');
|
||||
|
|
@ -304,12 +299,26 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std::
|
|||
|
||||
valueName = valueName.substr(0, L) + valueName.substr(R + 1);
|
||||
|
||||
// if it doesn't exist, make it
|
||||
for (auto& sc : impl->specialCategoryDescriptors) {
|
||||
if (sc->key.empty() || !valueName.starts_with(sc->name))
|
||||
if (sc->key.empty() || !valueName.starts_with(sc->name + ":"))
|
||||
continue;
|
||||
|
||||
// bingo
|
||||
bool keyExists = false;
|
||||
for (const auto& specialCat : impl->specialCategories) {
|
||||
if (specialCat->key != sc->key || specialCat->name != sc->name)
|
||||
continue;
|
||||
|
||||
if (CATKEY != std::string_view{std::any_cast<const char*>(specialCat->values[sc->key].getValue())})
|
||||
continue;
|
||||
|
||||
// existing special
|
||||
keyExists = true;
|
||||
}
|
||||
|
||||
if (keyExists)
|
||||
break;
|
||||
|
||||
// if it doesn't exist, make it
|
||||
const auto PCAT = impl->specialCategories.emplace_back(std::make_unique<SSpecialCategory>()).get();
|
||||
PCAT->descriptor = sc.get();
|
||||
PCAT->name = sc->name;
|
||||
|
|
@ -358,11 +367,14 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std::
|
|||
if (!found) {
|
||||
// could be a dynamic category that doesnt exist yet
|
||||
for (auto& sc : impl->specialCategoryDescriptors) {
|
||||
if (sc->key.empty() || !valueName.starts_with(sc->name))
|
||||
if (sc->key.empty() || !valueName.starts_with(sc->name + ":"))
|
||||
continue;
|
||||
|
||||
// category does exist, check if value exists
|
||||
if (!sc->defaultValues.contains(VALUEONLYNAME) && VALUEONLYNAME != sc->key)
|
||||
// found value root to be a special category, get the trunk
|
||||
const auto VALUETRUNK = valueName.substr(sc->name.length() + 1);
|
||||
|
||||
// check if trunk is a value within the special category
|
||||
if (!sc->defaultValues.contains(VALUETRUNK) && VALUETRUNK != sc->key)
|
||||
break;
|
||||
|
||||
// bingo
|
||||
|
|
@ -550,7 +562,7 @@ std::optional<std::string> CConfigImpl::parseComment(const std::string& comment)
|
|||
|
||||
if (!ifBlockVariable.empty()) {
|
||||
if (ifBlockVariable.starts_with("!")) {
|
||||
negated = true;
|
||||
negated = true;
|
||||
ifBlockVariable = ifBlockVariable.substr(1);
|
||||
}
|
||||
|
||||
|
|
@ -835,9 +847,12 @@ CParseResult CConfig::parseLine(std::string line, bool dynamic) {
|
|||
return result;
|
||||
}
|
||||
|
||||
impl->currentSpecialKey = "";
|
||||
impl->currentSpecialCategory = nullptr;
|
||||
impl->categories.pop_back();
|
||||
|
||||
if (impl->categories.empty()) {
|
||||
impl->currentSpecialKey = "";
|
||||
impl->currentSpecialCategory = nullptr;
|
||||
}
|
||||
} else {
|
||||
// open a category.
|
||||
if (!line.ends_with("{")) {
|
||||
|
|
|
|||
|
|
@ -127,6 +127,27 @@ specialAnonymous {
|
|||
value = 3
|
||||
}
|
||||
|
||||
specialAnonymousNested {
|
||||
nested:value1 = 1
|
||||
nested:value2 = 2
|
||||
nested1:nested2:value1 = 10
|
||||
nested1:nested2:value2 = 11
|
||||
}
|
||||
|
||||
specialAnonymousNested {
|
||||
nested {
|
||||
value1 = 3
|
||||
value2 = 4
|
||||
}
|
||||
|
||||
nested1 {
|
||||
nested2 {
|
||||
value1 = 12
|
||||
value2 = 13
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flagsStuff {
|
||||
value = 2
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,6 +154,12 @@ int main(int argc, char** argv, char** envp) {
|
|||
config.addSpecialCategory("specialAnonymous", {.key = nullptr, .ignoreMissing = false, .anonymousKeyBased = true});
|
||||
config.addSpecialConfigValue("specialAnonymous", "value", (Hyprlang::INT)0);
|
||||
|
||||
config.addSpecialCategory("specialAnonymousNested", {.key = nullptr, .ignoreMissing = false, .anonymousKeyBased = true});
|
||||
config.addSpecialConfigValue("specialAnonymousNested", "nested:value1", (Hyprlang::INT)0);
|
||||
config.addSpecialConfigValue("specialAnonymousNested", "nested:value2", (Hyprlang::INT)0);
|
||||
config.addSpecialConfigValue("specialAnonymousNested", "nested1:nested2:value1", (Hyprlang::INT)0);
|
||||
config.addSpecialConfigValue("specialAnonymousNested", "nested1:nested2:value2", (Hyprlang::INT)0);
|
||||
|
||||
config.addConfigValue("multiline", "");
|
||||
|
||||
config.commence();
|
||||
|
|
@ -288,6 +294,12 @@ int main(int argc, char** argv, char** envp) {
|
|||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialGeneric:two", "value")), 2);
|
||||
EXPECT(config.parseDynamic("special[b]:value = 3").error, false);
|
||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("special", "value", "b")), 3);
|
||||
EXPECT(config.parseDynamic("specialAnonymousNested[c]:nested:value1 = 4").error, false);
|
||||
EXPECT(config.parseDynamic("specialAnonymousNested[c]:nested:value2 = 5").error, false);
|
||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialAnonymousNested", "nested:value1", "c")), (Hyprlang::INT)4);
|
||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialAnonymousNested", "nested:value2", "c")), (Hyprlang::INT)5);
|
||||
EXPECT(config.parseDynamic("specialAnonymousNested[c]:nested:value2 = 6").error, false);
|
||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialAnonymousNested", "nested:value2", "c")), (Hyprlang::INT)6);
|
||||
|
||||
// test dynamic special variable
|
||||
EXPECT(config.parseDynamic("$SPECIALVAL1 = 2").error, false);
|
||||
|
|
@ -302,8 +314,21 @@ int main(int argc, char** argv, char** envp) {
|
|||
// test anonymous
|
||||
EXPECT(config.listKeysForSpecialCategory("specialAnonymous").size(), 2);
|
||||
const auto KEYS = config.listKeysForSpecialCategory("specialAnonymous");
|
||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialAnonymous", "value", KEYS[0].c_str())), 2);
|
||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialAnonymous", "value", KEYS[1].c_str())), 3);
|
||||
|
||||
// test anonymous nested
|
||||
EXPECT(config.listKeysForSpecialCategory("specialAnonymousNested").size(), 2 + /*from dynamic*/ 1);
|
||||
const auto KEYS2 = config.listKeysForSpecialCategory("specialAnonymousNested");
|
||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialAnonymousNested", "nested:value1", KEYS2[0].c_str())), 1);
|
||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialAnonymousNested", "nested:value2", KEYS2[0].c_str())), 2);
|
||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialAnonymousNested", "nested:value1", KEYS2[1].c_str())), 3);
|
||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialAnonymousNested", "nested:value2", KEYS2[1].c_str())), 4);
|
||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialAnonymousNested", "nested1:nested2:value1", KEYS2[0].c_str())), 10);
|
||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialAnonymousNested", "nested1:nested2:value2", KEYS2[0].c_str())), 11);
|
||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialAnonymousNested", "nested1:nested2:value1", KEYS2[1].c_str())), 12);
|
||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialAnonymousNested", "nested1:nested2:value2", KEYS2[1].c_str())), 13);
|
||||
|
||||
// test sourcing
|
||||
std::cout << " → Testing sourcing\n";
|
||||
EXPECT(std::any_cast<int64_t>(config.getConfigValue("myColors:pink")), (Hyprlang::INT)0xFFc800c8);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue