diff options
Diffstat (limited to 'src')
30 files changed, 416 insertions, 316 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 83de3347bd..208df31596 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -174,7 +174,7 @@ if(NOT DEFINED ENV{SKIP_EXEC}) add_executable(nvim ${NEOVIM_GENERATED_SOURCES} ${NEOVIM_SOURCES} ${NEOVIM_HEADERS}) target_link_libraries(nvim ${NVIM_LINK_LIBRARIES}) - install(TARGETS nvim RUNTIME DESTINATION bin) + install_helper(TARGETS nvim) endif() if(NOT DEFINED ENV{SKIP_UNITTEST}) diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c index 72168d936a..3e5d00671a 100644 --- a/src/nvim/api/tabpage.c +++ b/src/nvim/api/tabpage.c @@ -7,6 +7,7 @@ #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/memory.h" +#include "nvim/window.h" /// Gets the number of windows in a tabpage /// @@ -18,27 +19,18 @@ ArrayOf(Window) tabpage_get_windows(Tabpage tabpage, Error *err) Array rv = ARRAY_DICT_INIT; tabpage_T *tab = find_tab_by_handle(tabpage, err); - if (!tab) { + if (!tab || !valid_tabpage(tab)) { return rv; } - tabpage_T *tp; - win_T *wp; - - FOR_ALL_TAB_WINDOWS(tp, wp) { - if (tp != tab) { - break; - } + FOR_ALL_WINDOWS_IN_TAB(wp, tab) { rv.size++; } rv.items = xmalloc(sizeof(Object) * rv.size); size_t i = 0; - FOR_ALL_TAB_WINDOWS(tp, wp) { - if (tp != tab) { - break; - } + FOR_ALL_WINDOWS_IN_TAB(wp, tab) { rv.items[i++] = WINDOW_OBJ(wp->handle); } @@ -90,18 +82,15 @@ Window tabpage_get_window(Tabpage tabpage, Error *err) Window rv = 0; tabpage_T *tab = find_tab_by_handle(tabpage, err); - if (!tab) { + if (!tab || !valid_tabpage(tab)) { return rv; } if (tab == curtab) { return vim_get_current_window(); } else { - tabpage_T *tp; - win_T *wp; - - FOR_ALL_TAB_WINDOWS(tp, wp) { - if (tp == tab && wp == tab->tp_curwin) { + FOR_ALL_WINDOWS_IN_TAB(wp, tab) { + if (wp == tab->tp_curwin) { return wp->handle; } } diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 93aa0439f0..5e0f3e0c32 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -380,8 +380,6 @@ void vim_set_current_buffer(Buffer buffer, Error *err) ArrayOf(Window) vim_get_windows(void) { Array rv = ARRAY_DICT_INIT; - tabpage_T *tp; - win_T *wp; FOR_ALL_TAB_WINDOWS(tp, wp) { rv.size++; diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 31fa54295a..83cddb85bf 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -514,13 +514,9 @@ void buf_freeall(buf_T *buf, int flags) reset_synblock(curwin); /* No folds in an empty buffer. */ - { - win_T *win; - tabpage_T *tp; - - FOR_ALL_TAB_WINDOWS(tp, win) { - if (win->w_buffer == buf) - clearFolding(win); + FOR_ALL_TAB_WINDOWS(tp, win) { + if (win->w_buffer == buf) { + clearFolding(win); } } @@ -4206,8 +4202,6 @@ int read_viminfo_bufferlist(vir_T *virp, int writing) void write_viminfo_bufferlist(FILE *fp) { - win_T *win; - tabpage_T *tp; char_u *line; int max_buffers; @@ -4284,8 +4278,12 @@ char_u *buf_spname(buf_T *buf) */ bool find_win_for_buf(buf_T *buf, win_T **wp, tabpage_T **tp) { - FOR_ALL_TAB_WINDOWS(*tp, *wp) { - if ((*wp)->w_buffer == buf) { + *wp = NULL; + *tp = NULL; + FOR_ALL_TAB_WINDOWS(tp2, wp2) { + if (wp2->w_buffer == buf) { + *tp = tp2; + *wp = wp2; return true; } } diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 8f540fbe09..7927473439 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -62,8 +62,7 @@ static int diff_a_works = MAYBE; /// @param buf void diff_buf_delete(buf_T *buf) { - tabpage_T *tp; - for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) { + FOR_ALL_TABS(tp) { int i = diff_buf_idx_tp(buf, tp); if (i != DB_COUNT) { @@ -175,8 +174,7 @@ static int diff_buf_idx_tp(buf_T *buf, tabpage_T *tp) /// @param buf void diff_invalidate(buf_T *buf) { - tabpage_T *tp; - for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) { + FOR_ALL_TABS(tp) { int i = diff_buf_idx_tp(buf, tp); if (i != DB_COUNT) { tp->tp_diff_invalid = TRUE; @@ -197,8 +195,7 @@ void diff_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after) { // Handle all tab pages that use the current buffer in a diff. - tabpage_T *tp; - for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) { + FOR_ALL_TABS(tp) { int idx = diff_buf_idx_tp(curbuf, tp); if (idx != DB_COUNT) { diff_mark_adjust_tp(tp, idx, line1, line2, amount, amount_after); @@ -1819,8 +1816,7 @@ int diffopt_changed(void) // If "icase" or "iwhite" was added or removed, need to update the diff. if (diff_flags != diff_flags_new) { - tabpage_T *tp; - for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) { + FOR_ALL_TABS(tp) { tp->tp_diff_invalid = TRUE; } } @@ -2376,15 +2372,14 @@ static void diff_fold_update(diff_T *dp, int skip_idx) /// @param buf The buffer to check. /// /// @return TRUE if buffer "buf" is in diff-mode. -int diff_mode_buf(buf_T *buf) +bool diff_mode_buf(buf_T *buf) { - tabpage_T *tp; - for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) { + FOR_ALL_TABS(tp) { if (diff_buf_idx_tp(buf, tp) != DB_COUNT) { - return TRUE; + return true; } } - return FALSE; + return false; } /// Move "count" times in direction "dir" to the next diff block. diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 3b450e5245..5131dc3b38 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -5610,12 +5610,18 @@ static void spell_back_to_badword(void) int stop_arrow(void) { if (arrow_used) { + Insstart = curwin->w_cursor; //new insertion starts here + if (Insstart.col > Insstart_orig.col && !ins_need_undo) { + // Don't update the original insert position when moved to the + // right, except when nothing was inserted yet. + update_Insstart_orig = FALSE; + } + Insstart_textlen = (colnr_T)linetabsize(get_cursor_line_ptr()); + if (u_save_cursor() == OK) { arrow_used = FALSE; ins_need_undo = FALSE; } - Insstart = curwin->w_cursor; /* new insertion starts here */ - Insstart_textlen = (colnr_T)linetabsize(get_cursor_line_ptr()); ai_col = 0; if (State & VREPLACE_FLAG) { orig_line_count = curbuf->b_ml.ml_line_count; diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 0dd261f53a..0ae96365b2 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -5403,11 +5403,9 @@ static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo_style, int int garbage_collect(void) { int copyID; - win_T *wp; funccall_T *fc, **pfc; int did_free; int did_free_funccal = FALSE; - tabpage_T *tp; /* Only do this once. */ want_garbage_collect = FALSE; @@ -5442,14 +5440,16 @@ int garbage_collect(void) } /* window-local variables */ - FOR_ALL_TAB_WINDOWS(tp, wp) - set_ref_in_item(&wp->w_winvar.di_tv, copyID); + FOR_ALL_TAB_WINDOWS(tp, wp) { + set_ref_in_item(&wp->w_winvar.di_tv, copyID); + } if (aucmd_win != NULL) set_ref_in_item(&aucmd_win->w_winvar.di_tv, copyID); /* tabpage-local variables */ - for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) + FOR_ALL_TABS(tp) { set_ref_in_item(&tp->tp_winvar.di_tv, copyID); + } /* global variables */ set_ref_in_ht(&globvarht, copyID); @@ -9588,21 +9588,27 @@ find_win_by_nr ( tabpage_T *tp /* NULL for current tab page */ ) { - win_T *wp; - int nr; - - nr = get_tv_number_chk(vp, NULL); + int nr = get_tv_number_chk(vp, NULL); - if (nr < 0) + if (nr < 0) { return NULL; - if (nr == 0) + } + + if (nr == 0) { return curwin; + } - for (wp = (tp == NULL || tp == curtab) ? firstwin : tp->tp_firstwin; - wp != NULL; wp = wp->w_next) - if (--nr <= 0) - break; - return wp; + // This method accepts NULL as an alias for curtab. + if (tp == NULL) { + tp = curtab; + } + + FOR_ALL_WINDOWS_IN_TAB(wp, tp) { + if (--nr <= 0) { + return wp; + } + } + return NULL; } /* @@ -13455,15 +13461,36 @@ static int item_compare(const void *s1, const void *s2) { sortItem_T *si1, *si2; char_u *p1, *p2; - char_u *tofree1, *tofree2; + char_u *tofree1 = NULL, *tofree2 = NULL; int res; char_u numbuf1[NUMBUFLEN]; char_u numbuf2[NUMBUFLEN]; si1 = (sortItem_T *)s1; si2 = (sortItem_T *)s2; - p1 = tv2string(&si1->item->li_tv, &tofree1, numbuf1, 0); - p2 = tv2string(&si2->item->li_tv, &tofree2, numbuf2, 0); + typval_T *tv1 = &si1->item->li_tv; + typval_T *tv2 = &si2->item->li_tv; + // tv2string() puts quotes around a string and allocates memory. Don't do + // that for string variables. Use a single quote when comparing with a + // non-string to do what the docs promise. + if (tv1->v_type == VAR_STRING) { + if (tv2->v_type != VAR_STRING || item_compare_numeric) { + p1 = (char_u *)"'"; + } else { + p1 = tv1->vval.v_string; + } + } else { + p1 = tv2string(tv1, &tofree1, numbuf1, 0); + } + if (tv2->v_type == VAR_STRING) { + if (tv1->v_type != VAR_STRING || item_compare_numeric) { + p2 = (char_u *)"'"; + } else { + p2 = tv2->vval.v_string; + } + } else { + p2 = tv2string(tv2, &tofree2, numbuf2, 0); + } if (p1 == NULL) p1 = (char_u *)""; if (p2 == NULL) @@ -13481,8 +13508,8 @@ static int item_compare(const void *s1, const void *s2) res = n1 == n2 ? 0 : n1 > n2 ? 1 : -1; } - // When the result would be zero, compare the pointers themselves. Makes - // the sort stable. + // When the result would be zero, compare the item indexes. Makes the + // sort stable. if (res == 0 && !item_compare_keep_zero) { res = si1->idx > si2->idx ? 1 : -1; } diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 163d20f13a..44604b68c4 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -2962,13 +2962,10 @@ do_ecmd ( /* It's possible that all lines in the buffer changed. Need to update * automatic folding for all windows where it's used. */ - { - win_T *win; - tabpage_T *tp; - - FOR_ALL_TAB_WINDOWS(tp, win) - if (win->w_buffer == curbuf) + FOR_ALL_TAB_WINDOWS(tp, win) { + if (win->w_buffer == curbuf) { foldUpdateAll(win); + } } /* Change directories when the 'acd' option is set. */ diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index c3d34e9991..0703c76b8a 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -1204,7 +1204,6 @@ check_changed_any ( int bufnum = 0; int bufcount = 0; int *bufnrs; - tabpage_T *tp; FOR_ALL_BUFFERS(buf) { ++bufcount; @@ -1225,9 +1224,9 @@ check_changed_any ( } /* buf in other tab */ - for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) { + FOR_ALL_TABS(tp) { if (tp != curtab) { - for (win_T *wp = tp->tp_firstwin; wp != NULL; wp = wp->w_next) { + FOR_ALL_WINDOWS_IN_TAB(wp, tp) { add_bufnum(bufnrs, &bufnum, wp->w_buffer->b_fnum); } } @@ -1282,7 +1281,6 @@ check_changed_any ( /* Try to find a window that contains the buffer. */ if (buf != curbuf) { - win_T *wp; FOR_ALL_TAB_WINDOWS(tp, wp) { if (wp->w_buffer == buf) { goto_tabpage_win(tp, wp); @@ -1510,12 +1508,11 @@ do_arglist ( */ static void alist_check_arg_idx(void) { - win_T *win; - tabpage_T *tp; - - FOR_ALL_TAB_WINDOWS(tp, win) - if (win->w_alist == curwin->w_alist) - check_arg_idx(win); + FOR_ALL_TAB_WINDOWS(tp, win) { + if (win->w_alist == curwin->w_alist) { + check_arg_idx(win); + } + } } /* diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 1117b6fbcf..7fb109403e 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -5267,9 +5267,6 @@ static void ex_tabclose(exarg_T *eap) */ static void ex_tabonly(exarg_T *eap) { - tabpage_T *tp; - int done; - if (cmdwin_type != 0) cmdwin_result = K_IGNORE; else if (first_tabpage->tp_next == NULL) @@ -5277,8 +5274,8 @@ static void ex_tabonly(exarg_T *eap) else { /* Repeat this up to a 1000 times, because autocommands may mess * up the lists. */ - for (done = 0; done < 1000; ++done) { - for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) + for (int done = 0; done < 1000; ++done) { + FOR_ALL_TABS(tp) { if (tp->tp_topframe != topframe) { tabpage_close_other(tp, eap->forceit); /* if we failed to close it quit */ @@ -5287,8 +5284,10 @@ static void ex_tabonly(exarg_T *eap) /* start over, "tp" is now invalid */ break; } - if (first_tabpage->tp_next == NULL) + } + if (first_tabpage->tp_next == NULL) { break; + } } } } @@ -5607,18 +5606,21 @@ alist_add ( */ void alist_slash_adjust(void) { - int i; - win_T *wp; - tabpage_T *tp; - - for (i = 0; i < GARGCOUNT; ++i) - if (GARGLIST[i].ae_fname != NULL) + for (int i = 0; i < GARGCOUNT; ++i) { + if (GARGLIST[i].ae_fname != NULL) { slash_adjust(GARGLIST[i].ae_fname); - FOR_ALL_TAB_WINDOWS(tp, wp) - if (wp->w_alist != &global_alist) - for (i = 0; i < WARGCOUNT(wp); ++i) - if (WARGLIST(wp)[i].ae_fname != NULL) - slash_adjust(WARGLIST(wp)[i].ae_fname); + } + } + + FOR_ALL_TAB_WINDOWS(tp, wp) { + if (wp->w_alist != &global_alist) { + for (int i = 0; i < WARGCOUNT(wp); ++i) { + if (WARGLIST(wp)[i].ae_fname != NULL) { + slash_adjust(WARGLIST(wp)[i].ae_fname); + } + } + } + } } #endif @@ -5808,24 +5810,27 @@ static void ex_tabmove(exarg_T *eap) */ static void ex_tabs(exarg_T *eap) { - tabpage_T *tp; - win_T *wp; int tabcount = 1; msg_start(); msg_scroll = TRUE; - for (tp = first_tabpage; tp != NULL && !got_int; tp = tp->tp_next) { + + FOR_ALL_TABS(tp) { + if (got_int) { + break; + } + msg_putchar('\n'); vim_snprintf((char *)IObuff, IOSIZE, _("Tab page %d"), tabcount++); msg_outtrans_attr(IObuff, hl_attr(HLF_T)); out_flush(); /* output one line at a time */ ui_breakcheck(); - if (tp == curtab) - wp = firstwin; - else - wp = tp->tp_firstwin; - for (; wp != NULL && !got_int; wp = wp->w_next) { + FOR_ALL_WINDOWS_IN_TAB(wp, tp) { + if (got_int) { + break; + } + msg_putchar('\n'); msg_putchar(wp == curwin ? '>' : ' '); msg_putchar(' '); diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 72dd7170ce..fbce4428db 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -5102,16 +5102,15 @@ void buf_reload(buf_T *buf, int orig_mode) check_cursor(); update_topline(); keep_filetype = FALSE; - { - win_T *wp; - tabpage_T *tp; - /* Update folds unless they are defined manually. */ - FOR_ALL_TAB_WINDOWS(tp, wp) + /* Update folds unless they are defined manually. */ + FOR_ALL_TAB_WINDOWS(tp, wp) { if (wp->w_buffer == curwin->w_buffer - && !foldmethodIsManual(wp)) + && !foldmethodIsManual(wp)) { foldUpdateAll(wp); + } } + /* If the mode didn't change and 'readonly' was set, keep the old * value; the user probably used the ":view" command. But don't * reset it, might have had a read error. */ @@ -6269,14 +6268,11 @@ aucmd_restbuf ( * page. Do not trigger autocommands here. */ block_autocmds(); if (curwin != aucmd_win) { - tabpage_T *tp; - win_T *wp; - - FOR_ALL_TAB_WINDOWS(tp, wp) - { + FOR_ALL_TAB_WINDOWS(tp, wp) { if (wp == aucmd_win) { - if (tp != curtab) + if (tp != curtab) { goto_tabpage_tp(tp, TRUE, TRUE); + } win_goto(aucmd_win); goto win_found; } diff --git a/src/nvim/globals.h b/src/nvim/globals.h index efad3c3af1..2025295c11 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -521,15 +521,19 @@ EXTERN win_T *firstwin; /* first window */ EXTERN win_T *lastwin; /* last window */ EXTERN win_T *prevwin INIT(= NULL); /* previous window */ # define W_NEXT(wp) ((wp)->w_next) -# define FOR_ALL_WINDOWS(wp) for (win_T *wp = firstwin; wp != NULL; wp = wp->w_next) +# define FOR_ALL_WINDOWS(wp) \ + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) /* * When using this macro "break" only breaks out of the inner loop. Use "goto" * to break out of the tabpage loop. */ # define FOR_ALL_TAB_WINDOWS(tp, wp) \ - for ((tp) = first_tabpage; (tp) != NULL; (tp) = (tp)->tp_next) \ - for ((wp) = ((tp) == curtab) \ - ? firstwin : (tp)->tp_firstwin; (wp); (wp) = (wp)->w_next) + FOR_ALL_TABS(tp) \ + FOR_ALL_WINDOWS_IN_TAB(wp, tp) + +# define FOR_ALL_WINDOWS_IN_TAB(wp, tp) \ + for (win_T *wp = ((tp) == curtab) \ + ? firstwin : (tp)->tp_firstwin; wp != NULL; wp = wp->w_next) EXTERN win_T *curwin; /* currently active window */ @@ -550,6 +554,9 @@ EXTERN tabpage_T *first_tabpage; EXTERN tabpage_T *curtab; EXTERN int redraw_tabline INIT(= FALSE); /* need to redraw tabline */ +// Iterates over all tabs in the tab list +# define FOR_ALL_TABS(tp) for (tabpage_T *tp = first_tabpage; tp != NULL; tp = tp->tp_next) + /* * All buffers are linked in a list. 'firstbuf' points to the first entry, * 'lastbuf' to the last entry and 'curbuf' to the currently active buffer. diff --git a/src/nvim/main.c b/src/nvim/main.c index 7dc299e73b..e3f1d88dff 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -758,7 +758,6 @@ main_loop ( /* Exit properly */ void getout(int exitval) { - win_T *wp; tabpage_T *tp, *next_tp; exiting = TRUE; @@ -780,11 +779,12 @@ void getout(int exitval) /* Trigger BufWinLeave for all windows, but only once per buffer. */ for (tp = first_tabpage; tp != NULL; tp = next_tp) { next_tp = tp->tp_next; - for (wp = (tp == curtab) - ? firstwin : tp->tp_firstwin; wp != NULL; wp = wp->w_next) { - if (wp->w_buffer == NULL) + FOR_ALL_WINDOWS_IN_TAB(wp, tp) { + if (wp->w_buffer == NULL) { /* Autocmd must have close the buffer already, skip. */ continue; + } + buf_T *buf = wp->w_buffer; if (buf->b_changedtick != -1) { apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, diff --git a/src/nvim/mark.c b/src/nvim/mark.c index 6339cf8275..a66bf43c13 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -898,8 +898,6 @@ void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after) int i; int fnum = curbuf->b_fnum; linenr_T *lp; - win_T *win; - tabpage_T *tab; static pos_T initpos = INIT_POS_T(1, 0, 0); if (line2 < line1 && amount_after == 0L) /* nothing to do */ @@ -939,8 +937,9 @@ void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after) /* quickfix marks */ qf_mark_adjust(NULL, line1, line2, amount, amount_after); /* location lists */ - FOR_ALL_TAB_WINDOWS(tab, win) - qf_mark_adjust(win, line1, line2, amount, amount_after); + FOR_ALL_TAB_WINDOWS(tab, win) { + qf_mark_adjust(win, line1, line2, amount, amount_after); + } sign_mark_adjust(line1, line2, amount, amount_after); } @@ -958,21 +957,26 @@ void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after) /* * Adjust items in all windows related to the current buffer. */ - FOR_ALL_TAB_WINDOWS(tab, win) - { - if (!cmdmod.lockmarks) + FOR_ALL_TAB_WINDOWS(tab, win) { + if (!cmdmod.lockmarks) { /* Marks in the jumplist. When deleting lines, this may create * duplicate marks in the jumplist, they will be removed later. */ - for (i = 0; i < win->w_jumplistlen; ++i) - if (win->w_jumplist[i].fmark.fnum == fnum) + for (i = 0; i < win->w_jumplistlen; ++i) { + if (win->w_jumplist[i].fmark.fnum == fnum) { one_adjust_nodel(&(win->w_jumplist[i].fmark.mark.lnum)); + } + } + } if (win->w_buffer == curbuf) { - if (!cmdmod.lockmarks) + if (!cmdmod.lockmarks) { /* marks in the tag stack */ - for (i = 0; i < win->w_tagstacklen; i++) - if (win->w_tagstack[i].fmark.fnum == fnum) + for (i = 0; i < win->w_tagstacklen; i++) { + if (win->w_tagstack[i].fmark.fnum == fnum) { one_adjust_nodel(&(win->w_tagstack[i].fmark.mark.lnum)); + } + } + } /* the displayed Visual area */ if (win->w_old_cursor_lnum != 0) { @@ -985,12 +989,14 @@ void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after) if (win != curwin) { if (win->w_topline >= line1 && win->w_topline <= line2) { if (amount == MAXLNUM) { /* topline is deleted */ - if (line1 <= 1) + if (line1 <= 1) { win->w_topline = 1; - else + } else { win->w_topline = line1 - 1; - } else /* keep topline on the same line */ + } + } else { /* keep topline on the same line */ win->w_topline += amount; + } win->w_topfill = 0; } else if (amount_after && win->w_topline > line2) { win->w_topline += amount_after; @@ -998,15 +1004,18 @@ void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after) } if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2) { if (amount == MAXLNUM) { /* line with cursor is deleted */ - if (line1 <= 1) + if (line1 <= 1) { win->w_cursor.lnum = 1; - else + } else { win->w_cursor.lnum = line1 - 1; + } win->w_cursor.col = 0; - } else /* keep cursor on the same line */ + } else { /* keep cursor on the same line */ win->w_cursor.lnum += amount; - } else if (amount_after && win->w_cursor.lnum > line2) + } + } else if (amount_after && win->w_cursor.lnum > line2) { win->w_cursor.lnum += amount_after; + } } /* adjust folds */ @@ -1338,12 +1347,6 @@ int removable(char_u *name) */ int write_viminfo_marks(FILE *fp_out) { - int count; - int is_mark_set; - int i; - win_T *win; - tabpage_T *tp; - /* * Set b_last_cursor for the all buffers that have a window. */ @@ -1352,22 +1355,22 @@ int write_viminfo_marks(FILE *fp_out) } fputs(_("\n# History of marks within files (newest to oldest):\n"), fp_out); - count = 0; + int count = 0; FOR_ALL_BUFFERS(buf) { /* * Only write something if buffer has been loaded and at least one * mark is set. */ if (buf->b_marks_read) { - if (buf->b_last_cursor.lnum != 0) - is_mark_set = TRUE; - else { - is_mark_set = FALSE; - for (i = 0; i < NMARKS; i++) + bool is_mark_set = true; + if (buf->b_last_cursor.lnum == 0) { + is_mark_set = false; + for (int i = 0; i < NMARKS; i++) { if (buf->b_namedm[i].lnum != 0) { - is_mark_set = TRUE; + is_mark_set = true; break; } + } } if (is_mark_set && buf->b_ffname != NULL && buf->b_ffname[0] != NUL && !removable(buf->b_ffname)) { @@ -1378,10 +1381,12 @@ int write_viminfo_marks(FILE *fp_out) write_one_mark(fp_out, '^', &buf->b_last_insert); write_one_mark(fp_out, '.', &buf->b_last_change); /* changelist positions are stored oldest first */ - for (i = 0; i < buf->b_changelistlen; ++i) + for (int i = 0; i < buf->b_changelistlen; ++i) { write_one_mark(fp_out, '+', &buf->b_changelist[i]); - for (i = 0; i < NMARKS; i++) + } + for (int i = 0; i < NMARKS; i++) { write_one_mark(fp_out, 'a' + i, &buf->b_namedm[i]); + } count++; } } diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 1c3d6e372c..f4dffb0bcd 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -452,13 +452,9 @@ void free_all_mem(void) p_hi = 0; init_history(); - { - win_T *win; - tabpage_T *tab; - - qf_free_all(NULL); - /* Free all location lists */ - FOR_ALL_TAB_WINDOWS(tab, win) + qf_free_all(NULL); + /* Free all location lists */ + FOR_ALL_TAB_WINDOWS(tab, win) { qf_free_all(win); } diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index d7e9618639..52780b9a57 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -2027,8 +2027,6 @@ changed_lines_buf ( */ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume, long xtra) { - win_T *wp; - tabpage_T *tp; int i; int cols; pos_T *p; @@ -2072,21 +2070,21 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume, long xtra curbuf->b_changelistlen = JUMPLISTSIZE - 1; memmove(curbuf->b_changelist, curbuf->b_changelist + 1, sizeof(pos_T) * (JUMPLISTSIZE - 1)); - FOR_ALL_TAB_WINDOWS(tp, wp) - { + FOR_ALL_TAB_WINDOWS(tp, wp) { /* Correct position in changelist for other windows on * this buffer. */ - if (wp->w_buffer == curbuf && wp->w_changelistidx > 0) + if (wp->w_buffer == curbuf && wp->w_changelistidx > 0) { --wp->w_changelistidx; + } } } - FOR_ALL_TAB_WINDOWS(tp, wp) - { + FOR_ALL_TAB_WINDOWS(tp, wp) { /* For other windows, if the position in the changelist is * at the end it stays at the end. */ if (wp->w_buffer == curbuf - && wp->w_changelistidx == curbuf->b_changelistlen) + && wp->w_changelistidx == curbuf->b_changelistlen) { ++wp->w_changelistidx; + } } ++curbuf->b_changelistlen; } @@ -2098,8 +2096,7 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume, long xtra curwin->w_changelistidx = curbuf->b_changelistlen; } - FOR_ALL_TAB_WINDOWS(tp, wp) - { + FOR_ALL_TAB_WINDOWS(tp, wp) { if (wp->w_buffer == curbuf) { /* Mark this window to be redrawn later. */ if (wp->w_redr_type < VALID) diff --git a/src/nvim/option.c b/src/nvim/option.c index b26b6ed4cc..96265681df 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2210,17 +2210,16 @@ set_options_default ( int opt_flags /* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */ ) { - int i; - win_T *wp; - tabpage_T *tp; - - for (i = 0; !istermoption(&options[i]); i++) - if (!(options[i].flags & P_NODEFAULT)) + for (int i = 0; !istermoption(&options[i]); i++) { + if (!(options[i].flags & P_NODEFAULT)) { set_option_default(i, opt_flags, p_cp); + } + } /* The 'scroll' option must be computed for all windows. */ - FOR_ALL_TAB_WINDOWS(tp, wp) - win_comp_scroll(wp); + FOR_ALL_TAB_WINDOWS(tp, wp) { + win_comp_scroll(wp); + } } /// Set the Vi-default value of a string option. @@ -5532,13 +5531,11 @@ set_num_option ( errmsg = e_positive; curbuf->b_p_tw = 0; } - { - win_T *wp; - tabpage_T *tp; - FOR_ALL_TAB_WINDOWS(tp, wp) + FOR_ALL_TAB_WINDOWS(tp, wp) { check_colorcolumn(wp); } + } /* diff --git a/src/nvim/po/CMakeLists.txt b/src/nvim/po/CMakeLists.txt index 4a9c97dc20..0ed39e8c49 100644 --- a/src/nvim/po/CMakeLists.txt +++ b/src/nvim/po/CMakeLists.txt @@ -71,7 +71,7 @@ if(HAVE_WORKING_LIBINTL AND GETTEXT_FOUND AND XGETTEXT_PRG AND ICONV_PRG AND -P ${CMAKE_MODULE_PATH}/RunMsgfmt.cmake DEPENDS ${poFile} ${NVIM_POT}) - install( + install_helper( FILES ${moFile} DESTINATION share/locale/${name}/LC_MESSAGES RENAME nvim.mo) diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 3bc70b6b41..b2a6b01d96 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -1466,11 +1466,7 @@ void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit) * then search in other tabs. */ if (!usable_win && (swb_flags & SWB_USETAB)) { - tabpage_T *tp; - win_T *wp; - - FOR_ALL_TAB_WINDOWS(tp, wp) - { + FOR_ALL_TAB_WINDOWS(tp, wp) { if (wp->w_buffer->b_fnum == qf_ptr->qf_fnum) { goto_tabpage_win(tp, wp); usable_win = true; @@ -2236,12 +2232,11 @@ static win_T *qf_find_win(qf_info_T *qi) */ static buf_T *qf_find_buf(qf_info_T *qi) { - tabpage_T *tp; - win_T *win; - - FOR_ALL_TAB_WINDOWS(tp, win) - if (is_qf_win(win, qi)) - return win->w_buffer; + FOR_ALL_TAB_WINDOWS(tp, win) { + if (is_qf_win(win, qi)) { + return win->w_buffer; + } + } return NULL; } diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 193c68860d..90da02bb1b 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -2790,17 +2790,29 @@ static int peekchr(void) * either "\|", "\)", "\&", or "\n" */ if (reg_magic >= MAGIC_OFF) { char_u *p = regparse + 1; + bool is_magic_all = (reg_magic == MAGIC_ALL); - /* ignore \c \C \m and \M after '$' */ + // ignore \c \C \m \M \v \V and \Z after '$' while (p[0] == '\\' && (p[1] == 'c' || p[1] == 'C' - || p[1] == 'm' || p[1] == 'M' || p[1] == 'Z')) + || p[1] == 'm' || p[1] == 'M' + || p[1] == 'v' || p[1] == 'V' + || p[1] == 'Z')) { + if (p[1] == 'v') { + is_magic_all = true; + } else if (p[1] == 'm' || p[1] == 'M' || p[1] == 'V') { + is_magic_all = false; + } p += 2; + } if (p[0] == NUL || (p[0] == '\\' && (p[1] == '|' || p[1] == '&' || p[1] == ')' || p[1] == 'n')) - || reg_magic == MAGIC_ALL) + || (is_magic_all + && (p[0] == '|' || p[0] == '&' || p[0] == ')')) + || reg_magic == MAGIC_ALL) { curchr = Magic('$'); + } } break; case '\\': diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 122c23ed84..c46b5fa48c 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -346,7 +346,7 @@ int redraw_asap(int type) * Note that when also inserting/deleting lines w_redraw_top and w_redraw_bot * may become invalid and the whole window will have to be redrawn. */ -void +void redrawWinline ( linenr_T lnum, int invalid /* window line height is invalid now */ @@ -2114,7 +2114,7 @@ static void copy_text_attr(int off, char_u *buf, int len, int attr) * Fill the foldcolumn at "p" for window "wp". * Only to be called when 'foldcolumn' > 0. */ -static void +static void fill_foldcolumn ( char_u *p, win_T *wp, @@ -2166,7 +2166,7 @@ fill_foldcolumn ( * * Return the number of last row the line occupies. */ -static int +static int win_line ( win_T *wp, linenr_T lnum, @@ -2655,8 +2655,8 @@ win_line ( } next_search_hl(wp, shl, lnum, (colnr_T)v, cur); - // Need to get the line again, a multi-line regexp may have made it - // invalid. + // Need to get the line again, a multi-line regexp may have made it + // invalid. line = ml_get_buf(wp->w_buffer, lnum, false); ptr = line + v; @@ -2672,7 +2672,7 @@ win_line ( } else { shl->endcol = MAXCOL; } - // Highlight one character for an empty match. + // Highlight one character for an empty match. if (shl->startcol == shl->endcol) { if (has_mbyte && line[shl->endcol] != NUL) { shl->endcol += (*mb_ptr2len)(line + shl->endcol); @@ -2680,7 +2680,7 @@ win_line ( ++shl->endcol; } } - if ((long)shl->startcol < v) { // match at leftcol + if ((long)shl->startcol < v) { // match at leftcol shl->attr_cur = shl->attr; search_attr = shl->attr; } @@ -2830,9 +2830,12 @@ win_line ( if (wp->w_p_bri && n_extra == 0 && row != startrow && filler_lines == 0) { char_attr = 0; // was: hl_attr(HLF_AT); - if (diff_hlf != (hlf_T)0) + if (diff_hlf != (hlf_T)0) { char_attr = hl_attr(diff_hlf); - + if (wp->w_p_cul && lnum == wp->w_cursor.lnum) { + char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUL)); + } + } p_extra = NULL; c_extra = ' '; n_extra = get_breakindent_win(wp, ml_get_buf(wp->w_buffer, lnum, FALSE)); @@ -2869,8 +2872,9 @@ win_line ( if (tocol == vcol) tocol += n_extra; /* combine 'showbreak' with 'cursorline' */ - if (wp->w_p_cul && lnum == wp->w_cursor.lnum) - char_attr = hl_combine_attr(char_attr, HLF_CLN); + if (wp->w_p_cul && lnum == wp->w_cursor.lnum) { + char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUL)); + } } } @@ -2948,7 +2952,7 @@ win_line ( && v >= (long)shl->startcol && v < (long)shl->endcol) { shl->attr_cur = shl->attr; - } else if (v >= (long)shl->endcol) { + } else if (v >= (long)shl->endcol && shl->lnum == lnum) { shl->attr_cur = 0; next_search_hl(wp, shl, lnum, (colnr_T)v, cur); @@ -3016,6 +3020,9 @@ win_line ( && n_extra == 0) diff_hlf = HLF_CHD; /* changed line */ line_attr = hl_attr(diff_hlf); + if (wp->w_p_cul && lnum == wp->w_cursor.lnum) { + line_attr = hl_combine_attr(line_attr, hl_attr(HLF_CUL)); + } } /* Decide which of the highlight attributes to use. */ @@ -3620,8 +3627,12 @@ win_line ( char_attr = line_attr; if (diff_hlf == HLF_TXD) { diff_hlf = HLF_CHD; - if (attr == 0 || char_attr != attr) + if (attr == 0 || char_attr != attr) { char_attr = hl_attr(diff_hlf); + if (wp->w_p_cul && lnum == wp->w_cursor.lnum) { + char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUL)); + } + } } } } @@ -4676,7 +4687,7 @@ static int skip_status_match_char(expand_T *xp, char_u *s) * * If inversion is possible we use it. Else '=' characters are used. */ -void +void win_redr_status_matches ( expand_T *xp, int num_matches, @@ -4962,7 +4973,7 @@ void win_redr_status(win_T *wp) fillchar = fillchar_status(&attr, wp == curwin); else fillchar = fillchar_vsep(&attr); - screen_putchar(fillchar, wp->w_winrow + wp->w_height, + screen_putchar(fillchar, wp->w_winrow + wp->w_height, W_ENDCOL(wp), attr); } busy = FALSE; @@ -5024,7 +5035,7 @@ int stl_connected(win_T *wp) /* * Get the value to show for the language mappings, active 'keymap'. */ -int +int get_keymap_str ( win_T *wp, char_u *buf, /* buffer for the result */ @@ -5068,7 +5079,7 @@ get_keymap_str ( * Redraw the status line or ruler of window "wp". * When "wp" is NULL redraw the tab pages line from 'tabline'. */ -static void +static void win_redr_custom ( win_T *wp, int draw_ruler /* TRUE or FALSE */ @@ -5606,7 +5617,7 @@ static void prepare_search_hl(win_T *wp, linenr_T lnum) if (cur != NULL) { cur->pos.cur = 0; } - bool pos_inprogress = true; // mark that a position match search is + bool pos_inprogress = true; // mark that a position match search is // in progress n = 0; while (shl->first_lnum < lnum && (shl->rm.regprog != NULL @@ -5637,7 +5648,7 @@ static void prepare_search_hl(win_T *wp, linenr_T lnum) * shl->lnum is zero. * Careful: Any pointers for buffer lines will become invalid. */ -static void +static void next_search_hl ( win_T *win, match_T *shl, /* points to search_hl or a match */ @@ -5705,9 +5716,9 @@ next_search_hl ( if (shl->rm.regprog != NULL) { nmatched = vim_regexec_multi(&shl->rm, win, shl->buf, lnum, matchcol, &(shl->tm)); if (called_emsg || got_int) { - // Error while handling regexp: stop using this regexp. + // Error while handling regexp: stop using this regexp. if (shl == &search_hl) { - // don't free regprog in the match list, it's a copy + // don't free regprog in the match list, it's a copy vim_regfree(shl->rm.regprog); SET_NO_HLSEARCH(TRUE); } @@ -5735,11 +5746,11 @@ next_search_hl ( static int next_search_hl_pos( - match_T *shl, // points to a match + match_T *shl, // points to a match linenr_T lnum, - posmatch_T *posmatch, // match positions + posmatch_T *posmatch, // match positions colnr_T mincol // minimal column for a match -) +) { int i; int bot = -1; @@ -5754,8 +5765,8 @@ next_search_hl_pos( } if (posmatch->pos[i].lnum == lnum) { if (shl->lnum == lnum) { - // partially sort positions by column numbers - // on the same line + // partially sort positions by column numbers + // on the same line if (posmatch->pos[i].col < posmatch->pos[bot].col) { llpos_T tmp = posmatch->pos[i]; @@ -5772,7 +5783,7 @@ next_search_hl_pos( if (shl->lnum == lnum) { colnr_T start = posmatch->pos[bot].col == 0 ? 0: posmatch->pos[bot].col - 1; - colnr_T end = posmatch->pos[bot].col == 0 + colnr_T end = posmatch->pos[bot].col == 0 ? MAXCOL : start + posmatch->pos[bot].len; shl->rm.startpos[0].lnum = 0; @@ -6263,7 +6274,6 @@ int screen_valid(int doclear) void screenalloc(bool doclear) { int new_row, old_row; - win_T *wp; int outofmem = FALSE; int len; schar_T *new_ScreenLines; @@ -6275,7 +6285,6 @@ void screenalloc(bool doclear) unsigned *new_LineOffset; char_u *new_LineWraps; short *new_TabPageIdxs; - tabpage_T *tp; static int entered = FALSE; /* avoid recursiveness */ static int done_outofmem_msg = FALSE; /* did outofmem message */ int retry_count = 0; @@ -6328,8 +6337,9 @@ retry: * Continuing with the old ScreenLines may result in a crash, because the * size is wrong. */ - FOR_ALL_TAB_WINDOWS(tp, wp) - win_free_lsize(wp); + FOR_ALL_TAB_WINDOWS(tp, wp) { + win_free_lsize(wp); + } if (aucmd_win != NULL) win_free_lsize(aucmd_win); @@ -6349,8 +6359,7 @@ retry: new_LineWraps = xmalloc((size_t)(Rows * sizeof(char_u))); new_TabPageIdxs = xmalloc((size_t)(Columns * sizeof(short))); - FOR_ALL_TAB_WINDOWS(tp, wp) - { + FOR_ALL_TAB_WINDOWS(tp, wp) { win_alloc_lines(wp); } if (aucmd_win != NULL && aucmd_win->w_lines == NULL) { @@ -7093,7 +7102,7 @@ static void win_rest_invalid(win_T *wp) * * return FAIL for failure, OK for success. */ -int +int screen_ins_lines ( int off, int row, @@ -7266,7 +7275,7 @@ screen_ins_lines ( * * Return OK for success, FAIL if the lines are not deleted. */ -int +int screen_del_lines ( int off, int row, @@ -7632,8 +7641,7 @@ void unshowmode(int force) static void draw_tabline(void) { int tabcount = 0; - tabpage_T *tp; - int tabwidth; + int tabwidth = 0; int col = 0; int scol = 0; int attr; @@ -7675,18 +7683,27 @@ static void draw_tabline(void) (char_u *)"", OPT_FREE, SID_ERROR); called_emsg |= save_called_emsg; } else { - for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) + FOR_ALL_TABS(tp) { ++tabcount; + } - tabwidth = (Columns - 1 + tabcount / 2) / tabcount; - if (tabwidth < 6) + if (tabcount > 0) { + tabwidth = (Columns - 1 + tabcount / 2) / tabcount; + } + + if (tabwidth < 6) { tabwidth = 6; + } attr = attr_nosel; tabcount = 0; scol = 0; - for (tp = first_tabpage; tp != NULL && col < Columns - 4; - tp = tp->tp_next) { + + FOR_ALL_TABS(tp) { + if (col >= Columns - 4) { + break; + } + scol = col; if (tp->tp_topframe == topframe) @@ -7718,8 +7735,7 @@ static void draw_tabline(void) if (col + len >= Columns - 3) break; screen_puts_len(NameBuff, len, 0, col, - hl_combine_attr(attr, hl_attr(HLF_T)) - ); + hl_combine_attr(attr, hl_attr(HLF_T))); col += len; } if (modified) diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index 81dc49e800..9f04f880b5 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -33,6 +33,7 @@ SCRIPTS := test_autoformat_join.out \ test106.out test107.out \ test_options.out \ test_listlbr.out test_listlbr_utf8.out \ + test_changelist.out \ test_breakindent.out \ test_insertcount.out diff --git a/src/nvim/testdir/test39.in b/src/nvim/testdir/test39.in index c1e1cc49a6..7d1c672522 100644 --- a/src/nvim/testdir/test39.in +++ b/src/nvim/testdir/test39.in @@ -23,6 +23,9 @@ G$khhhhhkkcmno /^aaaa/ :exe ":norm! l\<C-V>jjjlllI\<Right>\<Right> \<Esc>" :/^aa/,/^$/w >> test.out +/xaaa$/ +:exe ":norm! \<C-V>jjjI<>\<Left>p\<Esc>" +:/xaaa$/,/^$/w >> test.out :" Test for Visual block was created with the last <C-v>$ /^A23$/ :exe ":norm! l\<C-V>j$Aab\<Esc>" @@ -77,6 +80,11 @@ bbbbbb cccccc dddddd +xaaa +bbbb +cccc +dddd + A23 4567 diff --git a/src/nvim/testdir/test39.ok b/src/nvim/testdir/test39.ok Binary files differindex ef7a2c6442..d8e901563a 100644 --- a/src/nvim/testdir/test39.ok +++ b/src/nvim/testdir/test39.ok diff --git a/src/nvim/testdir/test63.in b/src/nvim/testdir/test63.in index ea66ee6dea..ff05afbf81 100644 --- a/src/nvim/testdir/test63.in +++ b/src/nvim/testdir/test63.in @@ -3,6 +3,7 @@ Test for ":match", ":2match", ":3match", "clearmatches()", "getmatches()", STARTTEST :so small.vim +:set encoding=utf8 :" --- Check that "matcharg()" returns the correct group and pattern if a match :" --- is defined. :let @r = "*** Test 1: " @@ -164,7 +165,27 @@ STARTTEST :if v1 != v5 && v6 == v1 && v8 == v5 && v10 == v5 && v11 == v1 : let @r .= "OK\n" :else -: let @r .= "FAILED\n" +: let @r .= "FAILED: " . v5 . "/" . v6 . "/" . v8 . "/" . v10 . "/" . v11 . "\n" +:endif +:call clearmatches() +:" +:call setline(1, 'abcdΣabcdef') +:call matchaddpos("MyGroup1", [[1, 4, 2], [1, 9, 2]]) +:1 +:redraw! +:let v1 = screenattr(1, 1) +:let v4 = screenattr(1, 4) +:let v5 = screenattr(1, 5) +:let v6 = screenattr(1, 6) +:let v7 = screenattr(1, 7) +:let v8 = screenattr(1, 8) +:let v9 = screenattr(1, 9) +:let v10 = screenattr(1, 10) +:let @r .= string(getmatches())."\n" +:if v1 != v4 && v5 == v4 && v6 == v1 && v7 == v1 && v8 == v4 && v9 == v4 && v10 == v1 +: let @r .= "OK\n" +:else +: let @r .= "FAILED: " . v4 . "/" . v5 . "/" . v6 . "/" . v7 . "/" . v8 . "/" . v9 . "/" . v10 . "\n" :endif :call clearmatches() G"rp diff --git a/src/nvim/testdir/test63.ok b/src/nvim/testdir/test63.ok index f804b693ac..5d619395b7 100644 --- a/src/nvim/testdir/test63.ok +++ b/src/nvim/testdir/test63.ok @@ -12,3 +12,5 @@ Results of test63: *** Test 11: [{'group': 'MyGroup1', 'id': 3, 'priority': 10, 'pos1': [1, 5, 1], 'pos2': [1, 8, 3]}] OK +[{'group': 'MyGroup1', 'id': 11, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1, 9, 2]}] +OK diff --git a/src/nvim/testdir/test_changelist.in b/src/nvim/testdir/test_changelist.in new file mode 100644 index 0000000000..6c7c4306c3 --- /dev/null +++ b/src/nvim/testdir/test_changelist.in @@ -0,0 +1,22 @@ +Test changelist position after splitting window +Set 'undolevels' to make changelist for sourced file + +STARTTEST +:so small.vim +Gkylp:set ul=100 +Gylp:set ul=100 +gg +:vsplit +:try +: normal g; +: normal ggVGcpass +:catch +: normal ggVGcfail +:finally +: %w! test.out +:endtry +:qa! +ENDTEST + +1 +2 diff --git a/src/nvim/testdir/test_changelist.ok b/src/nvim/testdir/test_changelist.ok new file mode 100644 index 0000000000..2ae28399f5 --- /dev/null +++ b/src/nvim/testdir/test_changelist.ok @@ -0,0 +1 @@ +pass diff --git a/src/nvim/version.c b/src/nvim/version.c index 200d34e2fb..bcde020839 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -217,13 +217,13 @@ static int included_patches[] = { //414, //413 NA //412 NA - //411, + 411, 410, //409 NA //408, - //407, + 407, //406, - //405, + 405, //404 NA //403 NA //402, @@ -237,12 +237,12 @@ static int included_patches[] = { //394, //393, 392, - //391, + 391, //390, //389, 388, 387, - //386, + 386, //385, //384 NA 383, @@ -268,7 +268,7 @@ static int included_patches[] = { //363, 362, 361, - //360, + 360, 359, 358, 357, diff --git a/src/nvim/window.c b/src/nvim/window.c index f41a5d8872..2a6dcf1743 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -948,6 +948,9 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) p_wh = size; } + // Keep same changelist position in new window. + wp->w_changelistidx = oldwin->w_changelistidx; + /* * make the new window the current window */ @@ -1674,13 +1677,12 @@ close_windows ( int keep_curwin /* don't close "curwin" */ ) { - win_T *wp; tabpage_T *tp, *nexttp; int h = tabline_height(); ++RedrawingDisabled; - for (wp = firstwin; wp != NULL && lastwin != firstwin; ) { + for (win_T *wp = firstwin; wp != NULL && lastwin != firstwin; ) { if (wp->w_buffer == buf && (!keep_curwin || wp != curwin) && !(wp->w_closing || wp->w_buffer->b_closing) ) { @@ -1695,8 +1697,8 @@ close_windows ( /* Also check windows in other tab pages. */ for (tp = first_tabpage; tp != NULL; tp = nexttp) { nexttp = tp->tp_next; - if (tp != curtab) - for (wp = tp->tp_firstwin; wp != NULL; wp = wp->w_next) + if (tp != curtab) { + FOR_ALL_WINDOWS_IN_TAB(wp, tp) { if (wp->w_buffer == buf && !(wp->w_closing || wp->w_buffer->b_closing) ) { @@ -1707,6 +1709,8 @@ close_windows ( nexttp = first_tabpage; break; } + } + } } --RedrawingDisabled; @@ -1963,7 +1967,6 @@ int win_close(win_T *win, int free_buf) */ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) { - win_T *wp; int dir; tabpage_T *ptp = NULL; int free_tp = FALSE; @@ -1982,10 +1985,18 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) return; /* Autocommands may have closed the window already. */ - for (wp = tp->tp_firstwin; wp != NULL && wp != win; wp = wp->w_next) - ; - if (wp == NULL) - return; + { + bool found_window = false; + FOR_ALL_WINDOWS_IN_TAB(wp, tp) { + if (wp == win) { + found_window = true; + break; + } + } + if (!found_window) { + return; + } + } /* When closing the last window in a tab page remove the tab page. */ if (tp->tp_firstwin == tp->tp_lastwin) { @@ -2986,14 +2997,14 @@ int make_tabpages(int maxcount) /* * Return TRUE when "tpc" points to a valid tab page. */ -int valid_tabpage(tabpage_T *tpc) +bool valid_tabpage(tabpage_T *tpc) { - tabpage_T *tp; - - for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) - if (tp == tpc) - return TRUE; - return FALSE; + FOR_ALL_TABS(tp) { + if (tp == tpc) { + return true; + } + } + return false; } /* @@ -3285,14 +3296,11 @@ void win_goto(win_T *wp) */ tabpage_T *win_find_tabpage(win_T *win) { - win_T *wp; - tabpage_T *tp; - - for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) - for (wp = (tp == curtab ? firstwin : tp->tp_firstwin); - wp != NULL; wp = wp->w_next) - if (wp == win) - return tp; + FOR_ALL_TAB_WINDOWS(tp, wp) { + if (wp == win) { + return tp; + } + } return NULL; } @@ -3549,28 +3557,36 @@ win_T *buf_jump_open_win(buf_T *buf) */ win_T *buf_jump_open_tab(buf_T *buf) { - win_T *wp; - tabpage_T *tp; - /* First try the current tab page. */ - wp = buf_jump_open_win(buf); - if (wp != NULL) - return wp; + // First try the current tab page. + { + win_T *wp = buf_jump_open_win(buf); + if (wp != NULL) + return wp; + } - for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) + FOR_ALL_TABS(tp) { + // Skip the current tab since we already checked it. if (tp != curtab) { - for (wp = tp->tp_firstwin; wp != NULL; wp = wp->w_next) - if (wp->w_buffer == buf) - break; - if (wp != NULL) { - goto_tabpage_win(tp, wp); - if (curwin != wp) - wp = NULL; /* something went wrong */ - break; + FOR_ALL_WINDOWS_IN_TAB(wp, tp) { + if (wp->w_buffer == buf) { + goto_tabpage_win(tp, wp); + + // If we the current window didn't switch, + // something went wrong. + if (curwin != wp) { + wp = NULL; + } + + // Return the window we switched to. + return wp; + } } } + } - return wp; + // If we made it this far, we didn't find the buffer. + return NULL; } /* @@ -4968,18 +4984,15 @@ int tabline_height(void) */ int min_rows(void) { - int total; - tabpage_T *tp; - int n; - if (firstwin == NULL) /* not initialized yet */ return MIN_LINES; - total = 0; - for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) { - n = frame_minheight(tp->tp_topframe, NULL); - if (total < n) + int total = 0; + FOR_ALL_TABS(tp) { + int n = frame_minheight(tp->tp_topframe, NULL); + if (total < n) { total = n; + } } total += tabline_height(); total += 1; /* count the room for the command line */ @@ -5019,16 +5032,15 @@ int only_one_window(void) */ void check_lnums(int do_curwin) { - win_T *wp; - - tabpage_T *tp; - - FOR_ALL_TAB_WINDOWS(tp, wp) - if ((do_curwin || wp != curwin) && wp->w_buffer == curbuf) { - if (wp->w_cursor.lnum > curbuf->b_ml.ml_line_count) - wp->w_cursor.lnum = curbuf->b_ml.ml_line_count; - if (wp->w_topline > curbuf->b_ml.ml_line_count) - wp->w_topline = curbuf->b_ml.ml_line_count; + FOR_ALL_TAB_WINDOWS(tp, wp) { + if ((do_curwin || wp != curwin) && wp->w_buffer == curbuf) { + if (wp->w_cursor.lnum > curbuf->b_ml.ml_line_count) { + wp->w_cursor.lnum = curbuf->b_ml.ml_line_count; + } + if (wp->w_topline > curbuf->b_ml.ml_line_count) { + wp->w_topline = curbuf->b_ml.ml_line_count; + } + } } } |