2010/7/28 Bram Moolenaar <b...@moolenaar.net>:
>
> Dominique Pellé wrote:
>
>> > Please try and review the attached patch.
>> > It think it does what's needed and it's rather simple:
>> >
>> > :setfiletype completes using things that match
>> > $VIMRUNTIME/{syntax,ftplugin,indent}/*.vim and
>> > ~/.vim/{syntax,ftplugin,indent}/*.vim
>> >
>> > :ownsyntax behaves as before, i.e. it completes using things that
>> > match $VIMRUNTIME/syntax/*.vim and ~/.vim/syntax/*.vim
>> >
>> > You can verify that :ownsyntax and :setfiletype complete
>> > differently with this example:
>> >
>> > :setfiletype host<CTRL-D>
>> > hostconf     hostsaccess
>> >
>> > :ownsyntax host<CTRL-D>
>> > hostconf
>> >
>> > I have not done anything about the special files such as
>> > syntax/2html.vim. I could hard-code something to exclude
>> > them but it'd be ugly. Hopefully we can consider moving
>> > those special files.
>>
>>
>> I send this patch again with slightly more elegant way of doing it
>> saving 3 lines of code. Sorry for the noise.
>
> Thanks.
>
> I'll await the updated version that re-uses the function to remove
> duplicates.
>
> Using fnamecmp() or STRCMP(): fnamecmp() should work the same or
> slightly better.  E.g. if there is an indent/perl.vim and
> syntax/Perl.vim it should end up only in "perl".  But only on systems
> where case is ignored.  That's about correct, it matches the way Vim
> will find and read the file from the filetype.  Another solution would
> be to lower case the name always, as filetypes are supposed to be lower
> case.


Here is the updated patch taking into account Nazri's comments.
Using fnamecmp() is fine indeed after rethinking about it.

remove_duplicates() now also loops backwards to avoid moving
elements that would later be removed.

You can check that completion works with this example:

You can verify that :ownsyntax and :setfiletype complete
differently with this example:

  :setfiletype host<CTRL-D>
  hostconf     hostsaccess

  :ownsyntax host<CTRL-D>
  hostconf

Still remains to be solved the problem of the few files such as
syntax/2html.vim which are not syntax or ftplugin files.
I'd prefer to move those special files somewhere else.  Is that OK?

Cheers
-- Dominique

-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
diff -r 33148c37f3c9 src/ex_getln.c
--- a/src/ex_getln.c	Wed Jul 28 19:38:16 2010 +0200
+++ b/src/ex_getln.c	Wed Jul 28 20:43:48 2010 +0200
@@ -4116,6 +4116,7 @@
 	if (context == EXPAND_HELP
 		|| context == EXPAND_COLORS
 		|| context == EXPAND_COMPILER
+		|| context == EXPAND_OWNSYNTAX
 		|| context == EXPAND_FILETYPE
 		|| (context == EXPAND_TAGS && fname[0] == '/'))
 	    retval = vim_strnsave(fname, len);
@@ -4502,8 +4503,10 @@
 	return ExpandRTDir(pat, num_file, file, "colors");
     if (xp->xp_context == EXPAND_COMPILER)
 	return ExpandRTDir(pat, num_file, file, "compiler");
+    if (xp->xp_context == EXPAND_OWNSYNTAX)
+	return ExpandRTDir(pat, num_file, file, "syntax");
     if (xp->xp_context == EXPAND_FILETYPE)
-	return ExpandRTDir(pat, num_file, file, "syntax");
+	return ExpandRTDir(pat, num_file, file, "{syntax,indent,ftplugin}");
 # if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL)
     if (xp->xp_context == EXPAND_USER_LIST)
 	return ExpandUserList(xp, num_file, file);
@@ -4944,14 +4947,16 @@
 
 /*
  * Expand color scheme, compiler or filetype names:
- * 'runtimepath'/{dirname}/{pat}.vim
+ * 'runtimepath'/{dirnames}/{pat}.vim
+ * dirnames may contain one directory (ex: "colorscheme") or can be a glob
+ * expression matching multiple directories (ex: "{syntax,ftplugin,indent}").
  */
     static int
-ExpandRTDir(pat, num_file, file, dirname)
+ExpandRTDir(pat, num_file, file, dirnames)
     char_u	*pat;
     int		*num_file;
     char_u	***file;
-    char	*dirname;	/* "colors", "compiler" or "syntax" */
+    char	*dirnames;
 {
     char_u	*all;
     char_u	*s;
@@ -4960,10 +4965,10 @@
 
     *num_file = 0;
     *file = NULL;
-    s = alloc((unsigned)(STRLEN(pat) + STRLEN(dirname) + 7));
+    s = alloc((unsigned)(STRLEN(pat) + STRLEN(dirnames) + 7));
     if (s == NULL)
 	return FAIL;
-    sprintf((char *)s, "%s/%s*.vim", dirname, pat);
+    sprintf((char *)s, "%s/%s*.vim", dirnames, pat);
     all = globpath(p_rtp, s, 0);
     vim_free(s);
     if (all == NULL)
@@ -4991,6 +4996,13 @@
 	    ++e;
     }
     vim_free(all);
