From da6a605c936c72bcacf695e007364167bb86e3ec Mon Sep 17 00:00:00 2001 From: Yaraslau Tamashevich Date: Sun, 12 Jan 2025 22:30:10 +0100 Subject: [PATCH] Make some actions non repeatable --- src/contour/Actions.h | 4 ++++ src/contour/TerminalSession.cpp | 28 ++++++++++++++++++++++++---- src/crispy/utils.h | 3 +++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/contour/Actions.h b/src/contour/Actions.h index 14ccf1c397..687a04dfce 100644 --- a/src/contour/Actions.h +++ b/src/contour/Actions.h @@ -2,6 +2,7 @@ #pragma once #include +#include #include #include @@ -151,6 +152,9 @@ using Action = std::variant; +template +concept NonRepeatableActionConcept = crispy::one_of; + std::optional fromString(std::string const& name); namespace documentation diff --git a/src/contour/TerminalSession.cpp b/src/contour/TerminalSession.cpp index b491048608..492456795c 100644 --- a/src/contour/TerminalSession.cpp +++ b/src/contour/TerminalSession.cpp @@ -814,6 +814,28 @@ void TerminalSession::onScrollOffsetChanged(vtbackend::ScrollOffset value) } // }}} // {{{ Input Events + +void handleAction(auto const& actions, auto eventType, auto callback) +{ + if (eventType == KeyboardEventType::Press) + callback(*actions); + else if (eventType == KeyboardEventType::Repeat) + { + // filter out actions that are not repeatable + std::vector tmpActions; + auto set = crispy::overloaded { + [&]([[maybe_unused]] actions::NonRepeatableActionConcept auto const& action) {}, + [&](auto const& action) { tmpActions.emplace_back(action); }, + }; + + for (auto const& action: *actions) + { + std::visit(set, action); + } + callback(tmpActions); + } +} + void TerminalSession::sendKeyEvent(Key key, Modifiers modifiers, KeyboardEventType eventType, Timestamp now) { inputLog()("Key {} event received: {} {}", eventType, modifiers, key); @@ -833,8 +855,7 @@ void TerminalSession::sendKeyEvent(Key key, Modifiers modifiers, KeyboardEventTy if (auto const* actions = config::apply(_config.inputMappings.value().keyMappings, key, modifiers, matchModeFlags())) { - if (eventType == KeyboardEventType::Press) - executeAllActions(*actions); + handleAction(actions, eventType, [&](auto const& actions) { executeAllActions(actions); }); return; } } @@ -869,8 +890,7 @@ void TerminalSession::sendCharEvent( config::apply(_config.inputMappings.value().charMappings, value, modifiers, matchModeFlags()); actions && !_terminal.inputHandler().isEditingSearch()) { - if (eventType == KeyboardEventType::Press) - executeAllActions(*actions); + handleAction(actions, eventType, [&](auto const& actions) { executeAllActions(actions); }); return; } } diff --git a/src/crispy/utils.h b/src/crispy/utils.h index 43553845ad..a1ef58519f 100644 --- a/src/crispy/utils.h +++ b/src/crispy/utils.h @@ -560,4 +560,7 @@ struct overloaded: Ts... template overloaded(Ts...) -> overloaded; +template +concept one_of = (std::same_as || ...); + } // namespace crispy