summaryrefslogtreecommitdiffstats
path: root/source/dialogs
diff options
context:
space:
mode:
authorMoritz Maxeiner <moritz@ucworks.org>2017-01-26 19:46:46 +0100
committerDave Davenport <DaveDavenport@users.noreply.github.com>2017-01-26 19:46:46 +0100
commit6b9dc1d0819fbde20b35c8ab20592f57a445611c (patch)
tree7dbcbcfb331dbe4d0c43f8cfdbc5365f977b2156 /source/dialogs
parent9941efa5f411348585a63efdacb1be382ab065ee (diff)
Combi mode: Bang mode prefixes with len>1 (#542)
* Combi mode: Bang mode prefixes with len>1 This is required to match on modes that share a prefix. Let 'power' and 'pass' be such modes for the following explanation: Previously, only the first character of after the bang was compared, so '!p' would always be matched to the 'pass' mode and there was no way to limit selection in combi mode to the 'power' mode. Now we can use prefixes of arbitrary length following the bang such as '!po' (matches 'power' mode), or '!pa' (matches 'pass' mode). Prefixes of length 1 are unchanged compared to the previous behaviour, i.e. '!p' will still match 'pass'. * Combi-mode prefixes should be utf-8 aware
Diffstat (limited to 'source/dialogs')
-rw-r--r--source/dialogs/combi.c46
1 files changed, 29 insertions, 17 deletions
diff --git a/source/dialogs/combi.c b/source/dialogs/combi.c
index a3f09284..f63c49bf 100644
--- a/source/dialogs/combi.c
+++ b/source/dialogs/combi.c
@@ -29,6 +29,7 @@
#include <stdio.h>
#include <rofi.h>
#include "settings.h"
+#include "helper.h"
#include <dialogs/dialogs.h>
@@ -151,18 +152,23 @@ static void combi_mode_destroy ( Mode *sw )
static ModeMode combi_mode_result ( Mode *sw, int mretv, char **input, unsigned int selected_line )
{
CombiModePrivateData *pd = mode_get_private_data ( sw );
- if ( *input[0] == '!' ) {
+
+ if ( input[0][0] == '!' ) {
int switcher = -1;
- for ( unsigned i = 0; switcher == -1 && i < pd->num_switchers; i++ ) {
- if ( ( *input )[1] == mode_get_name ( pd->switchers[i] )[0] ) {
- switcher = i;
+ char *eob = strchrnul ( input[0], ' ' );
+ ssize_t bang_len = g_utf8_pointer_to_offset ( input[0], eob ) - 1;
+ if ( bang_len > 0 ) {
+ for ( unsigned i = 0; switcher == -1 && i < pd->num_switchers; i++ ) {
+ const char *mode_name = mode_get_name ( pd->switchers[i] );
+ size_t mode_name_len = g_utf8_strlen ( mode_name, -1 );
+ if ( (size_t) bang_len <= mode_name_len && utf8_strncmp ( &input[0][1], mode_name, bang_len ) == 0 ) {
+ switcher = i;
+ }
}
}
- if ( switcher >= 0 ) {
- char *n = strchr ( *input, ' ' );
- // skip whitespace
- if ( n != NULL ) {
- n++;
+ if ( switcher >= 0 ) {
+ if ( eob[0] == ' ' ) {
+ char *n = eob+1;
return mode_result ( pd->switchers[switcher], mretv, &n,
selected_line - pd->starts[switcher] );
}
@@ -223,7 +229,7 @@ static char * combi_get_completion ( const Mode *sw, unsigned int index )
for ( unsigned i = 0; i < pd->num_switchers; i++ ) {
if ( index >= pd->starts[i] && index < ( pd->starts[i] + pd->lengths[i] ) ) {
char *comp = mode_get_completion ( pd->switchers[i], index - pd->starts[i] );
- char *mcomp = g_strdup_printf ( "!%c %s", mode_get_name ( pd->switchers[i] )[0], comp );
+ char *mcomp = g_strdup_printf ( "!%s %s", mode_get_name ( pd->switchers[i] ), comp );
g_free ( comp );
return mcomp;
}
@@ -237,14 +243,20 @@ static char * combi_preprocess_input ( Mode *sw, const char *input )
{
CombiModePrivateData *pd = mode_get_private_data ( sw );
pd->current = NULL;
- if ( input != NULL && input[0] == '!' && strlen ( input ) > 1 ) {
- for ( unsigned i = 0; i < pd->num_switchers; i++ ) {
- if ( input[1] == mode_get_name ( pd->switchers[i] )[0] ) {
- pd->current = pd->switchers[i];
- if ( input[2] == '\0' ) {
- return NULL;
+ if ( input != NULL && input[0] == '!' ) {
+ char *eob = strchrnul ( input, ' ' );
+ ssize_t bang_len = g_utf8_pointer_to_offset ( input, eob ) - 1;
+ if ( bang_len > 0 ) {
+ for ( unsigned i = 0; i < pd->num_switchers; i++ ) {
+ const char *mode_name = mode_get_name ( pd->switchers[i] );
+ size_t mode_name_len = g_utf8_strlen ( mode_name, -1 );
+ if ( (size_t) bang_len <= mode_name_len && utf8_strncmp ( &input[1], mode_name, bang_len ) == 0 ) {
+ pd->current = pd->switchers[i];
+ if ( eob[0] == '\0' || eob[1] == '\0' ) {
+ return NULL;
+ }
+ return g_strdup ( eob+1 );
}
- return g_strdup ( &input[2] );
}
}
}