[PATCH] history_ignoredups (was: [PATCH] HISTCONTROL_ignoredups)

Tomas Styblo tripie at cpan.org
Sun Dec 29 09:18:50 UTC 2002


Hello.

I updated the history ignore duplicates patch for pre2.

It has following effects:

- Duplicates in existing history file are discarded when the
  history is loaded.

- If a newly inserted entry is a duplicate of an existing entry,
  then the older entry is moved to the first position in the list
  (from the point of view of the user) and the new entry is not
  inserted again.

I also put the patch to the patch tracker.

-- 
Tomas Styblo <tripie at cpan.org>
PGP: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xC97EA4B6
-------------- next part --------------
diff -purN mc-4.6.0-pre2/src/widget.c mc-4.6.0-pre2.new/src/widget.c
--- mc-4.6.0-pre2/src/widget.c	Thu Dec 26 00:31:14 2002
+++ mc-4.6.0-pre2.new/src/widget.c	Sun Dec 29 09:14:07 2002
@@ -803,12 +803,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)
@@ -823,12 +823,25 @@ 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. */
+	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 */
@@ -837,9 +850,10 @@ 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;
 
@@ -853,7 +867,6 @@ history_put (char *input_name, Hist *h)
 	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 */
@@ -873,11 +886,21 @@ history_put (char *input_name, Hist *h)
 	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. */
+	    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);
@@ -1049,7 +1072,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;
 
@@ -1063,11 +1086,32 @@ 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;
-    	new = g_new (Hist, 1);
+	/* 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;
+	}
+	new = g_new (Hist, 1);
 	in->history->next = new;
     } else
     	new = g_new (Hist, 1);


More information about the mc-devel mailing list