Skip to content

Commit

Permalink
Allow mapping of sequences in context blocks (2)
Browse files Browse the repository at this point in the history
  • Loading branch information
houmain committed Aug 24, 2021
1 parent 099f1fb commit 23ad2c7
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 11 deletions.
23 changes: 19 additions & 4 deletions src/config/ParseConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ namespace {
}
}
}

std::string generate_unique_name_from_sequence(const KeySequence& sequence) {
auto ss = std::stringstream();
ss << '#';
for (const auto& event : sequence)
ss << event.key << '/' << static_cast<int>(event.state) << ',';
return ss.str();
}
} // namespace

Config ParseConfig::operator()(std::istream& is, bool add_default_mappings) {
Expand Down Expand Up @@ -379,13 +387,20 @@ void ParseConfig::add_command(KeySequence input, std::string name) {

void ParseConfig::add_mapping(KeySequence input, KeySequence output) {
assert(!input.empty());
// assign a unique name per input sequence
auto name = generate_unique_name_from_sequence(input);
if (m_config.contexts.empty()) {
m_config.commands.push_back({ "", std::move(input), std::move(output), {} });
// creating mapping in default context, set default output expression
m_config.commands.push_back({ std::move(name), std::move(input), std::move(output), {} });
}
else if (m_config.contexts.back().system_filter_matched) {
// mapping sequence in context, generate unique command name
auto name = "#" + std::to_string(m_config.commands.size());
m_config.commands.push_back({ name, std::move(input), {}, {} });
// mapping sequence in context, try to override existing command
if (!std::count_if(m_config.commands.begin(), m_config.commands.end(),
[&](const Command& command) { return command.name == name; })) {
// create command with forwarding default mapping
const auto default_mapping = KeySequence{ { any_key, KeyState::Down } };
m_config.commands.push_back({ name, std::move(input), std::move(default_mapping), {} });
}
add_mapping(std::move(name), std::move(output));
}
}
Expand Down
85 changes: 78 additions & 7 deletions src/test/test3_Stage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,22 @@ namespace {
auto stream = std::stringstream(string);
auto config = parse_config(stream);
auto mappings = std::vector<Mapping>();
for (auto& command : config.commands)
auto override_sets = std::vector<MappingOverrideSet>();
for (auto& command : config.commands) {
mappings.push_back({
std::move(command.input),
std::move(command.default_mapping)
});
return Stage(std::move(mappings), { });
for (auto& context_mapping : command.context_mappings) {
if (context_mapping.context_index >= override_sets.size())
override_sets.resize(context_mapping.context_index + 1);
override_sets[context_mapping.context_index].push_back({
static_cast<int>(mappings.size()) - 1,
std::move(context_mapping.output)
});
}
}
return Stage(std::move(mappings), std::move(override_sets));
}

template<size_t N>
Expand Down Expand Up @@ -805,27 +815,88 @@ TEST_CASE("System context - partially mapped", "[Stage]") {

TEST_CASE("Mapping sequence in context", "[Stage]") {
auto config = R"(
R >> R
[title="Firefox"]
A >> B
R >> U
X >> Y
[title="Konsole"]
A >> C
R >> V
X >> Z
[system="Linux"]
A >> E
[system="Windows"]
A >> F
)";
Stage stage = create_stage(config);

[system="Windows"]
B >> H
#if defined(__linux__)
REQUIRE(apply_input(stage, "+A -A") == "+E -E");
#elif defined(_WIN32)
REQUIRE(apply_input(stage, "+A -A") == "+F -F");
#endif
REQUIRE(apply_input(stage, "+R -R") == "+R -R");
REQUIRE(apply_input(stage, "+X -X") == "+X -X"); // implicit default mapping forwards

stage.activate_override_set(0);
REQUIRE(apply_input(stage, "+A -A") == "+B -B");
REQUIRE(apply_input(stage, "+R -R") == "+U -U");
REQUIRE(apply_input(stage, "+X -X") == "+Y -Y");

stage.activate_override_set(1);
REQUIRE(apply_input(stage, "+A -A") == "+C -C");
REQUIRE(apply_input(stage, "+R -R") == "+V -V");
REQUIRE(apply_input(stage, "+X -X") == "+Z -Z");
}
//--------------------------------------------------------------------

TEST_CASE("Mapping sequence in context - comparison", "[Stage]") {
auto config = R"(
A >> command
R >> command2
command2 >> R
X >> command3
[title="Firefox"]
command >> B
command2 >> U
command3 >> Y
[title="Konsole"]
command >> C
command2 >> V
command3 >> Z
[system="Linux"]
B >> G
command >> E
[system="Windows"]
command >> F
)";
Stage stage = create_stage(config);

#if defined(__linux__)
REQUIRE(apply_input(stage, "+A -A") == "+E -E");
REQUIRE(apply_input(stage, "+B -B") == "+G -G");
#elif defined(_WIN32)
REQUIRE(apply_input(stage, "+A -A") == "+F -F");
REQUIRE(apply_input(stage, "+B -B") == "+H -H");
#endif
REQUIRE(apply_input(stage, "+R -R") == "+R -R");
REQUIRE(apply_input(stage, "+X -X") == ""); // no default mapping for command3

stage.activate_override_set(0);
REQUIRE(apply_input(stage, "+A -A") == "+B -B");
REQUIRE(apply_input(stage, "+R -R") == "+U -U");
REQUIRE(apply_input(stage, "+X -X") == "+Y -Y");

stage.activate_override_set(1);
REQUIRE(apply_input(stage, "+A -A") == "+C -C");
REQUIRE(apply_input(stage, "+R -R") == "+V -V");
REQUIRE(apply_input(stage, "+X -X") == "+Z -Z");
}

//--------------------------------------------------------------------
Expand Down

0 comments on commit 23ad2c7

Please sign in to comment.