diff --git a/src/Make_all.mak b/src/Make_all.mak index 8f0f4c1ddc..f5f0552b96 100644 --- a/src/Make_all.mak +++ b/src/Make_all.mak @@ -168,6 +168,7 @@ NEW_TESTS = \ test_stat \ test_statusline \ test_substitute \ + test_suspend \ test_swap \ test_syn_attr \ test_syntax \ diff --git a/src/ex_getln.c b/src/ex_getln.c index dd61afeca6..84e151d032 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -1308,7 +1308,11 @@ getcmdline( /* CTRL-\ e doesn't work when obtaining an expression, unless it * is in a mapping. */ if (c != Ctrl_N && c != Ctrl_G && (c != 'e' - || (ccline.cmdfirstc == '=' && KeyTyped))) + || (ccline.cmdfirstc == '=' && KeyTyped) +#ifdef FEAT_EVAL + || cmdline_star > 0 +#endif + )) { vungetc(c); c = Ctrl_BSL; @@ -1801,7 +1805,8 @@ getcmdline( new_cmdpos = -1; if (c == '=') { - if (ccline.cmdfirstc == '=')/* can't do this recursively */ + if (ccline.cmdfirstc == '=' // can't do this recursively + || cmdline_star > 0) // or when typing a password { beep_flush(); c = ESC; @@ -6516,8 +6521,11 @@ get_ccline_ptr(void) char_u * get_cmdline_str(void) { - struct cmdline_info *p = get_ccline_ptr(); + struct cmdline_info *p; + if (cmdline_star > 0) + return NULL; + p = get_ccline_ptr(); if (p == NULL) return NULL; return vim_strnsave(p->cmdbuff, p->cmdlen); diff --git a/src/gui_w32.c b/src/gui_w32.c index 8574b63fac..35c1790b49 100644 --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -3627,7 +3627,7 @@ gui_mch_browseW( WCHAR *extp = NULL; WCHAR *initdirp = NULL; WCHAR *filterp; - char_u *p; + char_u *p, *q; if (dflt == NULL) fileBuf[0] = NUL; @@ -3713,16 +3713,16 @@ gui_mch_browseW( /* Convert from UCS2 to 'encoding'. */ p = utf16_to_enc(fileBuf, NULL); - if (p != NULL) - /* when out of memory we get garbage for non-ASCII chars */ - STRCPY(fileBuf, p); - vim_free(p); + if (p == NULL) + return NULL; /* Give focus back to main window (when using MDI). */ SetFocus(s_hwnd); /* Shorten the file name if possible */ - return vim_strsave(shorten_fname1((char_u *)fileBuf)); + q = vim_strsave(shorten_fname1(p)); + vim_free(p); + return q; } # endif /* FEAT_MBYTE */ diff --git a/src/move.c b/src/move.c index 3cab00ab3c..03e7c11529 100644 --- a/src/move.c +++ b/src/move.c @@ -128,6 +128,12 @@ comp_botline(win_T *wp) #ifdef FEAT_SYN_HL static linenr_T last_cursorline = 0; + + void +reset_cursorline(void) +{ + last_cursorline = 0; +} #endif /* diff --git a/src/option.c b/src/option.c index dbe718ae8c..1568a1fa52 100644 --- a/src/option.c +++ b/src/option.c @@ -8429,6 +8429,11 @@ set_bool_option( p_lrm = !p_lnr; #endif +#ifdef FEAT_SYN_HL + else if ((int *)varp == &curwin->w_p_cul && !value && old_value) + reset_cursorline(); +#endif + #ifdef FEAT_PERSISTENT_UNDO /* 'undofile' */ else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf) diff --git a/src/os_unix.c b/src/os_unix.c index be4675f94f..38052fb459 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -8054,7 +8054,7 @@ xsmp_init(void) &smcallbacks, NULL, &xsmp.clientid, - sizeof(errorstring), + sizeof(errorstring) - 1, errorstring); if (xsmp.smcconn == NULL) { diff --git a/src/proto/move.pro b/src/proto/move.pro index 3bc3fd9c33..f66e9cd183 100644 --- a/src/proto/move.pro +++ b/src/proto/move.pro @@ -1,4 +1,5 @@ /* move.c */ +void reset_cursorline(void); void update_topline_redraw(void); void update_topline(void); void update_curswant(void); diff --git a/src/proto/quickfix.pro b/src/proto/quickfix.pro index 26a5de0bf6..c9c3a8c962 100644 --- a/src/proto/quickfix.pro +++ b/src/proto/quickfix.pro @@ -1,7 +1,7 @@ /* quickfix.c */ int qf_init(win_T *wp, char_u *efile, char_u *errorformat, int newlist, char_u *qf_title, char_u *enc); void qf_free_all(win_T *wp); -void copy_loclist(win_T *from, win_T *to); +void copy_loclist_stack(win_T *from, win_T *to); void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit); void qf_list(exarg_T *eap); void qf_age(exarg_T *eap); diff --git a/src/quickfix.c b/src/quickfix.c index 9c346519fa..1c3343f344 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -2044,122 +2044,136 @@ ll_get_or_alloc_list(win_T *wp) } /* - * Copy the location list from window "from" to window "to". + * Copy location list entries from 'from_qfl' to 'to_qfl'. + */ + static int +copy_loclist_entries(qf_list_T *from_qfl, qf_list_T *to_qfl, qf_info_T *to_qi) +{ + int i; + qfline_T *from_qfp; + qfline_T *prevp; + + // copy all the location entries in this list + for (i = 0, from_qfp = from_qfl->qf_start; + i < from_qfl->qf_count && from_qfp != NULL; + ++i, from_qfp = from_qfp->qf_next) + { + if (qf_add_entry(to_qi, + to_qi->qf_curlist, + NULL, + NULL, + from_qfp->qf_module, + 0, + from_qfp->qf_text, + from_qfp->qf_lnum, + from_qfp->qf_col, + from_qfp->qf_viscol, + from_qfp->qf_pattern, + from_qfp->qf_nr, + 0, + from_qfp->qf_valid) == FAIL) + return FAIL; + + // qf_add_entry() will not set the qf_num field, as the + // directory and file names are not supplied. So the qf_fnum + // field is copied here. + prevp = to_qfl->qf_last; + prevp->qf_fnum = from_qfp->qf_fnum; // file number + prevp->qf_type = from_qfp->qf_type; // error type + if (from_qfl->qf_ptr == from_qfp) + to_qfl->qf_ptr = prevp; // current location + } + + return OK; +} + +/* + * Copy the specified location list 'from_qfl' to 'to_qfl'. + */ + static int +copy_loclist(qf_list_T *from_qfl, qf_list_T *to_qfl, qf_info_T *to_qi) +{ + // Some of the fields are populated by qf_add_entry() + to_qfl->qf_nonevalid = from_qfl->qf_nonevalid; + to_qfl->qf_count = 0; + to_qfl->qf_index = 0; + to_qfl->qf_start = NULL; + to_qfl->qf_last = NULL; + to_qfl->qf_ptr = NULL; + if (from_qfl->qf_title != NULL) + to_qfl->qf_title = vim_strsave(from_qfl->qf_title); + else + to_qfl->qf_title = NULL; + if (from_qfl->qf_ctx != NULL) + { + to_qfl->qf_ctx = alloc_tv(); + if (to_qfl->qf_ctx != NULL) + copy_tv(from_qfl->qf_ctx, to_qfl->qf_ctx); + } + else + to_qfl->qf_ctx = NULL; + + if (from_qfl->qf_count) + if (copy_loclist_entries(from_qfl, to_qfl, to_qi) == FAIL) + return FAIL; + + to_qfl->qf_index = from_qfl->qf_index; // current index in the list + + // Assign a new ID for the location list + to_qfl->qf_id = ++last_qf_id; + to_qfl->qf_changedtick = 0L; + + // When no valid entries are present in the list, qf_ptr points to + // the first item in the list + if (to_qfl->qf_nonevalid) + { + to_qfl->qf_ptr = to_qfl->qf_start; + to_qfl->qf_index = 1; + } + + return OK; +} + +/* + * Copy the location list stack 'from' window to 'to' window. */ void -copy_loclist(win_T *from, win_T *to) +copy_loclist_stack(win_T *from, win_T *to) { qf_info_T *qi; int idx; - int i; - /* - * When copying from a location list window, copy the referenced - * location list. For other windows, copy the location list for - * that window. - */ + // When copying from a location list window, copy the referenced + // location list. For other windows, copy the location list for + // that window. if (IS_LL_WINDOW(from)) qi = from->w_llist_ref; else qi = from->w_llist; - if (qi == NULL) /* no location list to copy */ + if (qi == NULL) // no location list to copy return; - /* allocate a new location list */ + // allocate a new location list if ((to->w_llist = ll_new_list()) == NULL) return; to->w_llist->qf_listcount = qi->qf_listcount; - /* Copy the location lists one at a time */ + // Copy the location lists one at a time for (idx = 0; idx < qi->qf_listcount; ++idx) { - qf_list_T *from_qfl; - qf_list_T *to_qfl; - to->w_llist->qf_curlist = idx; - from_qfl = &qi->qf_lists[idx]; - to_qfl = &to->w_llist->qf_lists[idx]; - - /* Some of the fields are populated by qf_add_entry() */ - to_qfl->qf_nonevalid = from_qfl->qf_nonevalid; - to_qfl->qf_count = 0; - to_qfl->qf_index = 0; - to_qfl->qf_start = NULL; - to_qfl->qf_last = NULL; - to_qfl->qf_ptr = NULL; - if (from_qfl->qf_title != NULL) - to_qfl->qf_title = vim_strsave(from_qfl->qf_title); - else - to_qfl->qf_title = NULL; - if (from_qfl->qf_ctx != NULL) + if (copy_loclist(&qi->qf_lists[idx], + &to->w_llist->qf_lists[idx], to->w_llist) == FAIL) { - to_qfl->qf_ctx = alloc_tv(); - if (to_qfl->qf_ctx != NULL) - copy_tv(from_qfl->qf_ctx, to_qfl->qf_ctx); - } - else - to_qfl->qf_ctx = NULL; - - if (from_qfl->qf_count) - { - qfline_T *from_qfp; - qfline_T *prevp; - - /* copy all the location entries in this list */ - for (i = 0, from_qfp = from_qfl->qf_start; - i < from_qfl->qf_count && from_qfp != NULL; - ++i, from_qfp = from_qfp->qf_next) - { - if (qf_add_entry(to->w_llist, - to->w_llist->qf_curlist, - NULL, - NULL, - from_qfp->qf_module, - 0, - from_qfp->qf_text, - from_qfp->qf_lnum, - from_qfp->qf_col, - from_qfp->qf_viscol, - from_qfp->qf_pattern, - from_qfp->qf_nr, - 0, - from_qfp->qf_valid) == FAIL) - { - qf_free_all(to); - return; - } - /* - * qf_add_entry() will not set the qf_num field, as the - * directory and file names are not supplied. So the qf_fnum - * field is copied here. - */ - prevp = to->w_llist->qf_lists[to->w_llist->qf_curlist].qf_last; - prevp->qf_fnum = from_qfp->qf_fnum; /* file number */ - prevp->qf_type = from_qfp->qf_type; /* error type */ - if (from_qfl->qf_ptr == from_qfp) - to_qfl->qf_ptr = prevp; /* current location */ - } - } - - to_qfl->qf_index = from_qfl->qf_index; /* current index in the list */ - - /* Assign a new ID for the location list */ - to_qfl->qf_id = ++last_qf_id; - to_qfl->qf_changedtick = 0L; - - /* When no valid entries are present in the list, qf_ptr points to - * the first item in the list */ - if (to_qfl->qf_nonevalid) - { - to_qfl->qf_ptr = to_qfl->qf_start; - to_qfl->qf_index = 1; + qf_free_all(to); + return; } } - to->w_llist->qf_curlist = qi->qf_curlist; /* current list */ + to->w_llist->qf_curlist = qi->qf_curlist; // current list } /* @@ -2521,10 +2535,11 @@ get_prev_valid_entry( get_nth_valid_entry( qf_list_T *qfl, int errornr, - qfline_T *qf_ptr, - int *qf_index, - int dir) + int dir, + int *new_qfidx) { + qfline_T *qf_ptr = qfl->qf_ptr; + int qf_idx = qfl->qf_index; qfline_T *prev_qf_ptr; int prev_index; static char_u *e_no_more_items = (char_u *)N_("E553: No more items"); @@ -2533,16 +2548,16 @@ get_nth_valid_entry( while (errornr--) { prev_qf_ptr = qf_ptr; - prev_index = *qf_index; + prev_index = qf_idx; if (dir == FORWARD || dir == FORWARD_FILE) - qf_ptr = get_next_valid_entry(qfl, qf_ptr, qf_index, dir); + qf_ptr = get_next_valid_entry(qfl, qf_ptr, &qf_idx, dir); else - qf_ptr = get_prev_valid_entry(qfl, qf_ptr, qf_index, dir); + qf_ptr = get_prev_valid_entry(qfl, qf_ptr, &qf_idx, dir); if (qf_ptr == NULL) { qf_ptr = prev_qf_ptr; - *qf_index = prev_index; + qf_idx = prev_index; if (err != NULL) { EMSG(_(err)); @@ -2554,28 +2569,27 @@ get_nth_valid_entry( err = NULL; } + *new_qfidx = qf_idx; return qf_ptr; } /* - * Get n'th (errornr) quickfix entry + * Get n'th (errornr) quickfix entry from the current entry in the quickfix + * list 'qfl'. Returns a pointer to the new entry and the index in 'new_qfidx' */ static qfline_T * -get_nth_entry( - qf_list_T *qfl, - int errornr, - qfline_T *qf_ptr, - int *cur_qfidx) +get_nth_entry(qf_list_T *qfl, int errornr, int *new_qfidx) { - int qf_idx = *cur_qfidx; + qfline_T *qf_ptr = qfl->qf_ptr; + int qf_idx = qfl->qf_index; - /* New error number is less than the current error number */ + // New error number is less than the current error number while (errornr < qf_idx && qf_idx > 1 && qf_ptr->qf_prev != NULL) { --qf_idx; qf_ptr = qf_ptr->qf_prev; } - /* New error number is greater than the current error number */ + // New error number is greater than the current error number while (errornr > qf_idx && qf_idx < qfl->qf_count && qf_ptr->qf_next != NULL) { @@ -2583,7 +2597,33 @@ get_nth_entry( qf_ptr = qf_ptr->qf_next; } - *cur_qfidx = qf_idx; + *new_qfidx = qf_idx; + return qf_ptr; +} + +/* + * Get a entry specied by 'errornr' and 'dir' from the current + * quickfix/location list. 'errornr' specifies the index of the entry and 'dir' + * specifies the direction (FORWARD/BACKWARD/FORWARD_FILE/BACKWARD_FILE). + * Returns a pointer to the entry and the index of the new entry is stored in + * 'new_qfidx'. + */ + static qfline_T * +qf_get_entry( + qf_list_T *qfl, + int errornr, + int dir, + int *new_qfidx) +{ + qfline_T *qf_ptr = qfl->qf_ptr; + int qfidx = qfl->qf_index; + + if (dir != 0) // next/prev valid entry + qf_ptr = get_nth_valid_entry(qfl, errornr, dir, &qfidx); + else if (errornr != 0) // go to specified number + qf_ptr = get_nth_entry(qfl, errornr, &qfidx); + + *new_qfidx = qfidx; return qf_ptr; } @@ -2881,6 +2921,9 @@ qf_jump_to_usable_window(int qf_fnum, int *opened_window) /* * Edit the selected file or help file. + * Returns OK if successfully edited the file, FAIL on failing to open the + * buffer and NOTDONE if the quickfix/location list was freed by an autocmd + * when opening the buffer. */ static int qf_jump_edit_buffer( @@ -2888,8 +2931,7 @@ qf_jump_edit_buffer( qfline_T *qf_ptr, int forceit, win_T *oldwin, - int *opened_window, - int *abort) + int *opened_window) { qf_list_T *qfl = &qi->qf_lists[qi->qf_curlist]; int retval = OK; @@ -2925,13 +2967,13 @@ qf_jump_edit_buffer( if (!win_valid_any_tab(oldwin)) { EMSG(_("E924: Current window was closed")); - *abort = TRUE; *opened_window = FALSE; + return NOTDONE; } else if (!qflist_valid(oldwin, save_qfid)) { EMSG(_(e_loc_list_changed)); - *abort = TRUE; + return NOTDONE; } } else if (old_qf_curlist != qi->qf_curlist @@ -2941,11 +2983,8 @@ qf_jump_edit_buffer( EMSG(_("E925: Current quickfix was changed")); else EMSG(_(e_loc_list_changed)); - *abort = TRUE; + return NOTDONE; } - - if (*abort) - retval = FAIL; } return retval; @@ -3065,6 +3104,90 @@ qf_jump_print_msg( msg_scroll = i; } +/* + * Find a usable window for opening a file from the quickfix/location list. If + * a window is not found then open a new window. + * Returns OK if successfully jumped or opened a window. Returns FAIL if not + * able to jump/open a window. Returns NOTDONE if a file is not associated + * with the entry. + */ + static int +qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, int *opened_window) +{ + // For ":helpgrep" find a help window or open one. + if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0)) + if (jump_to_help_window(qi, opened_window) == FAIL) + return FAIL; + + // If currently in the quickfix window, find another window to show the + // file in. + if (bt_quickfix(curbuf) && !*opened_window) + { + // If there is no file specified, we don't know where to go. + // But do advance, otherwise ":cn" gets stuck. + if (qf_ptr->qf_fnum == 0) + return NOTDONE; + + if (qf_jump_to_usable_window(qf_ptr->qf_fnum, opened_window) == FAIL) + return FAIL; + } + + return OK; +} + +/* + * Edit a selected file from the quickfix/location list and jump to a + * particular line/column, adjust the folds and display a message about the + * jump. + * Returns OK on success and FAIL on failing to open the file/buffer. Returns + * NOTDONE if the quickfix/location list is freed by an autocmd when opening + * the file. + */ + static int +qf_jump_to_buffer( + qf_info_T *qi, + int qf_index, + qfline_T *qf_ptr, + int forceit, + win_T *oldwin, + int *opened_window, + int openfold, + int print_message) +{ + buf_T *old_curbuf; + linenr_T old_lnum; + int retval = OK; + + // If there is a file name, read the wanted file if needed, and check + // autowrite etc. + old_curbuf = curbuf; + old_lnum = curwin->w_cursor.lnum; + + if (qf_ptr->qf_fnum != 0) + { + retval = qf_jump_edit_buffer(qi, qf_ptr, forceit, oldwin, + opened_window); + if (retval != OK) + return retval; + } + + // When not switched to another buffer, still need to set pc mark + if (curbuf == old_curbuf) + setpcmark(); + + qf_jump_goto_line(qf_ptr->qf_lnum, qf_ptr->qf_col, qf_ptr->qf_viscol, + qf_ptr->qf_pattern); + +#ifdef FEAT_FOLDING + if ((fdo_flags & FDO_QUICKFIX) && openfold) + foldOpenCursor(); +#endif + if (print_message) + qf_jump_print_msg(qi, qf_index, qf_ptr, old_curbuf, old_lnum); + + return retval; +} + /* * jump to a quickfix line * if dir == FORWARD go "errornr" valid entries forward @@ -3085,15 +3208,13 @@ qf_jump(qf_info_T *qi, qfline_T *old_qf_ptr; int qf_index; int old_qf_index; - buf_T *old_curbuf; - linenr_T old_lnum; char_u *old_swb = p_swb; unsigned old_swb_flags = swb_flags; int opened_window = FALSE; win_T *oldwin = curwin; int print_message = TRUE; #ifdef FEAT_FOLDING - int old_KeyTyped = KeyTyped; /* getting file may reset it */ + int old_KeyTyped = KeyTyped; // getting file may reset it #endif int retval = OK; @@ -3113,96 +3234,44 @@ qf_jump(qf_info_T *qi, old_qf_ptr = qf_ptr; qf_index = qfl->qf_index; old_qf_index = qf_index; - if (dir != 0) /* next/prev valid entry */ + + qf_ptr = qf_get_entry(qfl, errornr, dir, &qf_index); + if (qf_ptr == NULL) { - qf_ptr = get_nth_valid_entry(qfl, errornr, qf_ptr, &qf_index, dir); - if (qf_ptr == NULL) - { - qf_ptr = old_qf_ptr; - qf_index = old_qf_index; - goto theend; - } + qf_ptr = old_qf_ptr; + qf_index = old_qf_index; + goto theend; } - else if (errornr != 0) /* go to specified number */ - qf_ptr = get_nth_entry(qfl, errornr, qf_ptr, &qf_index); qfl->qf_index = qf_index; if (qf_win_pos_update(qi, old_qf_index)) - /* No need to print the error message if it's visible in the error - * window */ + // No need to print the error message if it's visible in the error + // window print_message = FALSE; - /* - * For ":helpgrep" find a help window or open one. - */ - if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0)) - if (jump_to_help_window(qi, &opened_window) == FAIL) - goto theend; + retval = qf_jump_open_window(qi, qf_ptr, &opened_window); + if (retval == FAIL) + goto failed; + if (retval == NOTDONE) + goto theend; - /* - * If currently in the quickfix window, find another window to show the - * file in. - */ - if (bt_quickfix(curbuf) && !opened_window) + retval = qf_jump_to_buffer(qi, qf_index, qf_ptr, forceit, oldwin, + &opened_window, old_KeyTyped, print_message); + if (retval == NOTDONE) { - /* - * If there is no file specified, we don't know where to go. - * But do advance, otherwise ":cn" gets stuck. - */ - if (qf_ptr->qf_fnum == 0) - goto theend; - - if (qf_jump_to_usable_window(qf_ptr->qf_fnum, &opened_window) == FAIL) - goto failed; + // Quickfix/location list is freed by an autocmd + qi = NULL; + qf_ptr = NULL; } - /* - * If there is a file name, - * read the wanted file if needed, and check autowrite etc. - */ - old_curbuf = curbuf; - old_lnum = curwin->w_cursor.lnum; - - if (qf_ptr->qf_fnum != 0) - { - int abort = FALSE; - - retval = qf_jump_edit_buffer(qi, qf_ptr, forceit, oldwin, - &opened_window, &abort); - if (abort) - { - qi = NULL; - qf_ptr = NULL; - } - } - - if (retval == OK) - { - /* When not switched to another buffer, still need to set pc mark */ - if (curbuf == old_curbuf) - setpcmark(); - - if (qf_ptr != NULL) - qf_jump_goto_line(qf_ptr->qf_lnum, qf_ptr->qf_col, - qf_ptr->qf_viscol, qf_ptr->qf_pattern); - -#ifdef FEAT_FOLDING - if ((fdo_flags & FDO_QUICKFIX) && old_KeyTyped) - foldOpenCursor(); -#endif - if (print_message) - qf_jump_print_msg(qi, qf_index, qf_ptr, old_curbuf, old_lnum); - } - else + if (retval != OK) { if (opened_window) - win_close(curwin, TRUE); /* Close opened window */ + win_close(curwin, TRUE); // Close opened window if (qf_ptr != NULL && qf_ptr->qf_fnum != 0) { - /* - * Couldn't open file, so put index back where it was. This could - * happen if the file was readonly and we changed something. - */ + // Couldn't open file, so put index back where it was. This could + // happen if the file was readonly and we changed something. failed: qf_ptr = old_qf_ptr; qf_index = old_qf_index; @@ -3216,8 +3285,8 @@ theend: } if (p_swb != old_swb && opened_window) { - /* Restore old 'switchbuf' value, but not when an autocommand or - * modeline has changed the value. */ + // Restore old 'switchbuf' value, but not when an autocommand or + // modeline has changed the value. if (p_swb == empty_option) { p_swb = old_swb; diff --git a/src/testdir/test_alot.vim b/src/testdir/test_alot.vim index ea829e060d..3a0c6e0422 100644 --- a/src/testdir/test_alot.vim +++ b/src/testdir/test_alot.vim @@ -52,6 +52,7 @@ source test_set.vim source test_sort.vim source test_sha256.vim source test_statusline.vim +source test_suspend.vim source test_syn_attr.vim source test_tabline.vim source test_tabpage.vim diff --git a/src/testdir/test_arglist.vim b/src/testdir/test_arglist.vim index c558aab7d5..057cb0d5d6 100644 --- a/src/testdir/test_arglist.vim +++ b/src/testdir/test_arglist.vim @@ -94,6 +94,7 @@ func Test_argadd_empty_curbuf() call assert_equal('Xargadd', bufname('%')) call assert_equal(2, line('$')) + call delete('Xargadd') %argd bwipe! endfunc diff --git a/src/testdir/test_getcwd.vim b/src/testdir/test_getcwd.vim index 334b890772..5d97295e9a 100644 --- a/src/testdir/test_getcwd.vim +++ b/src/testdir/test_getcwd.vim @@ -98,3 +98,15 @@ function Test_GetCwd() call assert_equal("z Xdir3 1", GetCwdInfo(1, tp_nr)) call assert_equal(g:topdir, getcwd(-1)) endfunc + +function Test_GetCwd_lcd_shellslash() + new + let root = fnamemodify('/', ':p') + exe 'lcd '.root + let cwd = getcwd() + if !exists('+shellslash') || &shellslash + call assert_equal(cwd[-1:], '/') + else + call assert_equal(cwd[-1:], '\') + endif +endfunc diff --git a/src/testdir/test_startup.vim b/src/testdir/test_startup.vim index 4a296ec013..6f06ab877e 100644 --- a/src/testdir/test_startup.vim +++ b/src/testdir/test_startup.vim @@ -272,7 +272,7 @@ endfunc " Test the -V[N]{filename} argument to set the 'verbose' option to N " and set 'verbosefile' to filename. func Test_V_file_arg() - if RunVim([], [], ' --clean -X -V2Xverbosefile -c "set verbose? verbosefile?" -cq') + if RunVim([], [], ' --clean -V2Xverbosefile -c "set verbose? verbosefile?" -cq') let out = join(readfile('Xverbosefile'), "\n") call assert_match("sourcing \"$VIMRUNTIME[\\/]defaults\.vim\"\n", out) call assert_match("\n verbose=2\n", out) diff --git a/src/testdir/test_suspend.vim b/src/testdir/test_suspend.vim new file mode 100644 index 0000000000..462173e8cc --- /dev/null +++ b/src/testdir/test_suspend.vim @@ -0,0 +1,51 @@ +" Test :suspend + +source shared.vim + +func Test_suspend() + if !has('terminal') || !executable('/bin/sh') + return + endif + + let buf = term_start('/bin/sh') + " Wait for shell prompt. + call WaitForAssert({-> assert_match('$ $', term_getline(buf, '.'))}) + + call term_sendkeys(buf, v:progpath + \ . " --clean -X" + \ . " -c 'set nu'" + \ . " -c 'call setline(1, \"foo\")'" + \ . " Xfoo\") + " Cursor in terminal buffer should be on first line in spawned vim. + call WaitForAssert({-> assert_equal(' 1 foo', term_getline(buf, '.'))}) + + for suspend_cmd in [":suspend\", + \ ":stop\", + \ ":suspend!\", + \ ":stop!\", + \ "\"] + " Suspend and wait for shell prompt. + call term_sendkeys(buf, suspend_cmd) + call WaitForAssert({-> assert_match('$ $', term_getline(buf, '.'))}) + + " Without 'autowrite', buffer should not be written. + call assert_equal(0, filereadable('Xfoo')) + + call term_sendkeys(buf, "fg\") + call WaitForAssert({-> assert_equal(' 1 foo', term_getline(buf, '.'))}) + endfor + + " Test that :suspend! with 'autowrite' writes content of buffers if modified. + call term_sendkeys(buf, ":set autowrite\") + call assert_equal(0, filereadable('Xfoo')) + call term_sendkeys(buf, ":suspend\") + " Wait for shell prompt. + call WaitForAssert({-> assert_match('$ $', term_getline(buf, '.'))}) + call assert_equal(['foo'], readfile('Xfoo')) + call term_sendkeys(buf, "fg\") + call WaitForAssert({-> assert_equal(' 1 foo', term_getline(buf, '.'))}) + + exe buf . 'bwipe!' + call delete('Xfoo') + set autowrite& +endfunc diff --git a/src/version.c b/src/version.c index 70b5e11cac..95b39f40ac 100644 --- a/src/version.c +++ b/src/version.c @@ -809,6 +809,28 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 436, +/**/ + 435, +/**/ + 434, +/**/ + 433, +/**/ + 432, +/**/ + 431, +/**/ + 430, +/**/ + 429, +/**/ + 428, +/**/ + 427, +/**/ + 426, /**/ 425, /**/ diff --git a/src/window.c b/src/window.c index 4be5d00fb6..b91713ea80 100644 --- a/src/window.c +++ b/src/window.c @@ -1313,7 +1313,7 @@ win_init(win_T *newp, win_T *oldp, int flags UNUSED) newp->w_llist_ref = NULL; } else - copy_loclist(oldp, newp); + copy_loclist_stack(oldp, newp); #endif newp->w_localdir = (oldp->w_localdir == NULL) ? NULL : vim_strsave(oldp->w_localdir); diff --git a/src/xdiff/xemit.c b/src/xdiff/xemit.c index dae7f80430..d8a6f1ed38 100644 --- a/src/xdiff/xemit.c +++ b/src/xdiff/xemit.c @@ -31,7 +31,7 @@ static long xdl_get_rec(xdfile_t *xdf, long ri, char const **rec) { static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *ecb) { - long size, psize = strlen(pre); + long size, psize = (long)strlen(pre); char const *rec; size = xdl_get_rec(xdf, ri, &rec);