*** ../bash-3.2-patched/lib/readline/display.c 2007-12-13 22:31:16.000000000 -0500 --- lib/readline/display.c 2008-05-21 21:39:43.000000000 -0400 *************** *** 1,5 **** /* display.c -- readline redisplay facility. */ ! /* Copyright (C) 1987-2006 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for --- 1,5 ---- /* display.c -- readline redisplay facility. */ ! /* Copyright (C) 1987-2007 Free Software Foundation, Inc. This file is part of the GNU Readline Library, a library for *************** *** 66,79 **** static void cr PARAMS((void)); #if defined (HANDLE_MULTIBYTE) static int _rl_col_width PARAMS((const char *, int, int)); - static int *_rl_wrapped_line; #else # define _rl_col_width(l, s, e) (((e) <= (s)) ? 0 : (e) - (s)) #endif - static int *inv_lbreaks, *vis_lbreaks; - static int inv_lbsize, vis_lbsize; - /* Heuristic used to decide whether it is faster to move from CUR to NEW by backing up or outputting a carriage return and moving forward. CUR --- 66,103 ---- static void cr PARAMS((void)); + /* State of visible and invisible lines. */ + struct line_state + { + char *line; + int *lbreaks; + int lbsize; + #if defined (HANDLE_MULTIBYTE) + int *wrapped_line; + int wbsize; + #endif + }; + + /* The line display buffers. One is the line currently displayed on + the screen. The other is the line about to be displayed. */ + static struct line_state line_state_array[2]; + static struct line_state *line_state_visible = &line_state_array[0]; + static struct line_state *line_state_invisible = &line_state_array[1]; + static int line_structures_initialized = 0; + + /* Backwards-compatible names. */ + #define inv_lbreaks (line_state_invisible->lbreaks) + #define inv_lbsize (line_state_invisible->lbsize) + #define vis_lbreaks (line_state_visible->lbreaks) + #define vis_lbsize (line_state_visible->lbsize) + + #define visible_line (line_state_visible->line) + #define invisible_line (line_state_invisible->line) + #if defined (HANDLE_MULTIBYTE) static int _rl_col_width PARAMS((const char *, int, int)); #else # define _rl_col_width(l, s, e) (((e) <= (s)) ? 0 : (e) - (s)) #endif /* Heuristic used to decide whether it is faster to move from CUR to NEW by backing up or outputting a carriage return and moving forward. CUR *************** *** 84,88 **** buffer index in others. This macro is used when deciding whether the current cursor position is in the middle of a prompt string containing ! invisible characters. */ #define PROMPT_ENDING_INDEX \ ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1) --- 108,112 ---- buffer index in others. This macro is used when deciding whether the current cursor position is in the middle of a prompt string containing ! invisible characters. XXX - might need to take `modmark' into account. */ #define PROMPT_ENDING_INDEX \ ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1) *************** *** 142,145 **** --- 166,170 ---- static int cpos_adjusted; static int cpos_buffer_position; + static int prompt_multibyte_chars; /* Number of lines currently on screen minus 1. */ *************** *** 151,159 **** static int last_lmargin; - /* The line display buffers. One is the line currently displayed on - the screen. The other is the line about to be displayed. */ - static char *visible_line = (char *)NULL; - static char *invisible_line = (char *)NULL; - /* A buffer for `modeline' messages. */ static char msg_buf[128]; --- 176,179 ---- *************** *** 196,199 **** --- 216,223 ---- static int prompt_physical_chars; + /* set to a non-zero value by rl_redisplay if we are marking modified history + lines and the current line is so marked. */ + static int modmark; + /* Variables to save and restore prompt and display information. */ *************** *** 283,286 **** --- 307,315 ---- if (!ignoring) { + /* rl ends up being assigned to prompt_visible_length, + which is the number of characters in the buffer that + contribute to characters on the screen, which might + not be the same as the number of physical characters + on the screen in the presence of multibyte characters */ rl += ind - pind; physchars += _rl_col_width (pmt, pind, ind); *************** *** 444,454 **** /* should be enough. */ inv_lbsize = vis_lbsize = 256; ! inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int)); ! vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int)); #if defined (HANDLE_MULTIBYTE) ! _rl_wrapped_line = (int *)xmalloc (vis_lbsize * sizeof (int)); #endif inv_lbreaks[0] = vis_lbreaks[0] = 0; } } --- 473,491 ---- /* should be enough. */ inv_lbsize = vis_lbsize = 256; ! #if defined (HANDLE_MULTIBYTE) ! line_state_visible->wbsize = vis_lbsize; ! line_state_visible->wrapped_line = (int *)xmalloc (line_state_visible->wbsize * sizeof (int)); ! ! line_state_invisible->wbsize = inv_lbsize; ! line_state_invisible->wrapped_line = (int *)xmalloc (line_state_invisible->wbsize * sizeof (int)); #endif + + inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int)); + vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int)); inv_lbreaks[0] = vis_lbreaks[0] = 0; } + + line_structures_initialized = 1; } *************** *** 460,464 **** register char *line; int inv_botlin, lb_botlin, lb_linenum, o_cpos; ! int newlines, lpos, temp, modmark, n0, num; char *prompt_this_line; #if defined (HANDLE_MULTIBYTE) --- 497,501 ---- register char *line; int inv_botlin, lb_botlin, lb_linenum, o_cpos; ! int newlines, lpos, temp, n0, num; char *prompt_this_line; #if defined (HANDLE_MULTIBYTE) *************** *** 470,480 **** #endif ! if (!readline_echoing_p) return; if (!rl_display_prompt) rl_display_prompt = ""; ! if (invisible_line == 0 || vis_lbreaks == 0) { init_line_structures (0); --- 507,521 ---- #endif ! if (_rl_echoing_p == 0) return; + /* Block keyboard interrupts because this function manipulates global + data structures. */ + _rl_block_sigint (); + if (!rl_display_prompt) rl_display_prompt = ""; ! if (line_structures_initialized == 0) { init_line_structures (0); *************** *** 485,488 **** --- 526,531 ---- cpos_buffer_position = -1; + prompt_multibyte_chars = prompt_visible_length - prompt_physical_chars; + line = invisible_line; out = inv_botlin = 0; *************** *** 562,576 **** } - #if defined (HANDLE_MULTIBYTE) - #define CHECK_INV_LBREAKS() \ - do { \ - if (newlines >= (inv_lbsize - 2)) \ - { \ - inv_lbsize *= 2; \ - inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ - _rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \ - } \ - } while (0) - #else #define CHECK_INV_LBREAKS() \ do { \ --- 605,608 ---- *************** *** 581,585 **** } \ } while (0) - #endif /* HANDLE_MULTIBYTE */ #if defined (HANDLE_MULTIBYTE) --- 613,616 ---- *************** *** 593,600 **** inv_lbsize *= 2; \ inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ - _rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \ } \ inv_lbreaks[++newlines] = out; \ ! _rl_wrapped_line[newlines] = _rl_wrapped_multicolumn; \ lpos = 0; \ } \ --- 624,635 ---- inv_lbsize *= 2; \ inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ } \ inv_lbreaks[++newlines] = out; \ ! if (newlines >= (line_state_invisible->wbsize - 1)) \ ! { \ ! line_state_invisible->wbsize *= 2; \ ! line_state_invisible->wrapped_line = (int *)xrealloc (line_state_invisible->wrapped_line, line_state_invisible->wbsize * sizeof(int)); \ ! } \ ! line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; \ lpos = 0; \ } \ *************** *** 626,630 **** #if defined (HANDLE_MULTIBYTE) ! memset (_rl_wrapped_line, 0, vis_lbsize); num = 0; #endif --- 661,665 ---- #if defined (HANDLE_MULTIBYTE) ! memset (line_state_invisible->wrapped_line, 0, line_state_invisible->wbsize * sizeof (int)); num = 0; #endif *************** *** 648,652 **** Additional logic fix from Edward Catmur */ #if defined (HANDLE_MULTIBYTE) ! if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { n0 = num; --- 683,687 ---- Additional logic fix from Edward Catmur */ #if defined (HANDLE_MULTIBYTE) ! if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0) { n0 = num; *************** *** 671,674 **** --- 706,711 ---- /* Now account for invisible characters in the current line. */ + /* XXX - this assumes that all of the invisible characters are before + the line wrap. */ temp += ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line : ((newlines == 1) ? wrap_offset : 0)) *************** *** 677,681 **** inv_lbreaks[++newlines] = temp; #if defined (HANDLE_MULTIBYTE) ! if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) lpos -= _rl_col_width (local_prompt, n0, num); else --- 714,718 ---- inv_lbreaks[++newlines] = temp; #if defined (HANDLE_MULTIBYTE) ! if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0) lpos -= _rl_col_width (local_prompt, n0, num); else *************** *** 911,914 **** --- 948,955 ---- OFFSET (which has already been calculated above). */ + #define INVIS_FIRST() (prompt_physical_chars > _rl_screenwidth ? prompt_invis_chars_first_line : wrap_offset) + #define WRAP_OFFSET(line, offset) ((line == 0) \ + ? (offset ? INVIS_FIRST() : 0) \ + : ((line == prompt_last_screen_line) ? wrap_offset-prompt_invis_chars_first_line : 0)) #define W_OFFSET(line, offset) ((line) == 0 ? offset : 0) #define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l])) *************** *** 945,949 **** _rl_last_c_pos > wrap_offset && o_cpos < prompt_last_invisible) ! _rl_last_c_pos -= wrap_offset; /* If this is the line with the prompt, we might need to --- 986,1001 ---- _rl_last_c_pos > wrap_offset && o_cpos < prompt_last_invisible) ! _rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */ ! ! else if (linenum == prompt_last_screen_line && prompt_physical_chars > _rl_screenwidth && ! (MB_CUR_MAX > 1 && rl_byte_oriented == 0) && ! cpos_adjusted == 0 && ! _rl_last_c_pos != o_cpos && ! #if 0 ! _rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - (wrap_offset-prompt_invis_chars_first_line))) ! #else ! _rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line)) ! #endif ! _rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line); /* If this is the line with the prompt, we might need to *************** *** 965,968 **** --- 1017,1033 ---- _rl_clear_to_eol (nleft); } + #if 0 + /* This segment is intended to handle the case where the prompt + has invisible characters on the second line and the new line + to be displayed needs to clear the rest of the old characters + out (e.g., when printing the i-search prompt). In general, + the case of the new line being shorter than the old. + Incomplete */ + else if (linenum == prompt_last_screen_line && + prompt_physical_chars > _rl_screenwidth && + wrap_offset != prompt_invis_chars_first_line && + _rl_last_c_pos == out && + #endif + /* Since the new first line is now visible, save its length. */ *************** *** 1020,1028 **** tputs (_rl_term_cr, 1, _rl_output_character_function); #endif _rl_output_some_chars (local_prompt, nleft); if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) ! _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft) - wrap_offset; else ! _rl_last_c_pos = nleft; } --- 1085,1096 ---- tputs (_rl_term_cr, 1, _rl_output_character_function); #endif + if (modmark) + _rl_output_some_chars ("*", 1); + _rl_output_some_chars (local_prompt, nleft); if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) ! _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft) - wrap_offset + modmark; else ! _rl_last_c_pos = nleft + modmark; } *************** *** 1160,1174 **** /* Swap visible and non-visible lines. */ { ! char *vtemp = visible_line; ! int *itemp = vis_lbreaks, ntemp = vis_lbsize; ! ! visible_line = invisible_line; ! invisible_line = vtemp; ! vis_lbreaks = inv_lbreaks; ! inv_lbreaks = itemp; ! ! vis_lbsize = inv_lbsize; ! inv_lbsize = ntemp; rl_display_fixed = 0; --- 1228,1235 ---- /* Swap visible and non-visible lines. */ { ! struct line_state *vtemp = line_state_visible; ! line_state_visible = line_state_invisible; ! line_state_invisible = vtemp; rl_display_fixed = 0; *************** *** 1181,1184 **** --- 1242,1247 ---- visible_wrap_offset = wrap_offset; } + + _rl_release_sigint (); } *************** *** 1205,1209 **** { register char *ofd, *ols, *oe, *nfd, *nls, *ne; ! int temp, lendiff, wsatend, od, nd, o_cpos; int current_invis_chars; int col_lendiff, col_temp; --- 1268,1272 ---- { register char *ofd, *ols, *oe, *nfd, *nls, *ne; ! int temp, lendiff, wsatend, od, nd, twidth, o_cpos; int current_invis_chars; int col_lendiff, col_temp; *************** *** 1221,1225 **** temp = _rl_last_c_pos; else ! temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset); if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode && _rl_last_v_pos == current_line - 1) --- 1284,1288 ---- temp = _rl_last_c_pos; else ! temp = _rl_last_c_pos - WRAP_OFFSET (_rl_last_v_pos, visible_wrap_offset); if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode && _rl_last_v_pos == current_line - 1) *************** *** 1236,1241 **** character comsumes more than three columns, spaces will be inserted in the string buffer. */ ! if (_rl_wrapped_line[current_line] > 0) ! _rl_clear_to_eol (_rl_wrapped_line[current_line]); memset (&ps, 0, sizeof (mbstate_t)); --- 1299,1304 ---- character comsumes more than three columns, spaces will be inserted in the string buffer. */ ! if (current_line < line_state_visible->wbsize && line_state_visible->wrapped_line[current_line] > 0) ! _rl_clear_to_eol (line_state_visible->wrapped_line[current_line]); memset (&ps, 0, sizeof (mbstate_t)); *************** *** 1301,1305 **** only change is adding characters. */ temp = (omax < nmax) ? omax : nmax; ! if (memcmp (old, new, temp) == 0) { ofd = old + temp; --- 1364,1368 ---- only change is adding characters. */ temp = (omax < nmax) ? omax : nmax; ! if (memcmp (old, new, temp) == 0) /* adding at the end */ { ofd = old + temp; *************** *** 1454,1457 **** --- 1517,1522 ---- tputs (_rl_term_cr, 1, _rl_output_character_function); #endif + if (modmark) + _rl_output_some_chars ("*", 1); _rl_output_some_chars (local_prompt, lendiff); if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) *************** *** 1459,1467 **** /* We take wrap_offset into account here so we can pass correct information to _rl_move_cursor_relative. */ ! _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff) - wrap_offset; cpos_adjusted = 1; } else ! _rl_last_c_pos = lendiff; } --- 1524,1532 ---- /* We take wrap_offset into account here so we can pass correct information to _rl_move_cursor_relative. */ ! _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff) - wrap_offset + modmark; cpos_adjusted = 1; } else ! _rl_last_c_pos = lendiff + modmark; } *************** *** 1477,1481 **** invisible characters in the prompt string. Let's see if setting this when we make sure we're at the end of the drawn prompt string works. */ ! if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 && (_rl_last_c_pos > 0 || o_cpos > 0) && _rl_last_c_pos == prompt_physical_chars) --- 1542,1546 ---- invisible characters in the prompt string. Let's see if setting this when we make sure we're at the end of the drawn prompt string works. */ ! if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 && (_rl_last_c_pos > 0 || o_cpos > 0) && _rl_last_c_pos == prompt_physical_chars) *************** *** 1587,1599 **** { _rl_output_some_chars (nfd + lendiff, temp - lendiff); - #if 1 /* XXX -- this bears closer inspection. Fixes a redisplay bug reported against bash-3.0-alpha by Andreas Schwab involving multibyte characters and prompt strings with invisible characters, but was previously disabled. */ ! _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-col_lendiff); ! #else ! _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-lendiff); ! #endif } } --- 1652,1664 ---- { _rl_output_some_chars (nfd + lendiff, temp - lendiff); /* XXX -- this bears closer inspection. Fixes a redisplay bug reported against bash-3.0-alpha by Andreas Schwab involving multibyte characters and prompt strings with invisible characters, but was previously disabled. */ ! if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) ! twidth = _rl_col_width (nfd+lendiff, 0, temp-col_lendiff); ! else ! twidth = temp - lendiff; ! _rl_last_c_pos += twidth; } } *************** *** 1635,1640 **** if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { ! _rl_last_c_pos += _rl_col_width (nfd, 0, temp); ! if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible)) { _rl_last_c_pos -= wrap_offset; --- 1700,1705 ---- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { ! _rl_last_c_pos += _rl_col_width (nfd, 0, temp); ! if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible)) { _rl_last_c_pos -= wrap_offset; *************** *** 1642,1647 **** } } ! else ! _rl_last_c_pos += temp; } } --- 1707,1712 ---- } } ! else ! _rl_last_c_pos += temp; } } *************** *** 1789,1793 **** int cpos, dpos; /* current and desired cursor positions */ ! woff = W_OFFSET (_rl_last_v_pos, wrap_offset); cpos = _rl_last_c_pos; #if defined (HANDLE_MULTIBYTE) --- 1854,1858 ---- int cpos, dpos; /* current and desired cursor positions */ ! woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset); cpos = _rl_last_c_pos; #if defined (HANDLE_MULTIBYTE) *************** *** 1803,1807 **** prompt string, since they're both buffer indices and DPOS is a desired display position. */ ! if (new > prompt_last_invisible) /* XXX - don't use woff here */ { dpos -= woff; --- 1868,1876 ---- prompt string, since they're both buffer indices and DPOS is a desired display position. */ ! if ((new > prompt_last_invisible) || /* XXX - don't use woff here */ ! (prompt_physical_chars > _rl_screenwidth && ! _rl_last_v_pos == prompt_last_screen_line && ! wrap_offset != woff && ! new > (prompt_last_invisible-_rl_screenwidth-wrap_offset))) { dpos -= woff; *************** *** 2216,2220 **** if (MB_CUR_MAX == 1 || rl_byte_oriented) if (count != col) ! fprintf(stderr, "readline: debug: insert_some_chars: count (%d) != col (%d)\n", count, col); /* If IC is defined, then we do not have to "enter" insert mode. */ --- 2285,2289 ---- if (MB_CUR_MAX == 1 || rl_byte_oriented) if (count != col) ! _rl_ttymsg ("debug: insert_some_chars: count (%d) != col (%d)", count, col); /* If IC is defined, then we do not have to "enter" insert mode. */ *************** *** 2357,2364 **** char *t; ! /* Clear the current line and put the cursor at column 0. Make sure ! the right thing happens if we have wrapped to a new screen line. */ if (_rl_term_cr) { #if defined (__MSDOS__) putc ('\r', rl_outstream); --- 2426,2437 ---- char *t; ! /* Clear the last line (assuming that the screen size change will result in ! either more or fewer characters on that line only) and put the cursor at ! column 0. Make sure the right thing happens if we have wrapped to a new ! screen line. */ if (_rl_term_cr) { + _rl_move_vert (_rl_vis_botlin); + #if defined (__MSDOS__) putc ('\r', rl_outstream); *************** *** 2396,2400 **** _rl_clean_up_for_exit () { ! if (readline_echoing_p) { _rl_move_vert (_rl_vis_botlin); --- 2469,2473 ---- _rl_clean_up_for_exit () { ! if (_rl_echoing_p) { _rl_move_vert (_rl_vis_botlin); *************** *** 2452,2456 **** --- 2525,2532 ---- return 0; if (MB_CUR_MAX == 1 || rl_byte_oriented) + { + _rl_ttymsg ("_rl_col_width: called with MB_CUR_MAX == 1"); return (end - start); + } memset (&ps, 0, sizeof (mbstate_t));