From 4980981dad0acce71154205f3839e27f753274f1 Mon Sep 17 00:00:00 2001 From: edyfox Date: Thu, 12 Mar 2009 08:26:05 +0000 Subject: [PATCH] Merged from the latest developing branch. git-svn-id: https://vim.svn.sourceforge.net/svnroot/vim/trunk@1410 2a77ed30-b011-0410-a7ad-c7884a0aa172 --- src/diff.c | 2 +- src/ex_docmd.c | 15 ++++- src/fileio.c | 9 ++- src/misc2.c | 11 +++- src/ops.c | 144 ++++++++++++++++++++++++++------------------- src/screen.c | 86 ++++++++++++++++++--------- src/testdir/Make_amiga.mak | 4 +- src/testdir/Make_dos.mak | 2 +- src/testdir/Make_ming.mak | 2 +- src/testdir/Make_os2.mak | 3 +- src/testdir/Make_vms.mms | 5 +- src/testdir/Makefile | 2 +- src/testdir/test66.in | 25 ++++++++ src/testdir/test66.ok | 10 ++++ src/version.c | 18 ++++++ 15 files changed, 233 insertions(+), 105 deletions(-) create mode 100644 src/testdir/test66.in create mode 100644 src/testdir/test66.ok diff --git a/src/diff.c b/src/diff.c index c20d095d..34e78b6d 100644 --- a/src/diff.c +++ b/src/diff.c @@ -1153,7 +1153,7 @@ ex_diffoff(eap) for (wp = firstwin; wp != NULL; wp = wp->w_next) { - if (wp == curwin || eap->forceit) + if (wp == curwin || (eap->forceit && wp->w_p_diff)) { /* Set 'diff', 'scrollbind' off and 'wrap' on. */ wp->w_p_diff = FALSE; diff --git a/src/ex_docmd.c b/src/ex_docmd.c index c730d761..66d7fa96 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -5124,7 +5124,11 @@ uc_add_command(name, name_len, rep, argt, def, flags, compl, compl_arg, force) } vim_free(cmd->uc_rep); - cmd->uc_rep = 0; + cmd->uc_rep = NULL; +#if defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL) + vim_free(cmd->uc_compl_arg); + cmd->uc_compl_arg = NULL; +#endif break; } @@ -5941,7 +5945,7 @@ do_ucmd(eap) for (;;) { p = cmd->uc_rep; /* source */ - q = buf; /* destinateion */ + q = buf; /* destination */ totlen = 0; for (;;) @@ -7846,6 +7850,9 @@ free_cd_dir() { vim_free(prev_dir); prev_dir = NULL; + + vim_free(globaldir); + globaldir = NULL; } #endif @@ -7868,6 +7875,10 @@ ex_cd(eap) else #endif { +#ifdef FEAT_AUTOCMD + if (allbuf_locked()) + return; +#endif if (vim_strchr(p_cpo, CPO_CHDIR) != NULL && curbufIsChanged() && !eap->forceit) { diff --git a/src/fileio.c b/src/fileio.c index 342cf590..0d0269b7 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -5288,13 +5288,16 @@ buf_write_bytes(ip) /* Convert with iconv(). */ if (ip->bw_restlen > 0) { + char *fp; + /* Need to concatenate the remainder of the previous call and * the bytes of the current call. Use the end of the * conversion buffer for this. */ fromlen = len + ip->bw_restlen; - from = (char *)ip->bw_conv_buf + ip->bw_conv_buflen - fromlen; - mch_memmove((void *)from, ip->bw_rest, (size_t)ip->bw_restlen); - mch_memmove((void *)(from + ip->bw_restlen), buf, (size_t)len); + fp = (char *)ip->bw_conv_buf + ip->bw_conv_buflen - fromlen; + mch_memmove(fp, ip->bw_rest, (size_t)ip->bw_restlen); + mch_memmove(fp + ip->bw_restlen, buf, (size_t)len); + from = fp; tolen = ip->bw_conv_buflen - fromlen; } else diff --git a/src/misc2.c b/src/misc2.c index fafe931e..cfc1bad8 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -496,7 +496,8 @@ check_cursor_col() { colnr_T len; #ifdef FEAT_VIRTUALEDIT - colnr_T oldcol = curwin->w_cursor.col + curwin->w_cursor.coladd; + colnr_T oldcol = curwin->w_cursor.col; + colnr_T oldcoladd = curwin->w_cursor.col + curwin->w_cursor.coladd; #endif len = (colnr_T)STRLEN(ml_get_curline()); @@ -535,7 +536,13 @@ check_cursor_col() if (oldcol == MAXCOL) curwin->w_cursor.coladd = 0; else if (ve_flags == VE_ALL) - curwin->w_cursor.coladd = oldcol - curwin->w_cursor.col; + { + if (oldcoladd > curwin->w_cursor.col) + curwin->w_cursor.coladd = oldcoladd - curwin->w_cursor.col; + else + /* avoid weird number when there is a miscalculation or overflow */ + curwin->w_cursor.coladd = 0; + } #endif } diff --git a/src/ops.c b/src/ops.c index 557985c3..b60fca3e 100644 --- a/src/ops.c +++ b/src/ops.c @@ -72,11 +72,11 @@ static struct yankreg *y_previous = NULL; /* ptr to last written yankreg */ */ struct block_def { - int startspaces; /* 'extra' cols of first char */ - int endspaces; /* 'extra' cols of first char */ + int startspaces; /* 'extra' cols before first char */ + int endspaces; /* 'extra' cols after last char */ int textlen; /* chars in block */ - char_u *textstart; /* pointer to 1st char in block */ - colnr_T textcol; /* cols of chars (at least part.) in block */ + char_u *textstart; /* pointer to 1st char (partially) in block */ + colnr_T textcol; /* index of chars (partially) in block */ colnr_T start_vcol; /* start col of 1st char wholly inside block */ colnr_T end_vcol; /* start col of 1st char wholly after block */ #ifdef FEAT_VISUALEXTRA @@ -382,15 +382,14 @@ shift_block(oap, amount) { int left = (oap->op_type == OP_LSHIFT); int oldstate = State; - int total, split; - char_u *newp, *oldp, *midp, *ptr; + int total; + char_u *newp, *oldp; int oldcol = curwin->w_cursor.col; int p_sw = (int)curbuf->b_p_sw; int p_ts = (int)curbuf->b_p_ts; struct block_def bd; - int internal = 0; int incr; - colnr_T vcol, col = 0, ws_vcol; + colnr_T ws_vcol; int i = 0, j = 0; int len; @@ -456,67 +455,89 @@ shift_block(oap, amount) } else /* left */ { - vcol = oap->start_vcol; - /* walk vcol past ws to be removed */ - for (midp = oldp + bd.textcol; - vcol < (oap->start_vcol + total) && vim_iswhite(*midp); ) - { - incr = lbr_chartabsize_adv(&midp, (colnr_T)vcol); - vcol += incr; - } - /* internal is the block-internal ws replacing a split TAB */ - if (vcol > (oap->start_vcol + total)) - { - /* we have to split the TAB *(midp-1) */ - internal = vcol - (oap->start_vcol + total); - } - /* if 'expandtab' is not set, use TABs */ + colnr_T destination_col; /* column to which text in block will + be shifted */ + char_u *verbatim_copy_end; /* end of the part of the line which is + copied verbatim */ + colnr_T verbatim_copy_width;/* the (displayed) width of this part + of line */ + unsigned fill; /* nr of spaces that replace a TAB */ + unsigned new_line_len; /* the length of the line after the + block shift */ + size_t block_space_width; + size_t shift_amount; + char_u *non_white = bd.textstart; + colnr_T non_white_col; - split = bd.startspaces + internal; - if (split > 0) - { - if (!curbuf->b_p_et) - { - for (ptr = oldp, col = 0; ptr < oldp+bd.textcol; ) - col += lbr_chartabsize_adv(&ptr, (colnr_T)col); + /* + * Firstly, let's find the first non-whitespace character that is + * displayed after the block's start column and the character's column + * number. Also, let's calculate the width of all the whitespace + * characters that are displayed in the block and precede the searched + * non-whitespace character. + */ - /* col+1 now equals the start col of the first char of the - * block (may be < oap.start_vcol if we're splitting a TAB) */ - i = ((col % p_ts) + split) / p_ts; /* number of tabs */ - } - if (i) - j = ((col % p_ts) + split) % p_ts; /* number of spp */ - else - j = split; - } + /* If "bd.startspaces" is set, "bd.textstart" points to the character, + * the part of which is displayed at the block's beginning. Let's start + * searching from the next character. */ + if (bd.startspaces) + mb_ptr_adv(non_white); - newp = alloc_check(bd.textcol + i + j + (unsigned)STRLEN(midp) + 1); - if (newp == NULL) - return; - vim_memset(newp, NUL, (size_t)(bd.textcol + i + j + STRLEN(midp) + 1)); + /* The character's column is in "bd.start_vcol". */ + non_white_col = bd.start_vcol; - /* copy first part we want to keep */ - mch_memmove(newp, oldp, (size_t)bd.textcol); - /* Now copy any TABS and spp to ensure correct alignment! */ - while (vim_iswhite(*midp)) + while (vim_iswhite(*non_white)) { - if (*midp == TAB) - i++; - else /*space */ - j++; - midp++; + incr = lbr_chartabsize_adv(&non_white, non_white_col); + non_white_col += incr; } - /* We might have an extra TAB worth of spp now! */ - if (j / p_ts && !curbuf->b_p_et) + + block_space_width = non_white_col - oap->start_vcol; + /* We will shift by "total" or "block_space_width", whichever is less. + */ + shift_amount = (block_space_width < total? block_space_width: total); + + /* The column to which we will shift the text. */ + destination_col = non_white_col - shift_amount; + + /* Now let's find out how much of the beginning of the line we can + * reuse without modification. */ + verbatim_copy_end = bd.textstart; + verbatim_copy_width = bd.start_vcol; + + /* If "bd.startspaces" is set, "bd.textstart" points to the character + * preceding the block. We have to subtract its width to obtain its + * column number. */ + if (bd.startspaces) + verbatim_copy_width -= bd.start_char_vcols; + while (verbatim_copy_width < destination_col) { - i++; - j -= p_ts; + incr = lbr_chartabsize(verbatim_copy_end, verbatim_copy_width); + if (verbatim_copy_width + incr > destination_col) + break; + verbatim_copy_width += incr; + mb_ptr_adv(verbatim_copy_end); } - copy_chars(newp + bd.textcol, (size_t)i, TAB); - copy_spaces(newp + bd.textcol + i, (size_t)j); - /* the end */ - STRMOVE(newp + STRLEN(newp), midp); + /* If "destination_col" is different from the width of the initial + * part of the line that will be copied, it means we encountered a tab + * character, which we will have to partly replace with spaces. */ + fill = destination_col - verbatim_copy_width; + + /* The replacement line will consist of: + * - the beginning of the original line up to "verbatim_copy_end", + * - "fill" number of spaces, + * - the rest of the line, pointed to by non_white. */ + new_line_len = (unsigned)(verbatim_copy_end - oldp) + + fill + + (unsigned)STRLEN(non_white) + 1; + + newp = alloc_check(new_line_len); + if (newp == NULL) + return; + mch_memmove(newp, oldp, (size_t)(verbatim_copy_end - oldp)); + copy_spaces(newp + (verbatim_copy_end - oldp), (size_t)fill); + STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white); } /* replace the line */ ml_replace(curwin->w_cursor.lnum, newp, FALSE); @@ -4851,7 +4872,8 @@ paragraph_start(lnum) * - textlen includes the first/last char to be (partly) deleted * - start/endspaces is the number of columns that are taken by the * first/last deleted char minus the number of columns that have to be - * deleted. for yank and tilde: + * deleted. + * for yank and tilde: * - textlen includes the first/last char to be wholly yanked * - start/endspaces is the number of columns of the first/last yanked char * that are to be yanked. diff --git a/src/screen.c b/src/screen.c index 6d408eb9..d2785c46 100644 --- a/src/screen.c +++ b/src/screen.c @@ -3555,7 +3555,8 @@ win_line(wp, lnum, startrow, endrow, nochange) /* Use line_attr when not in the Visual or 'incsearch' area * (area_attr may be 0 when "noinvcur" is set). */ else if (line_attr != 0 && ((fromcol == -10 && tocol == MAXCOL) - || (vcol < fromcol || vcol >= tocol))) + || vcol < fromcol || vcol_prev < fromcol_prev + || vcol >= tocol)) char_attr = line_attr; #endif else @@ -5131,8 +5132,8 @@ screen_line(row, coloff, endcol, clear_width #endif #if defined(FEAT_GUI) || defined(UNIX) - /* The bold trick makes a single row of pixels appear in the next - * character. When a bold character is removed, the next + /* The bold trick makes a single column of pixels appear in the + * next character. When a bold character is removed, the next * character should be redrawn too. This happens for our own GUI * and for some xterms. */ if ( @@ -6275,9 +6276,15 @@ screen_puts_len(text, len, row, col, attr) int pcc[MAX_MCO]; # endif #endif +#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX) + int force_redraw_this; + int force_redraw_next = FALSE; +#endif + int need_redraw; if (ScreenLines == NULL || row >= screen_Rows) /* safety check */ return; + off = LineOffset[row] + col; #ifdef FEAT_MBYTE /* When drawing over the right halve of a double-wide char clear out the @@ -6287,10 +6294,21 @@ screen_puts_len(text, len, row, col, attr) && !gui.in_use # endif && mb_fix_col(col, row) != col) - screen_puts_len((char_u *)" ", 1, row, col - 1, 0); + { + ScreenLines[off - 1] = ' '; + ScreenAttrs[off - 1] = 0; + if (enc_utf8) + { + ScreenLinesUC[off - 1] = 0; + ScreenLinesC[0][off - 1] = 0; + } + /* redraw the previous cell, make it empty */ + screen_char(off - 1, row, col - 1); + /* force the cell at "col" to be redrawn */ + force_redraw_next = TRUE; + } #endif - off = LineOffset[row] + col; #ifdef FEAT_MBYTE max_off = LineOffset[row] + screen_Columns; #endif @@ -6354,7 +6372,12 @@ screen_puts_len(text, len, row, col, attr) } #endif - if (ScreenLines[off] != c +#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX) + force_redraw_this = force_redraw_next; + force_redraw_next = FALSE; +#endif + + need_redraw = ScreenLines[off] != c #ifdef FEAT_MBYTE || (mbyte_cells == 2 && ScreenLines[off + 1] != (enc_dbcs ? ptr[1] : 0)) @@ -6366,20 +6389,20 @@ screen_puts_len(text, len, row, col, attr) || screen_comp_differs(off, u8cc))) #endif || ScreenAttrs[off] != attr - || exmode_active + || exmode_active; + + if (need_redraw +#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX) + || force_redraw_this +#endif ) { #if defined(FEAT_GUI) || defined(UNIX) /* The bold trick makes a single row of pixels appear in the next * character. When a bold character is removed, the next * character should be redrawn too. This happens for our own GUI - * and for some xterms. - * Force the redraw by setting the attribute to a different value - * than "attr", the contents of ScreenLines[] may be needed by - * mb_off2cells() further on. - * Don't do this for the last drawn character, because the next - * character may not be redrawn. */ - if ( + * and for some xterms. */ + if (need_redraw && ScreenLines[off] != ' ' && ( # ifdef FEAT_GUI gui.in_use # endif @@ -6389,23 +6412,14 @@ screen_puts_len(text, len, row, col, attr) # ifdef UNIX term_is_xterm # endif - ) + )) { - int n; + int n = ScreenAttrs[off]; - n = ScreenAttrs[off]; -# ifdef FEAT_MBYTE - if (col + mbyte_cells < screen_Columns - && (n > HL_ALL || (n & HL_BOLD)) - && (len < 0 ? ptr[mbyte_blen] != NUL - : ptr + mbyte_blen < text + len)) - ScreenAttrs[off + mbyte_cells] = attr + 1; -# else - if (col + 1 < screen_Columns - && (n > HL_ALL || (n & HL_BOLD)) - && (len < 0 ? ptr[1] != NUL : ptr + 1 < text + len)) - ScreenLines[off + 1] = 0; -# endif + if (n > HL_ALL) + n = syn_attr2attr(n); + if (n & HL_BOLD) + force_redraw_next = TRUE; } #endif #ifdef FEAT_MBYTE @@ -6492,6 +6506,20 @@ screen_puts_len(text, len, row, col, attr) ++ptr; } } + +#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX) + /* If we detected the next character needs to be redrawn, but the text + * doesn't extend up to there, update the character here. */ + if (force_redraw_next && col < screen_Columns) + { +# ifdef FEAT_MBYTE + if (enc_dbcs != 0 && dbcs_off2cells(off, max_off) > 1) + screen_char_2(off, row, col); + else +# endif + screen_char(off, row, col); + } +#endif } #ifdef FEAT_SEARCH_EXTRA diff --git a/src/testdir/Make_amiga.mak b/src/testdir/Make_amiga.mak index 826b2445..50f4141c 100644 --- a/src/testdir/Make_amiga.mak +++ b/src/testdir/Make_amiga.mak @@ -25,7 +25,8 @@ SCRIPTS = test1.out test3.out test4.out test5.out test6.out \ test43.out test44.out test45.out test46.out test47.out \ test48.out test51.out test53.out test54.out test55.out \ test56.out test57.out test58.out test59.out test60.out \ - test61.out test62.out test63.out test64.out test65.out + test61.out test62.out test63.out test64.out test65.out \ + test66.out .SUFFIXES: .in .out @@ -110,3 +111,4 @@ test62.out: test62.in test63.out: test63.in test64.out: test64.in test65.out: test65.in +test66.out: test66.in diff --git a/src/testdir/Make_dos.mak b/src/testdir/Make_dos.mak index 829bf887..efe75685 100644 --- a/src/testdir/Make_dos.mak +++ b/src/testdir/Make_dos.mak @@ -26,7 +26,7 @@ SCRIPTS = test3.out test4.out test5.out test6.out test7.out \ test15.out test17.out test18.out test21.out test26.out \ test30.out test31.out test32.out test33.out test34.out \ test37.out test38.out test39.out test40.out test41.out \ - test42.out test52.out test65.out + test42.out test52.out test65.out test66.out SCRIPTS32 = test50.out diff --git a/src/testdir/Make_ming.mak b/src/testdir/Make_ming.mak index e94dcaa6..3ed77e57 100644 --- a/src/testdir/Make_ming.mak +++ b/src/testdir/Make_ming.mak @@ -45,7 +45,7 @@ SCRIPTS = test3.out test4.out test5.out test6.out test7.out \ test15.out test17.out test18.out test21.out test26.out \ test30.out test31.out test32.out test33.out test34.out \ test37.out test38.out test39.out test40.out test41.out \ - test42.out test52.out test65.out + test42.out test52.out test65.out test66.out SCRIPTS32 = test50.out diff --git a/src/testdir/Make_os2.mak b/src/testdir/Make_os2.mak index cbf0a846..e6696d87 100644 --- a/src/testdir/Make_os2.mak +++ b/src/testdir/Make_os2.mak @@ -25,7 +25,8 @@ SCRIPTS = test1.out test3.out test4.out test5.out test6.out \ test43.out test44.out test45.out test46.out test47.out \ test48.out test51.out test53.out test54.out test55.out \ test56.out test57.out test58.out test59.out test60.out \ - test61.out test62.out test63.out test64.out test65.out + test61.out test62.out test63.out test64.out test65.out \ + test66.out .SUFFIXES: .in .out diff --git a/src/testdir/Make_vms.mms b/src/testdir/Make_vms.mms index dc6ff96a..dfc79dd8 100644 --- a/src/testdir/Make_vms.mms +++ b/src/testdir/Make_vms.mms @@ -4,7 +4,7 @@ # Authors: Zoltan Arpadffy, # Sandor Kopanyi, # -# Last change: 2008 Aug 19 +# Last change: 2009 Mar 05 # # This has been tested on VMS 6.2 to 8.3 on DEC Alpha, VAX and IA64. # Edit the lines in the Configuration section below to select. @@ -68,7 +68,8 @@ SCRIPT = test1.out test2.out test3.out test4.out test5.out \ test43.out test44.out test45.out test46.out \ test48.out test51.out test53.out test54.out test55.out \ test56.out test57.out test60.out \ - test61.out test62.out test63.out test64.out test65.out + test61.out test62.out test63.out test64.out test65.out \ + test66.out .IFDEF WANT_GUI SCRIPT_GUI = test16.out diff --git a/src/testdir/Makefile b/src/testdir/Makefile index 3528bf6f..b60bd488 100644 --- a/src/testdir/Makefile +++ b/src/testdir/Makefile @@ -20,7 +20,7 @@ SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \ test48.out test49.out test51.out test52.out test53.out \ test54.out test55.out test56.out test57.out test58.out \ test59.out test60.out test61.out test62.out test63.out \ - test64.out test65.out + test64.out test65.out test66.out SCRIPTS_GUI = test16.out diff --git a/src/testdir/test66.in b/src/testdir/test66.in new file mode 100644 index 00000000..113b5406 --- /dev/null +++ b/src/testdir/test66.in @@ -0,0 +1,25 @@ + +Test for visual block shift and tab characters. + +STARTTEST +:so small.vim +/^abcdefgh +4jI j<<11|D +7|a  +7|a  +7|a 4k13|4j< +:$-4,$w! test.out +:$-4,$s/\s\+//g +4kI j<< +7|a  +7|a  +7|a 4k13|4j3< +:$-4,$w >> test.out +:qa! +ENDTEST + +abcdefghijklmnopqrstuvwxyz +abcdefghijklmnopqrstuvwxyz +abcdefghijklmnopqrstuvwxyz +abcdefghijklmnopqrstuvwxyz +abcdefghijklmnopqrstuvwxyz diff --git a/src/testdir/test66.ok b/src/testdir/test66.ok new file mode 100644 index 00000000..2c2249b0 --- /dev/null +++ b/src/testdir/test66.ok @@ -0,0 +1,10 @@ + abcdefghijklmnopqrstuvwxyz +abcdefghij + abc defghijklmnopqrstuvwxyz + abc defghijklmnopqrstuvwxyz + abc defghijklmnopqrstuvwxyz + abcdefghijklmnopqrstuvwxyz +abcdefghij + abc defghijklmnopqrstuvwxyz + abc defghijklmnopqrstuvwxyz + abc defghijklmnopqrstuvwxyz diff --git a/src/version.c b/src/version.c index 4388cd20..e9dd2723 100644 --- a/src/version.c +++ b/src/version.c @@ -677,6 +677,24 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 141, +/**/ + 140, +/**/ + 139, +/**/ + 138, +/**/ + 137, +/**/ + 136, +/**/ + 135, +/**/ + 134, +/**/ + 133, +/**/ 132, /**/ 131, -- 2.11.4.GIT