Re: [PATCH] HISTCONTROL_ignoredups (was: [PATCH] history_show_duplicates)



* Tomas Styblo <tripie cpan org> [Mon, 25 Nov 2002]:
> * Andrew V. Samoilov <sav bcs zp ua> [Mon, 25 Nov 2002]:
> > >Here is a patch which adds a new configuration option:
> > >
> > >    history_show_duplicates
> > >
> > >The option specifies whether the history panels will show
> > >duplicate entries more than once. 
> > 
> > Maybe it will be more consistent to use HISTCONTROL environment variable?
> 
> It's in fact a very good idea. I'll provide the new patch in a few
> days.

Here is the new patch. It allows the user to set the HISTCONTROL
environment variable to a value of "ignoredups" if he wants to
have only unique entries in history widgets.

-- 
Tomas Styblo <tripie cpan org>
PGP: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xC97EA4B6
"People demand freedom of speech as a compensation for
 the freedom of thought which they seldom use." -Kierkegaard
diff -purN mc-4.6.0-pre1/doc/mc.1.in mc-4.6.0-pre1.dev/doc/mc.1.in
--- mc-4.6.0-pre1/doc/mc.1.in	Wed Aug 21 03:08:46 2002
+++ mc-4.6.0-pre1.dev/doc/mc.1.in	Fri Nov 29 02:41:05 2002
@@ -1041,7 +1041,10 @@ contents or the date times, it just chec
 .PP
 The Command history command shows a list of typed commands. The
 selected command is copied to the command line. The command history
-can also be accessed by typing M-p or M-n.
+can also be accessed by typing M-p or M-n. Duplicate history entries
+are ignored if environment variable
+.B HISTCONTROL 
+is set to a value of "ignoredups".
 .PP
 The
 .\"LINK2"
diff -purN mc-4.6.0-pre1/src/setup.c mc-4.6.0-pre1.dev/src/setup.c
--- mc-4.6.0-pre1/src/setup.c	Mon Aug 19 06:16:47 2002
+++ mc-4.6.0-pre1.dev/src/setup.c	Fri Nov 29 03:33:19 2002
@@ -60,6 +60,7 @@
 extern char *find_ignore_dirs;
 
 extern int num_history_items_recorded;
+extern int history_ignoredups;
 
 char *profile_name;		/* .mc/ini */
 char *global_profile_name;	/* mc.lib */
