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 CLEAR_FIELD(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_ALL_WINDOWS_IN_TAB(tp, wp) 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_ALL_BUFFERS(buf) 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 // Clear 'shm' to avoid that the file message overwrites 647 // any output from the command. 648 p_shm_save = vim_strsave(p_shm); 649 set_option_value((char_u *)"shm", 0L, (char_u *)"", 0); 650 ex_cnext(eap); 651 set_option_value((char_u *)"shm", 0L, p_shm_save, 0); 652 vim_free(p_shm_save); 653 654 // If jumping to the next quickfix entry fails, quit here 655 if (qf_get_cur_idx(eap) == qf_idx) 656 break; 657 } 658 #endif 659 660 if (eap->cmdidx == CMD_windo) 661 { 662 validate_cursor(); // cursor may have moved 663 664 // required when 'scrollbind' has been set 665 if (curwin->w_p_scb) 666 do_check_scrollbind(TRUE); 667 } 668 669 if (eap->cmdidx == CMD_windo || eap->cmdidx == CMD_tabdo) 670 if (i+1 > eap->line2) 671 break; 672 if (eap->cmdidx == CMD_argdo && i >= eap->line2) 673 break; 674 } 675 listcmd_busy = FALSE; 676 } 677 678 #if defined(FEAT_SYN_HL) 679 if (save_ei != NULL) 680 { 681 buf_T *bnext; 682 aco_save_T aco; 683 684 au_event_restore(save_ei); 685 686 for (buf = firstbuf; buf != NULL; buf = bnext) 687 { 688 bnext = buf->b_next; 689 if (buf->b_nwindows > 0 && (buf->b_flags & BF_SYN_SET)) 690 { 691 buf->b_flags &= ~BF_SYN_SET; 692 693 // buffer was opened while Syntax autocommands were disabled, 694 // need to trigger them now. 695 if (buf == curbuf) 696 apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn, 697 curbuf->b_fname, TRUE, curbuf); 698 else 699 { 700 aucmd_prepbuf(&aco, buf); 701 apply_autocmds(EVENT_SYNTAX, buf->b_p_syn, 702 buf->b_fname, TRUE, buf); 703 aucmd_restbuf(&aco); 704 } 705 706 // start over, in case autocommands messed things up. 707 bnext = firstbuf; 708 } 709 } 710 } 711 #endif 712 #ifdef FEAT_CLIPBOARD 713 end_global_changes(); 714 #endif 715 } 716 717 #ifdef FEAT_EVAL 718 /* 719 * ":compiler[!] {name}" 720 */ 721 void 722 ex_compiler(exarg_T *eap) 723 { 724 char_u *buf; 725 char_u *old_cur_comp = NULL; 726 char_u *p; 727 728 if (*eap->arg == NUL) 729 { 730 // List all compiler scripts. 731 do_cmdline_cmd((char_u *)"echo globpath(&rtp, 'compiler/*.vim')"); 732 // ) keep the indenter happy... 733 } 734 else 735 { 736 buf = alloc(STRLEN(eap->arg) + 14); 737 if (buf != NULL) 738 { 739 if (eap->forceit) 740 { 741 // ":compiler! {name}" sets global options 742 do_cmdline_cmd((char_u *) 743 "command -nargs=* CompilerSet set <args>"); 744 } 745 else 746 { 747 // ":compiler! {name}" sets local options. 748 // To remain backwards compatible "current_compiler" is always 749 // used. A user's compiler plugin may set it, the distributed 750 // plugin will then skip the settings. Afterwards set 751 // "b:current_compiler" and restore "current_compiler". 752 // Explicitly prepend "g:" to make it work in a function. 753 old_cur_comp = get_var_value((char_u *)"g:current_compiler"); 754 if (old_cur_comp != NULL) 755 old_cur_comp = vim_strsave(old_cur_comp); 756 do_cmdline_cmd((char_u *) 757 "command -nargs=* CompilerSet setlocal <args>"); 758 } 759 do_unlet((char_u *)"g:current_compiler", TRUE); 760 do_unlet((char_u *)"b:current_compiler", TRUE); 761 762 sprintf((char *)buf, "compiler/%s.vim", eap->arg); 763 if (source_runtime(buf, DIP_ALL) == FAIL) 764 semsg(_("E666: compiler not supported: %s"), eap->arg); 765 vim_free(buf); 766 767 do_cmdline_cmd((char_u *)":delcommand CompilerSet"); 768 769 // Set "b:current_compiler" from "current_compiler". 770 p = get_var_value((char_u *)"g:current_compiler"); 771 if (p != NULL) 772 set_internal_string_var((char_u *)"b:current_compiler", p); 773 774 // Restore "current_compiler" for ":compiler {name}". 775 if (!eap->forceit) 776 { 777 if (old_cur_comp != NULL) 778 { 779 set_internal_string_var((char_u *)"g:current_compiler", 780 old_cur_comp); 781 vim_free(old_cur_comp); 782 } 783 else 784 do_unlet((char_u *)"g:current_compiler", TRUE); 785 } 786 } 787 } 788 } 789 #endif 790 791 #if defined(FEAT_PYTHON3) || defined(FEAT_PYTHON) || defined(PROTO) 792 793 # if (defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)) || defined(PROTO) 794 /* 795 * Detect Python 3 or 2, and initialize 'pyxversion'. 796 */ 797 void 798 init_pyxversion(void) 799 { 800 if (p_pyx == 0) 801 { 802 if (python3_enabled(FALSE)) 803 p_pyx = 3; 804 else if (python_enabled(FALSE)) 805 p_pyx = 2; 806 } 807 } 808 # endif 809 810 /* 811 * Does a file contain one of the following strings at the beginning of any 812 * line? 813 * "#!(any string)python2" => returns 2 814 * "#!(any string)python3" => returns 3 815 * "# requires python 2.x" => returns 2 816 * "# requires python 3.x" => returns 3 817 * otherwise return 0. 818 */ 819 static int 820 requires_py_version(char_u *filename) 821 { 822 FILE *file; 823 int requires_py_version = 0; 824 int i, lines; 825 826 lines = (int)p_mls; 827 if (lines < 0) 828 lines = 5; 829 830 file = mch_fopen((char *)filename, "r"); 831 if (file != NULL) 832 { 833 for (i = 0; i < lines; i++) 834 { 835 if (vim_fgets(IObuff, IOSIZE, file)) 836 break; 837 if (i == 0 && IObuff[0] == '#' && IObuff[1] == '!') 838 { 839 // Check shebang. 840 if (strstr((char *)IObuff + 2, "python2") != NULL) 841 { 842 requires_py_version = 2; 843 break; 844 } 845 if (strstr((char *)IObuff + 2, "python3") != NULL) 846 { 847 requires_py_version = 3; 848 break; 849 } 850 } 851 IObuff[21] = '\0'; 852 if (STRCMP("# requires python 2.x", IObuff) == 0) 853 { 854 requires_py_version = 2; 855 break; 856 } 857 if (STRCMP("# requires python 3.x", IObuff) == 0) 858 { 859 requires_py_version = 3; 860 break; 861 } 862 } 863 fclose(file); 864 } 865 return requires_py_version; 866 } 867 868 869 /* 870 * Source a python file using the requested python version. 871 */ 872 static void 873 source_pyx_file(exarg_T *eap, char_u *fname) 874 { 875 exarg_T ex; 876 int v = requires_py_version(fname); 877 878 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3) 879 init_pyxversion(); 880 # endif 881 if (v == 0) 882 { 883 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3) 884 // user didn't choose a preference, 'pyx' is used 885 v = p_pyx; 886 # elif defined(FEAT_PYTHON) 887 v = 2; 888 # elif defined(FEAT_PYTHON3) 889 v = 3; 890 # endif 891 } 892 893 /* 894 * now source, if required python version is not supported show 895 * unobtrusive message. 896 */ 897 if (eap == NULL) 898 CLEAR_FIELD(ex); 899 else 900 ex = *eap; 901 ex.arg = fname; 902 ex.cmd = (char_u *)(v == 2 ? "pyfile" : "pyfile3"); 903 904 if (v == 2) 905 { 906 # ifdef FEAT_PYTHON 907 ex_pyfile(&ex); 908 # else 909 vim_snprintf((char *)IObuff, IOSIZE, 910 _("W20: Required python version 2.x not supported, ignoring file: %s"), 911 fname); 912 msg((char *)IObuff); 913 # endif 914 return; 915 } 916 else 917 { 918 # ifdef FEAT_PYTHON3 919 ex_py3file(&ex); 920 # else 921 vim_snprintf((char *)IObuff, IOSIZE, 922 _("W21: Required python version 3.x not supported, ignoring file: %s"), 923 fname); 924 msg((char *)IObuff); 925 # endif 926 return; 927 } 928 } 929 930 /* 931 * ":pyxfile {fname}" 932 */ 933 void 934 ex_pyxfile(exarg_T *eap) 935 { 936 source_pyx_file(eap, eap->arg); 937 } 938 939 /* 940 * ":pyx" 941 */ 942 void 943 ex_pyx(exarg_T *eap) 944 { 945 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3) 946 init_pyxversion(); 947 if (p_pyx == 2) 948 ex_python(eap); 949 else 950 ex_py3(eap); 951 # elif defined(FEAT_PYTHON) 952 ex_python(eap); 953 # elif defined(FEAT_PYTHON3) 954 ex_py3(eap); 955 # endif 956 } 957 958 /* 959 * ":pyxdo" 960 */ 961 void 962 ex_pyxdo(exarg_T *eap) 963 { 964 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3) 965 init_pyxversion(); 966 if (p_pyx == 2) 967 ex_pydo(eap); 968 else 969 ex_py3do(eap); 970 # elif defined(FEAT_PYTHON) 971 ex_pydo(eap); 972 # elif defined(FEAT_PYTHON3) 973 ex_py3do(eap); 974 # endif 975 } 976 977 #endif 978 979 /* 980 * ":checktime [buffer]" 981 */ 982 void 983 ex_checktime(exarg_T *eap) 984 { 985 buf_T *buf; 986 int save_no_check_timestamps = no_check_timestamps; 987 988 no_check_timestamps = 0; 989 if (eap->addr_count == 0) // default is all buffers 990 check_timestamps(FALSE); 991 else 992 { 993 buf = buflist_findnr((int)eap->line2); 994 if (buf != NULL) // cannot happen? 995 (void)buf_check_timestamp(buf, FALSE); 996 } 997 no_check_timestamps = save_no_check_timestamps; 998 } 999