* Simon Pamies wrote, On 27.12.2006 12:19 Uhr:
> * Simon Pamies wrote, On 27.12.2006 11:50 Uhr:
>> Hi All,
>>
>> I had some problems using the :buffer listing. If you have many files
>> (read 30+) open, the :buffer list is cluttered up with long directory
>> names (especially if working with files scattered over many directories)
>> and you loose overview. Switching to another buffer can be a real pain
>> especially because the completion completes on directory names. If you
>> have directories named like files then you're typing stuff w/o getting
>> to your file.
> 
> I just discovered a bug introduced shortly before creating the diffs: If
> hitting WCHAR after menu is shown, completion will still take
> directories. Will fix that in the next few days.

Regardless if I'll find a possibility to implement this using plugins
here the fixed code (buffer.c.diff, others remain unchanged). Works for me.

Simon Pamies
Index: buffer.c
===================================================================
--- buffer.c    (revision 195)
+++ buffer.c    (working copy)
@@ -47,6 +47,7 @@
 static void    free_buffer __ARGS((buf_T *));
 static void    free_buffer_stuff __ARGS((buf_T *buf, int free_options));
 static void    clear_wininfo __ARGS((buf_T *buf));
+int             fill_shortnames __ARGS(());
 
 #ifdef UNIX
 # define dev_T dev_t
@@ -221,6 +222,11 @@
     foldUpdateAll(curwin);
 #endif
 
+    /* spamsch: Trigger setting of shortname but only
+     * option emacsbuflist is set */
+    if (p_embl)
+        fill_shortnames();
+
 #ifdef FEAT_AUTOCMD
     /* need to set w_topline, unless some autocommand already did that. */
     if (!(curwin->w_valid & VALID_TOPLINE))
@@ -449,6 +455,7 @@
 #endif
        vim_free(buf->b_ffname);
        vim_free(buf->b_sfname);
+        vim_free(buf->b_sname);
        if (buf->b_prev == NULL)
            firstbuf = buf->b_next;
        else
@@ -1569,6 +1576,8 @@
        buf->b_ffname = NULL;
        vim_free(buf->b_sfname);
        buf->b_sfname = NULL;
+        vim_free(buf->b_sname);
+        buf->b_sname = NULL;
        if (buf != curbuf)
            free_buffer(buf);
        return NULL;
@@ -1992,6 +2001,7 @@
     int                diffmode;       /* find diff-mode buffers only */
 {
     buf_T      *buf;
+    buf_T       *sbuf;
     regprog_T  *prog;
     int                match = -1;
     int                find_listed;
@@ -2059,7 +2069,22 @@
                    {
                        if (match >= 0)         /* already found a match */
                        {
-                           match = -2;
+
+                            /* spamsch: This case can happen if the 
+                             * short buffer name is used and we have
+                             * two buffers with the same name. But because
+                             * only one buffer shortname can match exactly
+                             * the given one we check the buffer names
+                             * for an exact match. */
+                            match = -2;
+
+                            if (p_embl) /* Check only if option is set */
+                                for (sbuf = firstbuf; sbuf != NULL; sbuf = 
sbuf->b_next)
+                                    if (STRCMP(sbuf->b_sname, pattern) == 0) {
+                                        match = sbuf->b_fnum;
+                                        break;
+                                    }
+
                            break;
                        }
                        match = buf->b_fnum;    /* remember first match */
@@ -2088,12 +2113,71 @@
 }
 #endif
 
+/*
+ * spamsch: Go through the buffer list and fill
+ * the field b_sname for each buffer
+ */
+    int
+fill_shortnames()
+{
+    buf_T       *buf;
+    buf_T       *sbuf;
+    char_u      *pos;
+    int         counter;
+    int         fcounter;
+
+    counter = fcounter = 0;
+    for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
+
+        buf->b_sname = NULL;
+
+        if (buf->b_ffname != NULL && buf->b_p_bl) {
+            counter++;
+
+            /* We want to have the filename so we search for
+             * the last slash and get stuff behind it */
+            pos = vim_strrchr(buf->b_ffname, '/');
+
+            char_u *cpstr;
+            cpstr = (char_u *)alloc(255 * sizeof(char_u));
+            if (cpstr == NULL)
+                return FAIL;
+
+            if (pos != NULL) {
+                vim_strncpy(cpstr, pos+1, (unsigned)STRLEN(pos)-1);
+
+                for (sbuf = firstbuf; sbuf != NULL; sbuf = sbuf->b_next)
+                    if (buf != sbuf)
+                        if (sbuf->b_sname != NULL)
+                            if (STRCMP(sbuf->b_sname, cpstr) == 0) {
+                                char bnamenum[255];
+                                sprintf(bnamenum, "<%d>", ++fcounter);
+                                STRCAT(cpstr, bnamenum);
+                                break;
+                            }
+
+            } else {
+                STRCPY(cpstr, buf->b_ffname);
+            }
+
+            /* Put name into buf->b_sname */
+            buf->b_sname = vim_strsave(cpstr);
+            vim_free(cpstr);
+        }
+    }
+
+    return OK;
+
+}
+
+
 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
 
 /*
  * Find all buffer names that match.
  * For command line expansion of ":buf" and ":sbuf".
  * Return OK if matches found, FAIL otherwise.
+ *
  */
     int
 ExpandBufnames(pat, num_file, file, options)
@@ -2206,11 +2290,24 @@
 {
     char_u     *match;
 
-    /* First try the short file name, then the long file name. */
-    match = fname_match(prog, buf->b_sfname);
-    if (match == NULL)
-       match = fname_match(prog, buf->b_ffname);
+    /* spamsch: First try b_sname as it contains the shortname */
+    if (p_embl) {
+        match = fname_match(prog, buf->b_sname);
 
+        /* I emacsbuflist is set then we only try to complete
+         on b_sname */
+        return match;
+
+    } else 
+        match = fname_match(prog, buf->b_sfname);
+
+    if (match == NULL) {
+        /* Try the short file name, then the long file name. */
+        match = fname_match(prog, buf->b_sfname);
+        if (match == NULL)
+            match = fname_match(prog, buf->b_ffname);
+    }
+
     return match;
 }
 
@@ -2549,8 +2646,10 @@
        /* Removing the name. */
        vim_free(buf->b_ffname);
        vim_free(buf->b_sfname);
+        vim_free(buf->b_sname);
        buf->b_ffname = NULL;
        buf->b_sfname = NULL;
+        buf->b_sname = NULL;
 #ifdef UNIX
        st.st_dev = (dev_T)-1;
 #endif
@@ -2602,8 +2701,10 @@
 #endif
        vim_free(buf->b_ffname);
        vim_free(buf->b_sfname);
+        vim_free(buf->b_sname);
        buf->b_ffname = ffname;
        buf->b_sfname = sfname;
+        buf->b_sname = NULL;
     }
     buf->b_fname = buf->b_sfname;
 #ifdef UNIX
@@ -2640,8 +2741,10 @@
     {
        vim_free(buf->b_sfname);
        vim_free(buf->b_ffname);
+        vim_free(buf->b_sname);
        buf->b_ffname = vim_strsave(name);
        buf->b_sfname = NULL;
+        buf->b_sname = NULL;
        /* Allocate ffname and expand into full path.  Also resolves .lnk
         * files on Win32. */
        fname_expand(buf, &buf->b_ffname, &buf->b_sfname);

Reply via email to