summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Ho <ken.fsfoundry.org@gmail.com>2019-07-03 03:27:46 +0800
committerDave Davenport <DaveDavenport@users.noreply.github.com>2019-07-02 21:27:46 +0200
commitbe21fbae5d11916619f1b259a4b2191fcb19dae8 (patch)
tree4e48f7b0569ed2157a101abaddf40bad344bc306
parent2ddb525ff3710a06f7091849710fab8482e39503 (diff)
add pythonic rows selection to -a and -u (#985)
-rw-r--r--doc/rofi.120
-rw-r--r--doc/rofi.1.markdown18
-rw-r--r--include/rofi-types.h4
-rw-r--r--source/dialogs/dmenu.c8
-rw-r--r--source/dialogs/script.c8
-rw-r--r--source/helper.c31
6 files changed, 60 insertions, 29 deletions
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;
}
}
}