+
+    /* Sort and remove duplicates which can happen when specifying multiple
+     * directories in dirnames such as "{syntax,ftplugin,indent}".
+     */
+    sort_strings((char_u **)ga.ga_data, ga.ga_len);
+    remove_duplicates(&ga);
+
     *file = ga.ga_data;
     *num_file = ga.ga_len;
     return OK;
diff -r 33148c37f3c9 src/misc1.c
--- a/src/misc1.c	Wed Jul 28 19:38:16 2010 +0200
+++ b/src/misc1.c	Wed Jul 28 20:43:48 2010 +0200
@@ -9238,7 +9238,6 @@
 #if defined(FEAT_SEARCHPATH)
 static int find_previous_pathsep __ARGS((char_u *path, char_u **psep));
 static int is_unique __ARGS((char_u *maybe_unique, garray_T *gap, int i));
-static void remove_duplicates __ARGS((garray_T *gap));
 static void uniquefy_paths __ARGS((garray_T *gap, char_u *pattern));
 static int expand_in_path __ARGS((garray_T *gap, char_u	*pattern, int flags));
 
@@ -9308,29 +9307,6 @@
 }
 
 /*
- * Remove adjacent duplicate entries from "gap", which is a list of file names
- * in allocated memory.
- */
-    static void
-remove_duplicates(gap)
-    garray_T *gap;
-{
-    int	    i;
-    int	    j;
-    char_u  **fnames = (char_u **)gap->ga_data;
-
-    for (i = 1; i < gap->ga_len; ++i)
-	if (fnamecmp(fnames[i - 1], fnames[i]) == 0)
-	{
-	    vim_free(fnames[i]);
-	    for (j = i + 1; j < gap->ga_len; ++j)
-		fnames[j - 1] = fnames[j];
-	    --gap->ga_len;
-	    --i;
-	}
-}
-
-/*
  * Sorts, removes duplicates and modifies all the fullpath names in gap so that
  * they are unique with respect to each other while conserving the part that
  * matches the pattern. Beware, this is at least O(n^2) wrt gap->ga_len.
@@ -9450,6 +9426,30 @@
 }
 #endif
 
+#if defined(FEAT_SEARCHPATH) || defined(FEAT_CMDL_COMPL) || defined(PROTO)
+/*
+ * Remove adjacent duplicate entries from "gap", which is a list of file names
+ * in allocated memory.
+ */
+    void
+remove_duplicates(gap)
+    garray_T	*gap;
+{
+    int	    i;
+    int	    j;
+    char_u  **fnames = (char_u **)gap->ga_data;
+
+    for (i = gap->ga_len - 1; i > 0; --i)
+	if (fnamecmp(fnames[i - 1], fnames[i]) == 0)
+	{
+	    vim_free(fnames[i]);
+	    for (j = i + 1; j < gap->ga_len; ++j)
+		fnames[j - 1] = fnames[j];
+	    --gap->ga_len;
+	}
+}
+#endif
+
 /*
  * Generic wildcard expansion code.
  *
diff -r 33148c37f3c9 src/proto/misc1.pro
--- a/src/proto/misc1.pro	Wed Jul 28 19:38:16 2010 +0200
+++ b/src/proto/misc1.pro	Wed Jul 28 20:43:48 2010 +0200
@@ -90,6 +90,7 @@
 int expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file, int flags));
 int match_suffix __ARGS((char_u *fname));
 int unix_expandpath __ARGS((garray_T *gap, char_u *path, int wildoff, int flags, int didstar));
+void remove_duplicates __ARGS((garray_T *gap));
 int gen_expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file, int flags));
 void addfile __ARGS((garray_T *gap, char_u *f, int flags));
 char_u *get_cmd_output __ARGS((char_u *cmd, char_u *infile, int flags));
diff -r 33148c37f3c9 src/vim.h
--- a/src/vim.h	Wed Jul 28 19:38:16 2010 +0200
+++ b/src/vim.h	Wed Jul 28 20:43:48 2010 +0200
@@ -774,7 +774,8 @@
 #define EXPAND_PROFILE		35
 #define EXPAND_BEHAVE		36
 #define EXPAND_FILETYPE		37
-#define EXPAND_FILES_IN_PATH    38
+#define EXPAND_FILES_IN_PATH	38
+#define EXPAND_OWNSYNTAX	39
 
 /* Values for exmode_active (0 is no exmode) */
 #define EXMODE_NORMAL		1

Raspunde prin e-mail lui