# HG changeset patch # User Bram Moolenaar # Date 1542393905 -3600 # Node ID c1be7c8bb602006b727fc99872949985bbcb9dd8 # Parent ad62eff820ee31376804f505c8faeec5ae6a80fc patch 8.1.0534: MS-Windows installer uses different $HOME than Vim commit https://github.com/vim/vim/commit/25a494ce609f54ce240b1986aad16ca27186d646 Author: Bram Moolenaar Date: Fri Nov 16 19:39:50 2018 +0100 patch 8.1.0534: MS-Windows installer uses different $HOME than Vim Problem: MS-Windows installer uses different $HOME than Vim. Solution: Use the Vim logic also in the MS-Windows installer. (Ken Takata, closes #3564) diff --git a/src/dosinst.c b/src/dosinst.c --- a/src/dosinst.c +++ b/src/dosinst.c @@ -115,14 +115,13 @@ enum vimfiles_dir_vim, vimfiles_dir_home }; -static char *(vimfiles_dir_choices[]) = +static char *(vimfiles_dir_choices[]) = { "\nCreate plugin directories:", "No", "In the VIM directory", "In your HOME directory", }; -static int vimfiles_dir_choice; /* non-zero when selected to install the popup menu entry. */ static int install_popup = 0; @@ -741,7 +740,8 @@ add_dummy_choice(void) choices[choice_count].installfunc = NULL; choices[choice_count].active = 0; choices[choice_count].changefunc = NULL; - choices[choice_count].installfunc = NULL; + choices[choice_count].text = NULL; + choices[choice_count].arg = 0; ++choice_count; } @@ -2089,6 +2089,8 @@ dir_remove_last(const char *path, char t static void set_directories_text(int idx) { + int vimfiles_dir_choice = choices[idx].arg; + if (vimfiles_dir_choice == (int)vimfiles_dir_none) alloc_text(idx, "Do NOT create plugin directories%s", ""); else @@ -2097,6 +2099,91 @@ set_directories_text(int idx) } /* + * To get the "real" home directory: + * - get value of $HOME + * - if not found, get value of $HOMEDRIVE$HOMEPATH + * - if not found, get value of $USERPROFILE + * + * This code is based on init_homedir() in misc1.c, keep in sync! + */ +static char *homedir = NULL; + + void +init_homedir(void) +{ + char *var; + char buf[MAX_PATH]; + + if (homedir != NULL) + { + free(homedir); + homedir = NULL; + } + + var = getenv("HOME"); + + /* + * Typically, $HOME is not defined on Windows, unless the user has + * specifically defined it for Vim's sake. However, on Windows NT + * platforms, $HOMEDRIVE and $HOMEPATH are automatically defined for + * each user. Try constructing $HOME from these. + */ + if (var == NULL || *var == NUL) + { + char *homedrive, *homepath; + + homedrive = getenv("HOMEDRIVE"); + homepath = getenv("HOMEPATH"); + if (homepath == NULL || *homepath == NUL) + homepath = "\\"; + if (homedrive != NULL + && strlen(homedrive) + strlen(homepath) < MAX_PATH) + { + sprintf(buf, "%s%s", homedrive, homepath); + if (buf[0] != NUL) + var = buf; + } + } + + if (var == NULL) + var = getenv("USERPROFILE"); + + /* + * Weird but true: $HOME may contain an indirect reference to another + * variable, esp. "%USERPROFILE%". Happens when $USERPROFILE isn't set + * when $HOME is being set. + */ + if (var != NULL && *var == '%') + { + char *p; + char *exp; + + p = strchr(var + 1, '%'); + if (p != NULL) + { + strncpy(buf, var + 1, p - (var + 1)); + buf[p - (var + 1)] = NUL; + exp = getenv(buf); + if (exp != NULL && *exp != NUL + && strlen(exp) + strlen(p) < MAX_PATH) + { + _snprintf(buf, MAX_PATH, "%s%s", exp, p + 1); + buf[MAX_PATH - 1] = NUL; + var = buf; + } + } + } + + if (var != NULL && *var == NUL) // empty is same as not set + var = NULL; + + if (var == NULL) + homedir = NULL; + else + homedir = _strdup(var); +} + +/* * Change the directory that the vim plugin directories will be created in: * $HOME, $VIM or nowhere. */ @@ -2106,9 +2193,9 @@ change_directories_choice(int idx) int choice_count = TABLE_SIZE(vimfiles_dir_choices); /* Don't offer the $HOME choice if $HOME isn't set. */ - if (getenv("HOME") == NULL) + if (homedir == NULL) --choice_count; - vimfiles_dir_choice = get_choice(vimfiles_dir_choices, choice_count); + choices[idx].arg = get_choice(vimfiles_dir_choices, choice_count); set_directories_text(idx); } @@ -2120,6 +2207,7 @@ change_directories_choice(int idx) install_vimfilesdir(int idx) { int i; + int vimfiles_dir_choice = choices[idx].arg; char *p; char vimdir_path[BUFSIZE]; char vimfiles_path[BUFSIZE]; @@ -2144,8 +2232,8 @@ install_vimfilesdir(int idx) } case vimfiles_dir_home: { - /* Find the $HOME directory. Its existence was already checked. */ - p = getenv("HOME"); + // Find the $HOME directory. Its existence was already checked. + p = homedir; if (p == NULL) { printf("Internal error: $HOME is NULL\n"); @@ -2156,7 +2244,7 @@ install_vimfilesdir(int idx) } case vimfiles_dir_none: { - /* Do not create vim plugin directory */ + // Do not create vim plugin directory. return; } } @@ -2185,14 +2273,15 @@ init_directories_choice(void) struct stat st; char tmp_dirname[BUFSIZE]; char *p; + int vimfiles_dir_choice; choices[choice_count].text = alloc(150); choices[choice_count].changefunc = change_directories_choice; choices[choice_count].installfunc = install_vimfilesdir; choices[choice_count].active = 1; - /* Check if the "compiler" directory already exists. That's a good - * indication that the plugin directories were already created. */ + // Check if the "compiler" directory already exists. That's a good + // indication that the plugin directories were already created. if (getenv("HOME") != NULL) { vimfiles_dir_choice = (int)vimfiles_dir_home; @@ -2204,7 +2293,7 @@ init_directories_choice(void) { vimfiles_dir_choice = (int)vimfiles_dir_vim; p = getenv("VIM"); - if (p == NULL) /* No $VIM in path, use the install dir */ + if (p == NULL) // No $VIM in path, use the install dir. dir_remove_last(installdir, tmp_dirname); else strcpy(tmp_dirname, p); @@ -2213,6 +2302,7 @@ init_directories_choice(void) vimfiles_dir_choice = (int)vimfiles_dir_none; } + choices[choice_count].arg = vimfiles_dir_choice; set_directories_text(choice_count); ++choice_count; } @@ -2369,6 +2459,8 @@ command_line_setup_choices(int argc, cha } else if (strcmp(argv[i], "-create-directories") == 0) { + int vimfiles_dir_choice; + init_directories_choice(); if (argv[i + 1][0] != '-') { @@ -2377,8 +2469,8 @@ command_line_setup_choices(int argc, cha vimfiles_dir_choice = (int)vimfiles_dir_vim; else if (strcmp(argv[i], "home") == 0) { - if (getenv("HOME") == NULL) /* No $HOME in environment */ - vimfiles_dir_choice = (int)vimfiles_dir_vim; + if (homedir == NULL) // No $HOME in environment + vimfiles_dir_choice = (int)vimfiles_dir_none; else vimfiles_dir_choice = (int)vimfiles_dir_home; } @@ -2391,6 +2483,7 @@ command_line_setup_choices(int argc, cha } else /* No choice specified, default to vim directory */ vimfiles_dir_choice = (int)vimfiles_dir_vim; + choices[choice_count - 1].arg = vimfiles_dir_choice; } else if (strcmp(argv[i], "-register-OLE") == 0) { @@ -2589,6 +2682,7 @@ main(int argc, char **argv) /* Initialize this program. */ do_inits(argv); + init_homedir(); if (argc > 1 && strcmp(argv[1], "-uninstall-check") == 0) { diff --git a/src/misc1.c b/src/misc1.c --- a/src/misc1.c +++ b/src/misc1.c @@ -3905,6 +3905,8 @@ vim_beep( * - do mch_dirname() to get the real name of that directory. * This also works with mounts and links. * Don't do this for MS-DOS, it will change the "current dir" for a drive. + * For Windows: + * This code is duplicated in init_homedir() in dosinst.c. Keep in sync! */ static char_u *homedir = NULL; diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -793,6 +793,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 534, +/**/ 533, /**/ 532,