mirror of
https://github.com/hyprwm/hyprlang.git
synced 2024-12-22 01:49:49 +01:00
API: add anonymous special categories
This commit is contained in:
parent
65a7f870a6
commit
378c3e273b
5 changed files with 62 additions and 10 deletions
|
@ -131,6 +131,17 @@ namespace Hyprlang {
|
|||
don't pop up an error if the config value is missing
|
||||
*/
|
||||
bool ignoreMissing = false;
|
||||
|
||||
/*!
|
||||
Make this category an anonymous special one.
|
||||
key has to be nullptr.
|
||||
|
||||
Anonymous special categories behave like key-based ones, but the keys
|
||||
will be automatically assigned without user input.
|
||||
|
||||
\since 0.4.0
|
||||
*/
|
||||
bool anonymousKeyBased = false;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
|
|
@ -8,7 +8,11 @@
|
|||
#include <expected>
|
||||
|
||||
using namespace Hyprlang;
|
||||
extern "C" char** environ;
|
||||
extern "C" char** environ;
|
||||
|
||||
// defines
|
||||
inline constexpr const char* ANONYMOUS_KEY = "__hyprlang_internal_anonymous_key";
|
||||
//
|
||||
|
||||
static std::string removeBeginEndSpacesTabs(std::string str) {
|
||||
if (str.empty())
|
||||
|
@ -107,14 +111,17 @@ void CConfig::addSpecialCategory(const char* name, SSpecialCategoryOptions optio
|
|||
PDESC->key = options.key ? options.key : "";
|
||||
PDESC->dontErrorOnMissing = options.ignoreMissing;
|
||||
|
||||
if (!options.key) {
|
||||
if (!options.key && !options.anonymousKeyBased) {
|
||||
const auto PCAT = impl->specialCategories.emplace_back(std::make_unique<SSpecialCategory>()).get();
|
||||
PCAT->descriptor = PDESC;
|
||||
PCAT->name = name;
|
||||
PCAT->key = options.key ? options.key : "";
|
||||
PCAT->key = "";
|
||||
PCAT->isStatic = true;
|
||||
if (!PCAT->key.empty())
|
||||
addSpecialConfigValue(name, options.key, CConfigValue("0"));
|
||||
}
|
||||
|
||||
if (options.anonymousKeyBased) {
|
||||
PDESC->key = ANONYMOUS_KEY;
|
||||
PDESC->anonymous = true;
|
||||
}
|
||||
|
||||
// sort longest to shortest
|
||||
|
@ -310,12 +317,26 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std::
|
|||
if (VALUEIT != PCAT->values.end())
|
||||
found = true;
|
||||
|
||||
if (VALUEIT == PCAT->values.end() || VALUEIT->first != sc->key) {
|
||||
result.setError(std::format("special category's first value must be the key. Key for <{}> is <{}>", PCAT->name, PCAT->key));
|
||||
return result;
|
||||
}
|
||||
if (sc->anonymous) {
|
||||
// find suitable key
|
||||
size_t biggest = 0;
|
||||
for (auto& catt : impl->specialCategories) {
|
||||
if (catt->anonymousID > biggest)
|
||||
biggest = catt->anonymousID;
|
||||
}
|
||||
|
||||
impl->currentSpecialKey = value;
|
||||
biggest++;
|
||||
|
||||
PCAT->values[ANONYMOUS_KEY].setFrom(std::to_string(biggest));
|
||||
impl->currentSpecialKey = std::to_string(biggest);
|
||||
PCAT->anonymousID = biggest;
|
||||
} else {
|
||||
if (VALUEIT == PCAT->values.end() || VALUEIT->first != sc->key) {
|
||||
result.setError(std::format("special category's first value must be the key. Key for <{}> is <{}>", PCAT->name, PCAT->key));
|
||||
return result;
|
||||
}
|
||||
impl->currentSpecialKey = value;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ struct SSpecialCategoryDescriptor {
|
|||
std::string key = "";
|
||||
std::unordered_map<std::string, SConfigDefaultValue> defaultValues;
|
||||
bool dontErrorOnMissing = false;
|
||||
bool anonymous = false;
|
||||
};
|
||||
|
||||
struct SSpecialCategory {
|
||||
|
@ -51,6 +52,9 @@ struct SSpecialCategory {
|
|||
bool isStatic = false;
|
||||
|
||||
void applyDefaults();
|
||||
|
||||
// for easy anonymous ID'ing
|
||||
size_t anonymousID = 0;
|
||||
};
|
||||
|
||||
class CConfigImpl {
|
||||
|
|
|
@ -53,6 +53,14 @@ specialGeneric {
|
|||
}
|
||||
}
|
||||
|
||||
specialAnonymous {
|
||||
value = 2
|
||||
}
|
||||
|
||||
specialAnonymous {
|
||||
value = 3
|
||||
}
|
||||
|
||||
testCategory:testValueHex = 0xFFfFaAbB
|
||||
|
||||
testStringQuotes = "Hello World!"
|
||||
|
|
|
@ -108,6 +108,9 @@ int main(int argc, char** argv, char** envp) {
|
|||
config.addSpecialCategory("special", {"key"});
|
||||
config.addSpecialConfigValue("special", "value", (Hyprlang::INT)0);
|
||||
|
||||
config.addSpecialCategory("specialAnonymous", {nullptr, false, true});
|
||||
config.addSpecialConfigValue("specialAnonymous", "value", (Hyprlang::INT)0);
|
||||
|
||||
config.commence();
|
||||
|
||||
config.addSpecialCategory("specialGeneric:one", {nullptr, true});
|
||||
|
@ -194,6 +197,11 @@ int main(int argc, char** argv, char** envp) {
|
|||
// test listing keys
|
||||
EXPECT(config.listKeysForSpecialCategory("special")[1], "b");
|
||||
|
||||
// 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[1].c_str())), 3);
|
||||
|
||||
// test sourcing
|
||||
std::cout << " → Testing sourcing\n";
|
||||
EXPECT(std::any_cast<int64_t>(config.getConfigValue("myColors:pink")), (Hyprlang::INT)0xFFc800c8);
|
||||
|
|
Loading…
Reference in a new issue