diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/buffer.c | 2 | ||||
-rw-r--r-- | src/nvim/eval.c | 31 | ||||
-rw-r--r-- | src/nvim/fileio.c | 8 | ||||
-rw-r--r-- | src/nvim/globals.h | 8 | ||||
-rw-r--r-- | src/nvim/screen.c | 82 | ||||
-rw-r--r-- | src/nvim/testdir/Makefile | 1 | ||||
-rw-r--r-- | src/nvim/testdir/test63.in | 23 | ||||
-rw-r--r-- | src/nvim/testdir/test63.ok | 2 | ||||
-rw-r--r-- | src/nvim/testdir/test_changelist.in | 22 | ||||
-rw-r--r-- | src/nvim/testdir/test_changelist.ok | 1 | ||||
-rw-r--r-- | src/nvim/version.c | 10 | ||||
-rw-r--r-- | src/nvim/window.c | 10 |
12 files changed, 149 insertions, 51 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 4eff8df9f5..83cddb85bf 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -318,7 +318,7 @@ close_buffer ( } else if (buf->b_p_bh[0] == 'u') /* 'bufhidden' == "unload" */ unload_buf = true; - if (win != NULL) { + if (win_valid(win)) { /* Set b_last_cursor when closing the last window for the buffer. * Remember the last cursor position and window options of the buffer. * This used to be only for the current window, but then options like diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 28f16d0e92..0ae96365b2 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -13461,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) @@ -13487,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/fileio.c b/src/nvim/fileio.c index ec91949def..fbce4428db 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -6750,7 +6750,8 @@ apply_autocmds_group ( --nesting; /* see matching increment above */ // When stopping to execute autocommands, restore the search patterns and - // the redo buffer. Free buffers in the au_pending_free_buf list. + // the redo buffer. Free any buffers in the au_pending_free_buf list and + // free any windows in the au_pending_free_win list. if (!autocmd_busy) { restore_search_patterns(); restoreRedobuff(); @@ -6760,6 +6761,11 @@ apply_autocmds_group ( free(au_pending_free_buf); au_pending_free_buf = b; } + while (au_pending_free_win != NULL) { + win_T *w = au_pending_free_win->w_next; + free(au_pending_free_win); + au_pending_free_win = w; + } } /* diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 465a48e5b2..2025295c11 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -468,10 +468,12 @@ EXTERN int keep_filetype INIT(= FALSE); /* value for did_filetype when * which one is preferred, au_new_curbuf is set to it */ EXTERN buf_T *au_new_curbuf INIT(= NULL); -// When deleting the buffer and autocmd_busy is TRUE, do not free the buffer -// but link it in the list starting with au_pending_free_buf, using b_next. -// Free the buffer when autocmd_busy is set to FALSE. +// When deleting a buffer/window and autocmd_busy is TRUE, do not free the +// buffer/window. but link it in the list starting with +// au_pending_free_buf/ap_pending_free_win, using b_next/w_next. +// Free the buffer/window when autocmd_busy is being set to FALSE. EXTERN buf_T *au_pending_free_buf INIT(= NULL); +EXTERN win_T *au_pending_free_win INIT(= NULL); /* * Mouse coordinates, set by check_termcode() diff --git a/src/nvim/screen.c b/src/nvim/screen.c index e882935e39..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; @@ -7091,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, @@ -7264,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, @@ -7630,7 +7641,7 @@ void unshowmode(int force) static void draw_tabline(void) { int tabcount = 0; - int tabwidth; + int tabwidth = 0; int col = 0; int scol = 0; int attr; @@ -7676,9 +7687,13 @@ static void draw_tabline(void) ++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; @@ -7720,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/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 cc1d5abc3f..1482ec4a5a 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -230,13 +230,13 @@ static int included_patches[] = { //414, //413 NA //412 NA - //411, + 411, 410, //409 NA //408, 407, //406, - //405, + 405, //404 NA //403 NA //402, @@ -250,12 +250,12 @@ static int included_patches[] = { //394, //393, 392, - //391, + 391, //390, //389, 388, 387, - //386, + 386, //385, //384 NA 383, @@ -321,7 +321,7 @@ static int included_patches[] = { 323, //322 NA //321 NA - //320, + 320, //319 NA 318, 317, diff --git a/src/nvim/window.c b/src/nvim/window.c index fbb283899b..4f94284186 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -950,6 +950,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 */ @@ -3694,7 +3697,12 @@ win_free ( if (wp != aucmd_win) win_remove(wp, tp); - free(wp); + if (autocmd_busy) { + wp->w_next = au_pending_free_win; + au_pending_free_win = wp; + } else { + free(wp); + } unblock_autocmds(); } |