blob: 809789fb7f0967cd1878cbe4aa833687ea2eacc7 [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001/* vi:set ts=8 sts=4 sw=4:
2 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9
10/*
11 * dosinst.c: Install program for Vim on MS-DOS and MS-Windows
12 *
13 * Compile with Make_mvc.mak, Make_bc3.mak, Make_bc5.mak or Make_djg.mak.
14 */
15
16/*
17 * Include common code for dosinst.c and uninstal.c.
18 */
19#define DOSINST
20#include "dosinst.h"
21
22/* Macro to do an error check I was typing over and over */
23#define CHECK_REG_ERROR(code) if (code != ERROR_SUCCESS) { printf("%ld error number: %ld\n", (long)__LINE__, (long)code); return 1; }
24
25int has_vim = 0; /* installable vim.exe exists */
26int has_gvim = 0; /* installable gvim.exe exists */
27
28char oldvimrc[BUFSIZE]; /* name of existing vimrc file */
29char vimrc[BUFSIZE]; /* name of vimrc file to create */
30
31char *default_bat_dir = NULL; /* when not NULL, use this as the default
32 directory to write .bat files in */
33char *default_vim_dir = NULL; /* when not NULL, use this as the default
34 install dir for NSIS */
Bram Moolenaar071d4272004-06-13 20:20:40 +000035
36/*
37 * Structure used for each choice the user can make.
38 */
39struct choice
40{
41 int active; /* non-zero when choice is active */
42 char *text; /* text displayed for this choice */
43 void (*changefunc)(int idx); /* function to change this choice */
44 int arg; /* argument for function */
45 void (*installfunc)(int idx); /* function to install this choice */
46};
47
48struct choice choices[30]; /* choices the user can make */
49int choice_count = 0; /* number of choices available */
50
51#define TABLE_SIZE(s) (int)(sizeof(s) / sizeof(*s))
52
53enum
54{
55 compat_vi = 1,
56 compat_some_enhancements,
57 compat_all_enhancements
58};
59char *(compat_choices[]) =
60{
61 "\nChoose the default way to run Vim:",
62 "Vi compatible",
Bram Moolenaarfff2bee2010-05-15 13:56:02 +020063 "with some Vim enhancements",
Bram Moolenaar071d4272004-06-13 20:20:40 +000064 "with syntax highlighting and other features switched on",
65};
66int compat_choice = (int)compat_all_enhancements;
67char *compat_text = "- run Vim %s";
68
69enum
70{
71 remap_no = 1,
72 remap_win
73};
74char *(remap_choices[]) =
75{
76 "\nChoose:",
77 "Do not remap keys for Windows behavior",
78 "Remap a few keys for Windows behavior (<C-V>, <C-C>, etc)",
79};
80int remap_choice = (int)remap_win;
81char *remap_text = "- %s";
82
83enum
84{
85 mouse_xterm = 1,
86 mouse_mswin
87};
88char *(mouse_choices[]) =
89{
90 "\nChoose the way how Vim uses the mouse:",
91 "right button extends selection (the Unix way)",
92 "right button has a popup menu (the Windows way)",
93};
94int mouse_choice = (int)mouse_mswin;
95char *mouse_text = "- The mouse %s";
96
97enum
98{
99 vimfiles_dir_none = 1,
100 vimfiles_dir_vim,
101 vimfiles_dir_home
102};
103static char *(vimfiles_dir_choices[]) =
104{
105 "\nCreate plugin directories:",
106 "No",
107 "In the VIM directory",
108 "In your HOME directory",
109};
110static int vimfiles_dir_choice;
111
112/* non-zero when selected to install the popup menu entry. */
113static int install_popup = 0;
114
115/* non-zero when selected to install the "Open with" entry. */
116static int install_openwith = 0;
117
118/* non-zero when need to add an uninstall entry in the registry */
119static int need_uninstall_entry = 0;
120
121/*
122 * Definitions of the directory name (under $VIM) of the vimfiles directory
123 * and its subdirectories:
124 */
125static char *(vimfiles_subdirs[]) =
126{
127 "colors",
128 "compiler",
129 "doc",
130 "ftdetect",
131 "ftplugin",
132 "indent",
133 "keymap",
134 "plugin",
135 "syntax",
136};
137
138/*
Bram Moolenaar071d4272004-06-13 20:20:40 +0000139 * Obtain a choice from a table.
140 * First entry is a question, others are choices.
141 */
142 static int
143get_choice(char **table, int entries)
144{
145 int answer;
146 int idx;
147 char dummy[100];
148
149 do
150 {
151 for (idx = 0; idx < entries; ++idx)
152 {
153 if (idx)
154 printf("%2d ", idx);
155 printf(table[idx]);
156 printf("\n");
157 }
158 printf("Choice: ");
159 if (scanf("%d", &answer) != 1)
160 {
161 scanf("%99s", dummy);
162 answer = 0;
163 }
164 }
165 while (answer < 1 || answer >= entries);
166
167 return answer;
168}
169
170/*
171 * Check if the user unpacked the archives properly.
172 * Sets "runtimeidx".
173 */
174 static void
175check_unpack(void)
176{
177 char buf[BUFSIZE];
178 FILE *fd;
179 struct stat st;
180
181 /* check for presence of the correct version number in installdir[] */
182 runtimeidx = strlen(installdir) - strlen(VIM_VERSION_NODOT);
183 if (runtimeidx <= 0
184 || stricmp(installdir + runtimeidx, VIM_VERSION_NODOT) != 0
185 || (installdir[runtimeidx - 1] != '/'
186 && installdir[runtimeidx - 1] != '\\'))
187 {
188 printf("ERROR: Install program not in directory \"%s\"\n",
189 VIM_VERSION_NODOT);
190 printf("This program can only work when it is located in its original directory\n");
191 myexit(1);
192 }
193
194 /* check if filetype.vim is present, which means the runtime archive has
195 * been unpacked */
196 sprintf(buf, "%s\\filetype.vim", installdir);
197 if (stat(buf, &st) < 0)
198 {
199 printf("ERROR: Cannot find filetype.vim in \"%s\"\n", installdir);
200 printf("It looks like you did not unpack the runtime archive.\n");
201 printf("You must unpack the runtime archive \"vim%srt.zip\" before installing.\n",
202 VIM_VERSION_NODOT + 3);
203 myexit(1);
204 }
205
206 /* Check if vim.exe or gvim.exe is in the current directory. */
207 if ((fd = fopen("gvim.exe", "r")) != NULL)
208 {
209 fclose(fd);
210 has_gvim = 1;
211 }
212 if ((fd = fopen("vim.exe", "r")) != NULL)
213 {
214 fclose(fd);
215 has_vim = 1;
216 }
217 if (!has_gvim && !has_vim)
218 {
219 printf("ERROR: Cannot find any Vim executables in \"%s\"\n\n",
220 installdir);
221 myexit(1);
222 }
223}
224
225/*
226 * Compare paths "p[plen]" to "q[qlen]". Return 0 if they match.
227 * Ignores case and differences between '/' and '\'.
228 * "plen" and "qlen" can be negative, strlen() is used then.
229 */
230 static int
231pathcmp(char *p, int plen, char *q, int qlen)
232{
233 int i;
234
235 if (plen < 0)
236 plen = strlen(p);
237 if (qlen < 0)
238 qlen = strlen(q);
239 for (i = 0; ; ++i)
240 {
241 /* End of "p": check if "q" also ends or just has a slash. */
242 if (i == plen)
243 {
244 if (i == qlen) /* match */
245 return 0;
246 if (i == qlen - 1 && (q[i] == '\\' || q[i] == '/'))
247 return 0; /* match with trailing slash */
248 return 1; /* no match */
249 }
250
251 /* End of "q": check if "p" also ends or just has a slash. */
252 if (i == qlen)
253 {
254 if (i == plen) /* match */
255 return 0;
256 if (i == plen - 1 && (p[i] == '\\' || p[i] == '/'))
257 return 0; /* match with trailing slash */
258 return 1; /* no match */
259 }
260
261 if (!(mytoupper(p[i]) == mytoupper(q[i])
262 || ((p[i] == '/' || p[i] == '\\')
263 && (q[i] == '/' || q[i] == '\\'))))
264 return 1; /* no match */
265 }
266 /*NOTREACHED*/
267}
268
269/*
270 * If the executable "**destination" is in the install directory, find another
271 * one in $PATH.
272 * On input "**destination" is the path of an executable in allocated memory
273 * (or NULL).
274 * "*destination" is set to NULL or the location of the file.
275 */
276 static void
277findoldfile(char **destination)
278{
279 char *bp = *destination;
280 size_t indir_l = strlen(installdir);
281 char *cp = bp + indir_l;
282 char *tmpname;
283 char *farname;
284
285 /*
286 * No action needed if exe not found or not in this directory.
287 */
288 if (bp == NULL
289 || strnicmp(bp, installdir, indir_l) != 0
290 || strchr("/\\", *cp++) == NULL
291 || strchr(cp, '\\') != NULL
292 || strchr(cp, '/') != NULL)
293 return;
294
295 tmpname = alloc((int)strlen(cp) + 1);
296 strcpy(tmpname, cp);
297 tmpname[strlen(tmpname) - 1] = 'x'; /* .exe -> .exx */
298
299 if (access(tmpname, 0) == 0)
300 {
301 printf("\nERROR: %s and %s clash. Remove or rename %s.\n",
302 tmpname, cp, tmpname);
303 myexit(1);
304 }
305
306 if (rename(cp, tmpname) != 0)
307 {
308 printf("\nERROR: failed to rename %s to %s: %s\n",
309 cp, tmpname, strerror(0));
310 myexit(1);
311 }
312
313 farname = searchpath_save(cp);
314
315 if (rename(tmpname, cp) != 0)
316 {
317 printf("\nERROR: failed to rename %s back to %s: %s\n",
318 tmpname, cp, strerror(0));
319 myexit(1);
320 }
321
322 free(*destination);
323 free(tmpname);
324 *destination = farname;
325}
326
327/*
328 * Check if there is a vim.[exe|bat|, gvim.[exe|bat|, etc. in the path.
329 * When "check_bat_only" is TRUE, only find "default_bat_dir".
330 */
331 static void
332find_bat_exe(int check_bat_only)
333{
334 int i;
335
Bram Moolenaar42bbef42006-03-25 22:02:07 +0000336 /* avoid looking in the "installdir" by chdir to system root */
337 mch_chdir(sysdrive);
338 mch_chdir("\\");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000339
340 for (i = 1; i < TARGET_COUNT; ++i)
341 {
342 targets[i].oldbat = searchpath_save(targets[i].batname);
343 if (!check_bat_only)
344 targets[i].oldexe = searchpath_save(targets[i].exename);
345
346 if (default_bat_dir == NULL && targets[i].oldbat != NULL)
347 {
348 default_bat_dir = alloc(strlen(targets[i].oldbat) + 1);
349 strcpy(default_bat_dir, targets[i].oldbat);
350 remove_tail(default_bat_dir);
351 }
352 if (check_bat_only && targets[i].oldbat != NULL)
Bram Moolenaar42bbef42006-03-25 22:02:07 +0000353 {
Bram Moolenaar071d4272004-06-13 20:20:40 +0000354 free(targets[i].oldbat);
Bram Moolenaar42bbef42006-03-25 22:02:07 +0000355 targets[i].oldbat = NULL;
356 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000357 }
358
359 mch_chdir(installdir);
360}
361
362#ifdef WIN3264
363/*
364 * Get the value of $VIMRUNTIME or $VIM and write it in $TEMP/vimini.ini, so
365 * that NSIS can read it.
366 * When not set, use the directory of a previously installed Vim.
367 */
368 static void
369get_vim_env(void)
370{
371 char *vim;
372 char buf[BUFSIZE];
373 FILE *fd;
374 char fname[BUFSIZE];
375
376 /* First get $VIMRUNTIME. If it's set, remove the tail. */
377 vim = getenv("VIMRUNTIME");
Bram Moolenaar181ace22013-02-13 14:36:44 +0100378 if (vim != NULL && *vim != 0 && strlen(vim) < BUFSIZE)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000379 {
380 strcpy(buf, vim);
381 remove_tail(buf);
382 vim = buf;
383 }
384 else
385 {
386 vim = getenv("VIM");
387 if (vim == NULL || *vim == 0)
388 {
389 /* Use the directory from an old uninstall entry. */
390 if (default_vim_dir != NULL)
391 vim = default_vim_dir;
392 else
393 /* Let NSIS know there is no default, it should use
Bram Moolenaarb8017e72007-05-10 18:59:07 +0000394 * $PROGRAMFILES. */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000395 vim = "";
396 }
397 }
398
399 /* NSIS also uses GetTempPath(), thus we should get the same directory
400 * name as where NSIS will look for vimini.ini. */
401 GetTempPath(BUFSIZE, fname);
402 add_pathsep(fname);
403 strcat(fname, "vimini.ini");
404
405 fd = fopen(fname, "w");
406 if (fd != NULL)
407 {
408 /* Make it look like an .ini file, so that NSIS can read it with a
409 * ReadINIStr command. */
410 fprintf(fd, "[vimini]\n");
411 fprintf(fd, "dir=\"%s\"\n", vim);
412 fclose(fd);
413 }
414 else
415 {
416 printf("Failed to open %s\n", fname);
Bram Moolenaarab8205e2010-07-07 15:14:03 +0200417 sleep(2);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000418 }
419}
420
Bram Moolenaarb230bd52010-05-25 21:02:00 +0200421static int num_windows;
422
423/*
424 * Callback used for EnumWindows():
425 * Count the window if the title looks like it is for the uninstaller.
426 */
427/*ARGSUSED*/
428 static BOOL CALLBACK
429window_cb(HWND hwnd, LPARAM lparam)
430{
431 char title[256];
432
433 title[0] = 0;
434 GetWindowText(hwnd, title, 256);
435 if (strstr(title, "Vim ") != NULL && strstr(title, "Uninstall:") != NULL)
436 ++num_windows;
437 return TRUE;
438}
439
Bram Moolenaar071d4272004-06-13 20:20:40 +0000440/*
441 * Check for already installed Vims.
442 * Return non-zero when found one.
443 */
444 static int
Bram Moolenaar442b4222010-05-24 21:34:22 +0200445uninstall_check(int skip_question)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000446{
447 HKEY key_handle;
448 HKEY uninstall_key_handle;
449 char *uninstall_key = "software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
450 char subkey_name_buff[BUFSIZE];
451 char temp_string_buffer[BUFSIZE];
452 DWORD local_bufsize = BUFSIZE;
453 FILETIME temp_pfiletime;
454 DWORD key_index;
455 char input;
456 long code;
457 DWORD value_type;
458 DWORD orig_num_keys;
459 DWORD new_num_keys;
460 int foundone = 0;
461
Bram Moolenaar760d14a2010-07-31 22:03:44 +0200462 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, uninstall_key, 0,
463 KEY_WOW64_64KEY | KEY_READ, &key_handle);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000464 CHECK_REG_ERROR(code);
465
466 for (key_index = 0;
467 RegEnumKeyEx(key_handle, key_index, subkey_name_buff, &local_bufsize,
468 NULL, NULL, NULL, &temp_pfiletime) != ERROR_NO_MORE_ITEMS;
469 key_index++)
470 {
471 local_bufsize = BUFSIZE;
472 if (strncmp("Vim", subkey_name_buff, 3) == 0)
473 {
474 /* Open the key named Vim* */
Bram Moolenaar760d14a2010-07-31 22:03:44 +0200475 code = RegOpenKeyEx(key_handle, subkey_name_buff, 0,
476 KEY_WOW64_64KEY | KEY_READ, &uninstall_key_handle);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000477 CHECK_REG_ERROR(code);
478
479 /* get the DisplayName out of it to show the user */
480 code = RegQueryValueEx(uninstall_key_handle, "displayname", 0,
481 &value_type, (LPBYTE)temp_string_buffer,
482 &local_bufsize);
483 local_bufsize = BUFSIZE;
484 CHECK_REG_ERROR(code);
485
486 foundone = 1;
487 printf("\n*********************************************************\n");
488 printf("Vim Install found what looks like an existing Vim version.\n");
489 printf("The name of the entry is:\n");
490 printf("\n \"%s\"\n\n", temp_string_buffer);
491
492 printf("Installing the new version will disable part of the existing version.\n");
493 printf("(The batch files used in a console and the \"Edit with Vim\" entry in\n");
494 printf("the popup menu will use the new version)\n");
495
Bram Moolenaar442b4222010-05-24 21:34:22 +0200496 if (skip_question)
497 printf("\nRunning uninstall program for \"%s\"\n", temp_string_buffer);
498 else
499 printf("\nDo you want to uninstall \"%s\" now?\n(y)es/(n)o) ", temp_string_buffer);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000500 fflush(stdout);
501
502 /* get the UninstallString */
503 code = RegQueryValueEx(uninstall_key_handle, "uninstallstring", 0,
504 &value_type, (LPBYTE)temp_string_buffer, &local_bufsize);
505 local_bufsize = BUFSIZE;
506 CHECK_REG_ERROR(code);
507
508 /* Remember the directory, it is used as the default for NSIS. */
509 default_vim_dir = alloc(strlen(temp_string_buffer) + 1);
510 strcpy(default_vim_dir, temp_string_buffer);
511 remove_tail(default_vim_dir);
512 remove_tail(default_vim_dir);
513
514 input = 'n';
515 do
516 {
517 if (input != 'n')
518 printf("%c is an invalid reply. Please enter either 'y' or 'n'\n", input);
519
Bram Moolenaar442b4222010-05-24 21:34:22 +0200520 if (skip_question)
521 input = 'y';
522 else
523 {
524 rewind(stdin);
525 scanf("%c", &input);
526 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000527 switch (input)
528 {
529 case 'y':
530 case 'Y':
531 /* save the number of uninstall keys so we can know if
532 * it changed */
533 RegQueryInfoKey(key_handle, NULL, NULL, NULL,
534 &orig_num_keys, NULL, NULL, NULL,
535 NULL, NULL, NULL, NULL);
536
Bram Moolenaar442b4222010-05-24 21:34:22 +0200537 /* Find existing .bat files before deleting them. */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000538 find_bat_exe(TRUE);
539
540 /* Execute the uninstall program. Put it in double
541 * quotes if there is an embedded space. */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000542 {
543 char buf[BUFSIZE];
544
Bram Moolenaarb230bd52010-05-25 21:02:00 +0200545 if (strchr(temp_string_buffer, ' ') != NULL)
546 sprintf(buf, "\"%s\"", temp_string_buffer);
547 else
548 strcpy(buf, temp_string_buffer);
549 run_command(buf);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000550 }
Bram Moolenaarb230bd52010-05-25 21:02:00 +0200551
552 /* Count the number of windows with a title that match
553 * the installer, so that we can check when it's done.
554 * The uninstaller copies itself, executes the copy
555 * and exits, thus we can't wait for the process to
556 * finish. */
Bram Moolenaarab8205e2010-07-07 15:14:03 +0200557 sleep(1); /* wait for uninstaller to start up */
Bram Moolenaarb230bd52010-05-25 21:02:00 +0200558 num_windows = 0;
559 EnumWindows(window_cb, 0);
Bram Moolenaarab8205e2010-07-07 15:14:03 +0200560 sleep(1); /* wait for windows to be counted */
Bram Moolenaarb230bd52010-05-25 21:02:00 +0200561 if (num_windows == 0)
562 {
563 /* Did not find the uninstaller, ask user to press
564 * Enter when done. Just in case. */
565 printf("Press Enter when the uninstaller is finished\n");
566 rewind(stdin);
567 (void)getchar();
568 }
569 else
570 {
571 printf("Waiting for the uninstaller to finish (press CTRL-C to abort).");
572 do
573 {
574 printf(".");
575 fflush(stdout);
576 num_windows = 0;
577 EnumWindows(window_cb, 0);
Bram Moolenaarab8205e2010-07-07 15:14:03 +0200578 sleep(1); /* wait for windows to be counted */
Bram Moolenaarb230bd52010-05-25 21:02:00 +0200579 } while (num_windows > 0);
580 }
581 printf("\nDone!\n");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000582
Bram Moolenaarfff2bee2010-05-15 13:56:02 +0200583 /* Check if an uninstall reg key was deleted.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000584 * if it was, we want to decrement key_index.
585 * if we don't do this, we will skip the key
586 * immediately after any key that we delete. */
587 RegQueryInfoKey(key_handle, NULL, NULL, NULL,
588 &new_num_keys, NULL, NULL, NULL,
589 NULL, NULL, NULL, NULL);
590 if (new_num_keys < orig_num_keys)
591 key_index--;
592
593 input = 'y';
594 break;
595
596 case 'n':
597 case 'N':
598 /* Do not uninstall */
599 input = 'n';
600 break;
601
602 default: /* just drop through and redo the loop */
603 break;
604 }
605
606 } while (input != 'n' && input != 'y');
607
608 RegCloseKey(uninstall_key_handle);
609 }
610 }
611 RegCloseKey(key_handle);
612
613 return foundone;
614}
615#endif
616
617/*
618 * Find out information about the system.
619 */
620 static void
621inspect_system(void)
622{
623 char *p;
624 char buf[BUFSIZE];
625 FILE *fd;
626 int i;
627 int foundone;
628
629 /* This may take a little while, let the user know what we're doing. */
630 printf("Inspecting system...\n");
631
632 /*
633 * If $VIM is set, check that it's pointing to our directory.
634 */
635 p = getenv("VIM");
636 if (p != NULL && pathcmp(p, -1, installdir, runtimeidx - 1) != 0)
637 {
638 printf("------------------------------------------------------\n");
639 printf("$VIM is set to \"%s\".\n", p);
640 printf("This is different from where this version of Vim is:\n");
641 strcpy(buf, installdir);
642 *(buf + runtimeidx - 1) = NUL;
643 printf("\"%s\"\n", buf);
644 printf("You must adjust or remove the setting of $VIM,\n");
645 if (interactive)
646 {
647 printf("to be able to use this install program.\n");
648 myexit(1);
649 }
650 printf("otherwise Vim WILL NOT WORK properly!\n");
651 printf("------------------------------------------------------\n");
652 }
653
654 /*
655 * If $VIMRUNTIME is set, check that it's pointing to our runtime directory.
656 */
657 p = getenv("VIMRUNTIME");
658 if (p != NULL && pathcmp(p, -1, installdir, -1) != 0)
659 {
660 printf("------------------------------------------------------\n");
661 printf("$VIMRUNTIME is set to \"%s\".\n", p);
662 printf("This is different from where this version of Vim is:\n");
663 printf("\"%s\"\n", installdir);
664 printf("You must adjust or remove the setting of $VIMRUNTIME,\n");
665 if (interactive)
666 {
667 printf("to be able to use this install program.\n");
668 myexit(1);
669 }
670 printf("otherwise Vim WILL NOT WORK properly!\n");
671 printf("------------------------------------------------------\n");
672 }
673
674 /*
675 * Check if there is a vim.[exe|bat|, gvim.[exe|bat|, etc. in the path.
676 */
677 find_bat_exe(FALSE);
678
679 /*
680 * A .exe in the install directory may be found anyway on Windows 2000.
681 * Check for this situation and find another executable if necessary.
682 * w.briscoe@ponl.com 2001-01-20
683 */
684 foundone = 0;
685 for (i = 1; i < TARGET_COUNT; ++i)
686 {
687 findoldfile(&(targets[i].oldexe));
688 if (targets[i].oldexe != NULL)
689 foundone = 1;
690 }
691
692 if (foundone)
693 {
694 printf("Warning: Found Vim executable(s) in your $PATH:\n");
695 for (i = 1; i < TARGET_COUNT; ++i)
696 if (targets[i].oldexe != NULL)
697 printf("%s\n", targets[i].oldexe);
698 printf("It will be used instead of the version you are installing.\n");
699 printf("Please delete or rename it, or adjust your $PATH setting.\n");
700 }
701
702 /*
703 * Check if there is an existing ../_vimrc or ../.vimrc file.
704 */
705 strcpy(oldvimrc, installdir);
706 strcpy(oldvimrc + runtimeidx, "_vimrc");
707 if ((fd = fopen(oldvimrc, "r")) == NULL)
708 {
709 strcpy(oldvimrc + runtimeidx, "vimrc~1"); /* short version of .vimrc */
710 if ((fd = fopen(oldvimrc, "r")) == NULL)
711 {
712 strcpy(oldvimrc + runtimeidx, ".vimrc");
713 fd = fopen(oldvimrc, "r");
714 }
715 }
716 if (fd != NULL)
717 fclose(fd);
718 else
719 *oldvimrc = NUL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000720}
721
722/*
723 * Add a dummy choice to avoid that the numbering changes depending on items
724 * in the environment. The user may type a number he remembered without
725 * looking.
726 */
727 static void
728add_dummy_choice(void)
729{
730 choices[choice_count].installfunc = NULL;
731 choices[choice_count].active = 0;
732 choices[choice_count].changefunc = NULL;
733 choices[choice_count].installfunc = NULL;
734 ++choice_count;
735}
736
737/***********************************************
738 * stuff for creating the batch files.
739 */
740
741/*
742 * Install the vim.bat, gvim.bat, etc. files.
743 */
744 static void
745install_bat_choice(int idx)
746{
747 char *batpath = targets[choices[idx].arg].batpath;
748 char *oldname = targets[choices[idx].arg].oldbat;
749 char *exename = targets[choices[idx].arg].exenamearg;
750 char *vimarg = targets[choices[idx].arg].exearg;
751 FILE *fd;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000752
753 if (*batpath != NUL)
754 {
755 fd = fopen(batpath, "w");
756 if (fd == NULL)
757 printf("\nERROR: Cannot open \"%s\" for writing.\n", batpath);
758 else
759 {
760 need_uninstall_entry = 1;
761
762 fprintf(fd, "@echo off\n");
Bram Moolenaar97b2ad32006-03-18 21:40:56 +0000763 fprintf(fd, "rem -- Run Vim --\n");
764 fprintf(fd, "\n");
Bram Moolenaare609ad52016-03-28 23:05:48 +0200765 fprintf(fd, "setlocal\n");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000766
Bram Moolenaar97b2ad32006-03-18 21:40:56 +0000767 /* Don't use double quotes for the "set" argument, also when it
Bram Moolenaar071d4272004-06-13 20:20:40 +0000768 * contains a space. The quotes would be included in the value
Bram Moolenaar97b2ad32006-03-18 21:40:56 +0000769 * for MSDOS and NT.
770 * The order of preference is:
771 * 1. $VIMRUNTIME/vim.exe (user preference)
772 * 2. $VIM/vim70/vim.exe (hard coded version)
773 * 3. installdir/vim.exe (hard coded install directory)
774 */
775 fprintf(fd, "set VIM_EXE_DIR=%s\n", installdir);
776 fprintf(fd, "if exist \"%%VIM%%\\%s\\%s\" set VIM_EXE_DIR=%%VIM%%\\%s\n",
777 VIM_VERSION_NODOT, exename, VIM_VERSION_NODOT);
778 fprintf(fd, "if exist \"%%VIMRUNTIME%%\\%s\" set VIM_EXE_DIR=%%VIMRUNTIME%%\n", exename);
779 fprintf(fd, "\n");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000780
781 /* Give an error message when the executable could not be found. */
Bram Moolenaar97b2ad32006-03-18 21:40:56 +0000782 fprintf(fd, "if exist \"%%VIM_EXE_DIR%%\\%s\" goto havevim\n",
783 exename);
784 fprintf(fd, "echo \"%%VIM_EXE_DIR%%\\%s\" not found\n", exename);
785 fprintf(fd, "goto eof\n");
786 fprintf(fd, "\n");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000787 fprintf(fd, ":havevim\n");
788
789 fprintf(fd, "rem collect the arguments in VIMARGS for Win95\n");
790 fprintf(fd, "set VIMARGS=\n");
791 if (*exename == 'g')
792 fprintf(fd, "set VIMNOFORK=\n");
793 fprintf(fd, ":loopstart\n");
794 fprintf(fd, "if .%%1==. goto loopend\n");
795 if (*exename == 'g')
796 {
Bram Moolenaare609ad52016-03-28 23:05:48 +0200797 fprintf(fd, "if NOT .%%1==.--nofork goto noforklongarg\n");
798 fprintf(fd, "set VIMNOFORK=1\n");
799 fprintf(fd, ":noforklongarg\n");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000800 fprintf(fd, "if NOT .%%1==.-f goto noforkarg\n");
801 fprintf(fd, "set VIMNOFORK=1\n");
802 fprintf(fd, ":noforkarg\n");
803 }
804 fprintf(fd, "set VIMARGS=%%VIMARGS%% %%1\n");
805 fprintf(fd, "shift\n");
Bram Moolenaar97b2ad32006-03-18 21:40:56 +0000806 fprintf(fd, "goto loopstart\n");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000807 fprintf(fd, ":loopend\n");
Bram Moolenaar97b2ad32006-03-18 21:40:56 +0000808 fprintf(fd, "\n");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000809
Bram Moolenaar97b2ad32006-03-18 21:40:56 +0000810 fprintf(fd, "if .%%OS%%==.Windows_NT goto ntaction\n");
811 fprintf(fd, "\n");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000812
813 /* For gvim.exe use "start" to avoid that the console window stays
814 * open. */
815 if (*exename == 'g')
816 {
817 fprintf(fd, "if .%%VIMNOFORK%%==.1 goto nofork\n");
818 fprintf(fd, "start ");
819 }
820
Bram Moolenaar97b2ad32006-03-18 21:40:56 +0000821 /* Always use quotes, $VIM or $VIMRUNTIME might have a space. */
822 fprintf(fd, "\"%%VIM_EXE_DIR%%\\%s\" %s %%VIMARGS%%\n",
823 exename, vimarg);
824 fprintf(fd, "goto eof\n");
825 fprintf(fd, "\n");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000826
827 if (*exename == 'g')
828 {
829 fprintf(fd, ":nofork\n");
830 fprintf(fd, "start /w ");
Bram Moolenaar97b2ad32006-03-18 21:40:56 +0000831 /* Always use quotes, $VIM or $VIMRUNTIME might have a space. */
832 fprintf(fd, "\"%%VIM_EXE_DIR%%\\%s\" %s %%VIMARGS%%\n",
833 exename, vimarg);
834 fprintf(fd, "goto eof\n");
835 fprintf(fd, "\n");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000836 }
837
838 fprintf(fd, ":ntaction\n");
839 fprintf(fd, "rem for WinNT we can use %%*\n");
840
841 /* For gvim.exe use "start /b" to avoid that the console window
842 * stays open. */
843 if (*exename == 'g')
844 {
845 fprintf(fd, "if .%%VIMNOFORK%%==.1 goto noforknt\n");
846 fprintf(fd, "start \"dummy\" /b ");
847 }
848
Bram Moolenaar97b2ad32006-03-18 21:40:56 +0000849 /* Always use quotes, $VIM or $VIMRUNTIME might have a space. */
850 fprintf(fd, "\"%%VIM_EXE_DIR%%\\%s\" %s %%*\n", exename, vimarg);
851 fprintf(fd, "goto eof\n");
852 fprintf(fd, "\n");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000853
854 if (*exename == 'g')
855 {
856 fprintf(fd, ":noforknt\n");
857 fprintf(fd, "start \"dummy\" /b /wait ");
Bram Moolenaar97b2ad32006-03-18 21:40:56 +0000858 /* Always use quotes, $VIM or $VIMRUNTIME might have a space. */
859 fprintf(fd, "\"%%VIM_EXE_DIR%%\\%s\" %s %%*\n",
860 exename, vimarg);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000861 }
862
863 fprintf(fd, "\n:eof\n");
864 fprintf(fd, "set VIMARGS=\n");
865 if (*exename == 'g')
866 fprintf(fd, "set VIMNOFORK=\n");
867
868 fclose(fd);
869 printf("%s has been %s\n", batpath,
870 oldname == NULL ? "created" : "overwritten");
871 }
872 }
873}
874
875/*
876 * Make the text string for choice "idx".
877 * The format "fmt" is must have one %s item, which "arg" is used for.
878 */
879 static void
880alloc_text(int idx, char *fmt, char *arg)
881{
882 if (choices[idx].text != NULL)
883 free(choices[idx].text);
884
885 choices[idx].text = alloc((int)(strlen(fmt) + strlen(arg)) - 1);
886 sprintf(choices[idx].text, fmt, arg);
887}
888
889/*
890 * Toggle the "Overwrite .../vim.bat" to "Don't overwrite".
891 */
892 static void
893toggle_bat_choice(int idx)
894{
895 char *batname = targets[choices[idx].arg].batpath;
896 char *oldname = targets[choices[idx].arg].oldbat;
897
898 if (*batname == NUL)
899 {
900 alloc_text(idx, " Overwrite %s", oldname);
901 strcpy(batname, oldname);
902 }
903 else
904 {
905 alloc_text(idx, " Do NOT overwrite %s", oldname);
906 *batname = NUL;
907 }
908}
909
910/*
911 * Do some work for a batch file entry: Append the batch file name to the path
912 * and set the text for the choice.
913 */
914 static void
915set_bat_text(int idx, char *batpath, char *name)
916{
917 strcat(batpath, name);
918
919 alloc_text(idx, " Create %s", batpath);
920}
921
922/*
923 * Select a directory to write the batch file line.
924 */
925 static void
926change_bat_choice(int idx)
927{
928 char *path;
929 char *batpath;
930 char *name;
931 int n;
932 char *s;
933 char *p;
934 int count;
935 char **names = NULL;
936 int i;
937 int target = choices[idx].arg;
938
939 name = targets[target].batname;
940 batpath = targets[target].batpath;
941
942 path = getenv("PATH");
943 if (path == NULL)
944 {
945 printf("\nERROR: The variable $PATH is not set\n");
946 return;
947 }
948
949 /*
950 * first round: count number of names in path;
951 * second round: save names to names[].
952 */
953 for (;;)
954 {
955 count = 1;
956 for (p = path; *p; )
957 {
958 s = strchr(p, ';');
959 if (s == NULL)
960 s = p + strlen(p);
961 if (names != NULL)
962 {
963 names[count] = alloc((int)(s - p) + 1);
964 strncpy(names[count], p, s - p);
965 names[count][s - p] = NUL;
966 }
967 ++count;
968 p = s;
969 if (*p != NUL)
970 ++p;
971 }
972 if (names != NULL)
973 break;
974 names = alloc((int)(count + 1) * sizeof(char *));
975 }
976 names[0] = alloc(50);
977 sprintf(names[0], "Select directory to create %s in:", name);
978 names[count] = alloc(50);
979 if (choices[idx].arg == 0)
980 sprintf(names[count], "Do not create any .bat file.");
981 else
982 sprintf(names[count], "Do not create a %s file.", name);
983 n = get_choice(names, count + 1);
984
985 if (n == count)
986 {
987 /* Selected last item, don't create bat file. */
988 *batpath = NUL;
989 if (choices[idx].arg != 0)
990 alloc_text(idx, " Do NOT create %s", name);
991 }
992 else
993 {
994 /* Selected one of the paths. For the first item only keep the path,
995 * for the others append the batch file name. */
996 strcpy(batpath, names[n]);
997 add_pathsep(batpath);
998 if (choices[idx].arg != 0)
999 set_bat_text(idx, batpath, name);
1000 }
1001
1002 for (i = 0; i <= count; ++i)
1003 free(names[i]);
1004 free(names);
1005}
1006
1007char *bat_text_yes = "Install .bat files to use Vim at the command line:";
1008char *bat_text_no = "do NOT install .bat files to use Vim at the command line";
1009
1010 static void
1011change_main_bat_choice(int idx)
1012{
1013 int i;
1014
1015 /* let the user select a default directory or NONE */
1016 change_bat_choice(idx);
1017
1018 if (targets[0].batpath[0] != NUL)
1019 choices[idx].text = bat_text_yes;
1020 else
1021 choices[idx].text = bat_text_no;
1022
1023 /* update the individual batch file selections */
1024 for (i = 1; i < TARGET_COUNT; ++i)
1025 {
1026 /* Only make it active when the first item has a path and the vim.exe
1027 * or gvim.exe exists (there is a changefunc then). */
1028 if (targets[0].batpath[0] != NUL
1029 && choices[idx + i].changefunc != NULL)
1030 {
1031 choices[idx + i].active = 1;
1032 if (choices[idx + i].changefunc == change_bat_choice
1033 && targets[i].batpath[0] != NUL)
1034 {
1035 strcpy(targets[i].batpath, targets[0].batpath);
1036 set_bat_text(idx + i, targets[i].batpath, targets[i].batname);
1037 }
1038 }
1039 else
1040 choices[idx + i].active = 0;
1041 }
1042}
1043
1044/*
1045 * Initialize a choice for creating a batch file.
1046 */
1047 static void
1048init_bat_choice(int target)
1049{
1050 char *batpath = targets[target].batpath;
1051 char *oldbat = targets[target].oldbat;
1052 char *p;
1053 int i;
1054
1055 choices[choice_count].arg = target;
1056 choices[choice_count].installfunc = install_bat_choice;
1057 choices[choice_count].active = 1;
1058 choices[choice_count].text = NULL; /* will be set below */
1059 if (oldbat != NULL)
1060 {
1061 /* A [g]vim.bat exists: Only choice is to overwrite it or not. */
1062 choices[choice_count].changefunc = toggle_bat_choice;
1063 *batpath = NUL;
1064 toggle_bat_choice(choice_count);
1065 }
1066 else
1067 {
1068 if (default_bat_dir != NULL)
1069 /* Prefer using the same path as an existing .bat file. */
1070 strcpy(batpath, default_bat_dir);
1071 else
1072 {
1073 /* No [g]vim.bat exists: Write it to a directory in $PATH. Use
1074 * $WINDIR by default, if it's empty the first item in $PATH. */
1075 p = getenv("WINDIR");
1076 if (p != NULL && *p != NUL)
1077 strcpy(batpath, p);
1078 else
1079 {
1080 p = getenv("PATH");
1081 if (p == NULL || *p == NUL) /* "cannot happen" */
1082 strcpy(batpath, "C:/Windows");
1083 else
1084 {
1085 i = 0;
1086 while (*p != NUL && *p != ';')
1087 batpath[i++] = *p++;
1088 batpath[i] = NUL;
1089 }
1090 }
1091 }
1092 add_pathsep(batpath);
1093 set_bat_text(choice_count, batpath, targets[target].batname);
1094
1095 choices[choice_count].changefunc = change_bat_choice;
1096 }
1097 ++choice_count;
1098}
1099
1100/*
1101 * Set up the choices for installing .bat files.
1102 * For these items "arg" is the index in targets[].
1103 */
1104 static void
1105init_bat_choices(void)
1106{
1107 int i;
1108
1109 /* The first item is used to switch installing batch files on/off and
1110 * setting the default path. */
1111 choices[choice_count].text = bat_text_yes;
1112 choices[choice_count].changefunc = change_main_bat_choice;
1113 choices[choice_count].installfunc = NULL;
1114 choices[choice_count].active = 1;
1115 choices[choice_count].arg = 0;
1116 ++choice_count;
1117
1118 /* Add items for each batch file target. Only used when not disabled by
1119 * the first item. When a .exe exists, don't offer to create a .bat. */
1120 for (i = 1; i < TARGET_COUNT; ++i)
1121 if (targets[i].oldexe == NULL
1122 && (targets[i].exenamearg[0] == 'g' ? has_gvim : has_vim))
1123 init_bat_choice(i);
1124 else
1125 add_dummy_choice();
1126}
1127
1128/*
1129 * Install the vimrc file.
1130 */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001131 static void
1132install_vimrc(int idx)
1133{
1134 FILE *fd, *tfd;
1135 char *fname;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001136
1137 /* If an old vimrc file exists, overwrite it.
1138 * Otherwise create a new one. */
1139 if (*oldvimrc != NUL)
1140 fname = oldvimrc;
1141 else
1142 fname = vimrc;
1143
1144 fd = fopen(fname, "w");
1145 if (fd == NULL)
1146 {
1147 printf("\nERROR: Cannot open \"%s\" for writing.\n", fname);
1148 return;
1149 }
1150 switch (compat_choice)
1151 {
1152 case compat_vi:
1153 fprintf(fd, "set compatible\n");
1154 break;
1155 case compat_some_enhancements:
1156 fprintf(fd, "set nocompatible\n");
1157 break;
1158 case compat_all_enhancements:
1159 fprintf(fd, "set nocompatible\n");
1160 fprintf(fd, "source $VIMRUNTIME/vimrc_example.vim\n");
1161 break;
1162 }
1163 switch (remap_choice)
1164 {
1165 case remap_no:
1166 break;
1167 case remap_win:
1168 fprintf(fd, "source $VIMRUNTIME/mswin.vim\n");
1169 break;
1170 }
1171 switch (mouse_choice)
1172 {
1173 case mouse_xterm:
1174 fprintf(fd, "behave xterm\n");
1175 break;
1176 case mouse_mswin:
1177 fprintf(fd, "behave mswin\n");
1178 break;
1179 }
1180 if ((tfd = fopen("diff.exe", "r")) != NULL)
1181 {
1182 /* Use the diff.exe that comes with the self-extracting gvim.exe. */
1183 fclose(tfd);
1184 fprintf(fd, "\n");
1185 fprintf(fd, "set diffexpr=MyDiff()\n");
1186 fprintf(fd, "function MyDiff()\n");
1187 fprintf(fd, " let opt = '-a --binary '\n");
1188 fprintf(fd, " if &diffopt =~ 'icase' | let opt = opt . '-i ' | endif\n");
1189 fprintf(fd, " if &diffopt =~ 'iwhite' | let opt = opt . '-b ' | endif\n");
1190 /* Use quotes only when needed, they may cause trouble. */
1191 fprintf(fd, " let arg1 = v:fname_in\n");
1192 fprintf(fd, " if arg1 =~ ' ' | let arg1 = '\"' . arg1 . '\"' | endif\n");
1193 fprintf(fd, " let arg2 = v:fname_new\n");
1194 fprintf(fd, " if arg2 =~ ' ' | let arg2 = '\"' . arg2 . '\"' | endif\n");
1195 fprintf(fd, " let arg3 = v:fname_out\n");
1196 fprintf(fd, " if arg3 =~ ' ' | let arg3 = '\"' . arg3 . '\"' | endif\n");
Bram Moolenaar33aec762006-01-22 23:30:12 +00001197
1198 /* If the path has a space: When using cmd.exe (Win NT/2000/XP) put
Bram Moolenaarc62a6442013-11-21 18:13:37 +01001199 * quotes around the diff command and rely on the default value of
1200 * shellxquote to solve the quoting problem for the whole command.
1201 *
Bram Moolenaar33aec762006-01-22 23:30:12 +00001202 * Otherwise put a double quote just before the space and at the
1203 * end of the command. Putting quotes around the whole thing
1204 * doesn't work on Win 95/98/ME. This is mostly guessed! */
Bram Moolenaar33aec762006-01-22 23:30:12 +00001205 fprintf(fd, " if $VIMRUNTIME =~ ' '\n");
1206 fprintf(fd, " if &sh =~ '\\<cmd'\n");
Bram Moolenaarc62a6442013-11-21 18:13:37 +01001207 fprintf(fd, " if empty(&shellxquote)\n");
1208 fprintf(fd, " let l:shxq_sav = ''\n");
1209 fprintf(fd, " set shellxquote&\n");
1210 fprintf(fd, " endif\n");
1211 fprintf(fd, " let cmd = '\"' . $VIMRUNTIME . '\\diff\"'\n");
Bram Moolenaar33aec762006-01-22 23:30:12 +00001212 fprintf(fd, " else\n");
1213 fprintf(fd, " let cmd = substitute($VIMRUNTIME, ' ', '\" ', '') . '\\diff\"'\n");
1214 fprintf(fd, " endif\n");
1215 fprintf(fd, " else\n");
1216 fprintf(fd, " let cmd = $VIMRUNTIME . '\\diff'\n");
1217 fprintf(fd, " endif\n");
Bram Moolenaarc62a6442013-11-21 18:13:37 +01001218 fprintf(fd, " silent execute '!' . cmd . ' ' . opt . arg1 . ' ' . arg2 . ' > ' . arg3\n");
1219 fprintf(fd, " if exists('l:shxq_sav')\n");
1220 fprintf(fd, " let &shellxquote=l:shxq_sav\n");
1221 fprintf(fd, " endif\n");
Bram Moolenaar071d4272004-06-13 20:20:40 +00001222 fprintf(fd, "endfunction\n");
1223 fprintf(fd, "\n");
1224 }
1225 fclose(fd);
1226 printf("%s has been written\n", fname);
1227}
1228
1229 static void
1230change_vimrc_choice(int idx)
1231{
1232 if (choices[idx].installfunc != NULL)
1233 {
1234 /* Switch to NOT change or create a vimrc file. */
1235 if (*oldvimrc != NUL)
1236 alloc_text(idx, "Do NOT change startup file %s", oldvimrc);
1237 else
1238 alloc_text(idx, "Do NOT create startup file %s", vimrc);
1239 choices[idx].installfunc = NULL;
1240 choices[idx + 1].active = 0;
1241 choices[idx + 2].active = 0;
1242 choices[idx + 3].active = 0;
1243 }
1244 else
1245 {
1246 /* Switch to change or create a vimrc file. */
1247 if (*oldvimrc != NUL)
1248 alloc_text(idx, "Overwrite startup file %s with:", oldvimrc);
1249 else
1250 alloc_text(idx, "Create startup file %s with:", vimrc);
1251 choices[idx].installfunc = install_vimrc;
1252 choices[idx + 1].active = 1;
1253 choices[idx + 2].active = 1;
1254 choices[idx + 3].active = 1;
1255 }
1256}
1257
1258/*
1259 * Change the choice how to run Vim.
1260 */
1261 static void
1262change_run_choice(int idx)
1263{
1264 compat_choice = get_choice(compat_choices, TABLE_SIZE(compat_choices));
1265 alloc_text(idx, compat_text, compat_choices[compat_choice]);
1266}
1267
1268/*
1269 * Change the choice if keys are to be remapped.
1270 */
1271 static void
1272change_remap_choice(int idx)
1273{
1274 remap_choice = get_choice(remap_choices, TABLE_SIZE(remap_choices));
1275 alloc_text(idx, remap_text, remap_choices[remap_choice]);
1276}
1277
1278/*
1279 * Change the choice how to select text.
1280 */
1281 static void
1282change_mouse_choice(int idx)
1283{
1284 mouse_choice = get_choice(mouse_choices, TABLE_SIZE(mouse_choices));
1285 alloc_text(idx, mouse_text, mouse_choices[mouse_choice]);
1286}
1287
1288 static void
1289init_vimrc_choices(void)
1290{
1291 /* set path for a new _vimrc file (also when not used) */
1292 strcpy(vimrc, installdir);
1293 strcpy(vimrc + runtimeidx, "_vimrc");
1294
1295 /* Set opposite value and then toggle it by calling change_vimrc_choice() */
1296 if (*oldvimrc == NUL)
1297 choices[choice_count].installfunc = NULL;
1298 else
1299 choices[choice_count].installfunc = install_vimrc;
1300 choices[choice_count].text = NULL;
1301 change_vimrc_choice(choice_count);
1302 choices[choice_count].changefunc = change_vimrc_choice;
1303 choices[choice_count].active = 1;
1304 ++choice_count;
1305
1306 /* default way to run Vim */
1307 alloc_text(choice_count, compat_text, compat_choices[compat_choice]);
1308 choices[choice_count].changefunc = change_run_choice;
1309 choices[choice_count].installfunc = NULL;
1310 choices[choice_count].active = (*oldvimrc == NUL);
1311 ++choice_count;
1312
1313 /* Whether to remap keys */
1314 alloc_text(choice_count, remap_text , remap_choices[remap_choice]);
1315 choices[choice_count].changefunc = change_remap_choice;
1316 choices[choice_count].installfunc = NULL;;
1317 choices[choice_count].active = (*oldvimrc == NUL);
1318 ++choice_count;
1319
1320 /* default way to use the mouse */
1321 alloc_text(choice_count, mouse_text, mouse_choices[mouse_choice]);
1322 choices[choice_count].changefunc = change_mouse_choice;
1323 choices[choice_count].installfunc = NULL;;
1324 choices[choice_count].active = (*oldvimrc == NUL);
1325 ++choice_count;
1326}
1327
Bram Moolenaarab8205e2010-07-07 15:14:03 +02001328#if defined(WIN3264)
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001329 static LONG
1330reg_create_key(
1331 HKEY root,
1332 const char *subkey,
1333 PHKEY phKey)
1334{
1335 DWORD disp;
1336
1337 *phKey = NULL;
1338 return RegCreateKeyEx(
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001339 root, subkey,
1340 0, NULL, REG_OPTION_NON_VOLATILE,
1341 KEY_WOW64_64KEY | KEY_WRITE,
1342 NULL, phKey, &disp);
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001343}
1344
1345 static LONG
1346reg_set_string_value(
1347 HKEY hKey,
1348 const char *value_name,
1349 const char *data)
1350{
1351 return RegSetValueEx(hKey, value_name, 0, REG_SZ,
1352 (LPBYTE)data, (DWORD)(1 + strlen(data)));
1353}
1354
1355 static LONG
1356reg_create_key_and_value(
1357 HKEY hRootKey,
1358 const char *subkey,
1359 const char *value_name,
1360 const char *data)
1361{
1362 HKEY hKey;
1363 LONG lRet = reg_create_key(hRootKey, subkey, &hKey);
1364
1365 if (ERROR_SUCCESS == lRet)
1366 {
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001367 lRet = reg_set_string_value(hKey, value_name, data);
1368 RegCloseKey(hKey);
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001369 }
1370 return lRet;
1371}
1372
1373 static LONG
1374register_inproc_server(
1375 HKEY hRootKey,
1376 const char *clsid,
1377 const char *extname,
1378 const char *module,
1379 const char *threading_model)
1380{
1381 CHAR subkey[BUFSIZE];
1382 LONG lRet;
1383
1384 sprintf(subkey, "CLSID\\%s", clsid);
1385 lRet = reg_create_key_and_value(hRootKey, subkey, NULL, extname);
1386 if (ERROR_SUCCESS == lRet)
1387 {
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001388 sprintf(subkey, "CLSID\\%s\\InProcServer32", clsid);
1389 lRet = reg_create_key_and_value(hRootKey, subkey, NULL, module);
1390 if (ERROR_SUCCESS == lRet)
1391 {
1392 lRet = reg_create_key_and_value(hRootKey, subkey,
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001393 "ThreadingModel", threading_model);
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001394 }
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001395 }
1396 return lRet;
1397}
1398
1399 static LONG
1400register_shellex(
1401 HKEY hRootKey,
1402 const char *clsid,
1403 const char *name,
1404 const char *exe_path)
1405{
1406 LONG lRet = reg_create_key_and_value(
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001407 hRootKey,
1408 "*\\shellex\\ContextMenuHandlers\\gvim",
1409 NULL,
1410 clsid);
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001411
1412 if (ERROR_SUCCESS == lRet)
1413 {
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001414 lRet = reg_create_key_and_value(
1415 HKEY_LOCAL_MACHINE,
1416 "Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved",
1417 clsid,
1418 name);
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001419
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001420 if (ERROR_SUCCESS == lRet)
1421 {
1422 lRet = reg_create_key_and_value(
1423 HKEY_LOCAL_MACHINE,
1424 "Software\\Vim\\Gvim",
1425 "path",
1426 exe_path);
1427 }
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001428 }
1429 return lRet;
1430}
1431
1432 static LONG
1433register_openwith(
1434 HKEY hRootKey,
1435 const char *exe_path)
1436{
Bram Moolenaar78050042010-07-31 20:53:54 +02001437 char exe_cmd[BUFSIZE];
1438 LONG lRet;
1439
Bram Moolenaarbbdcb482010-08-02 20:45:27 +02001440 sprintf(exe_cmd, "\"%s\" \"%%1\"", exe_path);
Bram Moolenaar78050042010-07-31 20:53:54 +02001441 lRet = reg_create_key_and_value(
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001442 hRootKey,
1443 "Applications\\gvim.exe\\shell\\edit\\command",
1444 NULL,
Bram Moolenaar78050042010-07-31 20:53:54 +02001445 exe_cmd);
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001446
1447 if (ERROR_SUCCESS == lRet)
1448 {
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001449 int i;
1450 static const char *openwith[] = {
1451 ".htm\\OpenWithList\\gvim.exe",
1452 ".vim\\OpenWithList\\gvim.exe",
1453 "*\\OpenWithList\\gvim.exe",
1454 };
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001455
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001456 for (i = 0; ERROR_SUCCESS == lRet
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001457 && i < sizeof(openwith) / sizeof(openwith[0]); i++)
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001458 {
1459 lRet = reg_create_key_and_value(hRootKey, openwith[i], NULL, "");
1460 }
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001461 }
1462
1463 return lRet;
1464}
1465
1466 static LONG
1467register_uninstall(
1468 HKEY hRootKey,
1469 const char *appname,
1470 const char *display_name,
1471 const char *uninstall_string)
1472{
1473 LONG lRet = reg_create_key_and_value(hRootKey, appname,
1474 "DisplayName", display_name);
1475
1476 if (ERROR_SUCCESS == lRet)
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001477 lRet = reg_create_key_and_value(hRootKey, appname,
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001478 "UninstallString", uninstall_string);
1479 return lRet;
1480}
Bram Moolenaarab8205e2010-07-07 15:14:03 +02001481#endif /* WIN3264 */
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001482
Bram Moolenaar071d4272004-06-13 20:20:40 +00001483/*
1484 * Add some entries to the registry:
1485 * - to add "Edit with Vim" to the context * menu
1486 * - to add Vim to the "Open with..." list
1487 * - to uninstall Vim
1488 */
1489/*ARGSUSED*/
Bram Moolenaarab8205e2010-07-07 15:14:03 +02001490 static int
Bram Moolenaar071d4272004-06-13 20:20:40 +00001491install_registry(void)
1492{
Bram Moolenaarab8205e2010-07-07 15:14:03 +02001493#ifdef WIN3264
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001494 LONG lRet = ERROR_SUCCESS;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001495 const char *vim_ext_ThreadingModel = "Apartment";
1496 const char *vim_ext_name = "Vim Shell Extension";
1497 const char *vim_ext_clsid = "{51EEE242-AD87-11d3-9C1E-0090278BBD99}";
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001498 char vim_exe_path[BUFSIZE];
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001499 char display_name[BUFSIZE];
1500 char uninstall_string[BUFSIZE];
Bram Moolenaar071d4272004-06-13 20:20:40 +00001501
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001502 sprintf(vim_exe_path, "%s\\gvim.exe", installdir);
1503
1504 if (install_popup)
1505 {
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001506 char bufg[BUFSIZE];
1507 struct stat st;
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001508
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001509 if (stat("gvimext.dll", &st) >= 0)
1510 sprintf(bufg, "%s\\gvimext.dll", installdir);
1511 else
1512 /* gvimext.dll is in gvimext subdir */
1513 sprintf(bufg, "%s\\gvimext\\gvimext.dll", installdir);
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001514
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001515 printf("Creating \"Edit with Vim\" popup menu entry\n");
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001516
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001517 lRet = register_inproc_server(
1518 HKEY_CLASSES_ROOT, vim_ext_clsid, vim_ext_name,
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001519 bufg, vim_ext_ThreadingModel);
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001520 if (ERROR_SUCCESS != lRet)
Bram Moolenaarab8205e2010-07-07 15:14:03 +02001521 return FAIL;
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001522 lRet = register_shellex(
1523 HKEY_CLASSES_ROOT, vim_ext_clsid, vim_ext_name, vim_exe_path);
1524 if (ERROR_SUCCESS != lRet)
Bram Moolenaarab8205e2010-07-07 15:14:03 +02001525 return FAIL;
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001526 }
1527
1528 if (install_openwith)
1529 {
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001530 printf("Creating \"Open with ...\" list entry\n");
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001531
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001532 lRet = register_openwith(HKEY_CLASSES_ROOT, vim_exe_path);
1533 if (ERROR_SUCCESS != lRet)
Bram Moolenaarab8205e2010-07-07 15:14:03 +02001534 return FAIL;
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001535 }
1536
1537 printf("Creating an uninstall entry\n");
1538
1539 /* For the NSIS installer use the generated uninstaller. */
1540 if (interactive)
1541 {
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001542 sprintf(display_name, "Vim " VIM_VERSION_SHORT);
Bram Moolenaar16d79a32010-07-18 22:33:56 +02001543 sprintf(uninstall_string, "%s\\uninstal.exe", installdir);
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001544 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001545 else
1546 {
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001547 sprintf(display_name, "Vim " VIM_VERSION_SHORT " (self-installing)");
Bram Moolenaar16d79a32010-07-18 22:33:56 +02001548 sprintf(uninstall_string, "%s\\uninstall-gui.exe", installdir);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001549 }
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001550
1551 lRet = register_uninstall(
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001552 HKEY_LOCAL_MACHINE,
1553 "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Vim " VIM_VERSION_SHORT,
1554 display_name,
1555 uninstall_string);
Bram Moolenaarab8205e2010-07-07 15:14:03 +02001556 if (ERROR_SUCCESS != lRet)
1557 return FAIL;
1558#endif /* WIN3264 */
Bram Moolenaarccd9ccf2010-07-07 13:19:55 +02001559
Bram Moolenaarab8205e2010-07-07 15:14:03 +02001560 return OK;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001561}
1562
1563 static void
1564change_popup_choice(int idx)
1565{
1566 if (install_popup == 0)
1567 {
1568 choices[idx].text = "Install an entry for Vim in the popup menu for the right\n mouse button so that you can edit any file with Vim";
1569 install_popup = 1;
1570 }
1571 else
1572 {
1573 choices[idx].text = "Do NOT install an entry for Vim in the popup menu for the\n right mouse button to edit any file with Vim";
1574 install_popup = 0;
1575 }
1576}
1577
1578/*
1579 * Only add the choice for the popup menu entry when gvim.exe was found and
1580 * both gvimext.dll and regedit.exe exist.
1581 */
1582 static void
1583init_popup_choice(void)
1584{
1585 struct stat st;
1586
1587 if (has_gvim
1588 && (stat("gvimext.dll", &st) >= 0
1589 || stat("gvimext/gvimext.dll", &st) >= 0)
1590#ifndef WIN3264
1591 && searchpath("regedit.exe") != NULL
1592#endif
1593 )
1594 {
1595 choices[choice_count].changefunc = change_popup_choice;
1596 choices[choice_count].installfunc = NULL;
1597 choices[choice_count].active = 1;
1598 change_popup_choice(choice_count); /* set the text */
1599 ++choice_count;
1600 }
1601 else
1602 add_dummy_choice();
1603}
1604
1605 static void
1606change_openwith_choice(int idx)
1607{
1608 if (install_openwith == 0)
1609 {
1610 choices[idx].text = "Add Vim to the \"Open With...\" list in the popup menu for the right\n mouse button so that you can edit any file with Vim";
1611 install_openwith = 1;
1612 }
1613 else
1614 {
1615 choices[idx].text = "Do NOT add Vim to the \"Open With...\" list in the popup menu for the\n right mouse button to edit any file with Vim";
1616 install_openwith = 0;
1617 }
1618}
1619
1620/*
1621 * Only add the choice for the open-with menu entry when gvim.exe was found
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02001622 * and regedit.exe exist.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001623 */
1624 static void
1625init_openwith_choice(void)
1626{
1627 if (has_gvim
1628#ifndef WIN3264
1629 && searchpath("regedit.exe") != NULL
1630#endif
1631 )
1632 {
1633 choices[choice_count].changefunc = change_openwith_choice;
1634 choices[choice_count].installfunc = NULL;
1635 choices[choice_count].active = 1;
1636 change_openwith_choice(choice_count); /* set the text */
1637 ++choice_count;
1638 }
1639 else
1640 add_dummy_choice();
1641}
1642
1643#ifdef WIN3264
1644/* create_shortcut
1645 *
1646 * Create a shell link.
1647 *
1648 * returns 0 on failure, non-zero on successful completion.
1649 *
1650 * NOTE: Currently untested with mingw.
1651 */
1652 int
1653create_shortcut(
1654 const char *shortcut_name,
1655 const char *iconfile_path,
1656 int iconindex,
1657 const char *shortcut_target,
1658 const char *shortcut_args,
1659 const char *workingdir
1660 )
1661{
1662 IShellLink *shelllink_ptr;
1663 HRESULT hres;
1664 IPersistFile *persistfile_ptr;
1665
1666 /* Initialize COM library */
1667 hres = CoInitialize(NULL);
1668 if (!SUCCEEDED(hres))
1669 {
1670 printf("Error: Could not open the COM library. Not creating shortcut.\n");
1671 return FAIL;
1672 }
1673
1674 /* Instantiate a COM object for the ShellLink, store a pointer to it
1675 * in shelllink_ptr. */
1676 hres = CoCreateInstance(&CLSID_ShellLink,
1677 NULL,
1678 CLSCTX_INPROC_SERVER,
1679 &IID_IShellLink,
1680 (void **) &shelllink_ptr);
1681
1682 if (SUCCEEDED(hres)) /* If the instantiation was successful... */
1683 {
1684 /* ...Then build a PersistFile interface for the ShellLink so we can
1685 * save it as a file after we build it. */
1686 hres = shelllink_ptr->lpVtbl->QueryInterface(shelllink_ptr,
1687 &IID_IPersistFile, (void **) &persistfile_ptr);
1688
1689 if (SUCCEEDED(hres))
1690 {
1691 wchar_t wsz[BUFSIZE];
1692
1693 /* translate the (possibly) multibyte shortcut filename to windows
1694 * Unicode so it can be used as a file name.
1695 */
1696 MultiByteToWideChar(CP_ACP, 0, shortcut_name, -1, wsz, BUFSIZE);
1697
1698 /* set the attributes */
1699 shelllink_ptr->lpVtbl->SetPath(shelllink_ptr, shortcut_target);
1700 shelllink_ptr->lpVtbl->SetWorkingDirectory(shelllink_ptr,
1701 workingdir);
1702 shelllink_ptr->lpVtbl->SetIconLocation(shelllink_ptr,
1703 iconfile_path, iconindex);
1704 shelllink_ptr->lpVtbl->SetArguments(shelllink_ptr, shortcut_args);
1705
1706 /* save the shortcut to a file and return the PersistFile object*/
1707 persistfile_ptr->lpVtbl->Save(persistfile_ptr, wsz, 1);
1708 persistfile_ptr->lpVtbl->Release(persistfile_ptr);
1709 }
1710 else
1711 {
1712 printf("QueryInterface Error\n");
1713 return FAIL;
1714 }
1715
1716 /* Return the ShellLink object */
1717 shelllink_ptr->lpVtbl->Release(shelllink_ptr);
1718 }
1719 else
1720 {
1721 printf("CoCreateInstance Error - hres = %08x\n", (int)hres);
1722 return FAIL;
1723 }
1724
1725 return OK;
1726}
1727
1728/*
1729 * Build a path to where we will put a specified link.
1730 *
1731 * Return 0 on error, non-zero on success
1732 */
1733 int
1734build_link_name(
1735 char *link_path,
1736 const char *link_name,
1737 const char *shell_folder_name)
1738{
1739 char shell_folder_path[BUFSIZE];
1740
1741 if (get_shell_folder_path(shell_folder_path, shell_folder_name) == FAIL)
1742 {
1743 printf("An error occurred while attempting to find the path to %s.\n",
1744 shell_folder_name);
1745 return FAIL;
1746 }
1747
1748 /* Make sure the directory exists (create Start Menu\Programs\Vim).
1749 * Ignore errors if it already exists. */
1750 vim_mkdir(shell_folder_path, 0755);
1751
1752 /* build the path to the shortcut and the path to gvim.exe */
1753 sprintf(link_path, "%s\\%s.lnk", shell_folder_path, link_name);
1754
1755 return OK;
1756}
1757
1758 static int
1759build_shortcut(
1760 const char *name, /* Name of the shortcut */
1761 const char *exename, /* Name of the executable (e.g., vim.exe) */
1762 const char *args,
1763 const char *shell_folder,
1764 const char *workingdir)
1765{
1766 char executable_path[BUFSIZE];
1767 char link_name[BUFSIZE];
1768
1769 sprintf(executable_path, "%s\\%s", installdir, exename);
1770
1771 if (build_link_name(link_name, name, shell_folder) == FAIL)
1772 {
1773 printf("An error has occurred. A shortcut to %s will not be created %s.\n",
1774 name,
1775 *shell_folder == 'd' ? "on the desktop" : "in the Start menu");
1776 return FAIL;
1777 }
1778
1779 /* Create the shortcut: */
1780 return create_shortcut(link_name, executable_path, 0,
1781 executable_path, args, workingdir);
1782}
1783
1784/*
1785 * We used to use "homedir" as the working directory, but that is a bad choice
Bram Moolenaar03e228a2013-11-07 04:49:27 +01001786 * on multi-user systems. However, not specifying a directory results in the
1787 * current directory to be c:\Windows\system32 on Windows 7. Use environment
1788 * variables instead.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001789 */
Bram Moolenaar03e228a2013-11-07 04:49:27 +01001790#define WORKDIR "%HOMEDRIVE%%HOMEPATH%"
Bram Moolenaar071d4272004-06-13 20:20:40 +00001791
1792/*
1793 * Create shortcut(s) in the Start Menu\Programs\Vim folder.
1794 */
1795 static void
1796install_start_menu(int idx)
1797{
1798 need_uninstall_entry = 1;
1799 printf("Creating start menu\n");
1800 if (has_vim)
1801 {
1802 if (build_shortcut("Vim", "vim.exe", "",
1803 VIM_STARTMENU, WORKDIR) == FAIL)
1804 return;
1805 if (build_shortcut("Vim Read-only", "vim.exe", "-R",
1806 VIM_STARTMENU, WORKDIR) == FAIL)
1807 return;
1808 if (build_shortcut("Vim Diff", "vim.exe", "-d",
1809 VIM_STARTMENU, WORKDIR) == FAIL)
1810 return;
1811 }
1812 if (has_gvim)
1813 {
1814 if (build_shortcut("gVim", "gvim.exe", "",
1815 VIM_STARTMENU, WORKDIR) == FAIL)
1816 return;
1817 if (build_shortcut("gVim Easy", "gvim.exe", "-y",
1818 VIM_STARTMENU, WORKDIR) == FAIL)
1819 return;
1820 if (build_shortcut("gVim Read-only", "gvim.exe", "-R",
1821 VIM_STARTMENU, WORKDIR) == FAIL)
1822 return;
1823 if (build_shortcut("gVim Diff", "gvim.exe", "-d",
1824 VIM_STARTMENU, WORKDIR) == FAIL)
1825 return;
1826 }
1827 if (build_shortcut("Uninstall",
1828 interactive ? "uninstal.exe" : "uninstall-gui.exe", "",
1829 VIM_STARTMENU, installdir) == FAIL)
1830 return;
1831 /* For Windows NT the working dir of the vimtutor.bat must be right,
1832 * otherwise gvim.exe won't be found and using gvimbat doesn't work. */
1833 if (build_shortcut("Vim tutor", "vimtutor.bat", "",
1834 VIM_STARTMENU, installdir) == FAIL)
1835 return;
1836 if (build_shortcut("Help", has_gvim ? "gvim.exe" : "vim.exe", "-c h",
1837 VIM_STARTMENU, WORKDIR) == FAIL)
1838 return;
1839 {
1840 char shell_folder_path[BUFSIZE];
1841
1842 /* Creating the URL shortcut works a bit differently... */
1843 if (get_shell_folder_path(shell_folder_path, VIM_STARTMENU) == FAIL)
1844 {
1845 printf("Finding the path of the Start menu failed\n");
1846 return ;
1847 }
1848 add_pathsep(shell_folder_path);
1849 strcat(shell_folder_path, "Vim Online.url");
1850 if (!WritePrivateProfileString("InternetShortcut", "URL",
1851 "http://vim.sf.net/", shell_folder_path))
1852 {
1853 printf("Creating the Vim online URL failed\n");
1854 return;
1855 }
1856 }
1857}
1858
1859 static void
1860toggle_startmenu_choice(int idx)
1861{
1862 if (choices[idx].installfunc == NULL)
1863 {
1864 choices[idx].installfunc = install_start_menu;
1865 choices[idx].text = "Add Vim to the Start menu";
1866 }
1867 else
1868 {
1869 choices[idx].installfunc = NULL;
1870 choices[idx].text = "Do NOT add Vim to the Start menu";
1871 }
1872}
1873
1874/*
1875 * Function to actually create the shortcuts
1876 *
1877 * Currently I am supplying no working directory to the shortcut. This
1878 * means that the initial working dir will be:
1879 * - the location of the shortcut if no file is supplied
1880 * - the location of the file being edited if a file is supplied (ie via
1881 * drag and drop onto the shortcut).
1882 */
1883 void
1884install_shortcut_gvim(int idx)
1885{
1886 /* Create shortcut(s) on the desktop */
1887 if (choices[idx].arg)
1888 {
1889 (void)build_shortcut(icon_names[0], "gvim.exe",
1890 "", "desktop", WORKDIR);
1891 need_uninstall_entry = 1;
1892 }
1893}
1894
1895 void
1896install_shortcut_evim(int idx)
1897{
1898 if (choices[idx].arg)
1899 {
1900 (void)build_shortcut(icon_names[1], "gvim.exe",
1901 "-y", "desktop", WORKDIR);
1902 need_uninstall_entry = 1;
1903 }
1904}
1905
1906 void
1907install_shortcut_gview(int idx)
1908{
1909 if (choices[idx].arg)
1910 {
1911 (void)build_shortcut(icon_names[2], "gvim.exe",
1912 "-R", "desktop", WORKDIR);
1913 need_uninstall_entry = 1;
1914 }
1915}
1916
1917 void
1918toggle_shortcut_choice(int idx)
1919{
1920 char *arg;
1921
1922 if (choices[idx].installfunc == install_shortcut_gvim)
1923 arg = "gVim";
1924 else if (choices[idx].installfunc == install_shortcut_evim)
1925 arg = "gVim Easy";
1926 else
1927 arg = "gVim Read-only";
1928 if (choices[idx].arg)
1929 {
1930 choices[idx].arg = 0;
1931 alloc_text(idx, "Do NOT create a desktop icon for %s", arg);
1932 }
1933 else
1934 {
1935 choices[idx].arg = 1;
1936 alloc_text(idx, "Create a desktop icon for %s", arg);
1937 }
1938}
1939#endif /* WIN3264 */
1940
1941 static void
1942init_startmenu_choice(void)
1943{
1944#ifdef WIN3264
1945 /* Start menu */
1946 choices[choice_count].changefunc = toggle_startmenu_choice;
1947 choices[choice_count].installfunc = NULL;
1948 choices[choice_count].active = 1;
1949 toggle_startmenu_choice(choice_count); /* set the text */
1950 ++choice_count;
1951#else
1952 add_dummy_choice();
1953#endif
1954}
1955
1956/*
1957 * Add the choice for the desktop shortcuts.
1958 */
1959 static void
1960init_shortcut_choices(void)
1961{
1962#ifdef WIN3264
1963 /* Shortcut to gvim */
1964 choices[choice_count].text = NULL;
1965 choices[choice_count].arg = 0;
1966 choices[choice_count].active = has_gvim;
1967 choices[choice_count].changefunc = toggle_shortcut_choice;
1968 choices[choice_count].installfunc = install_shortcut_gvim;
1969 toggle_shortcut_choice(choice_count);
1970 ++choice_count;
1971
1972 /* Shortcut to evim */
1973 choices[choice_count].text = NULL;
1974 choices[choice_count].arg = 0;
1975 choices[choice_count].active = has_gvim;
1976 choices[choice_count].changefunc = toggle_shortcut_choice;
1977 choices[choice_count].installfunc = install_shortcut_evim;
1978 toggle_shortcut_choice(choice_count);
1979 ++choice_count;
1980
1981 /* Shortcut to gview */
1982 choices[choice_count].text = NULL;
1983 choices[choice_count].arg = 0;
1984 choices[choice_count].active = has_gvim;
1985 choices[choice_count].changefunc = toggle_shortcut_choice;
1986 choices[choice_count].installfunc = install_shortcut_gview;
1987 toggle_shortcut_choice(choice_count);
1988 ++choice_count;
1989#else
1990 add_dummy_choice();
1991 add_dummy_choice();
1992 add_dummy_choice();
1993#endif
1994}
1995
1996#ifdef WIN3264
1997/*
1998 * Attempt to register OLE for Vim.
1999 */
2000 static void
2001install_OLE_register(void)
2002{
2003 char register_command_string[BUFSIZE + 30];
2004
2005 printf("\n--- Attempting to register Vim with OLE ---\n");
2006 printf("(There is no message whether this works or not.)\n");
2007
2008#ifndef __CYGWIN__
2009 sprintf(register_command_string, "\"%s\\gvim.exe\" -silent -register", installdir);
2010#else
2011 /* handle this differently for Cygwin which sometimes has trouble with
2012 * Windows-style pathnames here. */
2013 sprintf(register_command_string, "./gvim.exe -silent -register");
2014#endif
2015 system(register_command_string);
2016}
2017#endif /* WIN3264 */
2018
2019/*
2020 * Remove the last part of directory "path[]" to get its parent, and put the
2021 * result in "to[]".
2022 */
2023 static void
2024dir_remove_last(const char *path, char to[BUFSIZE])
2025{
2026 char c;
2027 long last_char_to_copy;
2028 long path_length = strlen(path);
2029
2030 /* skip the last character just in case it is a '\\' */
2031 last_char_to_copy = path_length - 2;
2032 c = path[last_char_to_copy];
2033
2034 while (c != '\\')
2035 {
2036 last_char_to_copy--;
2037 c = path[last_char_to_copy];
2038 }
2039
2040 strncpy(to, path, (size_t)last_char_to_copy);
2041 to[last_char_to_copy] = NUL;
2042}
2043
2044 static void
2045set_directories_text(int idx)
2046{
2047 if (vimfiles_dir_choice == (int)vimfiles_dir_none)
2048 alloc_text(idx, "Do NOT create plugin directories%s", "");
2049 else
2050 alloc_text(idx, "Create plugin directories: %s",
2051 vimfiles_dir_choices[vimfiles_dir_choice]);
2052}
2053
2054/*
2055 * Change the directory that the vim plugin directories will be created in:
2056 * $HOME, $VIM or nowhere.
2057 */
2058 static void
2059change_directories_choice(int idx)
2060{
2061 int choice_count = TABLE_SIZE(vimfiles_dir_choices);
2062
2063 /* Don't offer the $HOME choice if $HOME isn't set. */
2064 if (getenv("HOME") == NULL)
2065 --choice_count;
2066 vimfiles_dir_choice = get_choice(vimfiles_dir_choices, choice_count);
2067 set_directories_text(idx);
2068}
2069
2070/*
2071 * Create the plugin directories...
2072 */
2073/*ARGSUSED*/
2074 static void
2075install_vimfilesdir(int idx)
2076{
2077 int i;
2078 char *p;
2079 char vimdir_path[BUFSIZE];
2080 char vimfiles_path[BUFSIZE];
2081 char tmp_dirname[BUFSIZE];
2082
2083 /* switch on the location that the user wants the plugin directories
2084 * built in */
2085 switch (vimfiles_dir_choice)
2086 {
2087 case vimfiles_dir_vim:
2088 {
2089 /* Go to the %VIM% directory - check env first, then go one dir
2090 * below installdir if there is no %VIM% environment variable.
2091 * The accuracy of $VIM is checked in inspect_system(), so we
2092 * can be sure it is ok to use here. */
2093 p = getenv("VIM");
2094 if (p == NULL) /* No $VIM in path */
2095 dir_remove_last(installdir, vimdir_path);
2096 else
2097 strcpy(vimdir_path, p);
2098 break;
2099 }
2100 case vimfiles_dir_home:
2101 {
2102 /* Find the $HOME directory. Its existence was already checked. */
2103 p = getenv("HOME");
2104 if (p == NULL)
2105 {
2106 printf("Internal error: $HOME is NULL\n");
2107 p = "c:\\";
2108 }
2109 strcpy(vimdir_path, p);
2110 break;
2111 }
2112 case vimfiles_dir_none:
2113 {
2114 /* Do not create vim plugin directory */
2115 return;
2116 }
2117 }
2118
2119 /* Now, just create the directory. If it already exists, it will fail
2120 * silently. */
2121 sprintf(vimfiles_path, "%s\\vimfiles", vimdir_path);
2122 vim_mkdir(vimfiles_path, 0755);
2123
2124 printf("Creating the following directories in \"%s\":\n", vimfiles_path);
2125 for (i = 0; i < TABLE_SIZE(vimfiles_subdirs); i++)
2126 {
2127 sprintf(tmp_dirname, "%s\\%s", vimfiles_path, vimfiles_subdirs[i]);
2128 printf(" %s", vimfiles_subdirs[i]);
2129 vim_mkdir(tmp_dirname, 0755);
2130 }
2131 printf("\n");
2132}
2133
2134/*
2135 * Add the creation of runtime files to the setup sequence.
2136 */
2137 static void
2138init_directories_choice(void)
2139{
2140 struct stat st;
2141 char tmp_dirname[BUFSIZE];
2142 char *p;
2143
2144 choices[choice_count].text = alloc(150);
2145 choices[choice_count].changefunc = change_directories_choice;
2146 choices[choice_count].installfunc = install_vimfilesdir;
2147 choices[choice_count].active = 1;
2148
2149 /* Check if the "compiler" directory already exists. That's a good
2150 * indication that the plugin directories were already created. */
2151 if (getenv("HOME") != NULL)
2152 {
2153 vimfiles_dir_choice = (int)vimfiles_dir_home;
2154 sprintf(tmp_dirname, "%s\\vimfiles\\compiler", getenv("HOME"));
2155 if (stat(tmp_dirname, &st) == 0)
2156 vimfiles_dir_choice = (int)vimfiles_dir_none;
2157 }
2158 else
2159 {
2160 vimfiles_dir_choice = (int)vimfiles_dir_vim;
2161 p = getenv("VIM");
2162 if (p == NULL) /* No $VIM in path, use the install dir */
2163 dir_remove_last(installdir, tmp_dirname);
2164 else
2165 strcpy(tmp_dirname, p);
2166 strcat(tmp_dirname, "\\vimfiles\\compiler");
2167 if (stat(tmp_dirname, &st) == 0)
2168 vimfiles_dir_choice = (int)vimfiles_dir_none;
2169 }
2170
2171 set_directories_text(choice_count);
2172 ++choice_count;
2173}
2174
2175/*
2176 * Setup the choices and the default values.
2177 */
2178 static void
2179setup_choices(void)
2180{
2181 /* install the batch files */
2182 init_bat_choices();
2183
2184 /* (over) write _vimrc file */
2185 init_vimrc_choices();
2186
2187 /* Whether to add Vim to the popup menu */
2188 init_popup_choice();
2189
2190 /* Whether to add Vim to the "Open With..." menu */
2191 init_openwith_choice();
2192
2193 /* Whether to add Vim to the Start Menu. */
2194 init_startmenu_choice();
2195
2196 /* Whether to add shortcuts to the Desktop. */
2197 init_shortcut_choices();
2198
2199 /* Whether to create the runtime directories. */
2200 init_directories_choice();
2201}
2202
2203 static void
2204print_cmd_line_help(void)
2205{
2206 printf("Vim installer non-interactive command line arguments:\n");
2207 printf("\n");
2208 printf("-create-batfiles [vim gvim evim view gview vimdiff gvimdiff]\n");
2209 printf(" Create .bat files for Vim variants in the Windows directory.\n");
2210 printf("-create-vimrc\n");
2211 printf(" Create a default _vimrc file if one does not already exist.\n");
2212 printf("-install-popup\n");
2213 printf(" Install the Edit-with-Vim context menu entry\n");
2214 printf("-install-openwith\n");
2215 printf(" Add Vim to the \"Open With...\" context menu list\n");
2216#ifdef WIN3264
2217 printf("-add-start-menu");
2218 printf(" Add Vim to the start menu\n");
2219 printf("-install-icons");
2220 printf(" Create icons for gVim executables on the desktop\n");
2221#endif
2222 printf("-create-directories [vim|home]\n");
2223 printf(" Create runtime directories to drop plugins into; in the $VIM\n");
2224 printf(" or $HOME directory\n");
2225#ifdef WIN3264
2226 printf("-register-OLE");
Bram Moolenaarce0842a2005-07-18 21:58:11 +00002227 printf(" Ignored\n");
Bram Moolenaar071d4272004-06-13 20:20:40 +00002228#endif
2229 printf("\n");
2230}
2231
2232/*
2233 * Setup installation choices based on command line switches
2234 */
2235 static void
2236command_line_setup_choices(int argc, char **argv)
2237{
2238 int i, j;
2239
2240 for (i = 1; i < argc; i++)
2241 {
2242 if (strcmp(argv[i], "-create-batfiles") == 0)
2243 {
2244 if (i + 1 == argc)
2245 continue;
2246 while (argv[i + 1][0] != '-' && i < argc)
2247 {
2248 i++;
2249 for (j = 1; j < TARGET_COUNT; ++j)
2250 if ((targets[j].exenamearg[0] == 'g' ? has_gvim : has_vim)
2251 && strcmp(argv[i], targets[j].name) == 0)
2252 {
2253 init_bat_choice(j);
2254 break;
2255 }
2256 if (j == TARGET_COUNT)
2257 printf("%s is not a valid choice for -create-batfiles\n",
2258 argv[i]);
2259
2260 if (i + 1 == argc)
2261 break;
2262 }
2263 }
2264 else if (strcmp(argv[i], "-create-vimrc") == 0)
2265 {
2266 /* Setup default vimrc choices. If there is already a _vimrc file,
2267 * it will NOT be overwritten.
2268 */
2269 init_vimrc_choices();
2270 }
2271 else if (strcmp(argv[i], "-install-popup") == 0)
2272 {
2273 init_popup_choice();
2274 }
2275 else if (strcmp(argv[i], "-install-openwith") == 0)
2276 {
2277 init_openwith_choice();
2278 }
2279 else if (strcmp(argv[i], "-add-start-menu") == 0)
2280 {
2281 init_startmenu_choice();
2282 }
2283 else if (strcmp(argv[i], "-install-icons") == 0)
2284 {
2285 init_shortcut_choices();
2286 }
2287 else if (strcmp(argv[i], "-create-directories") == 0)
2288 {
2289 init_directories_choice();
2290 if (argv[i + 1][0] != '-')
2291 {
2292 i++;
2293 if (strcmp(argv[i], "vim") == 0)
2294 vimfiles_dir_choice = (int)vimfiles_dir_vim;
2295 else if (strcmp(argv[i], "home") == 0)
2296 {
2297 if (getenv("HOME") == NULL) /* No $HOME in environment */
2298 vimfiles_dir_choice = (int)vimfiles_dir_vim;
2299 else
2300 vimfiles_dir_choice = (int)vimfiles_dir_home;
2301 }
2302 else
2303 {
2304 printf("Unknown argument for -create-directories: %s\n",
2305 argv[i]);
2306 print_cmd_line_help();
2307 }
2308 }
2309 else /* No choice specified, default to vim directory */
2310 vimfiles_dir_choice = (int)vimfiles_dir_vim;
2311 }
2312#ifdef WIN3264
2313 else if (strcmp(argv[i], "-register-OLE") == 0)
2314 {
2315 /* This is always done when gvim is found */
2316 }
2317#endif
2318 else /* Unknown switch */
2319 {
2320 printf("Got unknown argument argv[%d] = %s\n", i, argv[i]);
2321 print_cmd_line_help();
2322 }
2323 }
2324}
2325
2326
2327/*
2328 * Show a few screens full of helpful information.
2329 */
2330 static void
2331show_help(void)
2332{
2333 static char *(items[]) =
2334 {
2335"Installing .bat files\n"
2336"---------------------\n"
2337"The vim.bat file is written in one of the directories in $PATH.\n"
2338"This makes it possible to start Vim from the command line.\n"
2339"If vim.exe can be found in $PATH, the choice for vim.bat will not be\n"
2340"present. It is assumed you will use the existing vim.exe.\n"
2341"If vim.bat can already be found in $PATH this is probably for an old\n"
2342"version of Vim (but this is not checked!). You can overwrite it.\n"
2343"If no vim.bat already exists, you can select one of the directories in\n"
2344"$PATH for creating the batch file, or disable creating a vim.bat file.\n"
2345"\n"
2346"If you choose not to create the vim.bat file, Vim can still be executed\n"
2347"in other ways, but not from the command line.\n"
2348"\n"
2349"The same applies to choices for gvim, evim, (g)view, and (g)vimdiff.\n"
2350"The first item can be used to change the path for all of them.\n"
2351,
2352"Creating a _vimrc file\n"
2353"----------------------\n"
2354"The _vimrc file is used to set options for how Vim behaves.\n"
2355"The install program can create a _vimrc file with a few basic choices.\n"
2356"You can edit this file later to tune your preferences.\n"
2357"If you already have a _vimrc or .vimrc file it can be overwritten.\n"
2358"Don't do that if you have made changes to it.\n"
2359,
2360"Vim features\n"
2361"------------\n"
2362"(this choice is only available when creating a _vimrc file)\n"
2363"1. Vim can run in Vi-compatible mode. Many nice Vim features are then\n"
2364" disabled. In the not-Vi-compatible mode Vim is still mostly Vi\n"
2365" compatible, but adds nice features like multi-level undo. Only\n"
2366" choose Vi-compatible if you really need full Vi compatibility.\n"
2367"2. Running Vim with some enhancements is useful when you want some of\n"
2368" the nice Vim features, but have a slow computer and want to keep it\n"
2369" really fast.\n"
2370"3. Syntax highlighting shows many files in color. Not only does this look\n"
2371" nice, it also makes it easier to spot errors and you can work faster.\n"
2372" The other features include editing compressed files.\n"
2373,
2374"Windows key mapping\n"
2375"-------------------\n"
2376"(this choice is only available when creating a _vimrc file)\n"
2377"Under MS-Windows the CTRL-C key copies text to the clipboard and CTRL-V\n"
2378"pastes text from the clipboard. There are a few more keys like these.\n"
2379"Unfortunately, in Vim these keys normally have another meaning.\n"
2380"1. Choose to have the keys like they normally are in Vim (useful if you\n"
2381" also use Vim on other systems).\n"
2382"2. Choose to have the keys work like they are used on MS-Windows (useful\n"
2383" if you mostly work on MS-Windows).\n"
2384,
2385"Mouse use\n"
2386"---------\n"
2387"(this choice is only available when creating a _vimrc file)\n"
2388"The right mouse button can be used in two ways:\n"
2389"1. The Unix way is to extend an existing selection. The popup menu is\n"
2390" not available.\n"
2391"2. The MS-Windows way is to show a popup menu, which allows you to\n"
2392" copy/paste text, undo/redo, etc. Extending the selection can still be\n"
2393" done by keeping SHIFT pressed while using the left mouse button\n"
2394,
2395"Edit-with-Vim context menu entry\n"
2396"--------------------------------\n"
2397"(this choice is only available when gvim.exe and gvimext.dll are present)\n"
2398"You can associate different file types with Vim, so that you can (double)\n"
2399"click on a file to edit it with Vim. This means you have to individually\n"
2400"select each file type.\n"
2401"An alternative is the option offered here: Install an \"Edit with Vim\"\n"
2402"entry in the popup menu for the right mouse button. This means you can\n"
2403"edit any file with Vim.\n"
2404,
2405"\"Open With...\" context menu entry\n"
2406"--------------------------------\n"
2407"(this choice is only available when gvim.exe is present)\n"
2408"This option adds Vim to the \"Open With...\" entry in the popup menu for\n"
2409"the right mouse button. This also makes it possible to edit HTML files\n"
2410"directly from Internet Explorer.\n"
2411,
2412"Add Vim to the Start menu\n"
2413"-------------------------\n"
2414"In Windows 95 and later, Vim can be added to the Start menu. This will\n"
2415"create a submenu with an entry for vim, gvim, evim, vimdiff, etc..\n"
2416,
2417"Icons on the desktop\n"
2418"--------------------\n"
2419"(these choices are only available when installing gvim)\n"
2420"In Windows 95 and later, shortcuts (icons) can be created on the Desktop.\n"
2421,
2422"Create plugin directories\n"
2423"-------------------------\n"
2424"Plugin directories allow extending Vim by dropping a file into a directory.\n"
2425"This choice allows creating them in $HOME (if you have a home directory) or\n"
2426"$VIM (used for everybody on the system).\n"
2427,
2428NULL
2429 };
2430 int i;
2431 int c;
2432
2433 rewind(stdin);
2434 printf("\n");
2435 for (i = 0; items[i] != NULL; ++i)
2436 {
2437 printf(items[i]);
2438 printf("\n");
2439 printf("Hit Enter to continue, b (back) or q (quit help): ");
2440 c = getchar();
2441 rewind(stdin);
2442 if (c == 'b' || c == 'B')
2443 {
2444 if (i == 0)
2445 --i;
2446 else
2447 i -= 2;
2448 }
2449 if (c == 'q' || c == 'Q')
2450 break;
2451 printf("\n");
2452 }
2453}
2454
2455/*
2456 * Install the choices.
2457 */
2458 static void
2459install(void)
2460{
2461 int i;
2462
2463 /* Install the selected choices. */
2464 for (i = 0; i < choice_count; ++i)
2465 if (choices[i].installfunc != NULL && choices[i].active)
2466 (choices[i].installfunc)(i);
2467
2468 /* Add some entries to the registry, if needed. */
2469 if (install_popup
2470 || install_openwith
2471 || (need_uninstall_entry && interactive)
2472 || !interactive)
2473 install_registry();
2474
2475#ifdef WIN3264
2476 /* Register gvim with OLE. */
2477 if (has_gvim)
2478 install_OLE_register();
2479#endif
2480}
2481
2482/*
2483 * request_choice
2484 */
2485 static void
2486request_choice(void)
2487{
2488 int i;
2489
2490 printf("\n\nInstall will do for you:\n");
2491 for (i = 0; i < choice_count; ++i)
2492 if (choices[i].active)
2493 printf("%2d %s\n", i + 1, choices[i].text);
2494 printf("To change an item, enter its number\n\n");
2495 printf("Enter item number, h (help), d (do it) or q (quit): ");
2496}
2497
2498 int
2499main(int argc, char **argv)
2500{
2501 int i;
2502 char buf[BUFSIZE];
2503
2504 /*
2505 * Run interactively if there are no command line arguments.
2506 */
2507 if (argc > 1)
2508 interactive = 0;
2509 else
2510 interactive = 1;
2511
2512 /* Initialize this program. */
2513 do_inits(argv);
2514
2515#ifdef WIN3264
2516 if (argc > 1 && strcmp(argv[1], "-uninstall-check") == 0)
2517 {
2518 /* Only check for already installed Vims. Used by NSIS installer. */
Bram Moolenaar442b4222010-05-24 21:34:22 +02002519 i = uninstall_check(1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002520
2521 /* Find the value of $VIM, because NSIS isn't able to do this by
2522 * itself. */
2523 get_vim_env();
2524
2525 /* When nothing found exit quietly. If something found wait for
Bram Moolenaarb230bd52010-05-25 21:02:00 +02002526 * a little while, so that the user can read the messages. */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002527 if (i)
Bram Moolenaarab8205e2010-07-07 15:14:03 +02002528 sleep(3);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002529 exit(0);
2530 }
2531#endif
2532
2533 printf("This program sets up the installation of Vim "
2534 VIM_VERSION_MEDIUM "\n\n");
2535
2536 /* Check if the user unpacked the archives properly. */
2537 check_unpack();
2538
2539#ifdef WIN3264
2540 /* Check for already installed Vims. */
2541 if (interactive)
Bram Moolenaar442b4222010-05-24 21:34:22 +02002542 uninstall_check(0);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002543#endif
2544
2545 /* Find out information about the system. */
2546 inspect_system();
2547
2548 if (interactive)
2549 {
2550 /* Setup all the choices. */
2551 setup_choices();
2552
2553 /* Let the user change choices and finally install (or quit). */
2554 for (;;)
2555 {
2556 request_choice();
2557 rewind(stdin);
2558 if (scanf("%99s", buf) == 1)
2559 {
2560 if (isdigit(buf[0]))
2561 {
2562 /* Change a choice. */
2563 i = atoi(buf);
2564 if (i > 0 && i <= choice_count && choices[i - 1].active)
2565 (choices[i - 1].changefunc)(i - 1);
2566 else
2567 printf("\nIllegal choice\n");
2568 }
2569 else if (buf[0] == 'h' || buf[0] == 'H')
2570 {
2571 /* Help */
2572 show_help();
2573 }
2574 else if (buf[0] == 'd' || buf[0] == 'D')
2575 {
2576 /* Install! */
2577 install();
2578 printf("\nThat finishes the installation. Happy Vimming!\n");
2579 break;
2580 }
2581 else if (buf[0] == 'q' || buf[0] == 'Q')
2582 {
2583 /* Quit */
2584 printf("\nExiting without anything done\n");
2585 break;
2586 }
2587 else
2588 printf("\nIllegal choice\n");
2589 }
2590 }
2591 printf("\n");
Bram Moolenaar442b4222010-05-24 21:34:22 +02002592 myexit(0);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002593 }
2594 else
2595 {
2596 /*
2597 * Run non-interactive - setup according to the command line switches
2598 */
2599 command_line_setup_choices(argc, argv);
2600 install();
Bram Moolenaar442b4222010-05-24 21:34:22 +02002601
2602 /* Avoid that the user has to hit Enter, just wait a little bit to
2603 * allow reading the messages. */
Bram Moolenaarab8205e2010-07-07 15:14:03 +02002604 sleep(2);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002605 }
2606
Bram Moolenaar071d4272004-06-13 20:20:40 +00002607 return 0;
2608}