# HG changeset patch # User Bram Moolenaar # Date 1676488503 -3600 # Node ID 4efcb5c68112ef927ec9804d7aee072157486c42 # Parent 7d8431f21c9886312ecf9181873e3fc110cbb547 patch 9.0.1313: some settings use the current codepage instead of 'encoding' Commit: https://github.com/vim/vim/commit/ce3189d56e867a2ffc077893b62f530d5b09150f Author: K.Takata Date: Wed Feb 15 19:13:43 2023 +0000 patch 9.0.1313: some settings use the current codepage instead of 'encoding' Problem: Some settings use the current codepage instead of 'encoding'. Solution: Adjust how options are initialized. (Ken Takata, closes https://github.com/vim/vim/issues/11992) diff --git a/src/misc1.c b/src/misc1.c --- a/src/misc1.c +++ b/src/misc1.c @@ -1311,6 +1311,32 @@ free_users(void) } #endif +#if defined(MSWIN) || defined(PROTO) +/* + * Initilize $VIM and $VIMRUNTIME when 'enc' is updated. + */ + void +init_vimdir(void) +{ + int mustfree; + char_u *p; + + mch_get_exe_name(); + + mustfree = FALSE; + didset_vim = FALSE; + p = vim_getenv((char_u *)"VIM", &mustfree); + if (mustfree) + vim_free(p); + + mustfree = FALSE; + didset_vimruntime = FALSE; + p = vim_getenv((char_u *)"VIMRUNTIME", &mustfree); + if (mustfree) + vim_free(p); +} +#endif + /* * Call expand_env() and store the result in an allocated string. * This is not very memory efficient, this expects the result to be freed @@ -1696,7 +1722,7 @@ vim_version_dir(char_u *vimdir) * Vim's version of getenv(). * Special handling of $HOME, $VIM and $VIMRUNTIME. * Also does ACP to 'enc' conversion for Win32. - * "mustfree" is set to TRUE when returned is allocated, it must be + * "mustfree" is set to TRUE when the returned string is allocated. It must be * initialized to FALSE by the caller. */ char_u * diff --git a/src/option.c b/src/option.c --- a/src/option.c +++ b/src/option.c @@ -600,6 +600,8 @@ set_init_1(int clean_arg) init_spell_chartab(); #endif + set_init_default_encoding(); + // Expand environment variables and things like "~" for the defaults. set_init_expand_env(); @@ -618,7 +620,6 @@ set_init_1(int clean_arg) didset_options2(); set_init_lang_env(); - set_init_default_encoding(); #ifdef FEAT_MULTI_LANG // Set the default for 'helplang'. diff --git a/src/optionstr.c b/src/optionstr.c --- a/src/optionstr.c +++ b/src/optionstr.c @@ -1054,9 +1054,12 @@ did_set_encoding(char_u **varp, char_u * } #if defined(MSWIN) - // $HOME may have characters in active code page. + // $HOME, $VIM and $VIMRUNTIME may have characters in active code page. if (varp == &p_enc) + { init_homedir(); + init_vimdir(); + } #endif } diff --git a/src/os_win32.c b/src/os_win32.c --- a/src/os_win32.c +++ b/src/os_win32.c @@ -254,7 +254,7 @@ static void restore_console_color_rgb(vo static int suppress_winsize = 1; // don't fiddle with console #endif -static char_u *exe_path = NULL; +static WCHAR *exe_pathw = NULL; static BOOL win8_or_later = FALSE; static BOOL win10_22H2_or_later = FALSE; @@ -462,27 +462,45 @@ wait_for_single_object( # endif #endif // !FEAT_GUI_MSWIN || VIMDLL - static void -get_exe_name(void) + void +mch_get_exe_name(void) { // Maximum length of $PATH is more than MAXPATHL. 8191 is often mentioned // as the maximum length that works (plus a NUL byte). #define MAX_ENV_PATH_LEN 8192 char temp[MAX_ENV_PATH_LEN]; char_u *p; - - if (exe_name == NULL) + WCHAR buf[MAX_PATH]; + int updated = FALSE; + static int enc_prev = -1; + + if (exe_name == NULL || exe_pathw == NULL || enc_prev != enc_codepage) { // store the name of the executable, may be used for $VIM - GetModuleFileName(NULL, temp, MAX_ENV_PATH_LEN - 1); - if (*temp != NUL) - exe_name = FullName_save((char_u *)temp, FALSE); - } - - if (exe_path != NULL || exe_name == NULL) + GetModuleFileNameW(NULL, buf, MAX_PATH); + if (*buf != NUL) + { + if (enc_codepage == -1) + enc_codepage = GetACP(); + if (exe_name != NULL) + vim_free(exe_name); + exe_name = utf16_to_enc(buf, NULL); + enc_prev = enc_codepage; + + WCHAR *wp = wcsrchr(buf, '\\'); + if (wp != NULL) + *wp = NUL; + if (exe_pathw != NULL) + vim_free(exe_pathw); + exe_pathw = _wcsdup(buf); + updated = TRUE; + } + } + + if (exe_pathw == NULL || !updated) return; - exe_path = vim_strnsave(exe_name, gettail_sep(exe_name) - exe_name); + char_u *exe_path = utf16_to_enc(exe_pathw, NULL); if (exe_path == NULL) return; @@ -503,6 +521,7 @@ get_exe_name(void) STRCAT(temp, exe_path); vim_setenv((char_u *)"PATH", (char_u *)temp); } + vim_free(exe_path); } /* @@ -538,10 +557,10 @@ vimLoadLib(const char *name) // NOTE: Do not use mch_dirname() and mch_chdir() here, they may call // vimLoadLib() recursively, which causes a stack overflow. - if (exe_path == NULL) - get_exe_name(); - - if (exe_path == NULL) + if (exe_pathw == NULL) + mch_get_exe_name(); + + if (exe_pathw == NULL) return NULL; WCHAR old_dirw[MAXPATHL]; @@ -552,7 +571,7 @@ vimLoadLib(const char *name) // Change directory to where the executable is, both to make // sure we find a .dll there and to avoid looking for a .dll // in the current directory. - SetCurrentDirectory((LPCSTR)exe_path); + SetCurrentDirectoryW(exe_pathw); dll = LoadLibrary(name); SetCurrentDirectoryW(old_dirw); return dll; @@ -3586,7 +3605,7 @@ mch_check_win( int argc UNUSED, char **argv UNUSED) { - get_exe_name(); + mch_get_exe_name(); #if defined(FEAT_GUI_MSWIN) && !defined(VIMDLL) return OK; // GUI always has a tty diff --git a/src/proto/misc1.pro b/src/proto/misc1.pro --- a/src/proto/misc1.pro +++ b/src/proto/misc1.pro @@ -26,6 +26,7 @@ void vim_beep(unsigned val); void init_homedir(void); void free_homedir(void); void free_users(void); +void init_vimdir(void); char_u *expand_env_save(char_u *src); char_u *expand_env_save_opt(char_u *src, int one); void expand_env(char_u *src, char_u *dst, int dstlen); diff --git a/src/proto/os_win32.pro b/src/proto/os_win32.pro --- a/src/proto/os_win32.pro +++ b/src/proto/os_win32.pro @@ -1,4 +1,5 @@ /* os_win32.c */ +void mch_get_exe_name(void); HINSTANCE vimLoadLib(const char *name); int mch_is_gui_executable(void); HINSTANCE find_imported_module_by_funcname(HINSTANCE hInst, const char *funcname); diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1313, +/**/ 1312, /**/ 1311,