Hi
Attached patch improves completion of Ex command ":language"
by completing available locales. It works by running command
"locale -a" to find available locales.
I only have the environment to test it on Linux.
Example:
:language messages fr<CTRL-D>
fr_BE.utf8 fr_CA.utf8 fr_CH.utf8 fr_FR.utf8 fr_LU.utf8
Regards
-- 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 fcea35e2a41f src/eval.c
--- a/src/eval.c Tue Feb 01 21:55:01 2011 +0100
+++ b/src/eval.c Sat Feb 05 22:26:49 2011 +0100
@@ -908,6 +908,7 @@
hash_clear(&compat_hashtab);
free_scriptnames();
+ free_locales();
/* global variables */
vars_clear(&globvarht);
diff -r fcea35e2a41f src/ex_cmds2.c
--- a/src/ex_cmds2.c Tue Feb 01 21:55:01 2011 +0100
+++ b/src/ex_cmds2.c Sat Feb 05 22:26:49 2011 +0100
@@ -69,6 +69,8 @@
static int debug_greedy = FALSE; /* batch mode debugging: don't save
and restore typeahead. */
+static char_u **locales = NULL; /* Array of all available locales */
+
/*
* do_debug(): Debug mode.
* Repeatedly get Ex commands, until told to continue normal execution.
@@ -1115,7 +1117,7 @@
static enum
{
PEXP_SUBCMD, /* expand :profile sub-commands */
- PEXP_FUNC, /* expand :profile func {funcname} */
+ PEXP_FUNC /* expand :profile func {funcname} */
} pexpand_what;
static char *pexpand_cmds[] = {
@@ -1484,7 +1486,7 @@
#endif
/*
- * Ask the user what to do when abondoning a changed buffer.
+ * Ask the user what to do when abandoning a changed buffer.
* Must check 'write' option first!
*/
void
@@ -4165,6 +4167,74 @@
}
# if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+
+/* Return an array of strings for all available locales + NULL for the
+ * last element. Return NULL in case of error. */
+ static char_u **
+find_locales()
+{
+ /* Array of all available locale strings + NULL for last entry */
+ char_u **all_locales;
+ char_u **realloc_all_locales;
+ char_u *loc;
+ int locale_count = 0;
+ int allocated_count = 2;
+
+ /* Find all available locales by running command "locale -a" */
+ char_u *locale_a = get_cmd_output((char_u *)"locale -a",
+ NULL, SHELL_SILENT);
+
+ /* Start by allocating 'allocated_count' locale entries. */
+ all_locales = (char_u **)alloc(sizeof(char_u *)*allocated_count);
+
+ if (locale_a == NULL || all_locales == NULL)
+ {
+ vim_free(locale_a);
+ return NULL;
+ }
+
+ /* Transform locale_a string where each locale is separated by "\n"
+ * into an array of locale strings. */
+ loc = (char_u *)strtok((char *)locale_a, "\n");
+
+ while (loc != NULL)
+ {
+ loc = vim_strsave(loc);
+ if (loc == NULL)
+ break;
+
+ if (allocated_count < locale_count + 1)
+ {
+ allocated_count *= 2;
+ realloc_all_locales = vim_realloc(all_locales,
+ sizeof(char_u *)*allocated_count);
+ if (realloc_all_locales == NULL)
+ break;
+ all_locales = realloc_all_locales;
+ }
+ all_locales[locale_count++] = loc;
+ loc = (char_u *)strtok(NULL, "\n");
+ }
+ vim_free(locale_a);
+ all_locales[locale_count] = NULL;
+ return all_locales;
+}
+
+# if defined(EXITFREE) || defined(PROTO)
+ void
+free_locales()
+{
+ int i;
+ if (locales)
+ {
+ for (i = 0; locales[i] != NULL; i++)
+ vim_free(locales[i]);
+ vim_free(locales);
+ locales = NULL;
+ }
+}
+#endif
+
/*
* Function given to ExpandGeneric() to obtain the possible arguments of the
* ":language" command.
@@ -4180,7 +4250,25 @@
return (char_u *)"ctype";
if (idx == 2)
return (char_u *)"time";
- return NULL;
+
+ /* Lazy initialization of all available locales. */
+ if (locales == NULL)
+ locales = find_locales();
+ return locales[idx - 3];
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the available locales.
+ */
+ char_u *
+get_locales(xp, idx)
+ expand_T *xp UNUSED;
+ int idx;
+{
+ /* Lazy initialization of all available locales. */
+ if (locales == NULL)
+ locales = find_locales();
+ return locales[idx];
}
# endif
diff -r fcea35e2a41f src/ex_docmd.c
--- a/src/ex_docmd.c Tue Feb 01 21:55:01 2011 +0100
+++ b/src/ex_docmd.c Sat Feb 05 22:26:49 2011 +0100
@@ -3847,13 +3847,24 @@
#if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
&& (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
case CMD_language:
- if (*skiptowhite(arg) == NUL)
+ p = skiptowhite(arg);
+ if (*p == NUL)
{
xp->xp_context = EXPAND_LANGUAGE;
xp->xp_pattern = arg;
}
else
- xp->xp_context = EXPAND_NOTHING;
+ {
+ if ( STRNICMP(arg, "messages", p - arg) == 0
+ || STRNICMP(arg, "ctype", p - arg) == 0
+ || STRNICMP(arg, "time", p - arg) == 0)
+ {
+ xp->xp_context = EXPAND_LOCALES;
+ xp->xp_pattern = skipwhite(p);
+ }
+ else
+ xp->xp_context = EXPAND_NOTHING;
+ }
break;
#endif
#if defined(FEAT_PROFILE)
diff -r fcea35e2a41f src/ex_getln.c
--- a/src/ex_getln.c Tue Feb 01 21:55:01 2011 +0100
+++ b/src/ex_getln.c Sat Feb 05 22:26:49 2011 +0100
@@ -4570,48 +4570,50 @@
int context;
char_u *((*func)__ARGS((expand_T *, int)));
int ic;
+ int escaped;
} tab[] =
{
- {EXPAND_COMMANDS, get_command_name, FALSE},
- {EXPAND_BEHAVE, get_behave_arg, TRUE},
+ {EXPAND_COMMANDS, get_command_name, FALSE, TRUE},
+ {EXPAND_BEHAVE, get_behave_arg, TRUE, TRUE},
#ifdef FEAT_USR_CMDS
- {EXPAND_USER_COMMANDS, get_user_commands, FALSE},
- {EXPAND_USER_CMD_FLAGS, get_user_cmd_flags, FALSE},
- {EXPAND_USER_NARGS, get_user_cmd_nargs, FALSE},
- {EXPAND_USER_COMPLETE, get_user_cmd_complete, FALSE},
+ {EXPAND_USER_COMMANDS, get_user_commands, FALSE, TRUE},
+ {EXPAND_USER_CMD_FLAGS, get_user_cmd_flags, FALSE, TRUE},
+ {EXPAND_USER_NARGS, get_user_cmd_nargs, FALSE, TRUE},
+ {EXPAND_USER_COMPLETE, get_user_cmd_complete, FALSE, TRUE},
#endif
#ifdef FEAT_EVAL
- {EXPAND_USER_VARS, get_user_var_name, FALSE},
- {EXPAND_FUNCTIONS, get_function_name, FALSE},
- {EXPAND_USER_FUNC, get_user_func_name, FALSE},
- {EXPAND_EXPRESSION, get_expr_name, FALSE},
+ {EXPAND_USER_VARS, get_user_var_name, FALSE, TRUE},
+ {EXPAND_FUNCTIONS, get_function_name, FALSE, TRUE},
+ {EXPAND_USER_FUNC, get_user_func_name, FALSE, TRUE},
+ {EXPAND_EXPRESSION, get_expr_name, FALSE, TRUE},
#endif
#ifdef FEAT_MENU
- {EXPAND_MENUS, get_menu_name, FALSE},
- {EXPAND_MENUNAMES, get_menu_names, FALSE},
+ {EXPAND_MENUS, get_menu_name, FALSE, TRUE},
+ {EXPAND_MENUNAMES, get_menu_names, FALSE, TRUE},
#endif
#ifdef FEAT_SYN_HL
- {EXPAND_SYNTAX, get_syntax_name, TRUE},
-#endif
- {EXPAND_HIGHLIGHT, get_highlight_name, TRUE},
+ {EXPAND_SYNTAX, get_syntax_name, TRUE, TRUE},
+#endif
+ {EXPAND_HIGHLIGHT, get_highlight_name, TRUE, TRUE},
#ifdef FEAT_AUTOCMD
- {EXPAND_EVENTS, get_event_name, TRUE},
- {EXPAND_AUGROUP, get_augroup_name, TRUE},
+ {EXPAND_EVENTS, get_event_name, TRUE, TRUE},
+ {EXPAND_AUGROUP, get_augroup_name, TRUE, TRUE},
#endif
#ifdef FEAT_CSCOPE
- {EXPAND_CSCOPE, get_cscope_name, TRUE},
+ {EXPAND_CSCOPE, get_cscope_name, TRUE, TRUE},
#endif
#ifdef FEAT_SIGNS
- {EXPAND_SIGN, get_sign_name, TRUE},
+ {EXPAND_SIGN, get_sign_name, TRUE, TRUE},
#endif
#ifdef FEAT_PROFILE
- {EXPAND_PROFILE, get_profile_name, TRUE},
+ {EXPAND_PROFILE, get_profile_name, TRUE, TRUE},
#endif
#if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
&& (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
- {EXPAND_LANGUAGE, get_lang_arg, TRUE},
-#endif
- {EXPAND_ENV_VARS, get_env_name, TRUE},
+ {EXPAND_LANGUAGE, get_lang_arg, TRUE, FALSE},
+ {EXPAND_LOCALES, get_locales, TRUE, FALSE},
+#endif
+ {EXPAND_ENV_VARS, get_env_name, TRUE, TRUE},
};
int i;
@@ -4625,7 +4627,8 @@
{
if (tab[i].ic)
regmatch.rm_ic = TRUE;
- ret = ExpandGeneric(xp, ®match, num_file, file, tab[i].func);
+ ret = ExpandGeneric(xp, ®match, num_file, file,
+ tab[i].func, tab[i].escaped);
break;
}
}
@@ -4647,12 +4650,13 @@
* Returns OK when no problems encountered, FAIL for error (out of memory).
*/
int
-ExpandGeneric(xp, regmatch, num_file, file, func)
+ExpandGeneric(xp, regmatch, num_file, file, func, escaped)
expand_T *xp;
regmatch_T *regmatch;
int *num_file;
char_u ***file;
char_u *((*func)__ARGS((expand_T *, int)));
+ int escaped;
/* returns a string from the list */
{
int i;
@@ -4678,7 +4682,10 @@
{
if (round)
{
- str = vim_strsave_escaped(str, (char_u *)" \t\\.");
+ if (escaped)
+ str = vim_strsave_escaped(str, (char_u *)" \t\\.");
+ else
+ str = vim_strsave(str);
(*file)[count] = str;
#ifdef FEAT_MENU
if (func == get_menu_names && str != NULL)
diff -r fcea35e2a41f src/proto/ex_cmds2.pro
--- a/src/proto/ex_cmds2.pro Tue Feb 01 21:55:01 2011 +0100
+++ b/src/proto/ex_cmds2.pro Sat Feb 05 22:26:49 2011 +0100
@@ -70,6 +70,7 @@
void scriptnames_slash_adjust __ARGS((void));
char_u *get_scriptname __ARGS((scid_T id));
void free_scriptnames __ARGS((void));
+void free_locales __ARGS((void));
char *fgets_cr __ARGS((char *s, int n, FILE *stream));
char_u *getsourceline __ARGS((int c, void *cookie, int indent));
void script_line_start __ARGS((void));
@@ -84,4 +85,5 @@
void set_lang_var __ARGS((void));
void ex_language __ARGS((exarg_T *eap));
char_u *get_lang_arg __ARGS((expand_T *xp, int idx));
+char_u *get_locales __ARGS((expand_T *xp, int idx));
/* vim: set ft=c : */
diff -r fcea35e2a41f src/proto/ex_getln.pro
--- a/src/proto/ex_getln.pro Tue Feb 01 21:55:01 2011 +0100
+++ b/src/proto/ex_getln.pro Sat Feb 05 22:26:49 2011 +0100
@@ -31,7 +31,7 @@
char_u *addstar __ARGS((char_u *fname, int len, int context));
void set_cmd_context __ARGS((expand_T *xp, char_u *str, int len, int col));
int expand_cmdline __ARGS((expand_T *xp, char_u *str, int col, int *matchcount, char_u ***matches));
-int ExpandGeneric __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file, char_u *((*func)(expand_T *, int))));
+int ExpandGeneric __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file, char_u *((*func)(expand_T *, int)), int escaped));
char_u *globpath __ARGS((char_u *path, char_u *file, int expand_options));
void init_history __ARGS((void));
int get_histtype __ARGS((char_u *name));
diff -r fcea35e2a41f src/vim.h
--- a/src/vim.h Tue Feb 01 21:55:01 2011 +0100
+++ b/src/vim.h Sat Feb 05 22:26:49 2011 +0100
@@ -786,6 +786,7 @@
#define EXPAND_FILETYPE 37
#define EXPAND_FILES_IN_PATH 38
#define EXPAND_OWNSYNTAX 39
+#define EXPAND_LOCALES 40
/* Values for exmode_active (0 is no exmode) */
#define EXMODE_NORMAL 1