# HG changeset patch # User Bram Moolenaar # Date 1305822400 -7200 # Node ID b0190e93e601f9061a797689a1eb95a86805f769 # Parent d9e5f15a6a361110d6c7015d5dac854e935b1470 updated for version 7.3.198 Problem: No completion for ":lang". Solution: Get locales to complete from. (Dominique Pelle) diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -911,6 +911,7 @@ eval_clear() hash_clear(&compat_hashtab); free_scriptnames(); + free_locales(); /* global variables */ vars_clear(&globvarht); diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -1476,7 +1476,7 @@ browse_save_fname(buf) #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 @@ -4153,6 +4153,82 @@ ex_language(eap) } # if defined(FEAT_CMDL_COMPL) || defined(PROTO) + +static char_u **locales = NULL; /* Array of all available locales */ +static int did_init_locales = FALSE; + +static void init_locales __ARGS((void)); +static char_u **find_locales __ARGS((void)); + +/* + * Lazy initialization of all available locales. + */ + static void +init_locales() +{ + if (!did_init_locales) + { + did_init_locales = TRUE; + locales = find_locales(); + } +} + +/* 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() +{ + garray_T locales_ga; + char_u *loc; + + /* Find all available locales by running command "locale -a". If this + * doesn't work we won't have completion. */ + char_u *locale_a = get_cmd_output((char_u *)"locale -a", + NULL, SHELL_SILENT); + if (locale_a == NULL) + return NULL; + ga_init2(&locales_ga, sizeof(char_u *), 20); + + /* 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) + { + if (ga_grow(&locales_ga, 1) == FAIL) + break; + loc = vim_strsave(loc); + if (loc == NULL) + break; + + ((char_u **)locales_ga.ga_data)[locales_ga.ga_len++] = loc; + loc = (char_u *)strtok(NULL, "\n"); + } + vim_free(locale_a); + if (ga_grow(&locales_ga, 1) == FAIL) + { + ga_clear(&locales_ga); + return NULL; + } + ((char_u **)locales_ga.ga_data)[locales_ga.ga_len] = NULL; + return (char_u **)locales_ga.ga_data; +} + +# if defined(EXITFREE) || defined(PROTO) + void +free_locales() +{ + int i; + if (locales != NULL) + { + 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. @@ -4168,7 +4244,25 @@ get_lang_arg(xp, idx) return (char_u *)"ctype"; if (idx == 2) return (char_u *)"time"; - return NULL; + + init_locales(); + if (locales == NULL) + return NULL; + 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; +{ + init_locales(); + if (locales == NULL) + return NULL; + return locales[idx]; } # endif diff --git a/src/ex_getln.c b/src/ex_getln.c --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -4571,48 +4571,50 @@ ExpandFromContext(xp, pat, num_file, fil 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; @@ -4626,7 +4628,8 @@ ExpandFromContext(xp, pat, num_file, fil { 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; } } @@ -4648,13 +4651,14 @@ ExpandFromContext(xp, pat, num_file, fil * 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))); /* returns a string from the list */ + int escaped; { int i; int count = 0; @@ -4679,7 +4683,10 @@ ExpandGeneric(xp, regmatch, num_file, fi { 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 --git a/src/proto/ex_cmds2.pro b/src/proto/ex_cmds2.pro --- a/src/proto/ex_cmds2.pro +++ b/src/proto/ex_cmds2.pro @@ -83,5 +83,7 @@ void ex_checktime __ARGS((exarg_T *eap)) char_u *get_mess_lang __ARGS((void)); void set_lang_var __ARGS((void)); void ex_language __ARGS((exarg_T *eap)); +void free_locales __ARGS((void)); 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 --git a/src/proto/ex_getln.pro b/src/proto/ex_getln.pro --- a/src/proto/ex_getln.pro +++ b/src/proto/ex_getln.pro @@ -31,7 +31,7 @@ char_u *sm_gettail __ARGS((char_u *s)); 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 --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -710,6 +710,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 198, +/**/ 197, /**/ 196, diff --git a/src/vim.h b/src/vim.h --- a/src/vim.h +++ b/src/vim.h @@ -779,6 +779,7 @@ extern char *(*dyn_libintl_textdomain)(c #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