@@ -496,7 +497,7 @@ setup_init (void)
 void
 load_setup (void)
 {
-    char *profile;
+    char *profile, *hc;
     int    i;
 
     profile = setup_init ();
@@ -510,6 +511,15 @@ load_setup (void)
 	*options [i].opt_addr =
 	    get_int (profile, options [i].opt_name, *options [i].opt_addr);
 
+    /* Get configuration from environment variables. */
+    /* Find out if the user wants to ignore duplicate history entries.
+     * Store the result into a global variable. This variable 
+     * will never be modified. */
+    hc = getenv("HISTCONTROL");
+    if (hc && ! strcmp(hc, "ignoredups")) {
+	history_ignoredups = 1;
+    }
+
     load_layout (profile);
 
     load_panelize ();
diff -purN mc-4.6.0-pre1/src/widget.c mc-4.6.0-pre1.dev/src/widget.c
--- mc-4.6.0-pre1/src/widget.c	Sat Jul 20 04:54:52 2002
+++ mc-4.6.0-pre1.dev/src/widget.c	Fri Nov 29 04:05:28 2002
@@ -47,6 +47,9 @@ static int button_event (Gpm_Event *even
 
 int quote = 0;
 
+/* Ignore duplicate history entries ? Initialized in setup.c. */
+int history_ignoredups = 0; 
+
 static int
 button_callback (Dlg_head *h, WButton *b, int Msg, int Par)
 {
@@ -798,12 +801,12 @@ int num_history_items_recorded = 60;
 
 Hist *history_get (char *input_name)
 {
-    int i;
-    Hist *old, *new;
+    int i, omitdup = 0;
+    Hist *old, *new, *hd;
     char *profile;
-    
-    old = new = NULL;
-    
+
+    old = new = hd = NULL;
+
     if (!num_history_items_recorded)	/* this is how to disable */
 	return 0;
     if (!input_name)
@@ -818,12 +821,27 @@ Hist *history_get (char *input_name)
 	GetPrivateProfileString (input_name, key_name, "", this_entry, sizeof (this_entry), profile);
 	if (!*this_entry)
 	    break;
-	new = g_new0 (Hist, 1);
-	new->text = g_strdup (this_entry);
-	new->prev = old;	/* set up list pointers */
-	if (old)
-	    old->next = new;
-	old = new;
+
+	/* Test if current entry is a duplicate. */
+	if (history_ignoredups) {
+        hd = old;
+	    omitdup = 0;
+	    while (hd) {
+		if (! strcmp (hd->text, this_entry)) {
+		    omitdup = 1;
+		    break;
+		}
+		hd = hd->prev;
+	    }
+	}
+	if (! omitdup) {
+	    new = g_new0 (Hist, 1);
+	    new->text = g_strdup (this_entry);
+	    new->prev = old;	/* set up list pointers */
+	    if (old)
+		old->next = new;
+	    old = new;
+	}
     }
     g_free (profile);
     return new;			/* return pointer to last entry in list */
@@ -831,9 +849,10 @@ Hist *history_get (char *input_name)
 
 void history_put (char *input_name, Hist *h)
 {
-    int i;
+    int i, omitdup = 0;
     char *profile;
-
+    Hist *hd;
+    
     if (!input_name)
 	return;
 
@@ -847,7 +866,6 @@ void history_put (char *input_name, Hist
 	return;
 
     profile = concat_dir_and_file (home_dir, HISTORY_FILE_NAME);
-
     if ((i = open (profile, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) != -1)
 	close (i);
     /* Just in case I forgot to strip passwords somewhere -- Norbert */
@@ -867,11 +885,23 @@ void history_put (char *input_name, Hist
 	profile_clean_section (input_name, profile);
 
     /* dump histories into profile */
-    for (i = 0; h; h = h->next){
-	if (h->text){
+    for (i = 0; h; h = h->next) {
+	if (h->text) {
+	    /* Test if current entry is a duplicate. */
+	    if (history_ignoredups) {
+		hd = h->prev;
+		omitdup = 0;
+		while (hd) {
+		    if (! strcmp (hd->text, h->text)) {
+			omitdup = 1;
+			break;
+		    }
+		    hd = hd->prev;
+		}
+	    }
 
-	    /* probably aren't any null entries, but lets be sure */
-	    if (*(h->text)){
+	    /* Skip duplicates and make sure there aren't any null entries. */
+	    if (! omitdup && *(h->text)){
 		char key_name[BUF_TINY];
 		g_snprintf (key_name, sizeof(key_name), "%d", i++);
 		WritePrivateProfileString (input_name, key_name, h->text, profile);
@@ -1061,7 +1091,7 @@ push_history (WInput *in, char *text)
 	N_(" FTP to machine "),
 	N_(" SMB link to machine ")
     };
-    Hist *new;
+    Hist *new, *hd;
     char *p;
     int i;
 
@@ -1075,10 +1105,39 @@ push_history (WInput *in, char *text)
     if (!*p)
         return 0;
     if (in->history){
+	/* Go to the last element of the history list. */
 	while (in->history->next)
 	    in->history = in->history->next;
-	if (!strcmp (in->history->text, text))
-	    return 1;
+	if (history_ignoredups) {
+	    /* If the new entry is a duplicate of any of the existing 
+	     * entries then move it to the end of the history list
+	     * instead of pushing it again. The result is that the last
+	     * command used is always presented as the first choice. */
+	    hd = in->history;
+	    while (hd) {
+		if (! strcmp(hd->text, text)) {
+		    if (hd != in->history) {
+			/* If the found dup is not the last entry
+			 * then move the dup to the end. */
+			in->history->next = hd;
+			hd->next->prev = hd->prev;
+			if (hd->prev) /* If dup is not first entry. */
+			    hd->prev->next = hd->next;
+			hd->next = NULL;
+			hd->prev = in->history;
+			in->history = hd;
+		    }
+		    return 1;
+		}
+		hd = hd->prev;
+	    }
+	}
+	else {
+	    /* The default mc behaviour: push the entry only if
+	     * it is not a duplicate of the _previous_ entry. */
+	    if (!strcmp (in->history->text, text))
+		return 1;
+	}
     	new = g_new (Hist, 1);
 	in->history->next = new;
     } else

Attachment: pgpWkTjRsJQXp.pgp
Description: PGP signature



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]