Mercurial > vim
view src/locale.c @ 35620:0dc032c77f1a v9.1.0553
patch 9.1.0553: filetype: *.mcmeta files are not recognized
Commit: https://github.com/vim/vim/commit/d33a518025765c4a3530ad6cfb6cab83a30c8f55
Author: Tomodachi94 <tomodachi94@protonmail.com>
Date: Tue Jul 9 19:55:16 2024 +0200
patch 9.1.0553: filetype: *.mcmeta files are not recognized
Problem: filetype: *.mcmeta files are not recognized
Solution: Detect '*.mcmeta' files as json filetype
(Tomodachi94)
"pack.mcmeta" was added to the JSON tests because that is the most common
filename with that extension.
There are currently 34,000 instances of this file extension on GitHub:
https://github.com/search?q=path%3A*.mcmeta&type=code&p=2
.zip files with this extension have downloads in the millions on sites
like CurseForge:
https://www.curseforge.com/minecraft/search?page=1&pageSize=20&sortBy=relevancy&class=texture-packs
Further reading about the file extension:
https://minecraft.wiki/w/Tutorials/Creating_a_resource_pack#Creating_a_.MCMETA_file
closes: #15189
Signed-off-by: Tomodachi94 <tomodachi94@protonmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Tue, 09 Jul 2024 20:00:08 +0200 |
parents | 238ca27dbfd2 |
children |
line wrap: on
line source
/* vi:set ts=8 sts=4 sw=4 noet: * * VIM - Vi IMproved by Bram Moolenaar * * Do ":help uganda" in Vim to read copying and usage conditions. * Do ":help credits" in Vim to see a list of people who contributed. * See README.txt for an overview of the Vim source code. */ /* * locale.c: functions for language/locale configuration */ #include "vim.h" #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \ && (defined(FEAT_EVAL) || defined(FEAT_MULTI_LANG)) # define HAVE_GET_LOCALE_VAL static char_u * get_locale_val(int what) { char_u *loc; // Obtain the locale value from the libraries. loc = (char_u *)setlocale(what, NULL); # ifdef MSWIN if (loc != NULL) { char_u *p; // setocale() returns something like "LC_COLLATE=<name>;LC_..." when // one of the values (e.g., LC_CTYPE) differs. p = vim_strchr(loc, '='); if (p != NULL) { loc = ++p; while (*p != NUL) // remove trailing newline { if (*p < ' ' || *p == ';') { *p = NUL; break; } ++p; } } } # endif return loc; } #endif #ifdef MSWIN /* * On MS-Windows locale names are strings like "German_Germany.1252", but * gettext expects "de". Try to translate one into another here for a few * supported languages. */ static char_u * gettext_lang(char_u *name) { int i; static char *(mtable[]) = { "afrikaans", "af", "czech", "cs", "dutch", "nl", "german", "de", "english_united kingdom", "en_GB", "spanish", "es", "french", "fr", "italian", "it", "japanese", "ja", "korean", "ko", "norwegian", "no", "polish", "pl", "russian", "ru", "slovak", "sk", "swedish", "sv", "ukrainian", "uk", "chinese_china", "zh_CN", "chinese_taiwan", "zh_TW", NULL}; for (i = 0; mtable[i] != NULL; i += 2) if (STRNICMP(mtable[i], name, STRLEN(mtable[i])) == 0) return (char_u *)mtable[i + 1]; return name; } #endif #if defined(FEAT_MULTI_LANG) || defined(PROTO) /* * Return TRUE when "lang" starts with a valid language name. * Rejects NULL, empty string, "C", "C.UTF-8" and others. */ static int is_valid_mess_lang(char_u *lang) { return lang != NULL && ASCII_ISALPHA(lang[0]) && ASCII_ISALPHA(lang[1]); } /* * Obtain the current messages language. Used to set the default for * 'helplang'. May return NULL or an empty string. */ char_u * get_mess_lang(void) { char_u *p; # ifdef HAVE_GET_LOCALE_VAL # if defined(LC_MESSAGES) p = get_locale_val(LC_MESSAGES); # else // This is necessary for Win32, where LC_MESSAGES is not defined and $LANG // may be set to the LCID number. LC_COLLATE is the best guess, LC_TIME // and LC_MONETARY may be set differently for a Japanese working in the // US. p = get_locale_val(LC_COLLATE); # endif # else p = mch_getenv((char_u *)"LC_ALL"); if (!is_valid_mess_lang(p)) { p = mch_getenv((char_u *)"LC_MESSAGES"); if (!is_valid_mess_lang(p)) p = mch_getenv((char_u *)"LANG"); } # endif # ifdef MSWIN p = gettext_lang(p); # endif return is_valid_mess_lang(p) ? p : NULL; } #endif // Complicated #if; matches with where get_mess_env() is used below. #if (defined(FEAT_EVAL) && !((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \ && defined(LC_MESSAGES))) \ || ((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \ && !defined(LC_MESSAGES)) /* * Get the language used for messages from the environment. */ static char_u * get_mess_env(void) { char_u *p; p = mch_getenv((char_u *)"LC_ALL"); if (p != NULL && *p != NUL) return p; p = mch_getenv((char_u *)"LC_MESSAGES"); if (p != NULL && *p != NUL) return p; p = mch_getenv((char_u *)"LANG"); if (p != NULL && VIM_ISDIGIT(*p)) p = NULL; // ignore something like "1043" # ifdef HAVE_GET_LOCALE_VAL if (p == NULL || *p == NUL) p = get_locale_val(LC_CTYPE); # endif return p; } #endif #if defined(FEAT_EVAL) || defined(PROTO) /* * Set the "v:lang" variable according to the current locale setting. * Also do "v:lc_time"and "v:ctype". */ void set_lang_var(void) { char_u *loc; # ifdef HAVE_GET_LOCALE_VAL loc = get_locale_val(LC_CTYPE); # else // setlocale() not supported: use the default value loc = (char_u *)"C"; # endif set_vim_var_string(VV_CTYPE, loc, -1); // When LC_MESSAGES isn't defined use the value from $LC_MESSAGES, fall // back to LC_CTYPE if it's empty. # if defined(HAVE_GET_LOCALE_VAL) && defined(LC_MESSAGES) loc = get_locale_val(LC_MESSAGES); # else loc = get_mess_env(); # endif set_vim_var_string(VV_LANG, loc, -1); # ifdef HAVE_GET_LOCALE_VAL loc = get_locale_val(LC_TIME); # endif set_vim_var_string(VV_LC_TIME, loc, -1); # ifdef HAVE_GET_LOCALE_VAL loc = get_locale_val(LC_COLLATE); # else // setlocale() not supported: use the default value loc = (char_u *)"C"; # endif set_vim_var_string(VV_COLLATE, loc, -1); } #endif #if defined(HAVE_LOCALE_H) || defined(X_LOCALE) /* * Setup to use the current locale (for ctype() and many other things). */ void init_locale(void) { setlocale(LC_ALL, ""); # ifdef FEAT_GUI_GTK // Tell Gtk not to change our locale settings. gtk_disable_setlocale(); # endif # if defined(LC_NUMERIC) // Make sure strtod() uses a decimal point, not a comma. setlocale(LC_NUMERIC, "C"); # endif # ifdef MSWIN // Apparently MS-Windows printf() may cause a crash when we give it 8-bit // text while it's expecting text in the current locale. This call avoids // that. setlocale(LC_CTYPE, "C"); # endif # ifdef FEAT_GETTEXT { int mustfree = FALSE; char_u *p; # ifdef DYNAMIC_GETTEXT // Initialize the gettext library dyn_libintl_init(); # endif // expand_env() doesn't work yet, because g_chartab[] is not // initialized yet, call vim_getenv() directly p = vim_getenv((char_u *)"VIMRUNTIME", &mustfree); if (p != NULL && *p != NUL) { vim_snprintf((char *)NameBuff, MAXPATHL, "%s/lang", p); bindtextdomain(VIMPACKAGE, (char *)NameBuff); } if (mustfree) vim_free(p); textdomain(VIMPACKAGE); } # endif } /* * ":language": Set the language (locale). */ void ex_language(exarg_T *eap) { char *loc; char_u *p; char_u *name; int what = LC_ALL; char *whatstr = ""; # ifdef LC_MESSAGES # define VIM_LC_MESSAGES LC_MESSAGES # else # define VIM_LC_MESSAGES 6789 # endif name = eap->arg; // Check for "messages {name}", "ctype {name}" or "time {name}" argument. // Allow abbreviation, but require at least 3 characters to avoid // confusion with a two letter language name "me" or "ct". p = skiptowhite(eap->arg); if ((*p == NUL || VIM_ISWHITE(*p)) && p - eap->arg >= 3) { if (STRNICMP(eap->arg, "messages", p - eap->arg) == 0) { what = VIM_LC_MESSAGES; name = skipwhite(p); whatstr = "messages "; } else if (STRNICMP(eap->arg, "ctype", p - eap->arg) == 0) { what = LC_CTYPE; name = skipwhite(p); whatstr = "ctype "; } else if (STRNICMP(eap->arg, "time", p - eap->arg) == 0) { what = LC_TIME; name = skipwhite(p); whatstr = "time "; } else if (STRNICMP(eap->arg, "collate", p - eap->arg) == 0) { what = LC_COLLATE; name = skipwhite(p); whatstr = "collate "; } } if (*name == NUL) { # ifndef LC_MESSAGES if (what == VIM_LC_MESSAGES) p = get_mess_env(); else # endif p = (char_u *)setlocale(what, NULL); if (p == NULL || *p == NUL) p = (char_u *)"Unknown"; smsg(_("Current %slanguage: \"%s\""), whatstr, p); } else { # ifndef LC_MESSAGES if (what == VIM_LC_MESSAGES) loc = ""; else # endif { loc = setlocale(what, (char *)name); # if defined(LC_NUMERIC) // Make sure strtod() uses a decimal point, not a comma. setlocale(LC_NUMERIC, "C"); # endif } if (loc == NULL) semsg(_(e_cannot_set_language_to_str), name); else { # ifdef HAVE_NL_MSG_CAT_CNTR // Need to do this for GNU gettext, otherwise cached translations // will be used again. extern int _nl_msg_cat_cntr; ++_nl_msg_cat_cntr; # endif // Reset $LC_ALL, otherwise it would overrule everything. vim_setenv((char_u *)"LC_ALL", (char_u *)""); if (what != LC_TIME && what != LC_COLLATE) { // Tell gettext() what to translate to. It apparently doesn't // use the currently effective locale. Also do this when // FEAT_GETTEXT isn't defined, so that shell commands use this // value. if (what == LC_ALL) { vim_setenv((char_u *)"LANG", name); // Clear $LANGUAGE because GNU gettext uses it. vim_setenv((char_u *)"LANGUAGE", (char_u *)""); # ifdef MSWIN // Apparently MS-Windows printf() may cause a crash when // we give it 8-bit text while it's expecting text in the // current locale. This call avoids that. setlocale(LC_CTYPE, "C"); # endif } if (what != LC_CTYPE) { char_u *mname; # ifdef MSWIN mname = gettext_lang(name); # else mname = name; # endif vim_setenv((char_u *)"LC_MESSAGES", mname); # ifdef FEAT_MULTI_LANG set_helplang_default(mname); # endif } } # ifdef FEAT_EVAL // Set v:lang, v:lc_time, v:collate and v:ctype to the final result. set_lang_var(); # endif maketitle(); } } } static char_u **locales = NULL; // Array of all available locales static int did_init_locales = FALSE; /* * 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(void) { garray_T locales_ga; char_u *loc; char_u *locale_list; # ifdef MSWIN size_t len = 0; # endif // Find all available locales by running command "locale -a". If this // doesn't work we won't have completion. # ifndef MSWIN locale_list = get_cmd_output((char_u *)"locale -a", NULL, SHELL_SILENT, NULL); # else // Find all available locales by examining the directories in // $VIMRUNTIME/lang/ { int options = WILD_SILENT|WILD_USE_NL|WILD_KEEP_ALL; expand_T xpc; char_u *p; ExpandInit(&xpc); xpc.xp_context = EXPAND_DIRECTORIES; locale_list = ExpandOne(&xpc, (char_u *)"$VIMRUNTIME/lang/*", NULL, options, WILD_ALL); ExpandCleanup(&xpc); if (locale_list == NULL) // Add a dummy input, that will be skipped lated but we need to // have something in locale_list so that the C locale is added at // the end. locale_list = vim_strsave((char_u *)".\n"); p = locale_list; // find the last directory delimiter while (p != NULL && *p != NUL) { if (*p == '\n') break; if (*p == '\\') len = p - locale_list; p++; } } # endif if (locale_list == NULL) return NULL; ga_init2(&locales_ga, sizeof(char_u *), 20); // Transform locale_list string where each locale is separated by "\n" // into an array of locale strings. loc = (char_u *)strtok((char *)locale_list, "\n"); while (loc != NULL) { int ignore = FALSE; # ifdef MSWIN if (len > 0) loc += len + 1; // skip locales with a dot (which indicates the charset) if (vim_strchr(loc, '.') != NULL) ignore = TRUE; # endif if (!ignore) { 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"); } # ifdef MSWIN // Add the C locale if (ga_grow(&locales_ga, 1) == OK) ((char_u **)locales_ga.ga_data)[locales_ga.ga_len++] = vim_strsave((char_u *)"C"); # endif vim_free(locale_list); 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; } /* * Lazy initialization of all available locales. */ static void init_locales(void) { if (did_init_locales) return; did_init_locales = TRUE; locales = find_locales(); } # if defined(EXITFREE) || defined(PROTO) void free_locales(void) { int i; if (locales == NULL) return; for (i = 0; locales[i] != NULL; i++) vim_free(locales[i]); VIM_CLEAR(locales); } # endif /* * Function given to ExpandGeneric() to obtain the possible arguments of the * ":language" command. */ char_u * get_lang_arg(expand_T *xp UNUSED, int idx) { if (idx == 0) return (char_u *)"messages"; if (idx == 1) return (char_u *)"ctype"; if (idx == 2) return (char_u *)"time"; if (idx == 3) return (char_u *)"collate"; init_locales(); if (locales == NULL) return NULL; return locales[idx - 4]; } /* * Function given to ExpandGeneric() to obtain the available locales. */ char_u * get_locales(expand_T *xp UNUSED, int idx) { init_locales(); if (locales == NULL) return NULL; return locales[idx]; } #endif