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