changeset 31962:4efcb5c68112 v9.0.1313

patch 9.0.1313: some settings use the current codepage instead of 'encoding' Commit: https://github.com/vim/vim/commit/ce3189d56e867a2ffc077893b62f530d5b09150f Author: K.Takata <kentkt@csc.jp> 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)
author Bram Moolenaar <Bram@vim.org>
date Wed, 15 Feb 2023 20:15:03 +0100
parents 7d8431f21c98
children da67a47e2c2c
files src/misc1.c src/option.c src/optionstr.c src/os_win32.c src/proto/misc1.pro src/proto/os_win32.pro src/version.c
diffstat 7 files changed, 74 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- 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 *
--- 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'.
--- 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
     }
 
--- 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
--- 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);
--- 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);
--- 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,