To: vim-dev@vim.org Subject: Patch 6.2.321 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.2.321 Problem: When using modeless selection, wrapping lines are not recognized, a line break is always inserted. Solution: Add LineWraps[] to remember whether a line wrapped or not. Files: src/globals.h, src/screen.c, src/ui.c *** ../vim-6.2.320/src/globals.h Wed Oct 29 14:37:09 2003 --- src/globals.h Sat Mar 6 15:13:54 2004 *************** *** 39,44 **** --- 39,45 ---- EXTERN schar_T *ScreenLines INIT(= NULL); EXTERN sattr_T *ScreenAttrs INIT(= NULL); EXTERN unsigned *LineOffset INIT(= NULL); + EXTERN char_u *LineWraps INIT(= NULL); #ifdef FEAT_MBYTE /* *** ../vim-6.2.320/src/screen.c Sun Jan 25 19:32:46 2004 --- src/screen.c Sat Mar 6 15:32:18 2004 *************** *** 14,23 **** * by remembering what is already on the screen, and only updating the parts * that changed. * ! * ScreenLines[] contains a copy of the whole screen, as it is currently ! * displayed (excluding text written by external commands). ! * ScreenAttrs[] contains the associated attributes. ! * LineOffset[] contains the offset into ScreenLines[] for each line. * For double-byte characters, two consecutive bytes in ScreenLines[] can form * one character which occupies two display cells. * For UTF-8 a multi-byte character is converted to Unicode and stored in --- 14,26 ---- * by remembering what is already on the screen, and only updating the parts * that changed. * ! * ScreenLines[off] Contains a copy of the whole screen, as it is currently ! * displayed (excluding text written by external commands). ! * ScreenAttrs[off] Contains the associated attributes. ! * LineOffset[row] Contains the offset into ScreenLines*[] and ScreenAttrs[] ! * for each line. ! * LineWraps[row] Flag for each line whether it wraps to the next line. ! * * For double-byte characters, two consecutive bytes in ScreenLines[] can form * one character which occupies two display cells. * For UTF-8 a multi-byte character is converted to Unicode and stored in *************** *** 4051,4105 **** break; } ! /* ! * Special trick to make copy/paste of wrapped lines work with ! * xterm/screen: write an extra character beyond the end of the ! * line. This will work with all terminal types (regardless of the ! * xn,am settings). ! * Only do this on a fast tty. ! * Only do this if the cursor is on the current line (something ! * has been written in it). ! * Don't do this for the GUI. ! * Don't do this for double-width characters. ! * Don't do this for a window not at the right screen border. ! */ ! if (p_tf && screen_cur_row == screen_row - 1 ! #ifdef FEAT_GUI ! && !gui.in_use ! #endif #ifdef FEAT_DIFF && filler_todo <= 0 #endif - #ifdef FEAT_MBYTE - && !(has_mbyte - && ((*mb_off2cells)(LineOffset[screen_row]) == 2 - || (*mb_off2cells)(LineOffset[screen_row - 1] - + (int)Columns - 2) == 2)) - #endif && W_WIDTH(wp) == Columns) { ! /* First make sure we are at the end of the screen line, then ! * output the same character again to let the terminal know ! * about the wrap. If the terminal doesn't auto-wrap, we ! * overwrite the character. */ ! if (screen_cur_col != W_WIDTH(wp)) ! screen_char(LineOffset[screen_row - 1] + (unsigned)Columns - 1, screen_row - 1, (int)(Columns - 1)); #ifdef FEAT_MBYTE ! /* When there is a multi-byte character, just output a space ! * to keep it simple. */ ! if (has_mbyte && mb_off2cells(LineOffset[screen_row - 1] + (unsigned)Columns - 1) != 1) ! out_char(' '); ! else #endif ! out_char(ScreenLines[LineOffset[screen_row - 1] + (Columns - 1)]); ! /* force a redraw of the first char on the next line */ ! ScreenAttrs[LineOffset[screen_row]] = (sattr_T)-1; ! screen_start(); /* don't know where cursor is now */ } col = 0; --- 4053,4114 ---- break; } ! if (screen_cur_row == screen_row - 1 #ifdef FEAT_DIFF && filler_todo <= 0 #endif && W_WIDTH(wp) == Columns) { ! /* Remember that the line wraps, used for modeless copy. */ ! LineWraps[screen_row - 1] = TRUE; ! ! /* ! * Special trick to make copy/paste of wrapped lines work with ! * xterm/screen: write an extra character beyond the end of ! * the line. This will work with all terminal types ! * (regardless of the xn,am settings). ! * Only do this on a fast tty. ! * Only do this if the cursor is on the current line ! * (something has been written in it). ! * Don't do this for the GUI. ! * Don't do this for double-width characters. ! * Don't do this for a window not at the right screen border. ! */ ! if (p_tf ! #ifdef FEAT_GUI ! && !gui.in_use ! #endif ! #ifdef FEAT_MBYTE ! && !(has_mbyte ! && ((*mb_off2cells)(LineOffset[screen_row]) == 2 ! || (*mb_off2cells)(LineOffset[screen_row - 1] ! + (int)Columns - 2) == 2)) ! #endif ! ) ! { ! /* First make sure we are at the end of the screen line, ! * then output the same character again to let the ! * terminal know about the wrap. If the terminal doesn't ! * auto-wrap, we overwrite the character. */ ! if (screen_cur_col != W_WIDTH(wp)) ! screen_char(LineOffset[screen_row - 1] + (unsigned)Columns - 1, screen_row - 1, (int)(Columns - 1)); #ifdef FEAT_MBYTE ! /* When there is a multi-byte character, just output a ! * space to keep it simple. */ ! if (has_mbyte && mb_off2cells(LineOffset[screen_row - 1] + (unsigned)Columns - 1) != 1) ! out_char(' '); ! else #endif ! out_char(ScreenLines[LineOffset[screen_row - 1] + (Columns - 1)]); ! /* force a redraw of the first char on the next line */ ! ScreenAttrs[LineOffset[screen_row]] = (sattr_T)-1; ! screen_start(); /* don't know where cursor is now */ ! } } col = 0; *************** *** 4509,4517 **** } } - #ifdef FEAT_VERTSPLIT if (clear_width > 0) { /* For a window that's left of another, draw the separator char. */ if (col + coloff < Columns) { --- 4518,4526 ---- } } if (clear_width > 0) { + #ifdef FEAT_VERTSPLIT /* For a window that's left of another, draw the separator char. */ if (col + coloff < Columns) { *************** *** 4543,4550 **** screen_char(off_to, row, col + coloff); } } ! } #endif } #ifdef FEAT_RIGHTLEFT --- 4552,4561 ---- screen_char(off_to, row, col + coloff); } } ! else #endif + LineWraps[row] = FALSE; + } } #ifdef FEAT_RIGHTLEFT *************** *** 6290,6295 **** --- 6301,6308 ---- c = c2; } } + if (end_col == Columns) + LineWraps[row] = FALSE; if (row == Rows - 1) /* overwritten the command line */ { redraw_cmdline = TRUE; *************** *** 6363,6368 **** --- 6376,6382 ---- #endif sattr_T *new_ScreenAttrs; unsigned *new_LineOffset; + char_u *new_LineWraps; static int entered = FALSE; /* avoid recursiveness */ /* *************** *** 6436,6441 **** --- 6450,6456 ---- (Rows + 1) * Columns * sizeof(sattr_T)), FALSE); new_LineOffset = (unsigned *)lalloc((long_u)( Rows * sizeof(unsigned)), FALSE); + new_LineWraps = (char_u *)lalloc((long_u)(Rows * sizeof(char_u)), FALSE); FOR_ALL_WINDOWS(wp) { *************** *** 6456,6461 **** --- 6471,6477 ---- #endif || new_ScreenAttrs == NULL || new_LineOffset == NULL + || new_LineWraps == NULL || outofmem) { do_outofmem_msg((long_u)((Rows + 1) * Columns)); /* guess the size */ *************** *** 6475,6486 **** --- 6491,6505 ---- new_ScreenAttrs = NULL; vim_free(new_LineOffset); new_LineOffset = NULL; + vim_free(new_LineWraps); + new_LineWraps = NULL; } else { for (new_row = 0; new_row < Rows; ++new_row) { new_LineOffset[new_row] = new_row * Columns; + new_LineWraps[new_row] = FALSE; /* * If the screen is not going to be cleared, copy as much as *************** *** 6564,6569 **** --- 6583,6589 ---- #endif ScreenAttrs = new_ScreenAttrs; LineOffset = new_LineOffset; + LineWraps = new_LineWraps; /* It's important that screen_Rows and screen_Columns reflect the actual * size of ScreenLines[]. Set them before calling anything. */ *************** *** 6636,6642 **** --- 6656,6665 ---- /* blank out ScreenLines */ for (i = 0; i < Rows; ++i) + { lineclear(LineOffset[i], (int)Columns); + LineWraps[i] = FALSE; + } if (can_clear(T_CL)) { *************** *** 7462,7467 **** --- 7485,7491 ---- lineclear(LineOffset[j] + wp->w_wincol, wp->w_width); else lineinvalid(LineOffset[j] + wp->w_wincol, wp->w_width); + LineWraps[j] = FALSE; } else #endif *************** *** 7469,7476 **** --- 7493,7504 ---- j = end - 1 - i; temp = LineOffset[j]; while ((j -= line_count) >= row) + { LineOffset[j + line_count] = LineOffset[j]; + LineWraps[j + line_count] = LineWraps[j]; + } LineOffset[j + line_count] = temp; + LineWraps[j + line_count] = FALSE; if (can_clear((char_u *)" ")) lineclear(temp, (int)Columns); else *************** *** 7691,7696 **** --- 7719,7725 ---- lineclear(LineOffset[j] + wp->w_wincol, wp->w_width); else lineinvalid(LineOffset[j] + wp->w_wincol, wp->w_width); + LineWraps[j] = FALSE; } else #endif *************** *** 7699,7706 **** --- 7728,7739 ---- j = row + i; temp = LineOffset[j]; while ((j += line_count) <= end - 1) + { LineOffset[j - line_count] = LineOffset[j]; + LineWraps[j - line_count] = LineWraps[j]; + } LineOffset[j - line_count] = temp; + LineWraps[j - line_count] = FALSE; if (can_clear((char_u *)" ")) lineclear(temp, (int)Columns); else *** ../vim-6.2.320/src/ui.c Sun Feb 29 14:45:49 2004 --- src/ui.c Sat Mar 6 14:56:35 2004 *************** *** 1183,1189 **** } /* If after the first row, we need to always add a newline */ ! if (row > row1) *bufp++ = NL; if (row < screen_Rows && end_col <= screen_Columns) --- 1183,1189 ---- } /* If after the first row, we need to always add a newline */ ! if (row > row1 && !LineWraps[row - 1]) *bufp++ = NL; if (row < screen_Rows && end_col <= screen_Columns) *** ../vim-6.2.320/src/version.c Sat Mar 6 21:06:59 2004 --- src/version.c Sat Mar 6 21:08:40 2004 *************** *** 639,640 **** --- 639,642 ---- { /* Add new patch number below this line */ + /**/ + 321, /**/ -- No man may purchase alcohol without written consent from his wife. [real standing law in Pennsylvania, United States of America] /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ Project leader for A-A-P -- http://www.A-A-P.org /// \\\ Buy at Amazon and help AIDS victims -- http://ICCF.nl/click1.html ///