diff --git a/config/config.c b/config/config.c index d1503c4d2..06bb998e6 100644 --- a/config/config.c +++ b/config/config.c @@ -91,6 +91,8 @@ Settings config = { .fixed_num_lines = TRUE, /** Do not use history */ .disable_history = FALSE, + /** Always place the last-executed item in first place */ + .pin_last = TRUE, /** Sort the displayed list */ .sort = FALSE, /** Use levenshtein sorting when matching */ diff --git a/doc/rofi.1 b/doc/rofi.1 index a650073fd..c5648805c 100644 --- a/doc/rofi.1 +++ b/doc/rofi.1 @@ -825,6 +825,12 @@ Disable history Enable, disable sorting\. This setting can be changed at runtime (see \fB\-kb\-toggle\-sort\fR)\. . .P +\fB\-pin\-last\fR to enable \fB\-no\-pin\-last\fR to disable +. +.P +Always place the last-executed item in first place +. +.P \fB\-levenshtein\-sort\fR to enable \fB\-no\-levenshtein\-sort\fR to disable . .P diff --git a/doc/rofi.1.markdown b/doc/rofi.1.markdown index 0e9df72e1..27da3477f 100644 --- a/doc/rofi.1.markdown +++ b/doc/rofi.1.markdown @@ -491,6 +491,11 @@ Disable history Enable, disable sorting. This setting can be changed at runtime (see `-kb-toggle-sort`). +`-pin-last` to enable +`-no-pin-last` to disable + +Always place the last-executed item in first place + `-levenshtein-sort` to enable `-no-levenshtein-sort` to disable diff --git a/doc/test_xr.txt b/doc/test_xr.txt index 4998d9314..c2c134d8e 100644 --- a/doc/test_xr.txt +++ b/doc/test_xr.txt @@ -44,6 +44,8 @@ rofi.window-command: xkill -id {window} ! rofi.drun-match-fields: name,generic,exec,categories ! "Disable history in run/ssh" Set from: File rofi.disable-history: false +! "Always place the last-executed item in first place" Set from: Default +! rofi.pin-last: true ! "Use sorting" Set from: Default ! rofi.sort: false ! "Use levenshtein sorting also for fuzzy matching" Set from: File diff --git a/include/history.h b/include/history.h index 114f068f2..a78d74bd7 100644 --- a/include/history.h +++ b/include/history.h @@ -36,6 +36,7 @@ * * This uses the following options from the #config object: * * #Settings::disable_history + * * #Settings::pin_last * * @{ */ diff --git a/include/settings.h b/include/settings.h index 6361b969f..9911796e3 100644 --- a/include/settings.h +++ b/include/settings.h @@ -30,6 +30,8 @@ #include +#include "rofi-types.h" + /** * Enumeration indicating the matching method to use. * @@ -102,6 +104,8 @@ typedef struct unsigned int fixed_num_lines; /** Do not use history */ unsigned int disable_history; + /** Always place the last-executed item in first place */ + unsigned int pin_last; /** Toggle to enable sorting. */ unsigned int sort; /** Desktop entries to match in drun */ diff --git a/source/history.c b/source/history.c index 277ebf588..f37966e86 100644 --- a/source/history.c +++ b/source/history.c @@ -62,7 +62,12 @@ static void __history_write_element_list ( FILE *fd, _element **list, unsigned i return; } // Sort the list before writing out. - g_qsort_with_data ( list, length, sizeof ( _element* ), __element_sort_func, NULL ); + if ( config.pin_last ) { + // Leave the pinned element at the top. + g_qsort_with_data ( list + 1, length - 1, sizeof ( _element* ), __element_sort_func, NULL ); + } else { + g_qsort_with_data ( list, length, sizeof ( _element* ), __element_sort_func, NULL ); + } // Get minimum index. int min_value = list[length - 1]->index; @@ -214,11 +219,21 @@ void history_set ( const char *filename, const char *entry ) // set # hits list[length]->index = 1; + // save position + curr = length; + length++; list[length] = NULL; } } + if ( config.pin_last && curr != 0 ) { + // Move the updated item to the top of the list. + _element *tmp = list[curr]; + memmove ( list + 1, list, curr * sizeof ( _element* ) ); + list[0] = tmp; + } + fd = fopen ( filename, "w" ); if ( fd == NULL ) { g_warning ( "Failed to open file: %s", g_strerror ( errno ) ); diff --git a/source/xrmoptions.c b/source/xrmoptions.c index 36c296be4..7e0f3f046 100644 --- a/source/xrmoptions.c +++ b/source/xrmoptions.c @@ -137,6 +137,8 @@ static XrmOption xrmOptions[] = { "Desktop entry fields to match in drun", CONFIG_DEFAULT }, { xrm_Boolean, "disable-history", { .num = &config.disable_history }, NULL, "Disable history in run/ssh", CONFIG_DEFAULT }, + { xrm_Boolean, "pin-last", { .num = &config.pin_last }, NULL, + "Always place the last-executed item in first place", CONFIG_DEFAULT }, { xrm_Boolean, "sort", { .num = &config.sort }, NULL, "Use sorting", CONFIG_DEFAULT }, { xrm_Boolean, "levenshtein-sort", { .num = &config.levenshtein_sort }, NULL, diff --git a/test/history-test.c b/test/history-test.c index 5d37469d3..bb598fca1 100644 --- a/test/history-test.c +++ b/test/history-test.c @@ -31,6 +31,7 @@ #include #include #include +#include #include static int test = 0; @@ -45,6 +46,7 @@ const char *file = "text"; static void history_test ( void ) { unlink ( file ); + config.pin_last = 0; // Empty list. unsigned int length = 0; @@ -114,6 +116,17 @@ static void history_test ( void ) g_strfreev ( retv ); + // Pinning the last entry + config.pin_last = 1; + for ( unsigned int in = 0; in < 10; in++ ) { + history_set ( file, "popular" ); + } + history_set ( file, "last" ); + + retv = history_get_list ( file, &length ); + TASSERT ( g_strcmp0 ( retv[0], "last" ) == 0 ); + g_strfreev ( retv ); + unlink ( file ); }