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 /* 18 * If 'autowrite' option set, try to write the file. 19 * Careful: autocommands may make "buf" invalid! 20 * 21 * return FAIL for failure, OK otherwise 22 */ 23 int 24 autowrite(buf_T *buf, int forceit) 25 { 26 int r; 27 bufref_T bufref; 28 29 if (!(p_aw || p_awa) || !p_write 30 #ifdef FEAT_QUICKFIX 31 // never autowrite a "nofile" or "nowrite" buffer 32 || bt_dontwrite(buf) 33 #endif 34 || (!forceit && buf->b_p_ro) || buf->b_ffname == NULL) 35 return FAIL; 36 set_bufref(&bufref, buf); 37 r = buf_write_all(buf, forceit); 38 39 // Writing may succeed but the buffer still changed, e.g., when there is a 40 // conversion error. We do want to return FAIL then. 41 if (bufref_valid(&bufref) && bufIsChanged(buf)) 42 r = FAIL; 43 return r; 44 } 45 46 /* 47 * Flush all buffers, except the ones that are readonly or are never written. 48 */ 49 void 50 autowrite_all(void) 51 { 52 buf_T *buf; 53 54 if (!(p_aw || p_awa) || !p_write) 55 return; 56 FOR_ALL_BUFFERS(buf) 57 if (bufIsChanged(buf) && !buf->b_p_ro && !bt_dontwrite(buf)) 58 { 59 bufref_T bufref; 60 61 set_bufref(&bufref, buf); 62 63 (void)buf_write_all(buf, FALSE); 64 65 // an autocommand may have deleted the buffer 66 if (!bufref_valid(&bufref)) 67 buf = firstbuf; 68 } 69 } 70 71 /* 72 * Return TRUE if buffer was changed and cannot be abandoned. 73 * For flags use the CCGD_ values. 74 */ 75 int 76 check_changed(buf_T *buf, int flags) 77 { 78 int forceit = (flags & CCGD_FORCEIT); 79 bufref_T bufref; 80 81 set_bufref(&bufref, buf); 82 83 if ( !forceit 84 && bufIsChanged(buf) 85 && ((flags & CCGD_MULTWIN) || buf->b_nwindows <= 1) 86 && (!(flags & CCGD_AW) || autowrite(buf, forceit) == FAIL)) 87 { 88 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 89 if ((p_confirm || cmdmod.confirm) && p_write) 90 { 91 buf_T *buf2; 92 int count = 0; 93 94 if (flags & CCGD_ALLBUF) 95 FOR_ALL_BUFFERS(buf2) 96 if (bufIsChanged(buf2) 97 && (buf2->b_ffname != NULL 98 # ifdef FEAT_BROWSE 99 || cmdmod.browse 100 # endif 101 )) 102 ++count; 103 if (!bufref_valid(&bufref)) 104 // Autocommand deleted buffer, oops! It's not changed now. 105 return FALSE; 106 107 dialog_changed(buf, count > 1); 108 109 if (!bufref_valid(&bufref)) 110 // Autocommand deleted buffer, oops! It's not changed now. 111 return FALSE; 112 return bufIsChanged(buf); 113 } 114 #endif 115 if (flags & CCGD_EXCMD) 116 no_write_message(); 117 else 118 no_write_message_nobang(curbuf); 119 return TRUE; 120 } 121 return FALSE; 122 } 123 124 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) || defined(PROTO) 125 126 #if defined(FEAT_BROWSE) || defined(PROTO) 127 /* 128 * When wanting to write a file without a file name, ask the user for a name. 129 */ 130 void 131 browse_save_fname(buf_T *buf) 132 { 133 if (buf->b_fname == NULL) 134 { 135 char_u *fname; 136 137 fname = do_browse(BROWSE_SAVE, (char_u *)_("Save As"), 138 NULL, NULL, NULL, NULL, buf); 139 if (fname != NULL) 140 { 141 if (setfname(buf, fname, NULL, TRUE) == OK) 142 buf->b_flags |= BF_NOTEDITED; 143 vim_free(fname); 144 } 145 } 146 } 147 #endif 148 149 /* 150 * Ask the user what to do when abandoning a changed buffer. 151 * Must check 'write' option first! 152 */ 153 void 154 dialog_changed( 155 buf_T *buf, 156 int checkall) // may abandon all changed buffers 157 { 158 char_u buff[DIALOG_MSG_SIZE]; 159 int ret; 160 buf_T *buf2; 161 exarg_T ea; 162 163 dialog_msg(buff, _("Save changes to \"%s\"?"), buf->b_fname); 164 if (checkall) 165 ret = vim_dialog_yesnoallcancel(VIM_QUESTION, NULL, buff, 1); 166 else 167 ret = vim_dialog_yesnocancel(VIM_QUESTION, NULL, buff, 1); 168 169 // Init ea pseudo-structure, this is needed for the check_overwrite() 170 // function. 171 vim_memset(&ea, 0, sizeof(ea)); 172 173 if (ret == VIM_YES) 174 { 175 #ifdef FEAT_BROWSE 176 // May get file name, when there is none 177 browse_save_fname(buf); 178 #endif 179 if (buf->b_fname != NULL && check_overwrite(&ea, buf, 180 buf->b_fname, buf->b_ffname, FALSE) == OK) 181 // didn't hit Cancel 182 (void)buf_write_all(buf, FALSE); 183 } 184 else if (ret == VIM_NO) 185 { 186 unchanged(buf, TRUE, FALSE); 187 } 188 else if (ret == VIM_ALL) 189 { 190 /* 191 * Write all modified files that can be written. 192 * Skip readonly buffers, these need to be confirmed 193 * individually. 194 */ 195 FOR_ALL_BUFFERS(buf2) 196 { 197 if (bufIsChanged(buf2) 198 && (buf2->b_ffname != NULL 199 #ifdef FEAT_BROWSE 200 || cmdmod.browse 201 #endif 202 ) 203 && !buf2->b_p_ro) 204 { 205 bufref_T bufref; 206 207 set_bufref(&bufref, buf2); 208 #ifdef FEAT_BROWSE 209 // May get file name, when there is none 210 browse_save_fname(buf2); 211 #endif 212 if (buf2->b_fname != NULL && check_overwrite(&ea, buf2, 213 buf2->b_fname, buf2->b_ffname, FALSE) == OK) 214 // didn't hit Cancel 215 (void)buf_write_all(buf2, FALSE); 216 217 // an autocommand may have deleted the buffer 218 if (!bufref_valid(&bufref)) 219 buf2 = firstbuf; 220 } 221 } 222 } 223 else if (ret == VIM_DISCARDALL) 224 { 225 /* 226 * mark all buffers as unchanged 227 */ 228 FOR_ALL_BUFFERS(buf2) 229 unchanged(buf2, TRUE, FALSE); 230 } 231 } 232 #endif 233 234 /* 235 * Return TRUE if the buffer "buf" can be abandoned, either by making it 236 * hidden, autowriting it or unloading it. 237 */ 238 int 239 can_abandon(buf_T *buf, int forceit) 240 { 241 return ( buf_hide(buf) 242 || !bufIsChanged(buf) 243 || buf->b_nwindows > 1 244 || autowrite(buf, forceit) == OK 245 || forceit); 246 } 247 248 /* 249 * Add a buffer number to "bufnrs", unless it's already there. 250 */ 251 static void 252 add_bufnum(int *bufnrs, int *bufnump, int nr) 253 { 254 int i; 255 256 for (i = 0; i < *bufnump; ++i) 257 if (bufnrs[i] == nr) 258 return; 259 bufnrs[*bufnump] = nr; 260 *bufnump = *bufnump + 1; 261 } 262 263 /* 264 * Return TRUE if any buffer was changed and cannot be abandoned. 265 * That changed buffer becomes the current buffer. 266 * When "unload" is TRUE the current buffer is unloaded instead of making it 267 * hidden. This is used for ":q!". 268 */ 269 int 270 check_changed_any( 271 int hidden, // Only check hidden buffers 272 int unload) 273 { 274 int ret = FALSE; 275 buf_T *buf; 276 int save; 277 int i; 278 int bufnum = 0; 279 int bufcount = 0; 280 int *bufnrs; 281 tabpage_T *tp; 282 win_T *wp; 283 284 // Make a list of all buffers, with the most important ones first. 285 FOR_ALL_BUFFERS(buf) 286 ++bufcount; 287 288 if (bufcount == 0) 289 return FALSE; 290 291 bufnrs = ALLOC_MULT(int, bufcount); 292 if (bufnrs == NULL) 293 return FALSE; 294 295 // curbuf 296 bufnrs[bufnum++] = curbuf->b_fnum; 297 298 // buffers in current tab 299 FOR_ALL_WINDOWS(wp) 300 if (wp->w_buffer != curbuf) 301 add_bufnum(bufnrs, &bufnum, wp->w_buffer->b_fnum); 302 303 // buffers in other tabs 304 FOR_ALL_TABPAGES(tp) 305 if (tp != curtab) 306 for (wp = tp->tp_firstwin; wp != NULL; wp = wp->w_next) 307 add_bufnum(bufnrs, &bufnum, wp->w_buffer->b_fnum); 308 309 // any other buffer 310 FOR_ALL_BUFFERS(buf) 311 add_bufnum(bufnrs, &bufnum, buf->b_fnum); 312 313 for (i = 0; i < bufnum; ++i) 314 { 315 buf = buflist_findnr(bufnrs[i]); 316 if (buf == NULL) 317 continue; 318 if ((!hidden || buf->b_nwindows == 0) && bufIsChanged(buf)) 319 { 320 bufref_T bufref; 321 322 set_bufref(&bufref, buf); 323 #ifdef FEAT_TERMINAL 324 if (term_job_running(buf->b_term)) 325 { 326 if (term_try_stop_job(buf) == FAIL) 327 break; 328 } 329 else 330 #endif 331 // Try auto-writing the buffer. If this fails but the buffer no 332 // longer exists it's not changed, that's OK. 333 if (check_changed(buf, (p_awa ? CCGD_AW : 0) 334 | CCGD_MULTWIN 335 | CCGD_ALLBUF) && bufref_valid(&bufref)) 336 break; // didn't save - still changes 337 } 338 } 339 340 if (i >= bufnum) 341 goto theend; 342 343 // Get here if "buf" cannot be abandoned. 344 ret = TRUE; 345 exiting = FALSE; 346 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 347 /* 348 * When ":confirm" used, don't give an error message. 349 */ 350 if (!(p_confirm || cmdmod.confirm)) 351 #endif 352 { 353 // There must be a wait_return for this message, do_buffer() 354 // may cause a redraw. But wait_return() is a no-op when vgetc() 355 // is busy (Quit used from window menu), then make sure we don't 356 // cause a scroll up. 357 if (vgetc_busy > 0) 358 { 359 msg_row = cmdline_row; 360 msg_col = 0; 361 msg_didout = FALSE; 362 } 363 if ( 364 #ifdef FEAT_TERMINAL 365 term_job_running(buf->b_term) 366 ? semsg(_("E947: Job still running in buffer \"%s\""), 367 buf->b_fname) 368 : 369 #endif 370 semsg(_("E162: No write since last change for buffer \"%s\""), 371 buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname)) 372 { 373 save = no_wait_return; 374 no_wait_return = FALSE; 375 wait_return(FALSE); 376 no_wait_return = save; 377 } 378 } 379 380 // Try to find a window that contains the buffer. 381 if (buf != curbuf) 382 FOR_ALL_TAB_WINDOWS(tp, wp) 383 if (wp->w_buffer == buf) 384 { 385 bufref_T bufref; 386 387 set_bufref(&bufref, buf); 388 389 goto_tabpage_win(tp, wp); 390 391 // Paranoia: did autocmd wipe out the buffer with changes? 392 if (!bufref_valid(&bufref)) 393 goto theend; 394 goto buf_found; 395 } 396 buf_found: 397 398 // Open the changed buffer in the current window. 399 if (buf != curbuf) 400 set_curbuf(buf, unload ? DOBUF_UNLOAD : DOBUF_GOTO); 401 402 theend: 403 vim_free(bufnrs); 404 return ret; 405 } 406 407 /* 408 * return FAIL if there is no file name, OK if there is one 409 * give error message for FAIL 410 */ 411 int 412 check_fname(void) 413 { 414 if (curbuf->b_ffname == NULL) 415 { 416 emsg(_(e_noname)); 417 return FAIL; 418 } 419 return OK; 420 } 421 422 /* 423 * flush the contents of a buffer, unless it has no file name 424 * 425 * return FAIL for failure, OK otherwise 426 */ 427 int 428 buf_write_all(buf_T *buf, int forceit) 429 { 430 int retval; 431 buf_T *old_curbuf = curbuf; 432 433 retval = (buf_write(buf, buf->b_ffname, buf->b_fname, 434 (linenr_T)1, buf->b_ml.ml_line_count, NULL, 435 FALSE, forceit, TRUE, FALSE)); 436 if (curbuf != old_curbuf) 437 { 438 msg_source(HL_ATTR(HLF_W)); 439 msg(_("Warning: Entered other buffer unexpectedly (check autocommands)")); 440 } 441 return retval; 442 } 443 444 /* 445 * ":argdo", ":windo", ":bufdo", ":tabdo", ":cdo", ":ldo", ":cfdo" and ":lfdo" 446 */ 447 void 448 ex_listdo(exarg_T *eap) 449 { 450 int i; 451 win_T *wp; 452 tabpage_T *tp; 453 buf_T *buf = curbuf; 454 int next_fnum = 0; 455 #if defined(FEAT_SYN_HL) 456 char_u *save_ei = NULL; 457 #endif 458 char_u *p_shm_save; 459 #ifdef FEAT_QUICKFIX 460 int qf_size = 0; 461 int qf_idx; 462 #endif 463 464 #ifndef FEAT_QUICKFIX 465 if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo || 466 eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo) 467 { 468 ex_ni(eap); 469 return; 470 } 471 #endif 472 473 #if defined(FEAT_SYN_HL) 474 if (eap->cmdidx != CMD_windo && eap->cmdidx != CMD_tabdo) 475 { 476 // Don't do syntax HL autocommands. Skipping the syntax file is a 477 // great speed improvement. 478 save_ei = au_event_disable(",Syntax"); 479 480 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 481 buf->b_flags &= ~BF_SYN_SET; 482 buf = curbuf; 483 } 484 #endif 485 #ifdef FEAT_CLIPBOARD 486 start_global_changes(); 487 #endif 488 489 if (eap->cmdidx == CMD_windo 490 || eap->cmdidx == CMD_tabdo 491 || buf_hide(curbuf) 492 || !check_changed(curbuf, CCGD_AW 493 | (eap->forceit ? CCGD_FORCEIT : 0) 494 | CCGD_EXCMD)) 495 { 496 i = 0; 497 // start at the eap->line1 argument/window/buffer 498 wp = firstwin; 499 tp = first_tabpage; 500 switch (eap->cmdidx) 501 { 502 case CMD_windo: 503 for ( ; wp != NULL && i + 1 < eap->line1; wp = wp->w_next) 504 i++; 505 break; 506 case CMD_tabdo: 507 for( ; tp != NULL && i + 1 < eap->line1; tp = tp->tp_next) 508 i++; 509 break; 510 case CMD_argdo: 511 i = eap->line1 - 1; 512 break; 513 default: 514 break; 515 } 516 // set pcmark now 517 if (eap->cmdidx == CMD_bufdo) 518 { 519 // Advance to the first listed buffer after "eap->line1". 520 for (buf = firstbuf; buf != NULL && (buf->b_fnum < eap->line1 521 || !buf->b_p_bl); buf = buf->b_next) 522 if (buf->b_fnum > eap->line2) 523 { 524 buf = NULL; 525 break; 526 } 527 if (buf != NULL) 528 goto_buffer(eap, DOBUF_FIRST, FORWARD, buf->b_fnum); 529 } 530 #ifdef FEAT_QUICKFIX 531 else if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo 532 || eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo) 533 { 534 qf_size = qf_get_valid_size(eap); 535 if (qf_size <= 0 || eap->line1 > qf_size) 536 buf = NULL; 537 else 538 { 539 ex_cc(eap); 540 541 buf = curbuf; 542 i = eap->line1 - 1; 543 if (eap->addr_count <= 0) 544 // default is all the quickfix/location list entries 545 eap->line2 = qf_size; 546 } 547 } 548 #endif 549 else 550 setpcmark(); 551 listcmd_busy = TRUE; // avoids setting pcmark below 552 553 while (!got_int && buf != NULL) 554 { 555 if (eap->cmdidx == CMD_argdo) 556 { 557 // go to argument "i" 558 if (i == ARGCOUNT) 559 break; 560 // Don't call do_argfile() when already there, it will try 561 // reloading the file. 562 if (curwin->w_arg_idx != i || !editing_arg_idx(curwin)) 563 { 564 // Clear 'shm' to avoid that the file message overwrites 565 // any output from the command. 566 p_shm_save = vim_strsave(p_shm); 567 set_option_value((char_u *)"shm", 0L, (char_u *)"", 0); 568 do_argfile(eap, i); 569 set_option_value((char_u *)"shm", 0L, p_shm_save, 0); 570 vim_free(p_shm_save); 571 } 572 if (curwin->w_arg_idx != i) 573 break; 574 } 575 else if (eap->cmdidx == CMD_windo) 576 { 577 // go to window "wp" 578 if (!win_valid(wp)) 579 break; 580 win_goto(wp); 581 if (curwin != wp) 582 break; // something must be wrong 583 wp = curwin->w_next; 584 } 585 else if (eap->cmdidx == CMD_tabdo) 586 { 587 // go to window "tp" 588 if (!valid_tabpage(tp)) 589 break; 590 goto_tabpage_tp(tp, TRUE, TRUE); 591 tp = tp->tp_next; 592 } 593 else if (eap->cmdidx == CMD_bufdo) 594 { 595 // Remember the number of the next listed buffer, in case 596 // ":bwipe" is used or autocommands do something strange. 597 next_fnum = -1; 598 for (buf = curbuf->b_next; buf != NULL; buf = buf->b_next) 599 if (buf->b_p_bl) 600 { 601 next_fnum = buf->b_fnum; 602 break; 603 } 604 } 605 606 ++i; 607 608 // execute the command 609 do_cmdline(eap->arg, eap->getline, eap->cookie, 610 DOCMD_VERBOSE + DOCMD_NOWAIT); 611 612 if (eap->cmdidx == CMD_bufdo) 613 { 614 // Done? 615 if (next_fnum < 0 || next_fnum > eap->line2) 616 break; 617 // Check if the buffer still exists. 618 FOR_ALL_BUFFERS(buf) 619 if (buf->b_fnum == next_fnum) 620 break; 621 if (buf == NULL) 622 break; 623 624 // Go to the next buffer. Clear 'shm' to avoid that the file 625 // message overwrites any output from the command. 626 p_shm_save = vim_strsave(p_shm); 627 set_option_value((char_u *)"shm", 0L, (char_u *)"", 0); 628 goto_buffer(eap, DOBUF_FIRST, FORWARD, next_fnum); 629 set_option_value((char_u *)"shm", 0L, p_shm_save, 0); 630 vim_free(p_shm_save); 631 632 // If autocommands took us elsewhere, quit here. 633 if (curbuf->b_fnum != next_fnum) 634 break; 635 } 636 637 #ifdef FEAT_QUICKFIX 638 if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo 639 || eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo) 640 { 641 if (i >= qf_size || i >= eap->line2) 642 break; 643 644 qf_idx = qf_get_cur_idx(eap); 645 646 ex_cnext(eap); 647 648 // If jumping to the next quickfix entry fails, quit here 649 if (qf_get_cur_idx(eap) == qf_idx) 650 break; 651 } 652 #endif 653 654 if (eap->cmdidx == CMD_windo) 655 { 656 validate_cursor(); // cursor may have moved 657 658 // required when 'scrollbind' has been set 659 if (curwin->w_p_scb) 660 do_check_scrollbind(TRUE); 661 } 662 663 if (eap->cmdidx == CMD_windo || eap->cmdidx == CMD_tabdo) 664 if (i+1 > eap->line2) 665 break; 666 if (eap->cmdidx == CMD_argdo && i >= eap->line2) 667 break; 668 } 669 listcmd_busy = FALSE; 670 } 671 672 #if defined(FEAT_SYN_HL) 673 if (save_ei != NULL) 674 { 675 buf_T *bnext; 676 aco_save_T aco; 677 678 au_event_restore(save_ei); 679 680 for (buf = firstbuf; buf != NULL; buf = bnext) 681 { 682 bnext = buf->b_next; 683 if (buf->b_nwindows > 0 && (buf->b_flags & BF_SYN_SET)) 684 { 685 buf->b_flags &= ~BF_SYN_SET; 686 687 // buffer was opened while Syntax autocommands were disabled, 688 // need to trigger them now. 689 if (buf == curbuf) 690 apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn, 691 curbuf->b_fname, TRUE, curbuf); 692 else 693 { 694 aucmd_prepbuf(&aco, buf); 695 apply_autocmds(EVENT_SYNTAX, buf->b_p_syn, 696 buf->b_fname, TRUE, buf); 697 aucmd_restbuf(&aco); 698 } 699 700 // start over, in case autocommands messed things up. 701 bnext = firstbuf; 702 } 703 } 704 } 705 #endif 706 #ifdef FEAT_CLIPBOARD 707 end_global_changes(); 708 #endif 709 } 710 711 #ifdef FEAT_EVAL 712 /* 713 * ":compiler[!] {name}" 714 */ 715 void 716 ex_compiler(exarg_T *eap) 717 { 718 char_u *buf; 719 char_u *old_cur_comp = NULL; 720 char_u *p; 721 722 if (*eap->arg == NUL) 723 { 724 // List all compiler scripts. 725 do_cmdline_cmd((char_u *)"echo globpath(&rtp, 'compiler/*.vim')"); 726 // ) keep the indenter happy... 727 } 728 else 729 { 730 buf = alloc(STRLEN(eap->arg) + 14); 731 if (buf != NULL) 732 { 733 if (eap->forceit) 734 { 735 // ":compiler! {name}" sets global options 736 do_cmdline_cmd((char_u *) 737 "command -nargs=* CompilerSet set <args>"); 738 } 739 else 740 { 741 // ":compiler! {name}" sets local options. 742 // To remain backwards compatible "current_compiler" is always 743 // used. A user's compiler plugin may set it, the distributed 744 // plugin will then skip the settings. Afterwards set 745 // "b:current_compiler" and restore "current_compiler". 746 // Explicitly prepend "g:" to make it work in a function. 747 old_cur_comp = get_var_value((char_u *)"g:current_compiler"); 748 if (old_cur_comp != NULL) 749 old_cur_comp = vim_strsave(old_cur_comp); 750 do_cmdline_cmd((char_u *) 751 "command -nargs=* CompilerSet setlocal <args>"); 752 } 753 do_unlet((char_u *)"g:current_compiler", TRUE); 754 do_unlet((char_u *)"b:current_compiler", TRUE); 755 756 sprintf((char *)buf, "compiler/%s.vim", eap->arg); 757 if (source_runtime(buf, DIP_ALL) == FAIL) 758 semsg(_("E666: compiler not supported: %s"), eap->arg); 759 vim_free(buf); 760 761 do_cmdline_cmd((char_u *)":delcommand CompilerSet"); 762 763 // Set "b:current_compiler" from "current_compiler". 764 p = get_var_value((char_u *)"g:current_compiler"); 765 if (p != NULL) 766 set_internal_string_var((char_u *)"b:current_compiler", p); 767 768 // Restore "current_compiler" for ":compiler {name}". 769 if (!eap->forceit) 770 { 771 if (old_cur_comp != NULL) 772 { 773 set_internal_string_var((char_u *)"g:current_compiler", 774 old_cur_comp); 775 vim_free(old_cur_comp); 776 } 777 else 778 do_unlet((char_u *)"g:current_compiler", TRUE); 779 } 780 } 781 } 782 } 783 #endif 784 785 #if defined(FEAT_PYTHON3) || defined(FEAT_PYTHON) || defined(PROTO) 786 787 # if (defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)) || defined(PROTO) 788 /* 789 * Detect Python 3 or 2, and initialize 'pyxversion'. 790 */ 791 void 792 init_pyxversion(void) 793 { 794 if (p_pyx == 0) 795 { 796 if (python3_enabled(FALSE)) 797 p_pyx = 3; 798 else if (python_enabled(FALSE)) 799 p_pyx = 2; 800 } 801 } 802 # endif 803 804 /* 805 * Does a file contain one of the following strings at the beginning of any 806 * line? 807 * "#!(any string)python2" => returns 2 808 * "#!(any string)python3" => returns 3 809 * "# requires python 2.x" => returns 2 810 * "# requires python 3.x" => returns 3 811 * otherwise return 0. 812 */ 813 static int 814 requires_py_version(char_u *filename) 815 { 816 FILE *file; 817 int requires_py_version = 0; 818 int i, lines; 819 820 lines = (int)p_mls; 821 if (lines < 0) 822 lines = 5; 823 824 file = mch_fopen((char *)filename, "r"); 825 if (file != NULL) 826 { 827 for (i = 0; i < lines; i++) 828 { 829 if (vim_fgets(IObuff, IOSIZE, file)) 830 break; 831 if (i == 0 && IObuff[0] == '#' && IObuff[1] == '!') 832 { 833 // Check shebang. 834 if (strstr((char *)IObuff + 2, "python2") != NULL) 835 { 836 requires_py_version = 2; 837 break; 838 } 839 if (strstr((char *)IObuff + 2, "python3") != NULL) 840 { 841 requires_py_version = 3; 842 break; 843 } 844 } 845 IObuff[21] = '\0'; 846 if (STRCMP("# requires python 2.x", IObuff) == 0) 847 { 848 requires_py_version = 2; 849 break; 850 } 851 if (STRCMP("# requires python 3.x", IObuff) == 0) 852 { 853 requires_py_version = 3; 854 break; 855 } 856 } 857 fclose(file); 858 } 859 return requires_py_version; 860 } 861 862 863 /* 864 * Source a python file using the requested python version. 865 */ 866 static void 867 source_pyx_file(exarg_T *eap, char_u *fname) 868 { 869 exarg_T ex; 870 int v = requires_py_version(fname); 871 872 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3) 873 init_pyxversion(); 874 # endif 875 if (v == 0) 876 { 877 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3) 878 // user didn't choose a preference, 'pyx' is used 879 v = p_pyx; 880 # elif defined(FEAT_PYTHON) 881 v = 2; 882 # elif defined(FEAT_PYTHON3) 883 v = 3; 884 # endif 885 } 886 887 /* 888 * now source, if required python version is not supported show 889 * unobtrusive message. 890 */ 891 if (eap == NULL) 892 vim_memset(&ex, 0, sizeof(ex)); 893 else 894 ex = *eap; 895 ex.arg = fname; 896 ex.cmd = (char_u *)(v == 2 ? "pyfile" : "pyfile3"); 897 898 if (v == 2) 899 { 900 # ifdef FEAT_PYTHON 901 ex_pyfile(&ex); 902 # else 903 vim_snprintf((char *)IObuff, IOSIZE, 904 _("W20: Required python version 2.x not supported, ignoring file: %s"), 905 fname); 906 msg((char *)IObuff); 907 # endif 908 return; 909 } 910 else 911 { 912 # ifdef FEAT_PYTHON3 913 ex_py3file(&ex); 914 # else 915 vim_snprintf((char *)IObuff, IOSIZE, 916 _("W21: Required python version 3.x not supported, ignoring file: %s"), 917 fname); 918 msg((char *)IObuff); 919 # endif 920 return; 921 } 922 } 923 924 /* 925 * ":pyxfile {fname}" 926 */ 927 void 928 ex_pyxfile(exarg_T *eap) 929 { 930 source_pyx_file(eap, eap->arg); 931 } 932 933 /* 934 * ":pyx" 935 */ 936 void 937 ex_pyx(exarg_T *eap) 938 { 939 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3) 940 init_pyxversion(); 941 if (p_pyx == 2) 942 ex_python(eap); 943 else 944 ex_py3(eap); 945 # elif defined(FEAT_PYTHON) 946 ex_python(eap); 947 # elif defined(FEAT_PYTHON3) 948 ex_py3(eap); 949 # endif 950 } 951 952 /* 953 * ":pyxdo" 954 */ 955 void 956 ex_pyxdo(exarg_T *eap) 957 { 958 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3) 959 init_pyxversion(); 960 if (p_pyx == 2) 961 ex_pydo(eap); 962 else 963 ex_py3do(eap); 964 # elif defined(FEAT_PYTHON) 965 ex_pydo(eap); 966 # elif defined(FEAT_PYTHON3) 967 ex_py3do(eap); 968 # endif 969 } 970 971 #endif 972 973 /* 974 * ":checktime [buffer]" 975 */ 976 void 977 ex_checktime(exarg_T *eap) 978 { 979 buf_T *buf; 980 int save_no_check_timestamps = no_check_timestamps; 981 982 no_check_timestamps = 0; 983 if (eap->addr_count == 0) // default is all buffers 984 check_timestamps(FALSE); 985 else 986 { 987 buf = buflist_findnr((int)eap->line2); 988 if (buf != NULL) // cannot happen? 989 (void)buf_check_timestamp(buf, FALSE); 990 } 991 no_check_timestamps = save_no_check_timestamps; 992 } 993 994 #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \ 995 && (defined(FEAT_EVAL) || defined(FEAT_MULTI_LANG)) 996 # define HAVE_GET_LOCALE_VAL 997 static char_u * 998 get_locale_val(int what) 999 { 1000 char_u *loc; 1001 1002 // Obtain the locale value from the libraries. 1003 loc = (char_u *)setlocale(what, NULL); 1004 1005 # ifdef MSWIN 1006 if (loc != NULL) 1007 { 1008 char_u *p; 1009 1010 // setocale() returns something like "LC_COLLATE=<name>;LC_..." when 1011 // one of the values (e.g., LC_CTYPE) differs. 1012 p = vim_strchr(loc, '='); 1013 if (p != NULL) 1014 { 1015 loc = ++p; 1016 while (*p != NUL) // remove trailing newline 1017 { 1018 if (*p < ' ' || *p == ';') 1019 { 1020 *p = NUL; 1021 break; 1022 } 1023 ++p; 1024 } 1025 } 1026 } 1027 # endif 1028 1029 return loc; 1030 } 1031 #endif 1032 1033 1034 #ifdef MSWIN 1035 /* 1036 * On MS-Windows locale names are strings like "German_Germany.1252", but 1037 * gettext expects "de". Try to translate one into another here for a few 1038 * supported languages. 1039 */ 1040 static char_u * 1041 gettext_lang(char_u *name) 1042 { 1043 int i; 1044 static char *(mtable[]) = { 1045 "afrikaans", "af", 1046 "czech", "cs", 1047 "dutch", "nl", 1048 "german", "de", 1049 "english_united kingdom", "en_GB", 1050 "spanish", "es", 1051 "french", "fr", 1052 "italian", "it", 1053 "japanese", "ja", 1054 "korean", "ko", 1055 "norwegian", "no", 1056 "polish", "pl", 1057 "russian", "ru", 1058 "slovak", "sk", 1059 "swedish", "sv", 1060 "ukrainian", "uk", 1061 "chinese_china", "zh_CN", 1062 "chinese_taiwan", "zh_TW", 1063 NULL}; 1064 1065 for (i = 0; mtable[i] != NULL; i += 2) 1066 if (STRNICMP(mtable[i], name, STRLEN(mtable[i])) == 0) 1067 return (char_u *)mtable[i + 1]; 1068 return name; 1069 } 1070 #endif 1071 1072 #if defined(FEAT_MULTI_LANG) || defined(PROTO) 1073 /* 1074 * Return TRUE when "lang" starts with a valid language name. 1075 * Rejects NULL, empty string, "C", "C.UTF-8" and others. 1076 */ 1077 static int 1078 is_valid_mess_lang(char_u *lang) 1079 { 1080 return lang != NULL && ASCII_ISALPHA(lang[0]) && ASCII_ISALPHA(lang[1]); 1081 } 1082 1083 /* 1084 * Obtain the current messages language. Used to set the default for 1085 * 'helplang'. May return NULL or an empty string. 1086 */ 1087 char_u * 1088 get_mess_lang(void) 1089 { 1090 char_u *p; 1091 1092 # ifdef HAVE_GET_LOCALE_VAL 1093 # if defined(LC_MESSAGES) 1094 p = get_locale_val(LC_MESSAGES); 1095 # else 1096 // This is necessary for Win32, where LC_MESSAGES is not defined and $LANG 1097 // may be set to the LCID number. LC_COLLATE is the best guess, LC_TIME 1098 // and LC_MONETARY may be set differently for a Japanese working in the 1099 // US. 1100 p = get_locale_val(LC_COLLATE); 1101 # endif 1102 # else 1103 p = mch_getenv((char_u *)"LC_ALL"); 1104 if (!is_valid_mess_lang(p)) 1105 { 1106 p = mch_getenv((char_u *)"LC_MESSAGES"); 1107 if (!is_valid_mess_lang(p)) 1108 p = mch_getenv((char_u *)"LANG"); 1109 } 1110 # endif 1111 # ifdef MSWIN 1112 p = gettext_lang(p); 1113 # endif 1114 return is_valid_mess_lang(p) ? p : NULL; 1115 } 1116 #endif 1117 1118 // Complicated #if; matches with where get_mess_env() is used below. 1119 #if (defined(FEAT_EVAL) && !((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \ 1120 && defined(LC_MESSAGES))) \ 1121 || ((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \ 1122 && !defined(LC_MESSAGES)) 1123 /* 1124 * Get the language used for messages from the environment. 1125 */ 1126 static char_u * 1127 get_mess_env(void) 1128 { 1129 char_u *p; 1130 1131 p = mch_getenv((char_u *)"LC_ALL"); 1132 if (p == NULL || *p == NUL) 1133 { 1134 p = mch_getenv((char_u *)"LC_MESSAGES"); 1135 if (p == NULL || *p == NUL) 1136 { 1137 p = mch_getenv((char_u *)"LANG"); 1138 if (p != NULL && VIM_ISDIGIT(*p)) 1139 p = NULL; // ignore something like "1043" 1140 # ifdef HAVE_GET_LOCALE_VAL 1141 if (p == NULL || *p == NUL) 1142 p = get_locale_val(LC_CTYPE); 1143 # endif 1144 } 1145 } 1146 return p; 1147 } 1148 #endif 1149 1150 #if defined(FEAT_EVAL) || defined(PROTO) 1151 1152 /* 1153 * Set the "v:lang" variable according to the current locale setting. 1154 * Also do "v:lc_time"and "v:ctype". 1155 */ 1156 void 1157 set_lang_var(void) 1158 { 1159 char_u *loc; 1160 1161 # ifdef HAVE_GET_LOCALE_VAL 1162 loc = get_locale_val(LC_CTYPE); 1163 # else 1164 // setlocale() not supported: use the default value 1165 loc = (char_u *)"C"; 1166 # endif 1167 set_vim_var_string(VV_CTYPE, loc, -1); 1168 1169 // When LC_MESSAGES isn't defined use the value from $LC_MESSAGES, fall 1170 // back to LC_CTYPE if it's empty. 1171 # if defined(HAVE_GET_LOCALE_VAL) && defined(LC_MESSAGES) 1172 loc = get_locale_val(LC_MESSAGES); 1173 # else 1174 loc = get_mess_env(); 1175 # endif 1176 set_vim_var_string(VV_LANG, loc, -1); 1177 1178 # ifdef HAVE_GET_LOCALE_VAL 1179 loc = get_locale_val(LC_TIME); 1180 # endif 1181 set_vim_var_string(VV_LC_TIME, loc, -1); 1182 } 1183 #endif 1184 1185 #if defined(HAVE_LOCALE_H) || defined(X_LOCALE) \ 1186 /* 1187 * ":language": Set the language (locale). 1188 */ 1189 void 1190 ex_language(exarg_T *eap) 1191 { 1192 char *loc; 1193 char_u *p; 1194 char_u *name; 1195 int what = LC_ALL; 1196 char *whatstr = ""; 1197 #ifdef LC_MESSAGES 1198 # define VIM_LC_MESSAGES LC_MESSAGES 1199 #else 1200 # define VIM_LC_MESSAGES 6789 1201 #endif 1202 1203 name = eap->arg; 1204 1205 // Check for "messages {name}", "ctype {name}" or "time {name}" argument. 1206 // Allow abbreviation, but require at least 3 characters to avoid 1207 // confusion with a two letter language name "me" or "ct". 1208 p = skiptowhite(eap->arg); 1209 if ((*p == NUL || VIM_ISWHITE(*p)) && p - eap->arg >= 3) 1210 { 1211 if (STRNICMP(eap->arg, "messages", p - eap->arg) == 0) 1212 { 1213 what = VIM_LC_MESSAGES; 1214 name = skipwhite(p); 1215 whatstr = "messages "; 1216 } 1217 else if (STRNICMP(eap->arg, "ctype", p - eap->arg) == 0) 1218 { 1219 what = LC_CTYPE; 1220 name = skipwhite(p); 1221 whatstr = "ctype "; 1222 } 1223 else if (STRNICMP(eap->arg, "time", p - eap->arg) == 0) 1224 { 1225 what = LC_TIME; 1226 name = skipwhite(p); 1227 whatstr = "time "; 1228 } 1229 } 1230 1231 if (*name == NUL) 1232 { 1233 #ifndef LC_MESSAGES 1234 if (what == VIM_LC_MESSAGES) 1235 p = get_mess_env(); 1236 else 1237 #endif 1238 p = (char_u *)setlocale(what, NULL); 1239 if (p == NULL || *p == NUL) 1240 p = (char_u *)"Unknown"; 1241 smsg(_("Current %slanguage: \"%s\""), whatstr, p); 1242 } 1243 else 1244 { 1245 #ifndef LC_MESSAGES 1246 if (what == VIM_LC_MESSAGES) 1247 loc = ""; 1248 else 1249 #endif 1250 { 1251 loc = setlocale(what, (char *)name); 1252 #if defined(FEAT_FLOAT) && defined(LC_NUMERIC) 1253 // Make sure strtod() uses a decimal point, not a comma. 1254 setlocale(LC_NUMERIC, "C"); 1255 #endif 1256 } 1257 if (loc == NULL) 1258 semsg(_("E197: Cannot set language to \"%s\""), name); 1259 else 1260 { 1261 #ifdef HAVE_NL_MSG_CAT_CNTR 1262 // Need to do this for GNU gettext, otherwise cached translations 1263 // will be used again. 1264 extern int _nl_msg_cat_cntr; 1265 1266 ++_nl_msg_cat_cntr; 1267 #endif 1268 // Reset $LC_ALL, otherwise it would overrule everything. 1269 vim_setenv((char_u *)"LC_ALL", (char_u *)""); 1270 1271 if (what != LC_TIME) 1272 { 1273 // Tell gettext() what to translate to. It apparently doesn't 1274 // use the currently effective locale. Also do this when 1275 // FEAT_GETTEXT isn't defined, so that shell commands use this 1276 // value. 1277 if (what == LC_ALL) 1278 { 1279 vim_setenv((char_u *)"LANG", name); 1280 1281 // Clear $LANGUAGE because GNU gettext uses it. 1282 vim_setenv((char_u *)"LANGUAGE", (char_u *)""); 1283 # ifdef MSWIN 1284 // Apparently MS-Windows printf() may cause a crash when 1285 // we give it 8-bit text while it's expecting text in the 1286 // current locale. This call avoids that. 1287 setlocale(LC_CTYPE, "C"); 1288 # endif 1289 } 1290 if (what != LC_CTYPE) 1291 { 1292 char_u *mname; 1293 #ifdef MSWIN 1294 mname = gettext_lang(name); 1295 #else 1296 mname = name; 1297 #endif 1298 vim_setenv((char_u *)"LC_MESSAGES", mname); 1299 #ifdef FEAT_MULTI_LANG 1300 set_helplang_default(mname); 1301 #endif 1302 } 1303 } 1304 1305 # ifdef FEAT_EVAL 1306 // Set v:lang, v:lc_time and v:ctype to the final result. 1307 set_lang_var(); 1308 # endif 1309 # ifdef FEAT_TITLE 1310 maketitle(); 1311 # endif 1312 } 1313 } 1314 } 1315 1316 static char_u **locales = NULL; // Array of all available locales 1317 1318 # ifndef MSWIN 1319 static int did_init_locales = FALSE; 1320 1321 /* 1322 * Return an array of strings for all available locales + NULL for the 1323 * last element. Return NULL in case of error. 1324 */ 1325 static char_u ** 1326 find_locales(void) 1327 { 1328 garray_T locales_ga; 1329 char_u *loc; 1330 1331 // Find all available locales by running command "locale -a". If this 1332 // doesn't work we won't have completion. 1333 char_u *locale_a = get_cmd_output((char_u *)"locale -a", 1334 NULL, SHELL_SILENT, NULL); 1335 if (locale_a == NULL) 1336 return NULL; 1337 ga_init2(&locales_ga, sizeof(char_u *), 20); 1338 1339 // Transform locale_a string where each locale is separated by "\n" 1340 // into an array of locale strings. 1341 loc = (char_u *)strtok((char *)locale_a, "\n"); 1342 1343 while (loc != NULL) 1344 { 1345 if (ga_grow(&locales_ga, 1) == FAIL) 1346 break; 1347 loc = vim_strsave(loc); 1348 if (loc == NULL) 1349 break; 1350 1351 ((char_u **)locales_ga.ga_data)[locales_ga.ga_len++] = loc; 1352 loc = (char_u *)strtok(NULL, "\n"); 1353 } 1354 vim_free(locale_a); 1355 if (ga_grow(&locales_ga, 1) == FAIL) 1356 { 1357 ga_clear(&locales_ga); 1358 return NULL; 1359 } 1360 ((char_u **)locales_ga.ga_data)[locales_ga.ga_len] = NULL; 1361 return (char_u **)locales_ga.ga_data; 1362 } 1363 # endif 1364 1365 /* 1366 * Lazy initialization of all available locales. 1367 */ 1368 static void 1369 init_locales(void) 1370 { 1371 # ifndef MSWIN 1372 if (!did_init_locales) 1373 { 1374 did_init_locales = TRUE; 1375 locales = find_locales(); 1376 } 1377 # endif 1378 } 1379 1380 # if defined(EXITFREE) || defined(PROTO) 1381 void 1382 free_locales(void) 1383 { 1384 int i; 1385 if (locales != NULL) 1386 { 1387 for (i = 0; locales[i] != NULL; i++) 1388 vim_free(locales[i]); 1389 VIM_CLEAR(locales); 1390 } 1391 } 1392 # endif 1393 1394 /* 1395 * Function given to ExpandGeneric() to obtain the possible arguments of the 1396 * ":language" command. 1397 */ 1398 char_u * 1399 get_lang_arg(expand_T *xp UNUSED, int idx) 1400 { 1401 if (idx == 0) 1402 return (char_u *)"messages"; 1403 if (idx == 1) 1404 return (char_u *)"ctype"; 1405 if (idx == 2) 1406 return (char_u *)"time"; 1407 1408 init_locales(); 1409 if (locales == NULL) 1410 return NULL; 1411 return locales[idx - 3]; 1412 } 1413 1414 /* 1415 * Function given to ExpandGeneric() to obtain the available locales. 1416 */ 1417 char_u * 1418 get_locales(expand_T *xp UNUSED, int idx) 1419 { 1420 init_locales(); 1421 if (locales == NULL) 1422 return NULL; 1423 return locales[idx]; 1424 } 1425 1426 #endif 1427