xref: /vim-8.2.3635/src/ex_cmds2.c (revision 1a928c20)
1 /* vi:set ts=8 sts=4 sw=4 noet:
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  * ex_cmds2.c: some more functions for command line commands
12  */
13 
14 #include "vim.h"
15 #include "version.h"
16 
17 #if defined(FEAT_EVAL) || defined(PROTO)
18 # if defined(FEAT_TIMERS) || defined(PROTO)
19 static timer_T	*first_timer = NULL;
20 static long	last_timer_id = 0;
21 
22 /*
23  * Return time left until "due".  Negative if past "due".
24  */
25     long
26 proftime_time_left(proftime_T *due, proftime_T *now)
27 {
28 #  ifdef MSWIN
29     LARGE_INTEGER fr;
30 
31     if (now->QuadPart > due->QuadPart)
32 	return 0;
33     QueryPerformanceFrequency(&fr);
34     return (long)(((double)(due->QuadPart - now->QuadPart)
35 		   / (double)fr.QuadPart) * 1000);
36 #  else
37     if (now->tv_sec > due->tv_sec)
38 	return 0;
39     return (due->tv_sec - now->tv_sec) * 1000
40 	+ (due->tv_usec - now->tv_usec) / 1000;
41 #  endif
42 }
43 
44 /*
45  * Insert a timer in the list of timers.
46  */
47     static void
48 insert_timer(timer_T *timer)
49 {
50     timer->tr_next = first_timer;
51     timer->tr_prev = NULL;
52     if (first_timer != NULL)
53 	first_timer->tr_prev = timer;
54     first_timer = timer;
55     did_add_timer = TRUE;
56 }
57 
58 /*
59  * Take a timer out of the list of timers.
60  */
61     static void
62 remove_timer(timer_T *timer)
63 {
64     if (timer->tr_prev == NULL)
65 	first_timer = timer->tr_next;
66     else
67 	timer->tr_prev->tr_next = timer->tr_next;
68     if (timer->tr_next != NULL)
69 	timer->tr_next->tr_prev = timer->tr_prev;
70 }
71 
72     static void
73 free_timer(timer_T *timer)
74 {
75     free_callback(&timer->tr_callback);
76     vim_free(timer);
77 }
78 
79 /*
80  * Create a timer and return it.  NULL if out of memory.
81  * Caller should set the callback.
82  */
83     timer_T *
84 create_timer(long msec, int repeat)
85 {
86     timer_T	*timer = ALLOC_CLEAR_ONE(timer_T);
87     long	prev_id = last_timer_id;
88 
89     if (timer == NULL)
90 	return NULL;
91     if (++last_timer_id <= prev_id)
92 	// Overflow!  Might cause duplicates...
93 	last_timer_id = 0;
94     timer->tr_id = last_timer_id;
95     insert_timer(timer);
96     if (repeat != 0)
97 	timer->tr_repeat = repeat - 1;
98     timer->tr_interval = msec;
99 
100     profile_setlimit(msec, &timer->tr_due);
101     return timer;
102 }
103 
104 /*
105  * Invoke the callback of "timer".
106  */
107     static void
108 timer_callback(timer_T *timer)
109 {
110     typval_T	rettv;
111     typval_T	argv[2];
112 
113     argv[0].v_type = VAR_NUMBER;
114     argv[0].vval.v_number = (varnumber_T)timer->tr_id;
115     argv[1].v_type = VAR_UNKNOWN;
116 
117     call_callback(&timer->tr_callback, -1, &rettv, 1, argv);
118     clear_tv(&rettv);
119 }
120 
121 /*
122  * Call timers that are due.
123  * Return the time in msec until the next timer is due.
124  * Returns -1 if there are no pending timers.
125  */
126     long
127 check_due_timer(void)
128 {
129     timer_T	*timer;
130     timer_T	*timer_next;
131     long	this_due;
132     long	next_due = -1;
133     proftime_T	now;
134     int		did_one = FALSE;
135     int		need_update_screen = FALSE;
136     long	current_id = last_timer_id;
137 
138     // Don't run any timers while exiting or dealing with an error.
139     if (exiting || aborting())
140 	return next_due;
141 
142     profile_start(&now);
143     for (timer = first_timer; timer != NULL && !got_int; timer = timer_next)
144     {
145 	timer_next = timer->tr_next;
146 
147 	if (timer->tr_id == -1 || timer->tr_firing || timer->tr_paused)
148 	    continue;
149 	this_due = proftime_time_left(&timer->tr_due, &now);
150 	if (this_due <= 1)
151 	{
152 	    // Save and restore a lot of flags, because the timer fires while
153 	    // waiting for a character, which might be halfway a command.
154 	    int save_timer_busy = timer_busy;
155 	    int save_vgetc_busy = vgetc_busy;
156 	    int save_did_emsg = did_emsg;
157 	    int save_called_emsg = called_emsg;
158 	    int save_must_redraw = must_redraw;
159 	    int save_trylevel = trylevel;
160 	    int save_did_throw = did_throw;
161 	    int save_ex_pressedreturn = get_pressedreturn();
162 	    int save_may_garbage_collect = may_garbage_collect;
163 	    except_T *save_current_exception = current_exception;
164 	    vimvars_save_T vvsave;
165 
166 	    // Create a scope for running the timer callback, ignoring most of
167 	    // the current scope, such as being inside a try/catch.
168 	    timer_busy = timer_busy > 0 || vgetc_busy > 0;
169 	    vgetc_busy = 0;
170 	    called_emsg = 0;
171 	    did_emsg = FALSE;
172 	    did_uncaught_emsg = FALSE;
173 	    must_redraw = 0;
174 	    trylevel = 0;
175 	    did_throw = FALSE;
176 	    current_exception = NULL;
177 	    may_garbage_collect = FALSE;
178 	    save_vimvars(&vvsave);
179 
180 	    timer->tr_firing = TRUE;
181 	    timer_callback(timer);
182 	    timer->tr_firing = FALSE;
183 
184 	    timer_next = timer->tr_next;
185 	    did_one = TRUE;
186 	    timer_busy = save_timer_busy;
187 	    vgetc_busy = save_vgetc_busy;
188 	    if (did_uncaught_emsg)
189 		++timer->tr_emsg_count;
190 	    did_emsg = save_did_emsg;
191 	    called_emsg = save_called_emsg;
192 	    trylevel = save_trylevel;
193 	    did_throw = save_did_throw;
194 	    current_exception = save_current_exception;
195 	    restore_vimvars(&vvsave);
196 	    if (must_redraw != 0)
197 		need_update_screen = TRUE;
198 	    must_redraw = must_redraw > save_must_redraw
199 					      ? must_redraw : save_must_redraw;
200 	    set_pressedreturn(save_ex_pressedreturn);
201 	    may_garbage_collect = save_may_garbage_collect;
202 
203 	    // Only fire the timer again if it repeats and stop_timer() wasn't
204 	    // called while inside the callback (tr_id == -1).
205 	    if (timer->tr_repeat != 0 && timer->tr_id != -1
206 		    && timer->tr_emsg_count < 3)
207 	    {
208 		profile_setlimit(timer->tr_interval, &timer->tr_due);
209 		this_due = proftime_time_left(&timer->tr_due, &now);
210 		if (this_due < 1)
211 		    this_due = 1;
212 		if (timer->tr_repeat > 0)
213 		    --timer->tr_repeat;
214 	    }
215 	    else
216 	    {
217 		this_due = -1;
218 		remove_timer(timer);
219 		free_timer(timer);
220 	    }
221 	}
222 	if (this_due > 0 && (next_due == -1 || next_due > this_due))
223 	    next_due = this_due;
224     }
225 
226     if (did_one)
227 	redraw_after_callback(need_update_screen);
228 
229 #ifdef FEAT_BEVAL_TERM
230     if (bevalexpr_due_set)
231     {
232 	this_due = proftime_time_left(&bevalexpr_due, &now);
233 	if (this_due <= 1)
234 	{
235 	    bevalexpr_due_set = FALSE;
236 	    if (balloonEval == NULL)
237 	    {
238 		balloonEval = ALLOC_CLEAR_ONE(BalloonEval);
239 		balloonEvalForTerm = TRUE;
240 	    }
241 	    if (balloonEval != NULL)
242 	    {
243 		general_beval_cb(balloonEval, 0);
244 		setcursor();
245 		out_flush();
246 	    }
247 	}
248 	else if (next_due == -1 || next_due > this_due)
249 	    next_due = this_due;
250     }
251 #endif
252 #ifdef FEAT_TERMINAL
253     // Some terminal windows may need their buffer updated.
254     next_due = term_check_timers(next_due, &now);
255 #endif
256 
257     return current_id != last_timer_id ? 1 : next_due;
258 }
259 
260 /*
261  * Find a timer by ID.  Returns NULL if not found;
262  */
263     static timer_T *
264 find_timer(long id)
265 {
266     timer_T *timer;
267 
268     if (id >= 0)
269     {
270 	for (timer = first_timer; timer != NULL; timer = timer->tr_next)
271 	    if (timer->tr_id == id)
272 		return timer;
273     }
274     return NULL;
275 }
276 
277 
278 /*
279  * Stop a timer and delete it.
280  */
281     void
282 stop_timer(timer_T *timer)
283 {
284     if (timer->tr_firing)
285 	// Free the timer after the callback returns.
286 	timer->tr_id = -1;
287     else
288     {
289 	remove_timer(timer);
290 	free_timer(timer);
291     }
292 }
293 
294     static void
295 stop_all_timers(void)
296 {
297     timer_T *timer;
298     timer_T *timer_next;
299 
300     for (timer = first_timer; timer != NULL; timer = timer_next)
301     {
302 	timer_next = timer->tr_next;
303 	stop_timer(timer);
304     }
305 }
306 
307     static void
308 add_timer_info(typval_T *rettv, timer_T *timer)
309 {
310     list_T	*list = rettv->vval.v_list;
311     dict_T	*dict = dict_alloc();
312     dictitem_T	*di;
313     long	remaining;
314     proftime_T	now;
315 
316     if (dict == NULL)
317 	return;
318     list_append_dict(list, dict);
319 
320     dict_add_number(dict, "id", timer->tr_id);
321     dict_add_number(dict, "time", (long)timer->tr_interval);
322 
323     profile_start(&now);
324     remaining = proftime_time_left(&timer->tr_due, &now);
325     dict_add_number(dict, "remaining", (long)remaining);
326 
327     dict_add_number(dict, "repeat",
328 		    (long)(timer->tr_repeat < 0 ? -1 : timer->tr_repeat + 1));
329     dict_add_number(dict, "paused", (long)(timer->tr_paused));
330 
331     di = dictitem_alloc((char_u *)"callback");
332     if (di != NULL)
333     {
334 	if (dict_add(dict, di) == FAIL)
335 	    vim_free(di);
336 	else
337 	    put_callback(&timer->tr_callback, &di->di_tv);
338     }
339 }
340 
341     static void
342 add_timer_info_all(typval_T *rettv)
343 {
344     timer_T *timer;
345 
346     for (timer = first_timer; timer != NULL; timer = timer->tr_next)
347 	if (timer->tr_id != -1)
348 	    add_timer_info(rettv, timer);
349 }
350 
351 /*
352  * Mark references in partials of timers.
353  */
354     int
355 set_ref_in_timer(int copyID)
356 {
357     int		abort = FALSE;
358     timer_T	*timer;
359     typval_T	tv;
360 
361     for (timer = first_timer; !abort && timer != NULL; timer = timer->tr_next)
362     {
363 	if (timer->tr_callback.cb_partial != NULL)
364 	{
365 	    tv.v_type = VAR_PARTIAL;
366 	    tv.vval.v_partial = timer->tr_callback.cb_partial;
367 	}
368 	else
369 	{
370 	    tv.v_type = VAR_FUNC;
371 	    tv.vval.v_string = timer->tr_callback.cb_name;
372 	}
373 	abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL);
374     }
375     return abort;
376 }
377 
378 # if defined(EXITFREE) || defined(PROTO)
379     void
380 timer_free_all()
381 {
382     timer_T *timer;
383 
384     while (first_timer != NULL)
385     {
386 	timer = first_timer;
387 	remove_timer(timer);
388 	free_timer(timer);
389     }
390 }
391 # endif
392 
393 /*
394  * "timer_info([timer])" function
395  */
396     void
397 f_timer_info(typval_T *argvars, typval_T *rettv)
398 {
399     timer_T *timer = NULL;
400 
401     if (rettv_list_alloc(rettv) != OK)
402 	return;
403     if (argvars[0].v_type != VAR_UNKNOWN)
404     {
405 	if (argvars[0].v_type != VAR_NUMBER)
406 	    emsg(_(e_number_exp));
407 	else
408 	{
409 	    timer = find_timer((int)tv_get_number(&argvars[0]));
410 	    if (timer != NULL)
411 		add_timer_info(rettv, timer);
412 	}
413     }
414     else
415 	add_timer_info_all(rettv);
416 }
417 
418 /*
419  * "timer_pause(timer, paused)" function
420  */
421     void
422 f_timer_pause(typval_T *argvars, typval_T *rettv UNUSED)
423 {
424     timer_T	*timer = NULL;
425     int		paused = (int)tv_get_number(&argvars[1]);
426 
427     if (argvars[0].v_type != VAR_NUMBER)
428 	emsg(_(e_number_exp));
429     else
430     {
431 	timer = find_timer((int)tv_get_number(&argvars[0]));
432 	if (timer != NULL)
433 	    timer->tr_paused = paused;
434     }
435 }
436 
437 /*
438  * "timer_start(time, callback [, options])" function
439  */
440     void
441 f_timer_start(typval_T *argvars, typval_T *rettv)
442 {
443     long	msec = (long)tv_get_number(&argvars[0]);
444     timer_T	*timer;
445     int		repeat = 0;
446     callback_T	callback;
447     dict_T	*dict;
448 
449     rettv->vval.v_number = -1;
450     if (check_secure())
451 	return;
452     if (argvars[2].v_type != VAR_UNKNOWN)
453     {
454 	if (argvars[2].v_type != VAR_DICT
455 				   || (dict = argvars[2].vval.v_dict) == NULL)
456 	{
457 	    semsg(_(e_invarg2), tv_get_string(&argvars[2]));
458 	    return;
459 	}
460 	if (dict_find(dict, (char_u *)"repeat", -1) != NULL)
461 	    repeat = dict_get_number(dict, (char_u *)"repeat");
462     }
463 
464     callback = get_callback(&argvars[1]);
465     if (callback.cb_name == NULL)
466 	return;
467 
468     timer = create_timer(msec, repeat);
469     if (timer == NULL)
470 	free_callback(&callback);
471     else
472     {
473 	set_callback(&timer->tr_callback, &callback);
474 	rettv->vval.v_number = (varnumber_T)timer->tr_id;
475     }
476 }
477 
478 /*
479  * "timer_stop(timer)" function
480  */
481     void
482 f_timer_stop(typval_T *argvars, typval_T *rettv UNUSED)
483 {
484     timer_T *timer;
485 
486     if (argvars[0].v_type != VAR_NUMBER)
487     {
488 	emsg(_(e_number_exp));
489 	return;
490     }
491     timer = find_timer((int)tv_get_number(&argvars[0]));
492     if (timer != NULL)
493 	stop_timer(timer);
494 }
495 
496 /*
497  * "timer_stopall()" function
498  */
499     void
500 f_timer_stopall(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
501 {
502     stop_all_timers();
503 }
504 
505 # endif // FEAT_TIMERS
506 
507 #endif // FEAT_EVAL
508 
509 /*
510  * If 'autowrite' option set, try to write the file.
511  * Careful: autocommands may make "buf" invalid!
512  *
513  * return FAIL for failure, OK otherwise
514  */
515     int
516 autowrite(buf_T *buf, int forceit)
517 {
518     int		r;
519     bufref_T	bufref;
520 
521     if (!(p_aw || p_awa) || !p_write
522 #ifdef FEAT_QUICKFIX
523 	    // never autowrite a "nofile" or "nowrite" buffer
524 	    || bt_dontwrite(buf)
525 #endif
526 	    || (!forceit && buf->b_p_ro) || buf->b_ffname == NULL)
527 	return FAIL;
528     set_bufref(&bufref, buf);
529     r = buf_write_all(buf, forceit);
530 
531     // Writing may succeed but the buffer still changed, e.g., when there is a
532     // conversion error.  We do want to return FAIL then.
533     if (bufref_valid(&bufref) && bufIsChanged(buf))
534 	r = FAIL;
535     return r;
536 }
537 
538 /*
539  * Flush all buffers, except the ones that are readonly or are never written.
540  */
541     void
542 autowrite_all(void)
543 {
544     buf_T	*buf;
545 
546     if (!(p_aw || p_awa) || !p_write)
547 	return;
548     FOR_ALL_BUFFERS(buf)
549 	if (bufIsChanged(buf) && !buf->b_p_ro && !bt_dontwrite(buf))
550 	{
551 	    bufref_T	bufref;
552 
553 	    set_bufref(&bufref, buf);
554 
555 	    (void)buf_write_all(buf, FALSE);
556 
557 	    // an autocommand may have deleted the buffer
558 	    if (!bufref_valid(&bufref))
559 		buf = firstbuf;
560 	}
561 }
562 
563 /*
564  * Return TRUE if buffer was changed and cannot be abandoned.
565  * For flags use the CCGD_ values.
566  */
567     int
568 check_changed(buf_T *buf, int flags)
569 {
570     int		forceit = (flags & CCGD_FORCEIT);
571     bufref_T	bufref;
572 
573     set_bufref(&bufref, buf);
574 
575     if (       !forceit
576 	    && bufIsChanged(buf)
577 	    && ((flags & CCGD_MULTWIN) || buf->b_nwindows <= 1)
578 	    && (!(flags & CCGD_AW) || autowrite(buf, forceit) == FAIL))
579     {
580 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
581 	if ((p_confirm || cmdmod.confirm) && p_write)
582 	{
583 	    buf_T	*buf2;
584 	    int		count = 0;
585 
586 	    if (flags & CCGD_ALLBUF)
587 		FOR_ALL_BUFFERS(buf2)
588 		    if (bufIsChanged(buf2)
589 				     && (buf2->b_ffname != NULL
590 # ifdef FEAT_BROWSE
591 					 || cmdmod.browse
592 # endif
593 					))
594 			++count;
595 	    if (!bufref_valid(&bufref))
596 		// Autocommand deleted buffer, oops!  It's not changed now.
597 		return FALSE;
598 
599 	    dialog_changed(buf, count > 1);
600 
601 	    if (!bufref_valid(&bufref))
602 		// Autocommand deleted buffer, oops!  It's not changed now.
603 		return FALSE;
604 	    return bufIsChanged(buf);
605 	}
606 #endif
607 	if (flags & CCGD_EXCMD)
608 	    no_write_message();
609 	else
610 	    no_write_message_nobang(curbuf);
611 	return TRUE;
612     }
613     return FALSE;
614 }
615 
616 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) || defined(PROTO)
617 
618 #if defined(FEAT_BROWSE) || defined(PROTO)
619 /*
620  * When wanting to write a file without a file name, ask the user for a name.
621  */
622     void
623 browse_save_fname(buf_T *buf)
624 {
625     if (buf->b_fname == NULL)
626     {
627 	char_u *fname;
628 
629 	fname = do_browse(BROWSE_SAVE, (char_u *)_("Save As"),
630 						 NULL, NULL, NULL, NULL, buf);
631 	if (fname != NULL)
632 	{
633 	    if (setfname(buf, fname, NULL, TRUE) == OK)
634 		buf->b_flags |= BF_NOTEDITED;
635 	    vim_free(fname);
636 	}
637     }
638 }
639 #endif
640 
641 /*
642  * Ask the user what to do when abandoning a changed buffer.
643  * Must check 'write' option first!
644  */
645     void
646 dialog_changed(
647     buf_T	*buf,
648     int		checkall)	// may abandon all changed buffers
649 {
650     char_u	buff[DIALOG_MSG_SIZE];
651     int		ret;
652     buf_T	*buf2;
653     exarg_T     ea;
654 
655     dialog_msg(buff, _("Save changes to \"%s\"?"), buf->b_fname);
656     if (checkall)
657 	ret = vim_dialog_yesnoallcancel(VIM_QUESTION, NULL, buff, 1);
658     else
659 	ret = vim_dialog_yesnocancel(VIM_QUESTION, NULL, buff, 1);
660 
661     // Init ea pseudo-structure, this is needed for the check_overwrite()
662     // function.
663     vim_memset(&ea, 0, sizeof(ea));
664 
665     if (ret == VIM_YES)
666     {
667 #ifdef FEAT_BROWSE
668 	// May get file name, when there is none
669 	browse_save_fname(buf);
670 #endif
671 	if (buf->b_fname != NULL && check_overwrite(&ea, buf,
672 				    buf->b_fname, buf->b_ffname, FALSE) == OK)
673 	    // didn't hit Cancel
674 	    (void)buf_write_all(buf, FALSE);
675     }
676     else if (ret == VIM_NO)
677     {
678 	unchanged(buf, TRUE, FALSE);
679     }
680     else if (ret == VIM_ALL)
681     {
682 	/*
683 	 * Write all modified files that can be written.
684 	 * Skip readonly buffers, these need to be confirmed
685 	 * individually.
686 	 */
687 	FOR_ALL_BUFFERS(buf2)
688 	{
689 	    if (bufIsChanged(buf2)
690 		    && (buf2->b_ffname != NULL
691 #ifdef FEAT_BROWSE
692 			|| cmdmod.browse
693 #endif
694 			)
695 		    && !buf2->b_p_ro)
696 	    {
697 		bufref_T bufref;
698 
699 		set_bufref(&bufref, buf2);
700 #ifdef FEAT_BROWSE
701 		// May get file name, when there is none
702 		browse_save_fname(buf2);
703 #endif
704 		if (buf2->b_fname != NULL && check_overwrite(&ea, buf2,
705 				  buf2->b_fname, buf2->b_ffname, FALSE) == OK)
706 		    // didn't hit Cancel
707 		    (void)buf_write_all(buf2, FALSE);
708 
709 		// an autocommand may have deleted the buffer
710 		if (!bufref_valid(&bufref))
711 		    buf2 = firstbuf;
712 	    }
713 	}
714     }
715     else if (ret == VIM_DISCARDALL)
716     {
717 	/*
718 	 * mark all buffers as unchanged
719 	 */
720 	FOR_ALL_BUFFERS(buf2)
721 	    unchanged(buf2, TRUE, FALSE);
722     }
723 }
724 #endif
725 
726 /*
727  * Return TRUE if the buffer "buf" can be abandoned, either by making it
728  * hidden, autowriting it or unloading it.
729  */
730     int
731 can_abandon(buf_T *buf, int forceit)
732 {
733     return (	   buf_hide(buf)
734 		|| !bufIsChanged(buf)
735 		|| buf->b_nwindows > 1
736 		|| autowrite(buf, forceit) == OK
737 		|| forceit);
738 }
739 
740 /*
741  * Add a buffer number to "bufnrs", unless it's already there.
742  */
743     static void
744 add_bufnum(int *bufnrs, int *bufnump, int nr)
745 {
746     int i;
747 
748     for (i = 0; i < *bufnump; ++i)
749 	if (bufnrs[i] == nr)
750 	    return;
751     bufnrs[*bufnump] = nr;
752     *bufnump = *bufnump + 1;
753 }
754 
755 /*
756  * Return TRUE if any buffer was changed and cannot be abandoned.
757  * That changed buffer becomes the current buffer.
758  * When "unload" is TRUE the current buffer is unloaded instead of making it
759  * hidden.  This is used for ":q!".
760  */
761     int
762 check_changed_any(
763     int		hidden,		// Only check hidden buffers
764     int		unload)
765 {
766     int		ret = FALSE;
767     buf_T	*buf;
768     int		save;
769     int		i;
770     int		bufnum = 0;
771     int		bufcount = 0;
772     int		*bufnrs;
773     tabpage_T   *tp;
774     win_T	*wp;
775 
776     // Make a list of all buffers, with the most important ones first.
777     FOR_ALL_BUFFERS(buf)
778 	++bufcount;
779 
780     if (bufcount == 0)
781 	return FALSE;
782 
783     bufnrs = ALLOC_MULT(int, bufcount);
784     if (bufnrs == NULL)
785 	return FALSE;
786 
787     // curbuf
788     bufnrs[bufnum++] = curbuf->b_fnum;
789 
790     // buffers in current tab
791     FOR_ALL_WINDOWS(wp)
792 	if (wp->w_buffer != curbuf)
793 	    add_bufnum(bufnrs, &bufnum, wp->w_buffer->b_fnum);
794 
795     // buffers in other tabs
796     FOR_ALL_TABPAGES(tp)
797 	if (tp != curtab)
798 	    for (wp = tp->tp_firstwin; wp != NULL; wp = wp->w_next)
799 		add_bufnum(bufnrs, &bufnum, wp->w_buffer->b_fnum);
800 
801     // any other buffer
802     FOR_ALL_BUFFERS(buf)
803 	add_bufnum(bufnrs, &bufnum, buf->b_fnum);
804 
805     for (i = 0; i < bufnum; ++i)
806     {
807 	buf = buflist_findnr(bufnrs[i]);
808 	if (buf == NULL)
809 	    continue;
810 	if ((!hidden || buf->b_nwindows == 0) && bufIsChanged(buf))
811 	{
812 	    bufref_T bufref;
813 
814 	    set_bufref(&bufref, buf);
815 #ifdef FEAT_TERMINAL
816 	    if (term_job_running(buf->b_term))
817 	    {
818 		if (term_try_stop_job(buf) == FAIL)
819 		    break;
820 	    }
821 	    else
822 #endif
823 	    // Try auto-writing the buffer.  If this fails but the buffer no
824 	    // longer exists it's not changed, that's OK.
825 	    if (check_changed(buf, (p_awa ? CCGD_AW : 0)
826 				 | CCGD_MULTWIN
827 				 | CCGD_ALLBUF) && bufref_valid(&bufref))
828 		break;	    // didn't save - still changes
829 	}
830     }
831 
832     if (i >= bufnum)
833 	goto theend;
834 
835     // Get here if "buf" cannot be abandoned.
836     ret = TRUE;
837     exiting = FALSE;
838 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
839     /*
840      * When ":confirm" used, don't give an error message.
841      */
842     if (!(p_confirm || cmdmod.confirm))
843 #endif
844     {
845 	// There must be a wait_return for this message, do_buffer()
846 	// may cause a redraw.  But wait_return() is a no-op when vgetc()
847 	// is busy (Quit used from window menu), then make sure we don't
848 	// cause a scroll up.
849 	if (vgetc_busy > 0)
850 	{
851 	    msg_row = cmdline_row;
852 	    msg_col = 0;
853 	    msg_didout = FALSE;
854 	}
855 	if (
856 #ifdef FEAT_TERMINAL
857 		term_job_running(buf->b_term)
858 		    ? semsg(_("E947: Job still running in buffer \"%s\""),
859 								  buf->b_fname)
860 		    :
861 #endif
862 		semsg(_("E162: No write since last change for buffer \"%s\""),
863 		    buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname))
864 	{
865 	    save = no_wait_return;
866 	    no_wait_return = FALSE;
867 	    wait_return(FALSE);
868 	    no_wait_return = save;
869 	}
870     }
871 
872     // Try to find a window that contains the buffer.
873     if (buf != curbuf)
874 	FOR_ALL_TAB_WINDOWS(tp, wp)
875 	    if (wp->w_buffer == buf)
876 	    {
877 		bufref_T bufref;
878 
879 		set_bufref(&bufref, buf);
880 
881 		goto_tabpage_win(tp, wp);
882 
883 		// Paranoia: did autocmd wipe out the buffer with changes?
884 		if (!bufref_valid(&bufref))
885 		    goto theend;
886 		goto buf_found;
887 	    }
888 buf_found:
889 
890     // Open the changed buffer in the current window.
891     if (buf != curbuf)
892 	set_curbuf(buf, unload ? DOBUF_UNLOAD : DOBUF_GOTO);
893 
894 theend:
895     vim_free(bufnrs);
896     return ret;
897 }
898 
899 /*
900  * return FAIL if there is no file name, OK if there is one
901  * give error message for FAIL
902  */
903     int
904 check_fname(void)
905 {
906     if (curbuf->b_ffname == NULL)
907     {
908 	emsg(_(e_noname));
909 	return FAIL;
910     }
911     return OK;
912 }
913 
914 /*
915  * flush the contents of a buffer, unless it has no file name
916  *
917  * return FAIL for failure, OK otherwise
918  */
919     int
920 buf_write_all(buf_T *buf, int forceit)
921 {
922     int	    retval;
923     buf_T	*old_curbuf = curbuf;
924 
925     retval = (buf_write(buf, buf->b_ffname, buf->b_fname,
926 				   (linenr_T)1, buf->b_ml.ml_line_count, NULL,
927 						  FALSE, forceit, TRUE, FALSE));
928     if (curbuf != old_curbuf)
929     {
930 	msg_source(HL_ATTR(HLF_W));
931 	msg(_("Warning: Entered other buffer unexpectedly (check autocommands)"));
932     }
933     return retval;
934 }
935 
936 /*
937  * ":argdo", ":windo", ":bufdo", ":tabdo", ":cdo", ":ldo", ":cfdo" and ":lfdo"
938  */
939     void
940 ex_listdo(exarg_T *eap)
941 {
942     int		i;
943     win_T	*wp;
944     tabpage_T	*tp;
945     buf_T	*buf = curbuf;
946     int		next_fnum = 0;
947 #if defined(FEAT_SYN_HL)
948     char_u	*save_ei = NULL;
949 #endif
950     char_u	*p_shm_save;
951 #ifdef FEAT_QUICKFIX
952     int		qf_size = 0;
953     int		qf_idx;
954 #endif
955 
956 #ifndef FEAT_QUICKFIX
957     if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo ||
958 	    eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo)
959     {
960 	ex_ni(eap);
961 	return;
962     }
963 #endif
964 
965 #if defined(FEAT_SYN_HL)
966     if (eap->cmdidx != CMD_windo && eap->cmdidx != CMD_tabdo)
967     {
968 	// Don't do syntax HL autocommands.  Skipping the syntax file is a
969 	// great speed improvement.
970 	save_ei = au_event_disable(",Syntax");
971 
972 	for (buf = firstbuf; buf != NULL; buf = buf->b_next)
973 	    buf->b_flags &= ~BF_SYN_SET;
974 	buf = curbuf;
975     }
976 #endif
977 #ifdef FEAT_CLIPBOARD
978     start_global_changes();
979 #endif
980 
981     if (eap->cmdidx == CMD_windo
982 	    || eap->cmdidx == CMD_tabdo
983 	    || buf_hide(curbuf)
984 	    || !check_changed(curbuf, CCGD_AW
985 				    | (eap->forceit ? CCGD_FORCEIT : 0)
986 				    | CCGD_EXCMD))
987     {
988 	i = 0;
989 	// start at the eap->line1 argument/window/buffer
990 	wp = firstwin;
991 	tp = first_tabpage;
992 	switch (eap->cmdidx)
993 	{
994 	    case CMD_windo:
995 		for ( ; wp != NULL && i + 1 < eap->line1; wp = wp->w_next)
996 		    i++;
997 		break;
998 	    case CMD_tabdo:
999 		for( ; tp != NULL && i + 1 < eap->line1; tp = tp->tp_next)
1000 		    i++;
1001 		break;
1002 	    case CMD_argdo:
1003 		i = eap->line1 - 1;
1004 		break;
1005 	    default:
1006 		break;
1007 	}
1008 	// set pcmark now
1009 	if (eap->cmdidx == CMD_bufdo)
1010 	{
1011 	    // Advance to the first listed buffer after "eap->line1".
1012 	    for (buf = firstbuf; buf != NULL && (buf->b_fnum < eap->line1
1013 					  || !buf->b_p_bl); buf = buf->b_next)
1014 		if (buf->b_fnum > eap->line2)
1015 		{
1016 		    buf = NULL;
1017 		    break;
1018 		}
1019 	    if (buf != NULL)
1020 		goto_buffer(eap, DOBUF_FIRST, FORWARD, buf->b_fnum);
1021 	}
1022 #ifdef FEAT_QUICKFIX
1023 	else if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo
1024 		|| eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo)
1025 	{
1026 	    qf_size = qf_get_valid_size(eap);
1027 	    if (qf_size <= 0 || eap->line1 > qf_size)
1028 		buf = NULL;
1029 	    else
1030 	    {
1031 		ex_cc(eap);
1032 
1033 		buf = curbuf;
1034 		i = eap->line1 - 1;
1035 		if (eap->addr_count <= 0)
1036 		    // default is all the quickfix/location list entries
1037 		    eap->line2 = qf_size;
1038 	    }
1039 	}
1040 #endif
1041 	else
1042 	    setpcmark();
1043 	listcmd_busy = TRUE;	    // avoids setting pcmark below
1044 
1045 	while (!got_int && buf != NULL)
1046 	{
1047 	    if (eap->cmdidx == CMD_argdo)
1048 	    {
1049 		// go to argument "i"
1050 		if (i == ARGCOUNT)
1051 		    break;
1052 		// Don't call do_argfile() when already there, it will try
1053 		// reloading the file.
1054 		if (curwin->w_arg_idx != i || !editing_arg_idx(curwin))
1055 		{
1056 		    // Clear 'shm' to avoid that the file message overwrites
1057 		    // any output from the command.
1058 		    p_shm_save = vim_strsave(p_shm);
1059 		    set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
1060 		    do_argfile(eap, i);
1061 		    set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
1062 		    vim_free(p_shm_save);
1063 		}
1064 		if (curwin->w_arg_idx != i)
1065 		    break;
1066 	    }
1067 	    else if (eap->cmdidx == CMD_windo)
1068 	    {
1069 		// go to window "wp"
1070 		if (!win_valid(wp))
1071 		    break;
1072 		win_goto(wp);
1073 		if (curwin != wp)
1074 		    break;  // something must be wrong
1075 		wp = curwin->w_next;
1076 	    }
1077 	    else if (eap->cmdidx == CMD_tabdo)
1078 	    {
1079 		// go to window "tp"
1080 		if (!valid_tabpage(tp))
1081 		    break;
1082 		goto_tabpage_tp(tp, TRUE, TRUE);
1083 		tp = tp->tp_next;
1084 	    }
1085 	    else if (eap->cmdidx == CMD_bufdo)
1086 	    {
1087 		// Remember the number of the next listed buffer, in case
1088 		// ":bwipe" is used or autocommands do something strange.
1089 		next_fnum = -1;
1090 		for (buf = curbuf->b_next; buf != NULL; buf = buf->b_next)
1091 		    if (buf->b_p_bl)
1092 		    {
1093 			next_fnum = buf->b_fnum;
1094 			break;
1095 		    }
1096 	    }
1097 
1098 	    ++i;
1099 
1100 	    // execute the command
1101 	    do_cmdline(eap->arg, eap->getline, eap->cookie,
1102 						DOCMD_VERBOSE + DOCMD_NOWAIT);
1103 
1104 	    if (eap->cmdidx == CMD_bufdo)
1105 	    {
1106 		// Done?
1107 		if (next_fnum < 0 || next_fnum > eap->line2)
1108 		    break;
1109 		// Check if the buffer still exists.
1110 		FOR_ALL_BUFFERS(buf)
1111 		    if (buf->b_fnum == next_fnum)
1112 			break;
1113 		if (buf == NULL)
1114 		    break;
1115 
1116 		// Go to the next buffer.  Clear 'shm' to avoid that the file
1117 		// message overwrites any output from the command.
1118 		p_shm_save = vim_strsave(p_shm);
1119 		set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
1120 		goto_buffer(eap, DOBUF_FIRST, FORWARD, next_fnum);
1121 		set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
1122 		vim_free(p_shm_save);
1123 
1124 		// If autocommands took us elsewhere, quit here.
1125 		if (curbuf->b_fnum != next_fnum)
1126 		    break;
1127 	    }
1128 
1129 #ifdef FEAT_QUICKFIX
1130 	    if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo
1131 		    || eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo)
1132 	    {
1133 		if (i >= qf_size || i >= eap->line2)
1134 		    break;
1135 
1136 		qf_idx = qf_get_cur_idx(eap);
1137 
1138 		ex_cnext(eap);
1139 
1140 		// If jumping to the next quickfix entry fails, quit here
1141 		if (qf_get_cur_idx(eap) == qf_idx)
1142 		    break;
1143 	    }
1144 #endif
1145 
1146 	    if (eap->cmdidx == CMD_windo)
1147 	    {
1148 		validate_cursor();	// cursor may have moved
1149 
1150 		// required when 'scrollbind' has been set
1151 		if (curwin->w_p_scb)
1152 		    do_check_scrollbind(TRUE);
1153 	    }
1154 
1155 	    if (eap->cmdidx == CMD_windo || eap->cmdidx == CMD_tabdo)
1156 		if (i+1 > eap->line2)
1157 		    break;
1158 	    if (eap->cmdidx == CMD_argdo && i >= eap->line2)
1159 		break;
1160 	}
1161 	listcmd_busy = FALSE;
1162     }
1163 
1164 #if defined(FEAT_SYN_HL)
1165     if (save_ei != NULL)
1166     {
1167 	buf_T		*bnext;
1168 	aco_save_T	aco;
1169 
1170 	au_event_restore(save_ei);
1171 
1172 	for (buf = firstbuf; buf != NULL; buf = bnext)
1173 	{
1174 	    bnext = buf->b_next;
1175 	    if (buf->b_nwindows > 0 && (buf->b_flags & BF_SYN_SET))
1176 	    {
1177 		buf->b_flags &= ~BF_SYN_SET;
1178 
1179 		// buffer was opened while Syntax autocommands were disabled,
1180 		// need to trigger them now.
1181 		if (buf == curbuf)
1182 		    apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn,
1183 					       curbuf->b_fname, TRUE, curbuf);
1184 		else
1185 		{
1186 		    aucmd_prepbuf(&aco, buf);
1187 		    apply_autocmds(EVENT_SYNTAX, buf->b_p_syn,
1188 						      buf->b_fname, TRUE, buf);
1189 		    aucmd_restbuf(&aco);
1190 		}
1191 
1192 		// start over, in case autocommands messed things up.
1193 		bnext = firstbuf;
1194 	    }
1195 	}
1196     }
1197 #endif
1198 #ifdef FEAT_CLIPBOARD
1199     end_global_changes();
1200 #endif
1201 }
1202 
1203 #ifdef FEAT_EVAL
1204 /*
1205  * ":compiler[!] {name}"
1206  */
1207     void
1208 ex_compiler(exarg_T *eap)
1209 {
1210     char_u	*buf;
1211     char_u	*old_cur_comp = NULL;
1212     char_u	*p;
1213 
1214     if (*eap->arg == NUL)
1215     {
1216 	// List all compiler scripts.
1217 	do_cmdline_cmd((char_u *)"echo globpath(&rtp, 'compiler/*.vim')");
1218 					// ) keep the indenter happy...
1219     }
1220     else
1221     {
1222 	buf = alloc(STRLEN(eap->arg) + 14);
1223 	if (buf != NULL)
1224 	{
1225 	    if (eap->forceit)
1226 	    {
1227 		// ":compiler! {name}" sets global options
1228 		do_cmdline_cmd((char_u *)
1229 				   "command -nargs=* CompilerSet set <args>");
1230 	    }
1231 	    else
1232 	    {
1233 		// ":compiler! {name}" sets local options.
1234 		// To remain backwards compatible "current_compiler" is always
1235 		// used.  A user's compiler plugin may set it, the distributed
1236 		// plugin will then skip the settings.  Afterwards set
1237 		// "b:current_compiler" and restore "current_compiler".
1238 		// Explicitly prepend "g:" to make it work in a function.
1239 		old_cur_comp = get_var_value((char_u *)"g:current_compiler");
1240 		if (old_cur_comp != NULL)
1241 		    old_cur_comp = vim_strsave(old_cur_comp);
1242 		do_cmdline_cmd((char_u *)
1243 			      "command -nargs=* CompilerSet setlocal <args>");
1244 	    }
1245 	    do_unlet((char_u *)"g:current_compiler", TRUE);
1246 	    do_unlet((char_u *)"b:current_compiler", TRUE);
1247 
1248 	    sprintf((char *)buf, "compiler/%s.vim", eap->arg);
1249 	    if (source_runtime(buf, DIP_ALL) == FAIL)
1250 		semsg(_("E666: compiler not supported: %s"), eap->arg);
1251 	    vim_free(buf);
1252 
1253 	    do_cmdline_cmd((char_u *)":delcommand CompilerSet");
1254 
1255 	    // Set "b:current_compiler" from "current_compiler".
1256 	    p = get_var_value((char_u *)"g:current_compiler");
1257 	    if (p != NULL)
1258 		set_internal_string_var((char_u *)"b:current_compiler", p);
1259 
1260 	    // Restore "current_compiler" for ":compiler {name}".
1261 	    if (!eap->forceit)
1262 	    {
1263 		if (old_cur_comp != NULL)
1264 		{
1265 		    set_internal_string_var((char_u *)"g:current_compiler",
1266 								old_cur_comp);
1267 		    vim_free(old_cur_comp);
1268 		}
1269 		else
1270 		    do_unlet((char_u *)"g:current_compiler", TRUE);
1271 	    }
1272 	}
1273     }
1274 }
1275 #endif
1276 
1277 #if defined(FEAT_PYTHON3) || defined(FEAT_PYTHON) || defined(PROTO)
1278 
1279 # if (defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)) || defined(PROTO)
1280 /*
1281  * Detect Python 3 or 2, and initialize 'pyxversion'.
1282  */
1283     void
1284 init_pyxversion(void)
1285 {
1286     if (p_pyx == 0)
1287     {
1288 	if (python3_enabled(FALSE))
1289 	    p_pyx = 3;
1290 	else if (python_enabled(FALSE))
1291 	    p_pyx = 2;
1292     }
1293 }
1294 # endif
1295 
1296 /*
1297  * Does a file contain one of the following strings at the beginning of any
1298  * line?
1299  * "#!(any string)python2"  => returns 2
1300  * "#!(any string)python3"  => returns 3
1301  * "# requires python 2.x"  => returns 2
1302  * "# requires python 3.x"  => returns 3
1303  * otherwise return 0.
1304  */
1305     static int
1306 requires_py_version(char_u *filename)
1307 {
1308     FILE    *file;
1309     int	    requires_py_version = 0;
1310     int	    i, lines;
1311 
1312     lines = (int)p_mls;
1313     if (lines < 0)
1314 	lines = 5;
1315 
1316     file = mch_fopen((char *)filename, "r");
1317     if (file != NULL)
1318     {
1319 	for (i = 0; i < lines; i++)
1320 	{
1321 	    if (vim_fgets(IObuff, IOSIZE, file))
1322 		break;
1323 	    if (i == 0 && IObuff[0] == '#' && IObuff[1] == '!')
1324 	    {
1325 		// Check shebang.
1326 		if (strstr((char *)IObuff + 2, "python2") != NULL)
1327 		{
1328 		    requires_py_version = 2;
1329 		    break;
1330 		}
1331 		if (strstr((char *)IObuff + 2, "python3") != NULL)
1332 		{
1333 		    requires_py_version = 3;
1334 		    break;
1335 		}
1336 	    }
1337 	    IObuff[21] = '\0';
1338 	    if (STRCMP("# requires python 2.x", IObuff) == 0)
1339 	    {
1340 		requires_py_version = 2;
1341 		break;
1342 	    }
1343 	    if (STRCMP("# requires python 3.x", IObuff) == 0)
1344 	    {
1345 		requires_py_version = 3;
1346 		break;
1347 	    }
1348 	}
1349 	fclose(file);
1350     }
1351     return requires_py_version;
1352 }
1353 
1354 
1355 /*
1356  * Source a python file using the requested python version.
1357  */
1358     static void
1359 source_pyx_file(exarg_T *eap, char_u *fname)
1360 {
1361     exarg_T ex;
1362     int	    v = requires_py_version(fname);
1363 
1364 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
1365     init_pyxversion();
1366 # endif
1367     if (v == 0)
1368     {
1369 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
1370 	// user didn't choose a preference, 'pyx' is used
1371 	v = p_pyx;
1372 # elif defined(FEAT_PYTHON)
1373 	v = 2;
1374 # elif defined(FEAT_PYTHON3)
1375 	v = 3;
1376 # endif
1377     }
1378 
1379     /*
1380      * now source, if required python version is not supported show
1381      * unobtrusive message.
1382      */
1383     if (eap == NULL)
1384 	vim_memset(&ex, 0, sizeof(ex));
1385     else
1386 	ex = *eap;
1387     ex.arg = fname;
1388     ex.cmd = (char_u *)(v == 2 ? "pyfile" : "pyfile3");
1389 
1390     if (v == 2)
1391     {
1392 # ifdef FEAT_PYTHON
1393 	ex_pyfile(&ex);
1394 # else
1395 	vim_snprintf((char *)IObuff, IOSIZE,
1396 		_("W20: Required python version 2.x not supported, ignoring file: %s"),
1397 		fname);
1398 	msg((char *)IObuff);
1399 # endif
1400 	return;
1401     }
1402     else
1403     {
1404 # ifdef FEAT_PYTHON3
1405 	ex_py3file(&ex);
1406 # else
1407 	vim_snprintf((char *)IObuff, IOSIZE,
1408 		_("W21: Required python version 3.x not supported, ignoring file: %s"),
1409 		fname);
1410 	msg((char *)IObuff);
1411 # endif
1412 	return;
1413     }
1414 }
1415 
1416 /*
1417  * ":pyxfile {fname}"
1418  */
1419     void
1420 ex_pyxfile(exarg_T *eap)
1421 {
1422     source_pyx_file(eap, eap->arg);
1423 }
1424 
1425 /*
1426  * ":pyx"
1427  */
1428     void
1429 ex_pyx(exarg_T *eap)
1430 {
1431 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
1432     init_pyxversion();
1433     if (p_pyx == 2)
1434 	ex_python(eap);
1435     else
1436 	ex_py3(eap);
1437 # elif defined(FEAT_PYTHON)
1438     ex_python(eap);
1439 # elif defined(FEAT_PYTHON3)
1440     ex_py3(eap);
1441 # endif
1442 }
1443 
1444 /*
1445  * ":pyxdo"
1446  */
1447     void
1448 ex_pyxdo(exarg_T *eap)
1449 {
1450 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
1451     init_pyxversion();
1452     if (p_pyx == 2)
1453 	ex_pydo(eap);
1454     else
1455 	ex_py3do(eap);
1456 # elif defined(FEAT_PYTHON)
1457     ex_pydo(eap);
1458 # elif defined(FEAT_PYTHON3)
1459     ex_py3do(eap);
1460 # endif
1461 }
1462 
1463 #endif
1464 
1465 /*
1466  * ":checktime [buffer]"
1467  */
1468     void
1469 ex_checktime(exarg_T *eap)
1470 {
1471     buf_T	*buf;
1472     int		save_no_check_timestamps = no_check_timestamps;
1473 
1474     no_check_timestamps = 0;
1475     if (eap->addr_count == 0)	// default is all buffers
1476 	check_timestamps(FALSE);
1477     else
1478     {
1479 	buf = buflist_findnr((int)eap->line2);
1480 	if (buf != NULL)	// cannot happen?
1481 	    (void)buf_check_timestamp(buf, FALSE);
1482     }
1483     no_check_timestamps = save_no_check_timestamps;
1484 }
1485 
1486 #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
1487 	&& (defined(FEAT_EVAL) || defined(FEAT_MULTI_LANG))
1488 # define HAVE_GET_LOCALE_VAL
1489     static char_u *
1490 get_locale_val(int what)
1491 {
1492     char_u	*loc;
1493 
1494     // Obtain the locale value from the libraries.
1495     loc = (char_u *)setlocale(what, NULL);
1496 
1497 # ifdef MSWIN
1498     if (loc != NULL)
1499     {
1500 	char_u	*p;
1501 
1502 	// setocale() returns something like "LC_COLLATE=<name>;LC_..." when
1503 	// one of the values (e.g., LC_CTYPE) differs.
1504 	p = vim_strchr(loc, '=');
1505 	if (p != NULL)
1506 	{
1507 	    loc = ++p;
1508 	    while (*p != NUL)	// remove trailing newline
1509 	    {
1510 		if (*p < ' ' || *p == ';')
1511 		{
1512 		    *p = NUL;
1513 		    break;
1514 		}
1515 		++p;
1516 	    }
1517 	}
1518     }
1519 # endif
1520 
1521     return loc;
1522 }
1523 #endif
1524 
1525 
1526 #ifdef MSWIN
1527 /*
1528  * On MS-Windows locale names are strings like "German_Germany.1252", but
1529  * gettext expects "de".  Try to translate one into another here for a few
1530  * supported languages.
1531  */
1532     static char_u *
1533 gettext_lang(char_u *name)
1534 {
1535     int		i;
1536     static char *(mtable[]) = {
1537 			"afrikaans",	"af",
1538 			"czech",	"cs",
1539 			"dutch",	"nl",
1540 			"german",	"de",
1541 			"english_united kingdom", "en_GB",
1542 			"spanish",	"es",
1543 			"french",	"fr",
1544 			"italian",	"it",
1545 			"japanese",	"ja",
1546 			"korean",	"ko",
1547 			"norwegian",	"no",
1548 			"polish",	"pl",
1549 			"russian",	"ru",
1550 			"slovak",	"sk",
1551 			"swedish",	"sv",
1552 			"ukrainian",	"uk",
1553 			"chinese_china", "zh_CN",
1554 			"chinese_taiwan", "zh_TW",
1555 			NULL};
1556 
1557     for (i = 0; mtable[i] != NULL; i += 2)
1558 	if (STRNICMP(mtable[i], name, STRLEN(mtable[i])) == 0)
1559 	    return (char_u *)mtable[i + 1];
1560     return name;
1561 }
1562 #endif
1563 
1564 #if defined(FEAT_MULTI_LANG) || defined(PROTO)
1565 /*
1566  * Return TRUE when "lang" starts with a valid language name.
1567  * Rejects NULL, empty string, "C", "C.UTF-8" and others.
1568  */
1569     static int
1570 is_valid_mess_lang(char_u *lang)
1571 {
1572     return lang != NULL && ASCII_ISALPHA(lang[0]) && ASCII_ISALPHA(lang[1]);
1573 }
1574 
1575 /*
1576  * Obtain the current messages language.  Used to set the default for
1577  * 'helplang'.  May return NULL or an empty string.
1578  */
1579     char_u *
1580 get_mess_lang(void)
1581 {
1582     char_u *p;
1583 
1584 # ifdef HAVE_GET_LOCALE_VAL
1585 #  if defined(LC_MESSAGES)
1586     p = get_locale_val(LC_MESSAGES);
1587 #  else
1588     // This is necessary for Win32, where LC_MESSAGES is not defined and $LANG
1589     // may be set to the LCID number.  LC_COLLATE is the best guess, LC_TIME
1590     // and LC_MONETARY may be set differently for a Japanese working in the
1591     // US.
1592     p = get_locale_val(LC_COLLATE);
1593 #  endif
1594 # else
1595     p = mch_getenv((char_u *)"LC_ALL");
1596     if (!is_valid_mess_lang(p))
1597     {
1598 	p = mch_getenv((char_u *)"LC_MESSAGES");
1599 	if (!is_valid_mess_lang(p))
1600 	    p = mch_getenv((char_u *)"LANG");
1601     }
1602 # endif
1603 # ifdef MSWIN
1604     p = gettext_lang(p);
1605 # endif
1606     return is_valid_mess_lang(p) ? p : NULL;
1607 }
1608 #endif
1609 
1610 // Complicated #if; matches with where get_mess_env() is used below.
1611 #if (defined(FEAT_EVAL) && !((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
1612 	    && defined(LC_MESSAGES))) \
1613 	|| ((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
1614 		&& !defined(LC_MESSAGES))
1615 /*
1616  * Get the language used for messages from the environment.
1617  */
1618     static char_u *
1619 get_mess_env(void)
1620 {
1621     char_u	*p;
1622 
1623     p = mch_getenv((char_u *)"LC_ALL");
1624     if (p == NULL || *p == NUL)
1625     {
1626 	p = mch_getenv((char_u *)"LC_MESSAGES");
1627 	if (p == NULL || *p == NUL)
1628 	{
1629 	    p = mch_getenv((char_u *)"LANG");
1630 	    if (p != NULL && VIM_ISDIGIT(*p))
1631 		p = NULL;		// ignore something like "1043"
1632 # ifdef HAVE_GET_LOCALE_VAL
1633 	    if (p == NULL || *p == NUL)
1634 		p = get_locale_val(LC_CTYPE);
1635 # endif
1636 	}
1637     }
1638     return p;
1639 }
1640 #endif
1641 
1642 #if defined(FEAT_EVAL) || defined(PROTO)
1643 
1644 /*
1645  * Set the "v:lang" variable according to the current locale setting.
1646  * Also do "v:lc_time"and "v:ctype".
1647  */
1648     void
1649 set_lang_var(void)
1650 {
1651     char_u	*loc;
1652 
1653 # ifdef HAVE_GET_LOCALE_VAL
1654     loc = get_locale_val(LC_CTYPE);
1655 # else
1656     // setlocale() not supported: use the default value
1657     loc = (char_u *)"C";
1658 # endif
1659     set_vim_var_string(VV_CTYPE, loc, -1);
1660 
1661     // When LC_MESSAGES isn't defined use the value from $LC_MESSAGES, fall
1662     // back to LC_CTYPE if it's empty.
1663 # if defined(HAVE_GET_LOCALE_VAL) && defined(LC_MESSAGES)
1664     loc = get_locale_val(LC_MESSAGES);
1665 # else
1666     loc = get_mess_env();
1667 # endif
1668     set_vim_var_string(VV_LANG, loc, -1);
1669 
1670 # ifdef HAVE_GET_LOCALE_VAL
1671     loc = get_locale_val(LC_TIME);
1672 # endif
1673     set_vim_var_string(VV_LC_TIME, loc, -1);
1674 }
1675 #endif
1676 
1677 #if defined(HAVE_LOCALE_H) || defined(X_LOCALE) \
1678 /*
1679  * ":language":  Set the language (locale).
1680  */
1681     void
1682 ex_language(exarg_T *eap)
1683 {
1684     char	*loc;
1685     char_u	*p;
1686     char_u	*name;
1687     int		what = LC_ALL;
1688     char	*whatstr = "";
1689 #ifdef LC_MESSAGES
1690 # define VIM_LC_MESSAGES LC_MESSAGES
1691 #else
1692 # define VIM_LC_MESSAGES 6789
1693 #endif
1694 
1695     name = eap->arg;
1696 
1697     // Check for "messages {name}", "ctype {name}" or "time {name}" argument.
1698     // Allow abbreviation, but require at least 3 characters to avoid
1699     // confusion with a two letter language name "me" or "ct".
1700     p = skiptowhite(eap->arg);
1701     if ((*p == NUL || VIM_ISWHITE(*p)) && p - eap->arg >= 3)
1702     {
1703 	if (STRNICMP(eap->arg, "messages", p - eap->arg) == 0)
1704 	{
1705 	    what = VIM_LC_MESSAGES;
1706 	    name = skipwhite(p);
1707 	    whatstr = "messages ";
1708 	}
1709 	else if (STRNICMP(eap->arg, "ctype", p - eap->arg) == 0)
1710 	{
1711 	    what = LC_CTYPE;
1712 	    name = skipwhite(p);
1713 	    whatstr = "ctype ";
1714 	}
1715 	else if (STRNICMP(eap->arg, "time", p - eap->arg) == 0)
1716 	{
1717 	    what = LC_TIME;
1718 	    name = skipwhite(p);
1719 	    whatstr = "time ";
1720 	}
1721     }
1722 
1723     if (*name == NUL)
1724     {
1725 #ifndef LC_MESSAGES
1726 	if (what == VIM_LC_MESSAGES)
1727 	    p = get_mess_env();
1728 	else
1729 #endif
1730 	    p = (char_u *)setlocale(what, NULL);
1731 	if (p == NULL || *p == NUL)
1732 	    p = (char_u *)"Unknown";
1733 	smsg(_("Current %slanguage: \"%s\""), whatstr, p);
1734     }
1735     else
1736     {
1737 #ifndef LC_MESSAGES
1738 	if (what == VIM_LC_MESSAGES)
1739 	    loc = "";
1740 	else
1741 #endif
1742 	{
1743 	    loc = setlocale(what, (char *)name);
1744 #if defined(FEAT_FLOAT) && defined(LC_NUMERIC)
1745 	    // Make sure strtod() uses a decimal point, not a comma.
1746 	    setlocale(LC_NUMERIC, "C");
1747 #endif
1748 	}
1749 	if (loc == NULL)
1750 	    semsg(_("E197: Cannot set language to \"%s\""), name);
1751 	else
1752 	{
1753 #ifdef HAVE_NL_MSG_CAT_CNTR
1754 	    // Need to do this for GNU gettext, otherwise cached translations
1755 	    // will be used again.
1756 	    extern int _nl_msg_cat_cntr;
1757 
1758 	    ++_nl_msg_cat_cntr;
1759 #endif
1760 	    // Reset $LC_ALL, otherwise it would overrule everything.
1761 	    vim_setenv((char_u *)"LC_ALL", (char_u *)"");
1762 
1763 	    if (what != LC_TIME)
1764 	    {
1765 		// Tell gettext() what to translate to.  It apparently doesn't
1766 		// use the currently effective locale.  Also do this when
1767 		// FEAT_GETTEXT isn't defined, so that shell commands use this
1768 		// value.
1769 		if (what == LC_ALL)
1770 		{
1771 		    vim_setenv((char_u *)"LANG", name);
1772 
1773 		    // Clear $LANGUAGE because GNU gettext uses it.
1774 		    vim_setenv((char_u *)"LANGUAGE", (char_u *)"");
1775 # ifdef MSWIN
1776 		    // Apparently MS-Windows printf() may cause a crash when
1777 		    // we give it 8-bit text while it's expecting text in the
1778 		    // current locale.  This call avoids that.
1779 		    setlocale(LC_CTYPE, "C");
1780 # endif
1781 		}
1782 		if (what != LC_CTYPE)
1783 		{
1784 		    char_u	*mname;
1785 #ifdef MSWIN
1786 		    mname = gettext_lang(name);
1787 #else
1788 		    mname = name;
1789 #endif
1790 		    vim_setenv((char_u *)"LC_MESSAGES", mname);
1791 #ifdef FEAT_MULTI_LANG
1792 		    set_helplang_default(mname);
1793 #endif
1794 		}
1795 	    }
1796 
1797 # ifdef FEAT_EVAL
1798 	    // Set v:lang, v:lc_time and v:ctype to the final result.
1799 	    set_lang_var();
1800 # endif
1801 # ifdef FEAT_TITLE
1802 	    maketitle();
1803 # endif
1804 	}
1805     }
1806 }
1807 
1808 static char_u	**locales = NULL;	// Array of all available locales
1809 
1810 # ifndef MSWIN
1811 static int	did_init_locales = FALSE;
1812 
1813 /*
1814  * Return an array of strings for all available locales + NULL for the
1815  * last element.  Return NULL in case of error.
1816  */
1817     static char_u **
1818 find_locales(void)
1819 {
1820     garray_T	locales_ga;
1821     char_u	*loc;
1822 
1823     // Find all available locales by running command "locale -a".  If this
1824     // doesn't work we won't have completion.
1825     char_u *locale_a = get_cmd_output((char_u *)"locale -a",
1826 						    NULL, SHELL_SILENT, NULL);
1827     if (locale_a == NULL)
1828 	return NULL;
1829     ga_init2(&locales_ga, sizeof(char_u *), 20);
1830 
1831     // Transform locale_a string where each locale is separated by "\n"
1832     // into an array of locale strings.
1833     loc = (char_u *)strtok((char *)locale_a, "\n");
1834 
1835     while (loc != NULL)
1836     {
1837 	if (ga_grow(&locales_ga, 1) == FAIL)
1838 	    break;
1839 	loc = vim_strsave(loc);
1840 	if (loc == NULL)
1841 	    break;
1842 
1843 	((char_u **)locales_ga.ga_data)[locales_ga.ga_len++] = loc;
1844 	loc = (char_u *)strtok(NULL, "\n");
1845     }
1846     vim_free(locale_a);
1847     if (ga_grow(&locales_ga, 1) == FAIL)
1848     {
1849 	ga_clear(&locales_ga);
1850 	return NULL;
1851     }
1852     ((char_u **)locales_ga.ga_data)[locales_ga.ga_len] = NULL;
1853     return (char_u **)locales_ga.ga_data;
1854 }
1855 # endif
1856 
1857 /*
1858  * Lazy initialization of all available locales.
1859  */
1860     static void
1861 init_locales(void)
1862 {
1863 #  ifndef MSWIN
1864     if (!did_init_locales)
1865     {
1866 	did_init_locales = TRUE;
1867 	locales = find_locales();
1868     }
1869 #  endif
1870 }
1871 
1872 #  if defined(EXITFREE) || defined(PROTO)
1873     void
1874 free_locales(void)
1875 {
1876     int			i;
1877     if (locales != NULL)
1878     {
1879 	for (i = 0; locales[i] != NULL; i++)
1880 	    vim_free(locales[i]);
1881 	VIM_CLEAR(locales);
1882     }
1883 }
1884 #  endif
1885 
1886 /*
1887  * Function given to ExpandGeneric() to obtain the possible arguments of the
1888  * ":language" command.
1889  */
1890     char_u *
1891 get_lang_arg(expand_T *xp UNUSED, int idx)
1892 {
1893     if (idx == 0)
1894 	return (char_u *)"messages";
1895     if (idx == 1)
1896 	return (char_u *)"ctype";
1897     if (idx == 2)
1898 	return (char_u *)"time";
1899 
1900     init_locales();
1901     if (locales == NULL)
1902 	return NULL;
1903     return locales[idx - 3];
1904 }
1905 
1906 /*
1907  * Function given to ExpandGeneric() to obtain the available locales.
1908  */
1909     char_u *
1910 get_locales(expand_T *xp UNUSED, int idx)
1911 {
1912     init_locales();
1913     if (locales == NULL)
1914 	return NULL;
1915     return locales[idx];
1916 }
1917 
1918 #endif
1919