* 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);