bug-bash
[Top][All Lists]
Advanced

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

[PATCH] preserving case in casefold completion


From: Peder Stray
Subject: [PATCH] preserving case in casefold completion
Date: 20 Sep 2001 19:57:02 +0200
User-agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7

[ Seems that some articles got lost on their way to my newsserver... so
  I post this patch again. ]

If you use case folding completion, bash/readline often changes the case
of the word you try to complete even if there exist a possible
completion without changing case. Let's say you have two directories,
'Mail' and 'mail', the only two straring with '[Mm]a'. If you have typed
either 'Ma' or 'ma' and press TAB for completion you get either 'Mail'
or 'mail' depending on which of the direcories occur first in the
match_list (usually depending on witch of the two were returned first by
readdir). The fact that bash/readline is inconsistent in which
completion it uses, and that it changes case unnecessary, has lead me to
write a patch to fix the problem. enjoy.

--- bash-2.05/lib/readline/complete.c.foldfix   Wed Feb 14 13:47:18 2001
+++ bash-2.05/lib/readline/complete.c   Mon Sep 17 21:16:20 2001
@@ -747,7 +747,7 @@
 }
 
 /* Find the common prefix of the list of matches, and put it into
-   matches[0]. */
+   match_list[0]. */
 static int
 compute_lcd_of_matches (match_list, matches, text)
      char **match_list;
@@ -803,7 +803,42 @@
   else
     {
       match_list[0] = xmalloc (low + 1);
-      strncpy (match_list[0], match_list[1], low);
+
+      /* If we use case folding, try to keep the same case as text */
+      if (_rl_completion_case_fold)
+       {
+
+         if (strlen(text) < low)
+           {
+             /* we need a sorted list to get consistent answers */
+             qsort (match_list+1, matches, sizeof (char *),
+                    (QSFUNC *)_rl_qsort_string_compare);
+
+             /* find the first entry in match_list with text as prefix */
+             for (i = 1; i <= matches; i++)
+               if (!strncmp(match_list[i], text, strlen (text)))
+                 {
+                   strncpy (match_list[0], match_list[i], low);
+                   break;
+                 }
+
+             /* no casematch, so use the first entry */
+             if (i > matches)
+               strncpy (match_list[0], match_list[1], low);
+
+           }
+         else
+           {
+             /* else just use text */
+             strncpy (match_list[0], text, low);
+           }
+
+       }
+      else
+       {
+         strncpy (match_list[0], match_list[1], low);
+       }
+
       match_list[0][low] = '\0';
     }
 


-- 
[ IRL: Peder Stray                                  ]
[ "A new life awaits you in the off world colonies" ]



reply via email to

[Prev in Thread] Current Thread [Next in Thread]