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