2020-10-19 06:09:36 +00:00
/*
* Copyright ( c ) 2020 , the SerenityOS developers .
*
2021-04-22 08:24:48 +00:00
* SPDX - License - Identifier : BSD - 2 - Clause
2020-10-19 06:09:36 +00:00
*/
2021-01-24 14:28:26 +00:00
# include <AK/Debug.h>
2020-10-19 06:09:36 +00:00
# include <LibLine/Editor.h>
namespace Line {
void KeyCallbackMachine : : register_key_input_callback ( Vector < Key > keys , Function < bool ( Editor & ) > callback )
{
m_key_callbacks . set ( keys , make < KeyCallback > ( move ( callback ) ) ) ;
}
void KeyCallbackMachine : : key_pressed ( Editor & editor , Key key )
{
2021-05-01 19:10:08 +00:00
dbgln_if ( CALLBACK_MACHINE_DEBUG , " Key<{}, {}> pressed, seq_length={}, {} things in the matching vector " , key . key , key . modifiers , m_sequence_length , m_current_matching_keys . size ( ) ) ;
2020-10-19 06:09:36 +00:00
if ( m_sequence_length = = 0 ) {
2021-02-23 19:42:32 +00:00
VERIFY ( m_current_matching_keys . is_empty ( ) ) ;
2020-10-19 06:09:36 +00:00
for ( auto & it : m_key_callbacks ) {
if ( it . key . first ( ) = = key )
m_current_matching_keys . append ( it . key ) ;
}
if ( m_current_matching_keys . is_empty ( ) ) {
m_should_process_this_key = true ;
return ;
}
}
+ + m_sequence_length ;
2021-07-21 11:42:54 +00:00
Vector < Vector < Key > > old_matching_keys ;
swap ( m_current_matching_keys , old_matching_keys ) ;
2020-10-19 06:09:36 +00:00
2021-07-21 11:42:54 +00:00
for ( auto & okey : old_matching_keys ) {
2020-10-19 06:09:36 +00:00
if ( okey . size ( ) < m_sequence_length )
continue ;
if ( okey [ m_sequence_length - 1 ] = = key )
m_current_matching_keys . append ( okey ) ;
}
if ( m_current_matching_keys . is_empty ( ) ) {
// Insert any keys that were captured
2021-07-21 11:42:54 +00:00
if ( ! old_matching_keys . is_empty ( ) ) {
auto & keys = old_matching_keys . first ( ) ;
2020-10-19 06:09:36 +00:00
for ( size_t i = 0 ; i < m_sequence_length - 1 ; + + i )
editor . insert ( keys [ i ] . key ) ;
}
m_sequence_length = 0 ;
m_should_process_this_key = true ;
return ;
}
2021-05-01 19:10:08 +00:00
if constexpr ( CALLBACK_MACHINE_DEBUG ) {
dbgln ( " seq_length={}, matching vector: " , m_sequence_length ) ;
for ( auto & key : m_current_matching_keys ) {
for ( auto & k : key )
dbgln ( " {}, {} " , k . key , k . modifiers ) ;
dbgln ( " " ) ;
}
2020-10-19 06:09:36 +00:00
}
m_should_process_this_key = false ;
for ( auto & key : m_current_matching_keys ) {
if ( key . size ( ) = = m_sequence_length ) {
m_should_process_this_key = m_key_callbacks . get ( key ) . value ( ) - > callback ( editor ) ;
m_sequence_length = 0 ;
m_current_matching_keys . clear ( ) ;
return ;
}
}
}
void KeyCallbackMachine : : interrupted ( Editor & editor )
{
m_sequence_length = 0 ;
m_current_matching_keys . clear ( ) ;
if ( auto callback = m_key_callbacks . get ( { ctrl ( ' C ' ) } ) ; callback . has_value ( ) )
m_should_process_this_key = callback . value ( ) - > callback ( editor ) ;
2021-01-06 16:59:43 +00:00
else
m_should_process_this_key = true ;
2020-10-19 06:09:36 +00:00
}
}