diff --git a/doc/rofi.1 b/doc/rofi.1 index bdd0a5ac..0e0cdb98 100644 --- a/doc/rofi.1 +++ b/doc/rofi.1 @@ -998,13 +998,29 @@ Makes dmenu searches case\-insensitive \fB\-a\fR \fIX\fR . .P -Active row, mark row X as active (starting at 0)\. You can specify single element: \-a 3 A range: \-a 3\-8 or a set of rows: \-a 0,2 or any combination: \-a 0,2\-3,9 +Active row, mark \fIX\fR as active. Where \fIX\fR is a comma-separated list of python(1)-style indices and ranges, e.g. +indices start at \fB0\fR, \fB\-1\fR refers to the last row with \fB\-2\fR preceding it, ranges are left-open and right-close, and so on. You can specify: +. +.IP "\(bu" 4 +A single row: \'\fB5\fR\' +. +.IP "\(bu" 4 +A range of (last 3) rows: \'\fB\-3:\fR\' +. +.IP "\(bu" 4 +4 rows starting from row 7: \'\fB7:11\fR\' (or in legacy notation: \'\fB7\-10\fR\') +. +.IP "\(bu" 4 +A set of rows: \'\fB2,0,\-9\fR\' +. +.IP "\(bu" 4 +Or any combination: \'\fB\5,-3:,7:11,2,0,\-9\fR\' . .P \fB\-u\fR \fIX\fR . .P -Urgent row, mark row X as urgent (starting at 0)\. You can specify single element: \-u 3 A range: \-u 3\-8 or a set of rows: \-u 0,2 or any combination: \-u 0,2\-3,9 +Urgent row, mark \fIX\fR as urgent\. See \fB\-a\fR option\ for details. . .P \fB\-only\-match\fR diff --git a/doc/rofi.1.markdown b/doc/rofi.1.markdown index 4472ef0f..e4225ee3 100644 --- a/doc/rofi.1.markdown +++ b/doc/rofi.1.markdown @@ -572,19 +572,17 @@ Makes dmenu searches case-insensitive `-a` *X* -Active row, mark row X as active (starting at 0). -You can specify single element: -a 3 -A range: -a 3-8 -or a set of rows: -a 0,2 -or any combination: -a 0,2-3,9 +Active row, mark *X* as active. Where *X* is a comma-separated list of python(1)-style indices and ranges, e.g. indices start at 0, -1 refers to the last row with -2 preceding it, ranges are left-open and right-close, and so on. You can specify: + + * A single row: '5' + * A range of (last 3) rows: '-3:' + * 4 rows starting from row 7: '7:11' (or in legacy notation: '7-10') + * A set of rows: '2,0,-9' + * Or any combination: '5,-3:,7:11,2,0,-9' `-u` *X* -Urgent row, mark row X as urgent (starting at 0). -You can specify single element: -u 3 -A range: -u 3-8 -or a set of rows: -u 0,2 -or any combination: -u 0,2-3,9 +Urgent row, mark *X* as urgent. See `-a` option for details. `-only-match` diff --git a/include/rofi-types.h b/include/rofi-types.h index ae9ccf02..bb294dad 100644 --- a/include/rofi-types.h +++ b/include/rofi-types.h @@ -224,8 +224,8 @@ typedef struct Property */ typedef struct rofi_range_pair { - unsigned int start; - unsigned int stop; + int start; + int stop; } rofi_range_pair; /** diff --git a/source/dialogs/dmenu.c b/source/dialogs/dmenu.c index 739e94e6..3dd086ad 100644 --- a/source/dialogs/dmenu.c +++ b/source/dialogs/dmenu.c @@ -247,12 +247,16 @@ static char *get_display_data ( const Mode *data, unsigned int index, int *state DmenuModePrivateData *pd = (DmenuModePrivateData *) mode_get_private_data ( sw ); DmenuScriptEntry *retv = (DmenuScriptEntry *) pd->cmd_list; for ( unsigned int i = 0; i < pd->num_active_list; i++ ) { - if ( index >= pd->active_list[i].start && index <= pd->active_list[i].stop ) { + unsigned int start = pd->active_list[i].start >= 0 ? pd->active_list[i].start : pd->cmd_list_length + pd->active_list[i].start; + unsigned int stop = pd->active_list[i].stop >= 0 ? pd->active_list[i].stop : pd->cmd_list_length + pd->active_list[i].stop; + if ( index >= start && index <= stop ) { *state |= ACTIVE; } } for ( unsigned int i = 0; i < pd->num_urgent_list; i++ ) { - if ( index >= pd->urgent_list[i].start && index <= pd->urgent_list[i].stop ) { + unsigned int start = pd->urgent_list[i].start >= 0 ? pd->urgent_list[i].start : pd->cmd_list_length + pd->urgent_list[i].start; + unsigned int stop = pd->urgent_list[i].stop >= 0 ? pd->urgent_list[i].stop : pd->cmd_list_length + pd->urgent_list[i].stop; + if ( index >= start && index <= stop ) { *state |= URGENT; } } diff --git a/source/dialogs/script.c b/source/dialogs/script.c index 770679ac..ac526052 100644 --- a/source/dialogs/script.c +++ b/source/dialogs/script.c @@ -295,12 +295,16 @@ static char *_get_display_value ( const Mode *sw, unsigned int selected_line, G_ { ScriptModePrivateData *pd = sw->private_data; for ( unsigned int i = 0; i < pd->num_active_list; i++ ) { - if ( selected_line >= pd->active_list[i].start && selected_line <= pd->active_list[i].stop ) { + unsigned int start = pd->active_list[i].start >= 0 ? pd->active_list[i].start : pd->cmd_list_length + pd->active_list[i].start; + unsigned int stop = pd->active_list[i].stop >= 0 ? pd->active_list[i].stop : pd->cmd_list_length + pd->active_list[i].stop; + if ( selected_line >= start && selected_line <= stop ) { *state |= ACTIVE; } } for ( unsigned int i = 0; i < pd->num_urgent_list; i++ ) { - if ( selected_line >= pd->urgent_list[i].start && selected_line <= pd->urgent_list[i].stop ) { + unsigned int start = pd->urgent_list[i].start >= 0 ? pd->urgent_list[i].start : pd->cmd_list_length + pd->urgent_list[i].start; + unsigned int stop = pd->urgent_list[i].stop >= 0 ? pd->urgent_list[i].stop : pd->cmd_list_length + pd->urgent_list[i].stop; + if ( selected_line >= start && selected_line <= stop ) { *state |= URGENT; } } diff --git a/source/helper.c b/source/helper.c index 8b522841..783dc2cf 100644 --- a/source/helper.c +++ b/source/helper.c @@ -1117,20 +1117,29 @@ cairo_surface_t* cairo_image_surface_create_from_svg ( const gchar* file, int he static void parse_pair ( char *input, rofi_range_pair *item ) { - int index = 0; - const char * const sep = "-"; - for ( char *token = strsep ( &input, sep ); token != NULL; token = strsep ( &input, sep ) ) { + // Skip leading blanks. + while ( input != NULL && isblank(*input) ) + ++input; + + const char *sep[] = { "-", ":" }; + int pythonic = ( strchr(input, ':') || input[0] == '-' ) ? 1 : 0; + int index = 0; + + for ( char *token = strsep ( &input, sep[pythonic] ); token != NULL; token = strsep ( &input, sep[pythonic] ) ) { if ( index == 0 ) { - item->start = item->stop = (unsigned int) strtoul ( token, NULL, 10 ); + item->start = item->stop = (int) strtol ( token, NULL, 10 ); index++; + continue; } - else { - if ( token[0] == '\0' ) { - item->stop = 0xFFFFFFFF; - } - else{ - item->stop = (unsigned int) strtoul ( token, NULL, 10 ); - } + + if ( token[0] == '\0' ) { + item->stop = -1; + continue; + } + + item->stop = (int) strtol ( token, NULL, 10 ); + if ( pythonic ) { + --item->stop; } } }