summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Davenport <qball@gmpclient.org>2017-09-29 08:32:09 +0200
committerDave Davenport <qball@gmpclient.org>2017-09-29 08:40:25 +0200
commitebffe5503d1709f00d4d7d85f0db4f8fe1dc4f42 (patch)
treec35dca4f2e9abeb271eeca3560b2ef83d3ff2831
parenta1ea3e268f92e9edcce6a794d98929effb036675 (diff)
Implement support for specifying negated match
- Prepending - inverts the matching result. - Fix logic window/drun browser. - Breaks API as argument token_match callback changed. - Update tests. Fixes: #665
-rw-r--r--include/helper-theme.h2
-rw-r--r--include/helper.h6
-rw-r--r--include/mode-private.h4
-rw-r--r--include/mode.h3
-rw-r--r--include/rofi-types.h10
-rw-r--r--include/view-internal.h2
-rw-r--r--source/dialogs/combi.c2
-rw-r--r--source/dialogs/dmenu.c6
-rw-r--r--source/dialogs/drun.c22
-rw-r--r--source/dialogs/help-keys.c2
-rw-r--r--source/dialogs/run.c2
-rw-r--r--source/dialogs/script.c2
-rw-r--r--source/dialogs/ssh.c2
-rw-r--r--source/dialogs/window.c12
-rw-r--r--source/helper.c39
-rw-r--r--source/history.c9
-rw-r--r--source/mode.c2
-rw-r--r--test/helper-tokenize.c9
-rw-r--r--test/mode-test.c4
19 files changed, 83 insertions, 57 deletions
diff --git a/include/helper-theme.h b/include/helper-theme.h
index b2ed659b..451320df 100644
--- a/include/helper-theme.h
+++ b/include/helper-theme.h
@@ -43,7 +43,7 @@
*
* @returns the updated retv list.
*/
-PangoAttrList *helper_token_match_get_pango_attr ( RofiHighlightColorStyle th, GRegex **tokens, const char *input, PangoAttrList *retv );
+PangoAttrList *helper_token_match_get_pango_attr ( RofiHighlightColorStyle th, rofi_int_matcher **tokens, const char *input, PangoAttrList *retv );
/**
* @param pfd Pango font description to validate.
diff --git a/include/helper.h b/include/helper.h
index a120ebab..b761e647 100644
--- a/include/helper.h
+++ b/include/helper.h
@@ -61,14 +61,14 @@ int helper_parse_setup ( char * string, char ***output, int *length, ... );
*
* @returns a newly allocated array of regex objest
*/
-GRegex **tokenize ( const char *input, int case_sensitive );
+rofi_int_matcher **tokenize ( const char *input, int case_sensitive );
/**
* @param tokens Array of regex objects
*
* Frees the array of regex expressions.
*/
-void tokenize_free ( GRegex ** tokens );
+void tokenize_free ( rofi_int_matcher ** tokens );
/**
* @param key The key to search for
@@ -136,7 +136,7 @@ int find_arg ( const char * const key );
*
* @returns TRUE when matches, FALSE otherwise
*/
-int helper_token_match ( GRegex * const *tokens, const char *input );
+int helper_token_match ( rofi_int_matcher * const *tokens, const char *input );
/**
* @param cmd The command to execute.
*
diff --git a/include/mode-private.h b/include/mode-private.h
index 14021183..a106c0bc 100644
--- a/include/mode-private.h
+++ b/include/mode-private.h
@@ -31,7 +31,7 @@
#include <gmodule.h>
/** ABI version to check if loaded plugin is compatible. */
-#define ABI_VERSION 0x00000005
+#define ABI_VERSION 0x00000006
/**
* @param data Pointer to #Mode object.
@@ -84,7 +84,7 @@ typedef char * ( *_mode_get_completion )( const Mode *sw, unsigned int selected_
*
* @returns 1 when it matches, 0 if not.
*/
-typedef int ( *_mode_token_match )( const Mode *data, GRegex **tokens, unsigned int index );
+typedef int ( *_mode_token_match )( const Mode *data, rofi_int_matcher **tokens, unsigned int index );
/**
* @param sw The #Mode pointer
diff --git a/include/mode.h b/include/mode.h
index 9b013ef3..d4acead9 100644
--- a/include/mode.h
+++ b/include/mode.h
@@ -29,6 +29,7 @@
#define ROFI_MODE_H
#include <cairo.h>
+#include <rofi-types.h>
/**
* @defgroup MODE Mode
*
@@ -164,7 +165,7 @@ ModeMode mode_result ( Mode *mode, int menu_retv, char **input, unsigned int sel
*
* @returns TRUE if matches
*/
-int mode_token_match ( const Mode *mode, GRegex **tokens, unsigned int selected_line );
+int mode_token_match ( const Mode *mode, rofi_int_matcher **tokens, unsigned int selected_line );
/**
* @param mode The mode to query
diff --git a/include/rofi-types.h b/include/rofi-types.h
index d9bae009..11255218 100644
--- a/include/rofi-types.h
+++ b/include/rofi-types.h
@@ -225,4 +225,14 @@ typedef struct rofi_range_pair
unsigned int start;
unsigned int stop;
} rofi_range_pair;
+
+
+/**
+ * Internal structure for matching.
+ */
+typedef struct rofi_int_matcher_t {
+ GRegex *regex;
+ gboolean invert;
+} rofi_int_matcher;
+
#endif // INCLUDE_ROFI_TYPES_H
diff --git a/include/view-internal.h b/include/view-internal.h
index 23d3ea71..ded7f9a6 100644
--- a/include/view-internal.h
+++ b/include/view-internal.h
@@ -126,7 +126,7 @@ struct RofiViewState
} mouse;
/** Regexs used for matching */
- GRegex **tokens;
+ rofi_int_matcher **tokens;
};
/** @} */
#endif
diff --git a/source/dialogs/combi.c b/source/dialogs/combi.c
index a41e54e6..f88a6fa0 100644
--- a/source/dialogs/combi.c
+++ b/source/dialogs/combi.c
@@ -187,7 +187,7 @@ static ModeMode combi_mode_result ( Mode *sw, int mretv, char **input, unsigned
}
return MODE_EXIT;
}
-static int combi_mode_match ( const Mode *sw, GRegex **tokens, unsigned int index )
+static int combi_mode_match ( const Mode *sw, rofi_int_matcher **tokens, unsigned int index )
{
CombiModePrivateData *pd = mode_get_private_data ( sw );
for ( unsigned i = 0; i < pd->num_switchers; i++ ) {
diff --git a/source/dialogs/dmenu.c b/source/dialogs/dmenu.c
index d1329a05..8bbf3a0a 100644
--- a/source/dialogs/dmenu.c
+++ b/source/dialogs/dmenu.c
@@ -371,7 +371,7 @@ static int dmenu_mode_init ( Mode *sw )
return TRUE;
}
-static int dmenu_token_match ( const Mode *sw, GRegex **tokens, unsigned int index )
+static int dmenu_token_match ( const Mode *sw, rofi_int_matcher **tokens, unsigned int index )
{
DmenuModePrivateData *rmpd = (DmenuModePrivateData *) mode_get_private_data ( sw );
return helper_token_match ( tokens, rmpd->cmd_list[index] );
@@ -612,7 +612,7 @@ int dmenu_switcher_dialog ( void )
char *select = NULL;
find_arg_str ( "-select", &select );
if ( select != NULL ) {
- GRegex **tokens = tokenize ( select, config.case_sensitive );
+ rofi_int_matcher **tokens = tokenize ( select, config.case_sensitive );
unsigned int i = 0;
for ( i = 0; i < cmd_list_length; i++ ) {
if ( helper_token_match ( tokens, cmd_list[i] ) ) {
@@ -623,7 +623,7 @@ int dmenu_switcher_dialog ( void )
tokenize_free ( tokens );
}
if ( find_arg ( "-dump" ) >= 0 ) {
- GRegex **tokens = tokenize ( config.filter ? config.filter : "", config.case_sensitive );
+ rofi_int_matcher **tokens = tokenize ( config.filter ? config.filter : "", config.case_sensitive );
unsigned int i = 0;
for ( i = 0; i < cmd_list_length; i++ ) {
if ( tokens == NULL || helper_token_match ( tokens, cmd_list[i] ) ) {
diff --git a/source/dialogs/drun.c b/source/dialogs/drun.c
index c891429b..d53880ac 100644
--- a/source/dialogs/drun.c
+++ b/source/dialogs/drun.c
@@ -667,32 +667,30 @@ static char *drun_get_completion ( const Mode *sw, unsigned int index )
}
}
-static int drun_token_match ( const Mode *data, GRegex **tokens, unsigned int index )
+static int drun_token_match ( const Mode *data, rofi_int_matcher **tokens, unsigned int index )
{
DRunModePrivateData *rmpd = (DRunModePrivateData *) mode_get_private_data ( data );
int match = 1;
if ( tokens ) {
for ( int j = 0; match && tokens != NULL && tokens[j] != NULL; j++ ) {
int test = 0;
- GRegex *ftokens[2] = { tokens[j], NULL };
+ rofi_int_matcher *ftokens[2] = { tokens[j], NULL };
// Match name
- if ( rmpd->entry_list[index].name &&
- helper_token_match ( ftokens, rmpd->entry_list[index].name ) ) {
- test = 1;
+ if ( rmpd->entry_list[index].name ) {
+ test = helper_token_match ( ftokens, rmpd->entry_list[index].name );
}
// Match generic name
- if ( !test && rmpd->entry_list[index].generic_name &&
- helper_token_match ( ftokens, rmpd->entry_list[index].generic_name ) ) {
- test = 1;
+ if ( test == tokens[j]->invert && rmpd->entry_list[index].generic_name) {
+ test = helper_token_match ( ftokens, rmpd->entry_list[index].generic_name );
}
// Match executable name.
- if ( !test && helper_token_match ( ftokens, rmpd->entry_list[index].exec ) ) {
- test = 1;
+ if ( test == tokens[j]->invert ) {
+ test = helper_token_match ( ftokens, rmpd->entry_list[index].exec );
}
// Match against category.
- if ( !test ) {
+ if ( test == tokens[j]->invert ) {
gchar **list = rmpd->entry_list[index].categories;
- for ( int iter = 0; !test && list && list[iter]; iter++ ) {
+ for ( int iter = 0; test == tokens[j]->invert && list && list[iter]; iter++ ) {
test = helper_token_match ( ftokens, list[iter] );
}
}
diff --git a/source/dialogs/help-keys.c b/source/dialogs/help-keys.c
index e7de6dee..25d5e041 100644
--- a/source/dialogs/help-keys.c
+++ b/source/dialogs/help-keys.c
@@ -104,7 +104,7 @@ static char *_get_display_value ( const Mode *sw, unsigned int selected_line, in
return g_strdup ( pd->messages[selected_line] );
}
static int help_keys_token_match ( const Mode *data,
- GRegex **tokens,
+ rofi_int_matcher **tokens,
unsigned int index
)
{
diff --git a/source/dialogs/run.c b/source/dialogs/run.c
index 561d02a3..8d7070ec 100644
--- a/source/dialogs/run.c
+++ b/source/dialogs/run.c
@@ -400,7 +400,7 @@ static char *_get_display_value ( const Mode *sw, unsigned int selected_line, G_
const RunModePrivateData *rmpd = (const RunModePrivateData *) sw->private_data;
return get_entry ? g_strdup ( rmpd->cmd_list[selected_line] ) : NULL;
}
-static int run_token_match ( const Mode *sw, GRegex **tokens, unsigned int index )
+static int run_token_match ( const Mode *sw, rofi_int_matcher **tokens, unsigned int index )
{
const RunModePrivateData *rmpd = (const RunModePrivateData *) sw->private_data;
return helper_token_match ( tokens, rmpd->cmd_list[index] );
diff --git a/source/dialogs/script.c b/source/dialogs/script.c
index 8d09e25e..60d19464 100644
--- a/source/dialogs/script.c
+++ b/source/dialogs/script.c
@@ -254,7 +254,7 @@ static char *_get_display_value ( const Mode *sw, unsigned int selected_line, G_
return get_entry ? g_strdup ( pd->cmd_list[selected_line] ) : NULL;
}
-static int script_token_match ( const Mode *sw, GRegex **tokens, unsigned int index )
+static int script_token_match ( const Mode *sw, rofi_int_matcher **tokens, unsigned int index )
{
ScriptModePrivateData *rmpd = sw->private_data;
return helper_token_match ( tokens, rmpd->cmd_list[index] );
diff --git a/source/dialogs/ssh.c b/source/dialogs/ssh.c
index 5ce66289..cb8216cb 100644
--- a/source/dialogs/ssh.c
+++ b/source/dialogs/ssh.c
@@ -516,7 +516,7 @@ static char *_get_display_value ( const Mode *sw, unsigned int selected_line, G_
*
* @returns TRUE if matches
*/
-static int ssh_token_match ( const Mode *sw, GRegex **tokens, unsigned int index )
+static int ssh_token_match ( const Mode *sw, rofi_int_matcher **tokens, unsigned int index )
{
SSHModePrivateData *rmpd = (SSHModePrivateData *) mode_get_private_data ( sw );
return helper_token_match ( tokens, rmpd->hosts_list[index] );
diff --git a/source/dialogs/window.c b/source/dialogs/window.c
index bc215795..0e6cb8c0 100644
--- a/source/dialogs/window.c
+++ b/source/dialogs/window.c
@@ -326,7 +326,7 @@ static client* window_client ( ModeModePrivateData *pd, xcb_window_t win )
g_free ( attr );
return c;
}
-static int window_match ( const Mode *sw, GRegex **tokens, unsigned int index )
+static int window_match ( const Mode *sw, rofi_int_matcher **tokens, unsigned int index )
{
ModeModePrivateData *rmpd = (ModeModePrivateData *) mode_get_private_data ( sw );
int match = 1;
@@ -343,23 +343,23 @@ static int window_match ( const Mode *sw, GRegex **tokens, unsigned int index )
// Now we want it to match only one item at the time.
// If hack not in place it would not match queries spanning multiple fields.
// e.g. when searching 'title element' and 'class element'
- GRegex *ftokens[2] = { tokens[j], NULL };
+ rofi_int_matcher *ftokens[2] = { tokens[j], NULL };
if ( c->title != NULL && c->title[0] != '\0' ) {
test = helper_token_match ( ftokens, c->title );
}
- if ( !test && c->class != NULL && c->class[0] != '\0' ) {
+ if ( test == tokens[j]->invert && c->class != NULL && c->class[0] != '\0' ) {
test = helper_token_match ( ftokens, c->class );
}
- if ( !test && c->role != NULL && c->role[0] != '\0' ) {
+ if ( test == tokens[j]->invert && c->role != NULL && c->role[0] != '\0' ) {
test = helper_token_match ( ftokens, c->role );
}
- if ( !test && c->name != NULL && c->name[0] != '\0' ) {
+ if ( test == tokens[j]->invert && c->name != NULL && c->name[0] != '\0' ) {
test = helper_token_match ( ftokens, c->name );
}
- if ( !test && c->wmdesktopstr != NULL && c->wmdesktopstr[0] != '\0' ) {
+ if ( test == tokens[j]->invert && c->wmdesktopstr != NULL && c->wmdesktopstr[0] != '\0' ) {
test = helper_token_match ( ftokens, c->wmdesktopstr );
}
diff --git a/source/helper.c b/source/helper.c
index e6d864df..8ead7f84 100644
--- a/source/helper.c
+++ b/source/helper.c
@@ -55,6 +55,7 @@
#include "rofi.h"
#include "view.h"
+
/**
* Textual description of positioning rofi.
*/
@@ -152,10 +153,12 @@ int helper_parse_setup ( char * string, char ***output, int *length, ... )
return FALSE;
}
-void tokenize_free ( GRegex ** tokens )
+void tokenize_free ( rofi_int_matcher ** tokens )
{
for ( size_t i = 0; tokens && tokens[i]; i++ ) {
- g_regex_unref ( (GRegex *) tokens[i] );
+ g_regex_unref ( (GRegex *) tokens[i]->regex );
+ g_free ( tokens[i] );
+
}
g_free ( tokens );
}
@@ -214,10 +217,15 @@ static inline GRegex * R ( const char *s, int case_sensitive )
return g_regex_new ( s, G_REGEX_OPTIMIZE | ( ( case_sensitive ) ? 0 : G_REGEX_CASELESS ), 0, NULL );
}
-static GRegex * create_regex ( const char *input, int case_sensitive )
+static rofi_int_matcher * create_regex ( const char *input, int case_sensitive )
{
GRegex * retv = NULL;
gchar *r;
+ rofi_int_matcher *rv = g_malloc0(sizeof(rofi_int_matcher));
+ if ( input && input[0] == '-') {
+ rv->invert = 1;
+ input++;
+ }
switch ( config.matching_method )
{
case MM_GLOB:
@@ -244,9 +252,10 @@ static GRegex * create_regex ( const char *input, int case_sensitive )
g_free ( r );
break;
}
- return retv;
+ rv->regex = retv;
+ return rv;
}
-GRegex **tokenize ( const char *input, int case_sensitive )
+rofi_int_matcher **tokenize ( const char *input, int case_sensitive )
{
if ( input == NULL ) {
return NULL;
@@ -257,10 +266,10 @@ GRegex **tokenize ( const char *input, int case_sensitive )
}
char *saveptr = NULL, *token;
- GRegex **retv = NULL;
+ rofi_int_matcher **retv = NULL;
if ( !config.tokenize ) {
- retv = g_malloc0 ( sizeof ( GRegex* ) * 2 );
- retv[0] = (GRegex *) create_regex ( input, case_sensitive );
+ retv = g_malloc0 ( sizeof ( rofi_int_matcher* ) * 2 );
+ retv[0] = create_regex ( input, case_sensitive );
return retv;
}
@@ -274,8 +283,8 @@ GRegex **tokenize ( const char *input, int case_sensitive )
// strtok should still be valid for utf8.
const char * const sep = " ";
for ( token = strtok_r ( str, sep, &saveptr ); token != NULL; token = strtok_r ( NULL, sep, &saveptr ) ) {
- retv = g_realloc ( retv, sizeof ( GRegex* ) * ( num_tokens + 2 ) );
- retv[num_tokens] = (GRegex *) create_regex ( token, case_sensitive );
+ retv = g_realloc ( retv, sizeof ( rofi_int_matcher* ) * ( num_tokens + 2 ) );
+ retv[num_tokens] = create_regex ( token, case_sensitive );
retv[num_tokens + 1] = NULL;
num_tokens++;
}
@@ -400,13 +409,14 @@ int find_arg_char ( const char * const key, char *val )
return FALSE;
}
-PangoAttrList *helper_token_match_get_pango_attr ( RofiHighlightColorStyle th, GRegex **tokens, const char *input, PangoAttrList *retv )
+PangoAttrList *helper_token_match_get_pango_attr ( RofiHighlightColorStyle th, rofi_int_matcher**tokens, const char *input, PangoAttrList *retv )
{
// Do a tokenized match.
if ( tokens ) {
for ( int j = 0; tokens[j]; j++ ) {
GMatchInfo *gmi = NULL;
- g_regex_match ( (GRegex *) tokens[j], input, G_REGEX_MATCH_PARTIAL, &gmi );
+ if ( tokens[j]->invert ) continue;
+ g_regex_match ( tokens[j]->regex, input, G_REGEX_MATCH_PARTIAL, &gmi );
while ( g_match_info_matches ( gmi ) ) {
int count = g_match_info_get_match_count ( gmi );
for ( int index = ( count > 1 ) ? 1 : 0; index < count; index++ ) {
@@ -460,13 +470,14 @@ PangoAttrList *helper_token_match_get_pango_attr ( RofiHighlightColorStyle th, G
return retv;
}
-int helper_token_match ( GRegex * const *tokens, const char *input )
+int helper_token_match ( rofi_int_matcher* const *tokens, const char *input )
{
int match = TRUE;
// Do a tokenized match.
if ( tokens ) {
for ( int j = 0; match && tokens[j]; j++ ) {
- match = g_regex_match ( (const GRegex *) tokens[j], input, 0, NULL );
+ match = g_regex_match ( tokens[j]->regex, input, 0, NULL );
+ match ^= tokens[j]->invert;
}
}
return match;
diff --git a/source/history.c b/source/history.c
index 56f2ffba..6b4a9794 100644
--- a/source/history.c
+++ b/source/history.c
@@ -80,6 +80,7 @@ static void __history_write_element_list ( FILE *fd, _element **list, unsigned i
static _element ** __history_get_element_list ( FILE *fd, unsigned int *length )
{
+ unsigned int real_length = 0;
_element **retv = NULL;
if ( length == NULL ) {
@@ -108,8 +109,12 @@ static _element ** __history_get_element_list ( FILE *fd, unsigned int *length )
if ( ( l - ( start - buffer ) ) < 2 ) {
continue;
}
- // Resize and check.
- retv = g_realloc ( retv, ( *length + 2 ) * sizeof ( _element* ) );
+ if ( real_length < (*length+2) )
+ {
+ real_length += 15;
+ // Resize and check.
+ retv = g_realloc ( retv, ( real_length ) * sizeof ( _element* ) );
+ }
retv[( *length )] = g_malloc ( sizeof ( _element ) );
diff --git a/source/mode.c b/source/mode.c
index c8ccfa68..28552e11 100644
--- a/source/mode.c
+++ b/source/mode.c
@@ -102,7 +102,7 @@ ModeMode mode_result ( Mode *mode, int menu_retv, char **input, unsigned int sel
return mode->_result ( mode, menu_retv, input, selected_line );
}
-int mode_token_match ( const Mode *mode, GRegex **tokens, unsigned int selected_line )
+int mode_token_match ( const Mode *mode, rofi_int_matcher **tokens, unsigned int selected_line )
{
g_assert ( mode != NULL );
g_assert ( mode->_token_match != NULL );
diff --git a/test/helper-tokenize.c b/test/helper-tokenize.c
index c251f04e..b4635df8 100644
--- a/test/helper-tokenize.c
+++ b/test/helper-tokenize.c
@@ -37,6 +37,7 @@
#include "xcb-internal.h"
#include "rofi.h"
#include "settings.h"
+#include "rofi-types.h"
static int test = 0;
@@ -75,7 +76,7 @@ int main ( G_GNUC_UNUSED int argc, G_GNUC_UNUSED char ** argv )
}
{
config.matching_method = MM_NORMAL;
- GRegex **tokens = tokenize ( "noot", FALSE );
+ rofi_int_matcher **tokens = tokenize ( "noot", FALSE );
TASSERT ( helper_token_match ( tokens, "aap noot mies") == TRUE );
TASSERT ( helper_token_match ( tokens, "aap mies") == FALSE );
@@ -108,7 +109,7 @@ int main ( G_GNUC_UNUSED int argc, G_GNUC_UNUSED char ** argv )
}
{
config.matching_method = MM_GLOB;
- GRegex **tokens = tokenize ( "noot", FALSE );
+ rofi_int_matcher **tokens = tokenize ( "noot", FALSE );
TASSERT ( helper_token_match ( tokens, "aap noot mies") == TRUE );
TASSERT ( helper_token_match ( tokens, "aap mies") == FALSE );
@@ -165,7 +166,7 @@ int main ( G_GNUC_UNUSED int argc, G_GNUC_UNUSED char ** argv )
}
{
config.matching_method = MM_FUZZY;
- GRegex **tokens = tokenize ( "noot", FALSE );
+ rofi_int_matcher **tokens = tokenize ( "noot", FALSE );
TASSERT ( helper_token_match ( tokens, "aap noot mies") == TRUE );
TASSERT ( helper_token_match ( tokens, "aap mies") == FALSE );
@@ -221,7 +222,7 @@ int main ( G_GNUC_UNUSED int argc, G_GNUC_UNUSED char ** argv )
}
{
config.matching_method = MM_REGEX;
- GRegex **tokens = tokenize ( "noot", FALSE );
+ rofi_int_matcher **tokens = tokenize ( "noot", FALSE );
TASSERT ( helper_token_match ( tokens, "aap noot mies") == TRUE );
TASSERT ( helper_token_match ( tokens, "aap mies") == FALSE );
diff --git a/test/mode-test.c b/test/mode-test.c
index 00720d95..1c1a271a 100644
--- a/test/mode-test.c
+++ b/test/mode-test.c
@@ -146,13 +146,13 @@ END_TEST
START_TEST(test_mode_match_entry)
{
- GRegex **t = tokenize( "primary-paste", FALSE );
+ rofi_int_matcher **t = tokenize( "primary-paste", FALSE );
ck_assert_ptr_nonnull ( t );
ck_assert_int_eq ( mode_token_match ( &help_keys_mode, t, 0), TRUE );
ck_assert_int_eq ( mode_token_match ( &help_keys_mode, t, 1), FALSE );
tokenize_free ( t );
- t = tokenize( "-paste", FALSE );
+ t = tokenize( "y-paste", FALSE );
ck_assert_ptr_nonnull ( t );
ck_assert_int_eq ( mode_token_match ( &help_keys_mode, t, 0), TRUE );