Package: grun
Version: 0.9.3-1
Followup-For: Bug #310748

Please find attached a patch to make grun use LRU order of entries.

-- System Information:
Debian Release: 5.0.4
  APT prefers stable
  APT policy: (600, 'stable'), (500, 'proposed-updates')
Architecture: i386 (i686)

Kernel: Linux 2.6.26-2-686 (SMP w/4 CPU cores)
Locale: LANG=ru_RU.KOI8-R, LC_CTYPE=ru_RU.KOI8-R (charmap=KOI8-R)
Shell: /bin/sh linked to /bin/bash

Versions of packages grun depends on:
ii  libc6                   2.7-18lenny2     GNU C Library: Shared libraries
ii  libglib2.0-0            2.16.6-3         The GLib library of C routines
ii  libgtk2.0-0             2.12.12-1~lenny1 The GTK+ graphical user interface 

grun recommends no packages.

Versions of packages grun suggests:
ii  kterm [x-terminal-emulator]   6.2.0-46   Multi-lingual terminal emulator fo
ii  xterm [x-terminal-emulator]   235-2      X terminal emulator

-- no debconf information
Implement wishlist bug #310748 `order of entries should be LRU'. Last recently
used command is immediately moved to the top of the command list.

It is ugly, but it works with the existing code. Since GtkList copies strings to
serve as labels I have no choice but to compare string contents, and not
pointers, when looking for LRU command in history.

--
/Dmitry <ledes...@gmail.com>

diff -ur grun-0.9.3/grun.c ../grun-0.9.3/grun.c
--- grun-0.9.3/grun.c   2008-01-14 19:28:10.000000000 +1300
+++ ../grun-0.9.3/grun.c        2010-04-18 04:19:03.000000000 +1200
@@ -63,7 +63,8 @@
 char *getLine(FILE *file);
 int isFileExec(const gchar *file);
 GList *loadHistory();
-int saveHistory(const char *cmd, sgrun *gdat);
+int appendHistory(const char *cmd, sgrun *gdat);
+int saveHistory(const sgrun *gdat);
 void gquit();
 void startApp(const gchar *cmd, sgrun *gdat);
 gint gcomplete(sgrun *gdat, const gchar *twrk, gint oldpos);
@@ -276,7 +277,8 @@
        return tmp;
 }
 
-int saveHistory(const char *cmd, sgrun *gdat) {
+/* Append newly added command to ~/.grun_history */
+int appendHistory(const char *cmd, sgrun *gdat) {
        FILE *fHnd;
        char *fname, *home_env;
        int err, found;
@@ -306,6 +308,32 @@
        return FALSE;
 }
 
+/* Save whole history to ~/.grun_history */
+int saveHistory(const sgrun *gdat) {
+       FILE *fHnd;
+       char *fname, *home_env;
+       GList *item;
+
+       home_env = getenv("HOME");
+       fname = g_strconcat(home_env, DIR_CHAR, DOT_CHAR, "grun_history", NULL);
+       
+       fHnd = fopen(fname, "wb");
+       g_free(fname);
+       
+       if (!fHnd) {
+               return FALSE;
+       }
+               
+       item = g_list_last(gdat->history);
+       while (item) {
+               fprintf(fHnd, "%s\n", (gchar *)item->data);
+               item = g_list_previous(item);
+       }
+       fclose(fHnd);
+
+       return TRUE;
+}
+
 void gquit() {
        gtk_main_quit();
        exit(0);
@@ -366,7 +394,7 @@
 
 void startApp(const gchar *cmd, sgrun *gdat) {
        char **args, *work, *twrk, *assoc, *hold, *split;
-       int cnt, len, scnt, res;
+       int cnt = FALSE, len, scnt, res;
 
        res = isFileExec(cmd);
        if (res != -1) {
@@ -406,7 +434,31 @@
          _exit(0);
        }
 
-       cnt = saveHistory(cmd, gdat);
+       /* Update ~/.grun_history if:
+        *   a new command was executed;
+        *   OR
+        *   LRU command changed (e.g. the oldest command was executed and thus
+        *   became first in list).
+        */
+       if (!GTK_LIST(GTK_COMBO(gdat->cmb)->list)->selection) {
+         cnt = appendHistory(cmd, gdat);
+         gdat->history = g_list_prepend(gdat->history, (gpointer) cmd);
+       } else {
+         const gchar *selectedCmd =
+           gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(gdat->cmb)->entry));
+         char  *lastHistoryCmd = gdat->history->data;
+         /* Move the currently selected command to the top of history, unless
+          * it's already there. */
+         if (strcmp(selectedCmd, lastHistoryCmd)) {
+           GList *item = gdat->history;
+           while (item && strcmp(item->data, selectedCmd)) {
+             item = g_list_next(item);
+           }
+           gdat->history = g_list_remove_link(gdat->history, item);
+           gdat->history = g_list_concat(item, gdat->history);
+           cnt = saveHistory(gdat);
+         }
+       }
 
        if ( ! (gdat->status & 0x80)) {
          g_list_free(gdat->history);
@@ -414,10 +466,8 @@
          return;
        }
 
-       if (cnt) {
-         gdat->history = g_list_prepend(gdat->history, (gpointer) cmd);
+       if (cnt)
          gtk_combo_set_popdown_strings(GTK_COMBO (gdat->cmb), gdat->history);
-       }
 
        /* the order does matter here;
           move the cursor first,

Reply via email to