1 /* display.c -- readline redisplay facility. */
3 /* Copyright (C) 1987-2017 Free Software Foundation, Inc.
5 This file is part of the GNU Readline Library (Readline), a library
6 for reading lines of text with interactive input and history editing.
8 Readline is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 Readline is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with Readline. If not, see <http://www.gnu.org/licenses/>.
22 #define READLINE_LIBRARY
24 #if defined (HAVE_CONFIG_H)
28 #include <sys/types.h>
30 #if defined (HAVE_UNISTD_H)
32 #endif /* HAVE_UNISTD_H */
34 #include "posixstat.h"
36 #if defined (HAVE_STDLIB_H)
39 # include "ansi_stdlib.h"
40 #endif /* HAVE_STDLIB_H */
48 /* System-specific feature definitions and include files. */
52 /* Termcap library stuff. */
55 /* Some standard library routines. */
59 #include "rlprivate.h"
62 #if !defined (strchr) && !defined (__STDC__)
63 extern char *strchr (), *strrchr ();
64 #endif /* !strchr && !__STDC__ */
66 static void update_line PARAMS((char *, char *, int, int, int, int));
67 static void space_to_eol PARAMS((int));
68 static void delete_chars PARAMS((int));
69 static void insert_some_chars PARAMS((char *, int, int));
70 static void open_some_spaces PARAMS((int));
71 static void cr PARAMS((void));
72 static void redraw_prompt PARAMS((char *));
74 /* Values for FLAGS */
75 #define PMT_MULTILINE 0x01
77 static char *expand_prompt PARAMS((char *, int, int *, int *, int *, int *));
79 /* State of visible and invisible lines. */
85 #if defined (HANDLE_MULTIBYTE)
91 /* The line display buffers. One is the line currently displayed on
92 the screen. The other is the line about to be displayed. */
93 static struct line_state line_state_array[2];
94 static struct line_state *line_state_visible = &line_state_array[0];
95 static struct line_state *line_state_invisible = &line_state_array[1];
96 static int line_structures_initialized = 0;
98 /* Backwards-compatible names. */
99 #define inv_lbreaks (line_state_invisible->lbreaks)
100 #define inv_lbsize (line_state_invisible->lbsize)
101 #define vis_lbreaks (line_state_visible->lbreaks)
102 #define vis_lbsize (line_state_visible->lbsize)
104 #define visible_line (line_state_visible->line)
105 #define invisible_line (line_state_invisible->line)
107 #if defined (HANDLE_MULTIBYTE)
108 static int _rl_col_width PARAMS((const char *, int, int, int));
110 # define _rl_col_width(l, s, e, f) (((e) <= (s)) ? 0 : (e) - (s))
113 /* Heuristic used to decide whether it is faster to move from CUR to NEW
114 by backing up or outputting a carriage return and moving forward. CUR
115 and NEW are either both buffer positions or absolute screen positions. */
116 #define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))
118 /* _rl_last_c_pos is an absolute cursor position in multibyte locales and a
119 buffer index in others. This macro is used when deciding whether the
120 current cursor position is in the middle of a prompt string containing
121 invisible characters. XXX - might need to take `modmark' into account. */
122 /* XXX - only valid when tested against _rl_last_c_pos; buffer indices need
123 to use prompt_last_invisible directly. */
124 #define PROMPT_ENDING_INDEX \
125 ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1)
127 /* **************************************************************** */
131 /* **************************************************************** */
133 /* This is the stuff that is hard for me. I never seem to write good
134 display routines in C. Let's see how I do this time. */
136 /* (PWP) Well... Good for a simple line updater, but totally ignores
137 the problems of input lines longer than the screen width.
139 update_line and the code that calls it makes a multiple line,
140 automatically wrapping line update. Careful attention needs
141 to be paid to the vertical position variables. */
143 /* Keep two buffers; one which reflects the current contents of the
144 screen, and the other to draw what we think the new contents should
145 be. Then compare the buffers, and make whatever changes to the
146 screen itself that we should. Finally, make the buffer that we
147 just drew into be the one which reflects the current contents of the
148 screen, and place the cursor where it belongs.
150 Commands that want to can fix the display themselves, and then let
151 this function know that the display has been fixed by setting the
152 RL_DISPLAY_FIXED variable. This is good for efficiency. */
154 /* Application-specific redisplay function. */
155 rl_voidfunc_t *rl_redisplay_function = rl_redisplay;
157 /* Global variables declared here. */
158 /* What YOU turn on when you have handled all redisplay yourself. */
159 int rl_display_fixed = 0;
161 /* The stuff that gets printed out before the actual text of the line.
162 This is usually pointing to rl_prompt. */
163 char *rl_display_prompt = (char *)NULL;
165 /* Variables used to include the editing mode in the prompt. */
166 char *_rl_emacs_mode_str;
167 int _rl_emacs_modestr_len;
169 char *_rl_vi_ins_mode_str;
170 int _rl_vi_ins_modestr_len;
172 char *_rl_vi_cmd_mode_str;
173 int _rl_vi_cmd_modestr_len;
175 /* Pseudo-global variables declared here. */
177 /* Hints for other parts of readline to give to the display engine. */
178 int _rl_suppress_redisplay = 0;
179 int _rl_want_redisplay = 0;
181 /* The visible cursor position. If you print some text, adjust this. */
182 /* NOTE: _rl_last_c_pos is used as a buffer index when not in a locale
183 supporting multibyte characters, and an absolute cursor position when
184 in such a locale. This is an artifact of the donated multibyte support.
185 Care must be taken when modifying its value. */
186 int _rl_last_c_pos = 0;
187 int _rl_last_v_pos = 0;
189 /* Number of physical lines consumed by the current line buffer currently
190 on screen minus 1. */
191 int _rl_vis_botlin = 0;
193 /* This is a hint update_line gives to rl_redisplay that it has adjusted the
194 value of _rl_last_c_pos *and* taken the presence of any invisible chars in
195 the prompt into account. rl_redisplay notes this and does not do the
196 adjustment itself. */
197 static int cpos_adjusted;
199 /* The index into the line buffer corresponding to the cursor position */
200 static int cpos_buffer_position;
202 /* A flag to note when we're displaying the first line of the prompt */
203 static int displaying_prompt_first_line;
204 /* The number of multibyte characters in the prompt, if any */
205 static int prompt_multibyte_chars;
207 static int _rl_inv_botlin = 0;
209 /* Variables used only in this file. */
210 /* The last left edge of text that was displayed. This is used when
211 doing horizontal scrolling. It shifts in thirds of a screenwidth. */
212 static int last_lmargin;
214 /* A buffer for `modeline' messages. */
215 static char *msg_buf = 0;
216 static int msg_bufsiz = 0;
218 /* Non-zero forces the redisplay even if we thought it was unnecessary. */
219 static int forced_display;
221 /* Default and initial buffer size. Can grow. */
222 static int line_size = 1024;
224 /* Variables to keep track of the expanded prompt string, which may
225 include invisible characters. */
227 static char *local_prompt, *local_prompt_prefix;
228 static int local_prompt_len;
229 static int prompt_prefix_length;
230 /* Number of chars in the buffer that contribute to visible chars on the screen.
231 This might be different from the number of physical chars in the presence
232 of multibyte characters */
233 static int prompt_visible_length;
235 /* The number of invisible characters in the line currently being
236 displayed on the screen. */
237 static int visible_wrap_offset;
239 /* The number of invisible characters in the prompt string. Static so it
240 can be shared between rl_redisplay and update_line */
241 static int wrap_offset;
243 /* The index of the last invisible character in the prompt string. */
244 static int prompt_last_invisible;
246 /* The length (buffer offset) of the first line of the last (possibly
247 multi-line) buffer displayed on the screen. */
248 static int visible_first_line_len;
250 /* Number of invisible characters on the first physical line of the prompt.
251 Only valid when the number of physical characters in the prompt exceeds
252 (or is equal to) _rl_screenwidth. */
253 static int prompt_invis_chars_first_line;
255 static int prompt_last_screen_line;
257 static int prompt_physical_chars;
259 /* An array of indexes into the prompt string where we will break physical
260 screen lines. It's easier to compute in expand_prompt and use later in
261 rl_redisplay instead of having rl_redisplay try to guess about invisible
262 characters in the prompt or use heuristics about where they are. */
263 static int *local_prompt_newlines;
265 /* set to a non-zero value by rl_redisplay if we are marking modified history
266 lines and the current line is so marked. */
269 static int line_totbytes;
271 /* Variables to save and restore prompt and display information. */
273 /* These are getting numerous enough that it's time to create a struct. */
275 static char *saved_local_prompt;
276 static char *saved_local_prefix;
277 static int *saved_local_prompt_newlines;
279 static int saved_last_invisible;
280 static int saved_visible_length;
281 static int saved_prefix_length;
282 static int saved_local_length;
283 static int saved_invis_chars_first_line;
284 static int saved_physical_chars;
286 /* Return a string indicating the editing mode, for use in the prompt. */
289 prompt_modestr (int *lenp)
291 if (rl_editing_mode == emacs_mode)
294 *lenp = _rl_emacs_mode_str ? _rl_emacs_modestr_len : RL_EMACS_MODESTR_DEFLEN;
295 return _rl_emacs_mode_str ? _rl_emacs_mode_str : RL_EMACS_MODESTR_DEFAULT;
297 else if (_rl_keymap == vi_insertion_keymap)
300 *lenp = _rl_vi_ins_mode_str ? _rl_vi_ins_modestr_len : RL_VI_INS_MODESTR_DEFLEN;
301 return _rl_vi_ins_mode_str ? _rl_vi_ins_mode_str : RL_VI_INS_MODESTR_DEFAULT; /* vi insert mode */
306 *lenp = _rl_vi_cmd_mode_str ? _rl_vi_cmd_modestr_len : RL_VI_CMD_MODESTR_DEFLEN;
307 return _rl_vi_cmd_mode_str ? _rl_vi_cmd_mode_str : RL_VI_CMD_MODESTR_DEFAULT; /* vi command mode */
311 /* Expand the prompt string S and return the number of visible
312 characters in *LP, if LP is not null. This is currently more-or-less
313 a placeholder for expansion. LIP, if non-null is a place to store the
314 index of the last invisible character in the returned string. NIFLP,
315 if non-zero, is a place to store the number of invisible characters in
316 the first prompt line. The previous are used as byte counts -- indexes
317 into a character buffer. *VLP gets the number of physical characters in
318 the expanded prompt (visible length) */
320 /* Current implementation:
321 \001 (^A) start non-visible characters
322 \002 (^B) end non-visible characters
323 all characters except \001 and \002 (following a \001) are copied to
324 the returned string; all characters except those between \001 and
325 \002 are assumed to be `visible'. */
327 /* Possible values for FLAGS:
328 PMT_MULTILINE caller indicates that this is part of a multiline prompt
331 /* This approximates the number of lines the prompt will take when displayed */
332 #define APPROX_DIV(n, d) (((n) < (d)) ? 1 : ((n) / (d)) + 1)
335 expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp)
337 char *r, *ret, *p, *igstart, *nprompt, *ms;
338 int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
339 int mlen, newlines, newlines_guess, bound;
342 /* We only expand the mode string for the last line of a multiline prompt
343 (a prompt with embedded newlines). */
344 ms = (((pmt == rl_prompt) ^ (flags & PMT_MULTILINE)) && _rl_show_mode_in_prompt) ? prompt_modestr (&mlen) : 0;
348 nprompt = (char *)xmalloc (l + mlen + 1);
349 memcpy (nprompt, ms, mlen);
350 strcpy (nprompt + mlen, pmt);
355 mb_cur_max = MB_CUR_MAX;
357 if (_rl_screenwidth == 0)
358 _rl_get_screen_size (0, 0); /* avoid division by zero */
360 /* Short-circuit if we can. We can do this if we are treating the prompt as
361 a sequence of bytes and there are no invisible characters in the prompt
362 to deal with. Since we populate local_prompt_newlines, we have to run
363 through the rest of the function if this prompt looks like it's going to
364 be longer than one screen line. */
365 if ((mb_cur_max <= 1 || rl_byte_oriented) && strchr (nprompt, RL_PROMPT_START_IGNORE) == 0)
367 l = strlen (nprompt);
368 if (l < (_rl_screenwidth > 0 ? _rl_screenwidth : 80))
370 r = (nprompt == pmt) ? savestring (pmt) : nprompt;
380 local_prompt_newlines = (int *) xrealloc (local_prompt_newlines, sizeof (int) * 2);
381 local_prompt_newlines[0] = 0;
382 local_prompt_newlines[1] = -1;
388 l = strlen (nprompt); /* XXX */
389 r = ret = (char *)xmalloc (l + 1);
391 /* Guess at how many screen lines the prompt will take to size the array that
392 keeps track of where the line wraps happen */
393 newlines_guess = (_rl_screenwidth > 0) ? APPROX_DIV(l, _rl_screenwidth) : APPROX_DIV(l, 80);
394 local_prompt_newlines = (int *) xrealloc (local_prompt_newlines, sizeof (int) * (newlines_guess + 1));
395 local_prompt_newlines[newlines = 0] = 0;
396 for (rl = 1; rl <= newlines_guess; rl++)
397 local_prompt_newlines[rl] = -1;
399 rl = physchars = 0; /* mode string now part of nprompt */
400 invfl = 0; /* invisible chars in first line of prompt */
401 invflset = 0; /* we only want to set invfl once */
402 igstart = 0; /* we're not ignoring any characters yet */
404 for (ignoring = last = ninvis = 0, p = nprompt; p && *p; p++)
406 /* This code strips the invisible character string markers
407 RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
408 if (ignoring == 0 && *p == RL_PROMPT_START_IGNORE) /* XXX - check ignoring? */
414 else if (ignoring && *p == RL_PROMPT_END_IGNORE)
417 if (p != (igstart + 1))
423 #if defined (HANDLE_MULTIBYTE)
424 if (mb_cur_max > 1 && rl_byte_oriented == 0)
427 ind = _rl_find_next_mbchar (nprompt, pind, 1, MB_FIND_NONZERO);
433 /* rl ends up being assigned to prompt_visible_length,
434 which is the number of characters in the buffer that
435 contribute to characters on the screen, which might
436 not be the same as the number of physical characters
437 on the screen in the presence of multibyte characters */
439 physchars += _rl_col_width (nprompt, pind, ind, 0);
442 ninvis += ind - pind;
443 p--; /* compensate for later increment */
451 rl++; /* visible length byte counter */
455 ninvis++; /* invisible chars byte counter */
458 if (invflset == 0 && physchars >= _rl_screenwidth)
464 if (physchars >= (bound = (newlines + 1) * _rl_screenwidth) && local_prompt_newlines[newlines+1] == -1)
467 if (physchars > bound) /* should rarely happen */
469 #if defined (HANDLE_MULTIBYTE)
470 *r = '\0'; /* need null-termination for strlen */
471 if (mb_cur_max > 1 && rl_byte_oriented == 0)
472 new = _rl_find_prev_mbchar (ret, r - ret, MB_FIND_ANY);
475 new = r - ret - (physchars - bound); /* XXX */
479 local_prompt_newlines[++newlines] = new;
484 if (rl < _rl_screenwidth)
503 /* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from
504 PMT and return the rest of PMT. */
506 _rl_strip_prompt (char *pmt)
510 ret = expand_prompt (pmt, 0, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL);
515 _rl_reset_prompt (void)
517 rl_visible_prompt_length = rl_expand_prompt (rl_prompt);
521 * Expand the prompt string into the various display components, if
524 * local_prompt = expanded last line of string in rl_display_prompt
525 * (portion after the final newline)
526 * local_prompt_prefix = portion before last newline of rl_display_prompt,
527 * expanded via expand_prompt
528 * prompt_visible_length = number of visible characters in local_prompt
529 * prompt_prefix_length = number of visible characters in local_prompt_prefix
531 * It also tries to keep track of the number of invisible characters in the
532 * prompt string, and where they are.
534 * This function is called once per call to readline(). It may also be
535 * called arbitrarily to expand the primary prompt.
537 * The return value is the number of visible characters on the last line
538 * of the (possibly multi-line) prompt. In this case, multi-line means
539 * there are embedded newlines in the prompt string itself, not that the
540 * number of physical characters exceeds the screen width and the prompt
544 rl_expand_prompt (char *prompt)
549 /* Clear out any saved values. */
551 FREE (local_prompt_prefix);
553 local_prompt = local_prompt_prefix = (char *)0;
554 local_prompt_len = 0;
555 prompt_last_invisible = prompt_invis_chars_first_line = 0;
556 prompt_visible_length = prompt_physical_chars = 0;
558 if (prompt == 0 || *prompt == 0)
561 p = strrchr (prompt, '\n');
564 /* The prompt is only one logical line, though it might wrap. */
565 local_prompt = expand_prompt (prompt, 0, &prompt_visible_length,
566 &prompt_last_invisible,
567 &prompt_invis_chars_first_line,
568 &prompt_physical_chars);
569 local_prompt_prefix = (char *)0;
570 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
571 return (prompt_visible_length);
575 /* The prompt spans multiple lines. */
577 local_prompt = expand_prompt (p, PMT_MULTILINE,
578 &prompt_visible_length,
579 &prompt_last_invisible,
580 &prompt_invis_chars_first_line,
581 &prompt_physical_chars);
583 /* The portion of the prompt string up to and including the
584 final newline is now null-terminated. */
585 local_prompt_prefix = expand_prompt (prompt, PMT_MULTILINE,
586 &prompt_prefix_length,
591 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
592 return (prompt_prefix_length);
596 /* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their associated
597 arrays of line break markers. MINSIZE is the minimum size of VISIBLE_LINE
598 and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is
599 increased. If the lines have already been allocated, this ensures that
600 they can hold at least MINSIZE characters. */
602 init_line_structures (int minsize)
606 if (minsize <= _rl_screenwidth) /* XXX - for gdb */
607 minsize = _rl_screenwidth + 1;
609 if (invisible_line == 0) /* initialize it */
611 if (line_size < minsize)
613 visible_line = (char *)xmalloc (line_size);
614 invisible_line = (char *)xmalloc (line_size);
616 else if (line_size < minsize) /* ensure it can hold MINSIZE chars */
619 if (line_size < minsize)
621 visible_line = (char *)xrealloc (visible_line, line_size);
622 invisible_line = (char *)xrealloc (invisible_line, line_size);
625 for (n = minsize; n < line_size; n++)
628 invisible_line[n] = 1;
631 if (vis_lbreaks == 0)
633 /* should be enough. */
634 inv_lbsize = vis_lbsize = 256;
636 #if defined (HANDLE_MULTIBYTE)
637 line_state_visible->wbsize = vis_lbsize;
638 line_state_visible->wrapped_line = (int *)xmalloc (line_state_visible->wbsize * sizeof (int));
640 line_state_invisible->wbsize = inv_lbsize;
641 line_state_invisible->wrapped_line = (int *)xmalloc (line_state_invisible->wbsize * sizeof (int));
644 inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int));
645 vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int));
646 inv_lbreaks[0] = vis_lbreaks[0] = 0;
649 line_structures_initialized = 1;
652 /* Basic redisplay algorithm. See comments inline. */
656 register int in, out, c, linenum, cursor_linenum;
658 int inv_botlin, lb_botlin, lb_linenum, o_cpos;
659 int newlines, lpos, temp, n0, num, prompt_lines_estimate;
660 char *prompt_this_line;
661 int mb_cur_max = MB_CUR_MAX;
662 #if defined (HANDLE_MULTIBYTE)
667 int _rl_wrapped_multicolumn = 0;
670 if (_rl_echoing_p == 0)
673 /* Block keyboard interrupts because this function manipulates global
676 RL_SETSTATE (RL_STATE_REDISPLAYING);
678 if (!rl_display_prompt)
679 rl_display_prompt = "";
681 if (line_structures_initialized == 0)
683 init_line_structures (0);
686 else if (line_size <= _rl_screenwidth)
687 init_line_structures (_rl_screenwidth + 1);
689 /* Draw the line into the buffer. */
690 cpos_buffer_position = -1;
692 prompt_multibyte_chars = prompt_visible_length - prompt_physical_chars;
694 line = invisible_line;
695 out = inv_botlin = 0;
697 /* Mark the line as modified or not. We only do this for history
700 if (_rl_mark_modified_lines && current_history () && rl_undo_list)
707 /* If someone thought that the redisplay was handled, but the currently
708 visible line has a different modification state than the one about
709 to become visible, then correct the caller's misconception. */
710 if (visible_line[0] != invisible_line[0])
711 rl_display_fixed = 0;
713 /* If the prompt to be displayed is the `primary' readline prompt (the
714 one passed to readline()), use the values we have already expanded.
715 If not, use what's already in rl_display_prompt. WRAP_OFFSET is the
716 number of non-visible characters in the prompt string. */
717 /* This is where we output the characters in the prompt before the last
718 newline, if any. If there aren't any embedded newlines, we don't
719 write anything. Copy the last line of the prompt string into the line in
721 if (rl_display_prompt == rl_prompt || local_prompt)
723 if (local_prompt_prefix && forced_display)
724 _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
726 if (local_prompt_len > 0)
728 temp = local_prompt_len + out + 2;
729 if (temp >= line_size)
731 line_size = (temp + 1024) - (temp % 1024);
732 visible_line = (char *)xrealloc (visible_line, line_size);
733 line = invisible_line = (char *)xrealloc (invisible_line, line_size);
735 strncpy (line + out, local_prompt, local_prompt_len);
736 out += local_prompt_len;
739 wrap_offset = local_prompt_len - prompt_visible_length;
744 prompt_this_line = strrchr (rl_display_prompt, '\n');
745 if (!prompt_this_line)
746 prompt_this_line = rl_display_prompt;
750 pmtlen = prompt_this_line - rl_display_prompt; /* temp var */
753 _rl_output_some_chars (rl_display_prompt, pmtlen);
754 /* Make sure we are at column zero even after a newline,
755 regardless of the state of terminal output processing. */
756 if (pmtlen < 2 || prompt_this_line[-2] != '\r')
761 prompt_physical_chars = pmtlen = strlen (prompt_this_line);
762 temp = pmtlen + out + 2;
763 if (temp >= line_size)
765 line_size = (temp + 1024) - (temp % 1024);
766 visible_line = (char *)xrealloc (visible_line, line_size);
767 line = invisible_line = (char *)xrealloc (invisible_line, line_size);
769 strncpy (line + out, prompt_this_line, pmtlen);
772 wrap_offset = prompt_invis_chars_first_line = 0;
775 #if defined (HANDLE_MULTIBYTE)
776 #define CHECK_INV_LBREAKS() \
778 if (newlines >= (inv_lbsize - 2)) \
781 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
783 if (newlines >= (line_state_invisible->wbsize - 2)) \
785 line_state_invisible->wbsize *= 2; \
786 line_state_invisible->wrapped_line = (int *)xrealloc (line_state_invisible->wrapped_line, line_state_invisible->wbsize * sizeof(int)); \
790 #define CHECK_INV_LBREAKS() \
792 if (newlines >= (inv_lbsize - 2)) \
795 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
798 #endif /* !HANDLE_MULTIBYTE */
800 #if defined (HANDLE_MULTIBYTE)
801 #define CHECK_LPOS() \
804 if (lpos >= _rl_screenwidth) \
806 if (newlines >= (inv_lbsize - 2)) \
809 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
811 inv_lbreaks[++newlines] = out; \
812 if (newlines >= (line_state_invisible->wbsize - 2)) \
814 line_state_invisible->wbsize *= 2; \
815 line_state_invisible->wrapped_line = (int *)xrealloc (line_state_invisible->wrapped_line, line_state_invisible->wbsize * sizeof(int)); \
817 line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; \
822 #define CHECK_LPOS() \
825 if (lpos >= _rl_screenwidth) \
827 if (newlines >= (inv_lbsize - 2)) \
830 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
832 inv_lbreaks[++newlines] = out; \
838 /* inv_lbreaks[i] is where line i starts in the buffer. */
839 inv_lbreaks[newlines = 0] = 0;
840 /* lpos is a physical cursor position, so it needs to be adjusted by the
841 number of invisible characters in the prompt, per line. We compute
842 the line breaks in the prompt string in expand_prompt, taking invisible
843 characters into account, and if lpos exceeds the screen width, we copy
844 the data in the loop below. */
845 lpos = prompt_physical_chars + modmark;
847 #if defined (HANDLE_MULTIBYTE)
848 memset (line_state_invisible->wrapped_line, 0, line_state_invisible->wbsize * sizeof (int));
852 /* prompt_invis_chars_first_line is the number of invisible characters in
853 the first physical line of the prompt.
854 wrap_offset - prompt_invis_chars_first_line is usually the number of
855 invis chars on the second (or, more generally, last) line. */
857 /* This is zero-based, used to set the newlines */
858 prompt_lines_estimate = lpos / _rl_screenwidth;
860 /* what if lpos is already >= _rl_screenwidth before we start drawing the
861 contents of the command line? */
862 if (lpos >= _rl_screenwidth)
866 /* first copy the linebreaks array we computed in expand_prompt */
867 while (local_prompt_newlines[newlines+1] != -1)
869 temp = local_prompt_newlines[newlines+1];
870 inv_lbreaks[++newlines] = temp;
873 /* Now set lpos from the last newline */
874 if (mb_cur_max > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
875 lpos = _rl_col_width (local_prompt, temp, local_prompt_len, 1) - (wrap_offset - prompt_invis_chars_first_line);
877 lpos -= (_rl_screenwidth * newlines);
880 prompt_last_screen_line = newlines;
882 /* Draw the rest of the line (after the prompt) into invisible_line, keeping
883 track of where the cursor is (cpos_buffer_position), the number of the
884 line containing the cursor (lb_linenum), the last line number (lb_botlin
886 It maintains an array of line breaks for display (inv_lbreaks).
887 This handles expanding tabs for display and displaying meta characters. */
889 #if defined (HANDLE_MULTIBYTE)
891 if (mb_cur_max > 1 && rl_byte_oriented == 0)
893 memset (&ps, 0, sizeof (mbstate_t));
894 if (_rl_utf8locale && UTF8_SINGLEBYTE(rl_line_buffer[0]))
896 wc = (wchar_t)rl_line_buffer[0];
900 wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps);
906 for (in = 0; in < rl_end; in++)
909 c = (unsigned char)rl_line_buffer[in];
911 #if defined (HANDLE_MULTIBYTE)
912 if (mb_cur_max > 1 && rl_byte_oriented == 0)
914 if (MB_INVALIDCH (wc_bytes))
916 /* Byte sequence is invalid or shortened. Assume that the
917 first byte represents a character. */
919 /* Assume that a character occupies a single column. */
921 memset (&ps, 0, sizeof (mbstate_t));
923 else if (MB_NULLWCH (wc_bytes))
924 break; /* Found '\0' */
928 wc_width = (temp >= 0) ? temp : 1;
933 if (out + 8 >= line_size) /* XXX - 8 for \t */
936 visible_line = (char *)xrealloc (visible_line, line_size);
937 invisible_line = (char *)xrealloc (invisible_line, line_size);
938 line = invisible_line;
943 cpos_buffer_position = out;
944 lb_linenum = newlines;
947 #if defined (HANDLE_MULTIBYTE)
948 if (META_CHAR (c) && _rl_output_meta_chars == 0) /* XXX - clean up */
953 if (_rl_output_meta_chars == 0)
955 sprintf (line + out, "\\%o", c);
957 if (lpos + 4 >= _rl_screenwidth)
959 temp = _rl_screenwidth - lpos;
960 CHECK_INV_LBREAKS ();
961 inv_lbreaks[++newlines] = out + temp;
962 #if defined (HANDLE_MULTIBYTE)
963 line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn;
978 #if defined (DISPLAY_TABS)
984 newout = (out | (int)7) + 1;
986 newout = out + 8 - lpos % 8;
989 if (lpos + temp >= _rl_screenwidth)
992 temp2 = _rl_screenwidth - lpos;
993 CHECK_INV_LBREAKS ();
994 inv_lbreaks[++newlines] = out + temp2;
995 #if defined (HANDLE_MULTIBYTE)
996 line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn;
1004 while (out < newout)
1010 else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
1012 line[out++] = '\0'; /* XXX - sentinel */
1013 CHECK_INV_LBREAKS ();
1014 inv_lbreaks[++newlines] = out;
1015 #if defined (HANDLE_MULTIBYTE)
1016 line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn;
1020 else if (CTRL_CHAR (c) || c == RUBOUT)
1024 line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
1029 #if defined (HANDLE_MULTIBYTE)
1030 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1034 _rl_wrapped_multicolumn = 0;
1036 if (_rl_screenwidth < lpos + wc_width)
1037 for (i = lpos; i < _rl_screenwidth; i++)
1039 /* The space will be removed in update_line() */
1041 _rl_wrapped_multicolumn++;
1046 cpos_buffer_position = out;
1047 lb_linenum = newlines;
1049 for (i = in; i < in+wc_bytes; i++)
1050 line[out++] = rl_line_buffer[i];
1051 for (i = 0; i < wc_width; i++)
1065 #if defined (HANDLE_MULTIBYTE)
1066 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1069 if (_rl_utf8locale && UTF8_SINGLEBYTE(rl_line_buffer[in]))
1071 wc = (wchar_t)rl_line_buffer[in];
1073 memset (&ps, 0, sizeof (mbstate_t)); /* re-init state */
1076 wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps);
1083 line_totbytes = out;
1084 if (cpos_buffer_position < 0)
1086 cpos_buffer_position = out;
1087 lb_linenum = newlines;
1090 inv_botlin = lb_botlin = _rl_inv_botlin = newlines;
1091 CHECK_INV_LBREAKS ();
1092 inv_lbreaks[newlines+1] = out;
1093 #if defined (HANDLE_MULTIBYTE)
1094 /* This should be 0 anyway */
1095 line_state_invisible->wrapped_line[newlines+1] = _rl_wrapped_multicolumn;
1097 cursor_linenum = lb_linenum;
1099 /* CPOS_BUFFER_POSITION == position in buffer where cursor should be placed.
1100 CURSOR_LINENUM == line number where the cursor should be placed. */
1102 /* PWP: now is when things get a bit hairy. The visible and invisible
1103 line buffers are really multiple lines, which would wrap every
1104 (screenwidth - 1) characters. Go through each in turn, finding
1105 the changed region and updating it. The line order is top to bottom. */
1107 /* If we can move the cursor up and down, then use multiple lines,
1108 otherwise, let long lines display in a single terminal line, and
1109 horizontally scroll it. */
1110 displaying_prompt_first_line = 1;
1111 if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
1113 int nleft, pos, changed_screen_line, tx;
1115 if (!rl_display_fixed || forced_display)
1119 /* If we have more than a screenful of material to display, then
1120 only display a screenful. We should display the last screen,
1122 if (out >= _rl_screenchars)
1124 #if defined (HANDLE_MULTIBYTE)
1125 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1126 out = _rl_find_prev_mbchar (line, _rl_screenchars, MB_FIND_ANY);
1129 out = _rl_screenchars - 1;
1132 /* The first line is at character position 0 in the buffer. The
1133 second and subsequent lines start at inv_lbreaks[N], offset by
1134 OFFSET (which has already been calculated above). */
1136 #define INVIS_FIRST() (prompt_physical_chars > _rl_screenwidth ? prompt_invis_chars_first_line : wrap_offset)
1137 #define WRAP_OFFSET(line, offset) ((line == 0) \
1138 ? (offset ? INVIS_FIRST() : 0) \
1139 : ((line == prompt_last_screen_line) ? wrap_offset-prompt_invis_chars_first_line : 0))
1140 #define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
1141 #define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
1142 #define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l])
1143 #define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
1144 #define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
1145 #define INV_LINE(line) (invisible_line + inv_lbreaks[line])
1147 #define OLD_CPOS_IN_PROMPT() (cpos_adjusted == 0 && \
1148 _rl_last_c_pos != o_cpos && \
1149 _rl_last_c_pos > wrap_offset && \
1150 o_cpos < prompt_last_invisible)
1152 /* For each line in the buffer, do the updating display. */
1153 for (linenum = 0; linenum <= inv_botlin; linenum++)
1155 /* This can lead us astray if we execute a program that changes
1156 the locale from a non-multibyte to a multibyte one. */
1157 o_cpos = _rl_last_c_pos;
1159 update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
1160 VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
1162 /* update_line potentially changes _rl_last_c_pos, but doesn't
1163 take invisible characters into account, since _rl_last_c_pos
1164 is an absolute cursor position in a multibyte locale. We
1165 choose to (mostly) compensate for that here, rather than
1166 change update_line itself. There are several cases in which
1167 update_line adjusts _rl_last_c_pos itself (so it can pass
1168 _rl_move_cursor_relative accurate values); it communicates
1169 this back by setting cpos_adjusted. If we assume that
1170 _rl_last_c_pos is correct (an absolute cursor position) each
1171 time update_line is called, then we can assume in our
1172 calculations that o_cpos does not need to be adjusted by
1174 if (linenum == 0 && (mb_cur_max > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT())
1175 _rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */
1176 else if (cpos_adjusted == 0 &&
1177 linenum == prompt_last_screen_line &&
1178 prompt_physical_chars > _rl_screenwidth &&
1179 (mb_cur_max > 1 && rl_byte_oriented == 0) &&
1180 _rl_last_c_pos != o_cpos &&
1181 _rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line)) /* XXX - rethink this last one */
1182 /* This assumes that all the invisible characters are split
1183 between the first and last lines of the prompt, if the
1184 prompt consumes more than two lines. It's usually right */
1185 /* XXX - not sure this is ever executed */
1186 _rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line);
1188 /* If this is the line with the prompt, we might need to
1189 compensate for invisible characters in the new line. Do
1190 this only if there is not more than one new line (which
1191 implies that we completely overwrite the old visible line)
1192 and the new line is shorter than the old. Make sure we are
1193 at the end of the new line before clearing. */
1195 inv_botlin == 0 && _rl_last_c_pos == out &&
1196 (wrap_offset > visible_wrap_offset) &&
1197 (_rl_last_c_pos < visible_first_line_len))
1199 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1200 nleft = _rl_screenwidth - _rl_last_c_pos;
1202 nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
1204 _rl_clear_to_eol (nleft);
1207 /* This segment is intended to handle the case where the prompt
1208 has invisible characters on the second line and the new line
1209 to be displayed needs to clear the rest of the old characters
1210 out (e.g., when printing the i-search prompt). In general,
1211 the case of the new line being shorter than the old.
1213 else if (linenum == prompt_last_screen_line &&
1214 prompt_physical_chars > _rl_screenwidth &&
1215 wrap_offset != prompt_invis_chars_first_line &&
1216 _rl_last_c_pos == out &&
1220 /* Since the new first line is now visible, save its length. */
1222 visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
1225 /* We may have deleted some lines. If so, clear the left over
1226 blank ones at the bottom out. */
1227 if (_rl_vis_botlin > inv_botlin)
1230 for (; linenum <= _rl_vis_botlin; linenum++)
1232 tt = VIS_CHARS (linenum);
1233 _rl_move_vert (linenum);
1234 _rl_move_cursor_relative (0, tt);
1236 ((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth);
1239 _rl_vis_botlin = inv_botlin;
1241 /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
1242 different screen line during this redisplay. */
1243 changed_screen_line = _rl_last_v_pos != cursor_linenum;
1244 if (changed_screen_line)
1246 _rl_move_vert (cursor_linenum);
1247 /* If we moved up to the line with the prompt using _rl_term_up,
1248 the physical cursor position on the screen stays the same,
1249 but the buffer position needs to be adjusted to account
1250 for invisible characters. */
1251 if ((mb_cur_max == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset)
1252 _rl_last_c_pos += wrap_offset;
1255 /* Now we move the cursor to where it needs to be. First, make
1256 sure we are on the correct line (cursor_linenum). */
1258 /* We have to reprint the prompt if it contains invisible
1259 characters, since it's not generally OK to just reprint
1260 the characters from the current cursor position. But we
1261 only need to reprint it if the cursor is before the last
1262 invisible character in the prompt string. */
1263 nleft = prompt_visible_length + wrap_offset;
1264 if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
1266 _rl_last_c_pos <= PROMPT_ENDING_INDEX && local_prompt)
1268 _rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt)
1271 #if defined (__MSDOS__)
1272 putc ('\r', rl_outstream);
1275 tputs (_rl_term_cr, 1, _rl_output_character_function);
1278 _rl_output_some_chars ("*", 1);
1280 _rl_output_some_chars (local_prompt, nleft);
1281 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1282 _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft, 1) - wrap_offset + modmark;
1284 _rl_last_c_pos = nleft + modmark;
1287 /* Where on that line? And where does that line start
1289 pos = inv_lbreaks[cursor_linenum];
1290 /* nleft == number of characters in the line buffer between the
1291 start of the line and the desired cursor position. */
1292 nleft = cpos_buffer_position - pos;
1294 /* NLEFT is now a number of characters in a buffer. When in a
1295 multibyte locale, however, _rl_last_c_pos is an absolute cursor
1296 position that doesn't take invisible characters in the prompt
1297 into account. We use a fudge factor to compensate. */
1299 /* Since _rl_backspace() doesn't know about invisible characters in
1300 the prompt, and there's no good way to tell it, we compensate for
1301 those characters here and call _rl_backspace() directly if
1303 if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
1305 /* TX == new physical cursor position in multibyte locale. */
1306 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1307 tx = _rl_col_width (&visible_line[pos], 0, nleft, 1) - visible_wrap_offset;
1310 if (tx >= 0 && _rl_last_c_pos > tx)
1312 _rl_backspace (_rl_last_c_pos - tx); /* XXX */
1313 _rl_last_c_pos = tx;
1317 /* We need to note that in a multibyte locale we are dealing with
1318 _rl_last_c_pos as an absolute cursor position, but moving to a
1319 point specified by a buffer position (NLEFT) that doesn't take
1320 invisible characters into account. */
1321 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1322 _rl_move_cursor_relative (nleft, &invisible_line[pos]);
1323 else if (nleft != _rl_last_c_pos)
1324 _rl_move_cursor_relative (nleft, &invisible_line[pos]);
1327 else /* Do horizontal scrolling. Much simpler */
1329 #define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
1330 int lmargin, ndisp, nleft, phys_c_pos, t;
1332 /* Always at top line. */
1335 /* Compute where in the buffer the displayed line should start. This
1338 /* The number of characters that will be displayed before the cursor. */
1339 ndisp = cpos_buffer_position - wrap_offset;
1340 nleft = prompt_visible_length + wrap_offset;
1341 /* Where the new cursor position will be on the screen. This can be
1342 longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
1343 phys_c_pos = cpos_buffer_position - (last_lmargin ? last_lmargin : wrap_offset);
1344 t = _rl_screenwidth / 3;
1346 /* If the number of characters had already exceeded the screenwidth,
1347 last_lmargin will be > 0. */
1349 /* If the number of characters to be displayed is more than the screen
1350 width, compute the starting offset so that the cursor is about
1351 two-thirds of the way across the screen. */
1352 if (phys_c_pos > _rl_screenwidth - 2)
1354 lmargin = cpos_buffer_position - (2 * t);
1357 /* If the left margin would be in the middle of a prompt with
1358 invisible characters, don't display the prompt at all. */
1359 if (wrap_offset && lmargin > 0 && lmargin < nleft)
1362 else if (ndisp < _rl_screenwidth - 2) /* XXX - was -1 */
1364 else if (phys_c_pos < 1)
1366 /* If we are moving back towards the beginning of the line and
1367 the last margin is no longer correct, compute a new one. */
1368 lmargin = ((cpos_buffer_position - 1) / t) * t; /* XXX */
1369 if (wrap_offset && lmargin > 0 && lmargin < nleft)
1373 lmargin = last_lmargin;
1375 displaying_prompt_first_line = lmargin < nleft;
1377 /* If the first character on the screen isn't the first character
1378 in the display line, indicate this with a special character. */
1380 line[lmargin] = '<';
1382 /* If SCREENWIDTH characters starting at LMARGIN do not encompass
1383 the whole line, indicate that with a special character at the
1384 right edge of the screen. If LMARGIN is 0, we need to take the
1385 wrap offset into account. */
1386 t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth;
1387 if (t > 0 && t < out)
1390 if (rl_display_fixed == 0 || forced_display || lmargin != last_lmargin)
1393 o_cpos = _rl_last_c_pos;
1395 update_line (&visible_line[last_lmargin],
1396 &invisible_line[lmargin],
1398 _rl_screenwidth + visible_wrap_offset,
1399 _rl_screenwidth + (lmargin ? 0 : wrap_offset),
1402 if ((mb_cur_max > 1 && rl_byte_oriented == 0) &&
1403 displaying_prompt_first_line && OLD_CPOS_IN_PROMPT())
1404 _rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */
1406 /* If the visible new line is shorter than the old, but the number
1407 of invisible characters is greater, and we are at the end of
1408 the new line, we need to clear to eol. */
1409 t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
1410 if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
1411 (_rl_last_c_pos == out) && displaying_prompt_first_line &&
1412 t < visible_first_line_len)
1414 nleft = _rl_screenwidth - t;
1415 _rl_clear_to_eol (nleft);
1417 visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
1418 if (visible_first_line_len > _rl_screenwidth)
1419 visible_first_line_len = _rl_screenwidth;
1421 _rl_move_cursor_relative (cpos_buffer_position - lmargin, &invisible_line[lmargin]);
1422 last_lmargin = lmargin;
1425 fflush (rl_outstream);
1427 /* Swap visible and non-visible lines. */
1429 struct line_state *vtemp = line_state_visible;
1431 line_state_visible = line_state_invisible;
1432 line_state_invisible = vtemp;
1434 rl_display_fixed = 0;
1435 /* If we are displaying on a single line, and last_lmargin is > 0, we
1436 are not displaying any invisible characters, so set visible_wrap_offset
1438 if (_rl_horizontal_scroll_mode && last_lmargin)
1439 visible_wrap_offset = 0;
1441 visible_wrap_offset = wrap_offset;
1444 RL_UNSETSTATE (RL_STATE_REDISPLAYING);
1445 _rl_release_sigint ();
1448 /* PWP: update_line() is based on finding the middle difference of each
1449 line on the screen; vis:
1451 /old first difference
1452 /beginning of line | /old last same /old EOL
1454 old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as
1455 new: eddie> Oh, my little buggy says to me, as lurgid as
1457 \beginning of line | \new last same \new end of line
1458 \new first difference
1460 All are character pointers for the sake of speed. Special cases for
1461 no differences, as well as for end of line additions must be handled.
1463 Could be made even smarter, but this works well enough */
1465 update_line (char *old, char *new, int current_line, int omax, int nmax, int inv_botlin)
1467 register char *ofd, *ols, *oe, *nfd, *nls, *ne;
1468 int temp, lendiff, wsatend, od, nd, twidth, o_cpos;
1469 int current_invis_chars;
1470 int col_lendiff, col_temp;
1471 int bytes_to_insert;
1472 int mb_cur_max = MB_CUR_MAX;
1473 #if defined (HANDLE_MULTIBYTE)
1474 mbstate_t ps_new, ps_old;
1475 int new_offset, old_offset;
1478 /* If we're at the right edge of a terminal that supports xn, we're
1479 ready to wrap around, so do so. This fixes problems with knowing
1480 the exact cursor position and cut-and-paste with certain terminal
1481 emulators. In this calculation, TEMP is the physical screen
1482 position of the cursor. */
1483 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1484 temp = _rl_last_c_pos;
1486 temp = _rl_last_c_pos - WRAP_OFFSET (_rl_last_v_pos, visible_wrap_offset);
1487 if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
1488 && _rl_last_v_pos == current_line - 1)
1490 /* We're going to wrap around by writing the first character of NEW to
1491 the screen and dealing with changes to what's visible by modifying
1492 OLD to match it. Complicated by the presence of multi-width
1493 characters at the end of the line or beginning of the new one. */
1494 /* old is always somewhere in visible_line; new is always somewhere in
1495 invisible_line. These should always be null-terminated. */
1496 #if defined (HANDLE_MULTIBYTE)
1497 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1501 int oldwidth, newwidth;
1502 int oldbytes, newbytes;
1505 /* This fixes only double-column characters, but if the wrapped
1506 character consumes more than three columns, spaces will be
1507 inserted in the string buffer. */
1508 /* XXX remember that we are working on the invisible line right now;
1509 we don't swap visible and invisible until just before rl_redisplay
1511 /* This will remove the extra placeholder space we added with
1512 _rl_wrapped_multicolumn */
1513 if (current_line < line_state_invisible->wbsize && line_state_invisible->wrapped_line[current_line] > 0)
1514 _rl_clear_to_eol (line_state_invisible->wrapped_line[current_line]);
1516 /* 1. how many screen positions does first char in old consume? */
1517 memset (&ps, 0, sizeof (mbstate_t));
1518 ret = mbrtowc (&wc, old, mb_cur_max, &ps);
1520 if (MB_INVALIDCH (ret))
1525 else if (MB_NULLWCH (ret))
1528 oldwidth = WCWIDTH (wc);
1532 /* 2. how many screen positions does the first char in new consume? */
1533 memset (&ps, 0, sizeof (mbstate_t));
1534 ret = mbrtowc (&wc, new, mb_cur_max, &ps);
1536 if (MB_INVALIDCH (ret))
1541 else if (MB_NULLWCH (ret))
1544 newwidth = WCWIDTH (wc);
1548 /* 3. if the new width is less than the old width, we need to keep
1549 going in new until we have consumed at least that many screen
1550 positions, and figure out how many bytes that will take */
1551 while (newbytes < nmax && newwidth < oldwidth)
1555 ret = mbrtowc (&wc, new+newbytes, mb_cur_max, &ps);
1556 if (MB_INVALIDCH (ret))
1561 else if (MB_NULLWCH (ret))
1566 newwidth += (t >= 0) ? t : 1;
1570 /* 4. If the new width is more than the old width, keep going in old
1571 until we have consumed exactly that many screen positions, and
1572 figure out how many bytes that will take. This is an optimization */
1573 while (oldbytes < omax && oldwidth < newwidth)
1577 ret = mbrtowc (&wc, old+oldbytes, mb_cur_max, &ps);
1578 if (MB_INVALIDCH (ret))
1583 else if (MB_NULLWCH (ret))
1588 oldwidth += (t >= 0) ? t : 1;
1592 /* 5. write the first newbytes of new, which takes newwidth. This is
1593 where the screen wrapping takes place, and we are now writing
1594 characters onto the new line. We need to fix up old so it
1595 accurately reflects what is on the screen after the
1596 _rl_output_some_chars below. */
1602 _rl_output_some_chars (new, newbytes);
1603 _rl_last_c_pos = newwidth;
1606 /* 5a. If the number of screen positions doesn't match, punt
1607 and do a dumb update. */
1608 if (newwidth != oldwidth)
1615 if (oldbytes != 0 && newbytes != 0)
1617 /* We have written as many bytes from new as we need to
1618 consume the first character of old. Fix up `old' so it
1619 reflects the new screen contents. We use +1 in the
1620 memmove call to copy the trailing NUL. */
1621 memmove (old+newbytes, old+oldbytes, strlen (old+oldbytes) + 1);
1622 memcpy (old, new, newbytes);
1623 j = newbytes - oldbytes;
1626 /* Fix up indices if we copy data from one line to another */
1627 for (i = current_line+1; i <= inv_botlin+1; i++)
1628 vis_lbreaks[i] += j;
1633 putc (' ', rl_outstream);
1636 if (old[0] && new[0])
1644 putc (new[0], rl_outstream);
1646 putc (' ', rl_outstream);
1649 if (old[0] && new[0])
1654 /* Find first difference. */
1655 #if defined (HANDLE_MULTIBYTE)
1656 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1658 /* See if the old line is a subset of the new line, so that the
1659 only change is adding characters. */
1660 temp = (omax < nmax) ? omax : nmax;
1661 if (memcmp (old, new, temp) == 0) /* adding at the end */
1663 new_offset = old_offset = temp;
1669 memset (&ps_new, 0, sizeof(mbstate_t));
1670 memset (&ps_old, 0, sizeof(mbstate_t));
1672 /* Are the old and new lines the same? */
1673 if (omax == nmax && STREQN (new, old, omax))
1682 /* Go through the line from the beginning and find the first
1684 new_offset = old_offset = 0;
1685 for (ofd = old, nfd = new;
1686 (ofd - old < omax) && *ofd &&
1687 _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
1689 old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
1690 new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
1692 ofd = old + old_offset;
1693 nfd = new + new_offset;
1700 for (ofd = old, nfd = new;
1701 (ofd - old < omax) && *ofd && (*ofd == *nfd);
1705 /* Move to the end of the screen line. ND and OD are used to keep track
1706 of the distance between ne and new and oe and old, respectively, to
1707 move a subtraction out of each loop. */
1708 for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
1709 for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
1711 /* If no difference, continue to next line. */
1712 if (ofd == oe && nfd == ne)
1715 #if defined (HANDLE_MULTIBYTE)
1716 if (mb_cur_max > 1 && rl_byte_oriented == 0 && _rl_utf8locale)
1719 mbstate_t ps = { 0 };
1722 /* If the first character in the difference is a zero-width character,
1723 assume it's a combining character and back one up so the two base
1724 characters no longer compare equivalently. */
1725 t = mbrtowc (&wc, ofd, mb_cur_max, &ps);
1726 if (t > 0 && UNICODE_COMBINING_CHAR (wc) && WCWIDTH (wc) == 0)
1728 old_offset = _rl_find_prev_mbchar (old, ofd - old, MB_FIND_ANY);
1729 new_offset = _rl_find_prev_mbchar (new, nfd - new, MB_FIND_ANY);
1730 ofd = old + old_offset; /* equal by definition */
1731 nfd = new + new_offset;
1736 wsatend = 1; /* flag for trailing whitespace */
1738 #if defined (HANDLE_MULTIBYTE)
1739 /* Find the last character that is the same between the two lines. This
1740 bounds the region that needs to change. */
1741 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1743 ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY);
1744 nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY);
1746 while ((ols > ofd) && (nls > nfd))
1748 memset (&ps_old, 0, sizeof (mbstate_t));
1749 memset (&ps_new, 0, sizeof (mbstate_t));
1752 /* On advice from jir@yamato.ibm.com */
1753 _rl_adjust_point (old, ols - old, &ps_old);
1754 _rl_adjust_point (new, nls - new, &ps_new);
1757 if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0)
1763 ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY);
1764 nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY);
1769 #endif /* HANDLE_MULTIBYTE */
1770 ols = oe - 1; /* find last same */
1772 while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
1779 #if defined (HANDLE_MULTIBYTE)
1788 #if defined (HANDLE_MULTIBYTE)
1789 /* This may not work for stateful encoding, but who cares? To handle
1790 stateful encoding properly, we have to scan each string from the
1791 beginning and compare. */
1792 else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0)
1794 else if (*ols != *nls)
1797 if (*ols) /* don't step past the NUL */
1799 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1800 ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY);
1806 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1807 nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY);
1813 /* count of invisible characters in the current invisible line. */
1814 current_invis_chars = W_OFFSET (current_line, wrap_offset);
1815 if (_rl_last_v_pos != current_line)
1817 _rl_move_vert (current_line);
1818 /* We have moved up to a new screen line. This line may or may not have
1819 invisible characters on it, but we do our best to recalculate
1820 visible_wrap_offset based on what we know. */
1821 if (current_line == 0)
1822 visible_wrap_offset = prompt_invis_chars_first_line; /* XXX */
1823 if ((mb_cur_max == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset)
1824 _rl_last_c_pos += visible_wrap_offset;
1827 /* If this is the first line and there are invisible characters in the
1828 prompt string, and the prompt string has not changed, and the current
1829 cursor position is before the last invisible character in the prompt,
1830 and the index of the character to move to is past the end of the prompt
1831 string, then redraw the entire prompt string. We can only do this
1832 reliably if the terminal supports a `cr' capability.
1834 This can also happen if the prompt string has changed, and the first
1835 difference in the line is in the middle of the prompt string, after a
1836 sequence of invisible characters (worst case) and before the end of
1837 the prompt. In this case, we have to redraw the entire prompt string
1838 so that the entire sequence of invisible characters is drawn. We need
1839 to handle the worst case, when the difference is after (or in the middle
1840 of) a sequence of invisible characters that changes the text color and
1841 before the sequence that restores the text color to normal. Then we have
1842 to make sure that the lines still differ -- if they don't, we can
1845 This is not an efficiency hack -- there is a problem with redrawing
1846 portions of the prompt string if they contain terminal escape
1847 sequences (like drawing the `unbold' sequence without a corresponding
1848 `bold') that manifests itself on certain terminals. */
1850 lendiff = local_prompt_len;
1853 od = ofd - old; /* index of first difference in visible line */
1854 nd = nfd - new; /* nd, od are buffer indexes */
1855 if (current_line == 0 && !_rl_horizontal_scroll_mode &&
1856 _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 &&
1857 (((od > 0 || nd > 0) && (od <= prompt_last_invisible || nd <= prompt_last_invisible)) ||
1858 ((od >= lendiff) && _rl_last_c_pos < PROMPT_ENDING_INDEX)))
1860 #if defined (__MSDOS__)
1861 putc ('\r', rl_outstream);
1863 tputs (_rl_term_cr, 1, _rl_output_character_function);
1866 _rl_output_some_chars ("*", 1);
1867 _rl_output_some_chars (local_prompt, lendiff);
1868 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1870 /* We take wrap_offset into account here so we can pass correct
1871 information to _rl_move_cursor_relative. */
1872 _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff, 1) - wrap_offset + modmark;
1876 _rl_last_c_pos = lendiff + modmark;
1878 /* Now if we have printed the prompt string because the first difference
1879 was within the prompt, see if we need to recompute where the lines
1880 differ. Check whether where we are now is past the last place where
1881 the old and new lines are the same and short-circuit now if we are. */
1882 if ((od <= prompt_last_invisible || nd <= prompt_last_invisible) &&
1884 lendiff > (ols-old) && lendiff > (nls-new))
1887 /* XXX - we need to fix up our calculations if we are now past the
1888 old ofd/nfd and the prompt length (or line length) has changed.
1889 We punt on the problem and do a dumb update. We'd like to be able
1890 to just output the prompt from the beginning of the line up to the
1891 first difference, but you don't know the number of invisible
1892 characters in that case.
1893 This needs a lot of work to be efficient. */
1894 if ((od <= prompt_last_invisible || nd <= prompt_last_invisible))
1896 nfd = new + lendiff; /* number of characters we output above */
1899 /* Do a dumb update and return */
1904 _rl_output_some_chars (nfd, temp);
1905 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1907 _rl_last_c_pos += _rl_col_width (new, nd, ne - new, 1);
1908 /* Need to adjust here based on wrap_offset. Guess that if
1909 this is the line containing the last line of the prompt
1910 we need to adjust by
1911 wrap_offset-prompt_invis_chars_first_line
1912 on the assumption that this is the number of invisible
1913 characters in the last line of the prompt. */
1914 if (wrap_offset > prompt_invis_chars_first_line &&
1915 current_line == prompt_last_screen_line &&
1916 prompt_physical_chars > _rl_screenwidth &&
1917 _rl_horizontal_scroll_mode == 0)
1919 _rl_last_c_pos -= wrap_offset - prompt_invis_chars_first_line;
1924 _rl_last_c_pos += temp;
1927 goto clear_rest_of_line; /* XXX */
1933 o_cpos = _rl_last_c_pos;
1935 /* When this function returns, _rl_last_c_pos is correct, and an absolute
1936 cursor position in multibyte mode, but a buffer index when not in a
1937 multibyte locale. */
1938 _rl_move_cursor_relative (od, old);
1940 #if defined (HANDLE_MULTIBYTE)
1941 /* We need to indicate that the cursor position is correct in the presence of
1942 invisible characters in the prompt string. Let's see if setting this when
1943 we make sure we're at the end of the drawn prompt string works. */
1944 if (current_line == 0 && mb_cur_max > 1 && rl_byte_oriented == 0 &&
1945 (_rl_last_c_pos > 0 || o_cpos > 0) &&
1946 _rl_last_c_pos == prompt_physical_chars)
1950 /* if (len (new) > len (old))
1951 lendiff == difference in buffer (bytes)
1952 col_lendiff == difference on screen (columns)
1953 When not using multibyte characters, these are equal */
1954 lendiff = (nls - nfd) - (ols - ofd);
1955 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1956 col_lendiff = _rl_col_width (new, nfd - new, nls - new, 1) - _rl_col_width (old, ofd - old, ols - old, 1);
1958 col_lendiff = lendiff;
1960 /* If we are changing the number of invisible characters in a line, and
1961 the spot of first difference is before the end of the invisible chars,
1962 lendiff needs to be adjusted. */
1963 if (current_line == 0 && /* !_rl_horizontal_scroll_mode && */
1964 current_invis_chars != visible_wrap_offset)
1966 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1968 lendiff += visible_wrap_offset - current_invis_chars;
1969 col_lendiff += visible_wrap_offset - current_invis_chars;
1973 lendiff += visible_wrap_offset - current_invis_chars;
1974 col_lendiff = lendiff;
1978 /* We use temp as a count of the number of bytes from the first difference
1979 to the end of the new line. col_temp is the corresponding number of
1980 screen columns. A `dumb' update moves to the spot of first difference
1981 and writes TEMP bytes. */
1982 /* Insert (diff (len (old), len (new)) ch. */
1984 if (mb_cur_max > 1 && rl_byte_oriented == 0)
1985 col_temp = _rl_col_width (new, nfd - new, ne - new, 1);
1989 /* how many bytes from the new line buffer to write to the display */
1990 bytes_to_insert = nls - nfd;
1992 /* col_lendiff > 0 if we are adding characters to the line */
1993 if (col_lendiff > 0) /* XXX - was lendiff */
1995 /* Non-zero if we're increasing the number of lines. */
1996 int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
1998 /* If col_lendiff is > 0, implying that the new string takes up more
1999 screen real estate than the old, but lendiff is < 0, meaning that it
2000 takes fewer bytes, we need to just output the characters starting
2001 from the first difference. These will overwrite what is on the
2002 display, so there's no reason to do a smart update. This can really
2003 only happen in a multibyte environment. */
2006 _rl_output_some_chars (nfd, temp);
2007 _rl_last_c_pos += col_temp; /* XXX - was _rl_col_width (nfd, 0, temp, 1); */
2008 /* If nfd begins before any invisible characters in the prompt,
2009 adjust _rl_last_c_pos to account for wrap_offset and set
2010 cpos_adjusted to let the caller know. */
2011 if (current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible))
2013 _rl_last_c_pos -= wrap_offset; /* XXX - prompt_invis_chars_first_line? */
2018 /* Sometimes it is cheaper to print the characters rather than
2019 use the terminal's capabilities. If we're growing the number
2020 of lines, make sure we actually cause the new line to wrap
2021 around on auto-wrapping terminals. */
2022 else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
2024 /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
2025 _rl_horizontal_scroll_mode == 1, inserting the characters with
2026 _rl_term_IC or _rl_term_ic will screw up the screen because of the
2027 invisible characters. We need to just draw them. */
2028 /* The same thing happens if we're trying to draw before the last
2029 invisible character in the prompt string or we're increasing the
2030 number of invisible characters in the line and we're not drawing
2031 the entire prompt string. */
2032 if (*ols && ((_rl_horizontal_scroll_mode &&
2033 _rl_last_c_pos == 0 &&
2034 lendiff > prompt_visible_length &&
2035 current_invis_chars > 0) == 0) &&
2036 (((mb_cur_max > 1 && rl_byte_oriented == 0) &&
2037 current_line == 0 && wrap_offset &&
2038 ((nfd - new) <= prompt_last_invisible) &&
2039 (col_lendiff < prompt_visible_length)) == 0) &&
2040 (visible_wrap_offset >= current_invis_chars))
2042 open_some_spaces (col_lendiff);
2043 _rl_output_some_chars (nfd, bytes_to_insert);
2044 if (mb_cur_max > 1 && rl_byte_oriented == 0)
2045 _rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1);
2047 _rl_last_c_pos += bytes_to_insert;
2049 else if ((mb_cur_max == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0)
2051 /* At the end of a line the characters do not have to
2052 be "inserted". They can just be placed on the screen. */
2053 _rl_output_some_chars (nfd, temp);
2054 _rl_last_c_pos += col_temp;
2057 else /* just write from first difference to end of new line */
2059 _rl_output_some_chars (nfd, temp);
2060 _rl_last_c_pos += col_temp;
2061 /* If nfd begins before the last invisible character in the
2062 prompt, adjust _rl_last_c_pos to account for wrap_offset
2063 and set cpos_adjusted to let the caller know. */
2064 if ((mb_cur_max > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible))
2066 _rl_last_c_pos -= wrap_offset; /* XXX - prompt_invis_chars_first_line? */
2072 if (bytes_to_insert > lendiff)
2074 /* If nfd begins before the last invisible character in the
2075 prompt, adjust _rl_last_c_pos to account for wrap_offset
2076 and set cpos_adjusted to let the caller know. */
2077 if ((mb_cur_max > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible))
2079 _rl_last_c_pos -= wrap_offset; /* XXX - prompt_invis_chars_first_line? */
2086 /* cannot insert chars, write to EOL */
2087 _rl_output_some_chars (nfd, temp);
2088 _rl_last_c_pos += col_temp;
2089 /* If we're in a multibyte locale and were before the last invisible
2090 char in the current line (which implies we just output some invisible
2091 characters) we need to adjust _rl_last_c_pos, since it represents
2092 a physical character position. */
2093 /* The current_line*rl_screenwidth+prompt_invis_chars_first_line is a
2094 crude attempt to compute how far into the new line buffer we are.
2095 It doesn't work well in the face of multibyte characters and needs
2096 to be rethought. XXX */
2097 if ((mb_cur_max > 1 && rl_byte_oriented == 0) &&
2098 current_line == prompt_last_screen_line && wrap_offset &&
2099 displaying_prompt_first_line &&
2100 wrap_offset != prompt_invis_chars_first_line &&
2101 ((nfd-new) < (prompt_last_invisible-(current_line*_rl_screenwidth+prompt_invis_chars_first_line))))
2103 _rl_last_c_pos -= wrap_offset - prompt_invis_chars_first_line;
2108 else /* Delete characters from line. */
2110 /* If possible and inexpensive to use terminal deletion, then do so. */
2111 if (_rl_term_dc && (2 * col_temp) >= -col_lendiff)
2113 /* If all we're doing is erasing the invisible characters in the
2114 prompt string, don't bother. It screws up the assumptions
2115 about what's on the screen. */
2116 if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
2117 displaying_prompt_first_line &&
2118 -lendiff == visible_wrap_offset)
2121 /* If we have moved lmargin and we're shrinking the line, we've
2122 already moved the cursor to the first character of the new line,
2123 so deleting -col_lendiff characters will mess up the cursor
2124 position calculation */
2125 if (_rl_horizontal_scroll_mode && displaying_prompt_first_line == 0 &&
2126 col_lendiff && _rl_last_c_pos < -col_lendiff)
2130 delete_chars (-col_lendiff); /* delete (diff) characters */
2132 /* Copy (new) chars to screen from first diff to last match,
2133 overwriting what is there. */
2134 if (bytes_to_insert > 0)
2136 /* If nfd begins at the prompt, or before the invisible
2137 characters in the prompt, we need to adjust _rl_last_c_pos
2138 in a multibyte locale to account for the wrap offset and
2139 set cpos_adjusted accordingly. */
2140 _rl_output_some_chars (nfd, bytes_to_insert);
2141 if (mb_cur_max > 1 && rl_byte_oriented == 0)
2143 _rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1);
2144 if (current_line == 0 && wrap_offset &&
2145 displaying_prompt_first_line &&
2146 _rl_last_c_pos >= wrap_offset && /* XXX was > */
2147 ((nfd - new) <= prompt_last_invisible))
2149 _rl_last_c_pos -= wrap_offset; /* XXX - prompt_invis_chars_first_line? */
2154 #ifdef HANDLE_MULTIBYTE
2155 /* If we write a non-space into the last screen column,
2156 remove the note that we added a space to compensate for
2157 a multibyte double-width character that didn't fit, since
2158 it's only valid for what was previously there. */
2159 /* XXX - watch this */
2160 if (_rl_last_c_pos == _rl_screenwidth &&
2161 line_state_invisible->wrapped_line[current_line+1] &&
2162 nfd[bytes_to_insert-1] != ' ')
2163 line_state_invisible->wrapped_line[current_line+1] = 0;
2168 _rl_last_c_pos += bytes_to_insert;
2170 /* XXX - we only want to do this if we are at the end of the line
2171 so we move there with _rl_move_cursor_relative */
2172 if (_rl_horizontal_scroll_mode && ((oe-old) > (ne-new)))
2174 _rl_move_cursor_relative (ne-new, new);
2175 goto clear_rest_of_line;
2179 /* Otherwise, print over the existing material. */
2184 /* If nfd begins at the prompt, or before the invisible
2185 characters in the prompt, we need to adjust _rl_last_c_pos
2186 in a multibyte locale to account for the wrap offset and
2187 set cpos_adjusted accordingly. */
2188 _rl_output_some_chars (nfd, temp);
2189 _rl_last_c_pos += col_temp; /* XXX */
2190 if (mb_cur_max > 1 && rl_byte_oriented == 0)
2192 if (current_line == 0 && wrap_offset &&
2193 displaying_prompt_first_line &&
2194 _rl_last_c_pos > wrap_offset &&
2195 ((nfd - new) <= prompt_last_invisible))
2197 _rl_last_c_pos -= wrap_offset; /* XXX - prompt_invis_chars_first_line? */
2203 lendiff = (oe - old) - (ne - new);
2204 if (mb_cur_max > 1 && rl_byte_oriented == 0)
2205 col_lendiff = _rl_col_width (old, 0, oe - old, 1) - _rl_col_width (new, 0, ne - new, 1);
2207 col_lendiff = lendiff;
2209 /* If we've already printed over the entire width of the screen,
2210 including the old material, then col_lendiff doesn't matter and
2211 space_to_eol will insert too many spaces. XXX - maybe we should
2212 adjust col_lendiff based on the difference between _rl_last_c_pos
2213 and _rl_screenwidth */
2214 if (col_lendiff && ((mb_cur_max == 1 || rl_byte_oriented) || (_rl_last_c_pos < _rl_screenwidth)))
2216 if (_rl_term_autowrap && current_line < inv_botlin)
2217 space_to_eol (col_lendiff);
2219 _rl_clear_to_eol (col_lendiff);
2225 /* Tell the update routines that we have moved onto a new (empty) line. */
2227 rl_on_new_line (void)
2230 visible_line[0] = '\0';
2232 _rl_last_c_pos = _rl_last_v_pos = 0;
2233 _rl_vis_botlin = last_lmargin = 0;
2235 vis_lbreaks[0] = vis_lbreaks[1] = 0;
2236 visible_wrap_offset = 0;
2240 /* Clear all screen lines occupied by the current readline line buffer
2243 rl_clear_visible_line (void)
2247 /* Make sure we move to column 0 so we clear the entire line */
2248 #if defined (__MSDOS__)
2249 putc ('\r', rl_outstream);
2251 tputs (_rl_term_cr, 1, _rl_output_character_function);
2255 /* Move to the last screen line of the current visible line */
2256 _rl_move_vert (_rl_vis_botlin);
2258 /* And erase screen lines going up to line 0 (first visible line) */
2259 for (curr_line = _rl_last_v_pos; curr_line >= 0; curr_line--)
2261 _rl_move_vert (curr_line);
2262 _rl_clear_to_eol (0);
2268 /* Tell the update routines that we have moved onto a new line with the
2269 prompt already displayed. Code originally from the version of readline
2270 distributed with CLISP. rl_expand_prompt must have already been called
2271 (explicitly or implicitly). This still doesn't work exactly right; it
2272 should use expand_prompt() */
2274 rl_on_new_line_with_prompt (void)
2276 int prompt_size, i, l, real_screenwidth, newlines;
2277 char *prompt_last_line, *lprompt;
2279 /* Initialize visible_line and invisible_line to ensure that they can hold
2280 the already-displayed prompt. */
2281 prompt_size = strlen (rl_prompt) + 1;
2282 init_line_structures (prompt_size);
2284 /* Make sure the line structures hold the already-displayed prompt for
2286 lprompt = local_prompt ? local_prompt : rl_prompt;
2287 strcpy (visible_line, lprompt);
2288 strcpy (invisible_line, lprompt);
2290 /* If the prompt contains newlines, take the last tail. */
2291 prompt_last_line = strrchr (rl_prompt, '\n');
2292 if (!prompt_last_line)
2293 prompt_last_line = rl_prompt;
2295 l = strlen (prompt_last_line);
2296 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
2297 _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l, 1); /* XXX */
2301 /* Dissect prompt_last_line into screen lines. Note that here we have
2302 to use the real screenwidth. Readline's notion of screenwidth might be
2303 one less, see terminal.c. */
2304 real_screenwidth = _rl_screenwidth + (_rl_term_autowrap ? 0 : 1);
2305 _rl_last_v_pos = l / real_screenwidth;
2306 /* If the prompt length is a multiple of real_screenwidth, we don't know
2307 whether the cursor is at the end of the last line, or already at the
2308 beginning of the next line. Output a newline just to be safe. */
2309 if (l > 0 && (l % real_screenwidth) == 0)
2310 _rl_output_some_chars ("\n", 1);
2313 newlines = 0; i = 0;
2316 _rl_vis_botlin = newlines;
2317 vis_lbreaks[newlines++] = i;
2318 i += real_screenwidth;
2320 vis_lbreaks[newlines] = l;
2321 visible_wrap_offset = 0;
2323 rl_display_prompt = rl_prompt; /* XXX - make sure it's set */
2328 /* Actually update the display, period. */
2330 rl_forced_update_display (void)
2332 register char *temp;
2336 temp = visible_line;
2342 (*rl_redisplay_function) ();
2346 /* Redraw only the last line of a multi-line prompt. */
2348 rl_redraw_prompt_last_line (void)
2352 t = strrchr (rl_display_prompt, '\n');
2354 redraw_prompt (++t);
2356 rl_forced_update_display ();
2359 /* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
2360 (Well, when we don't have multibyte characters, _rl_last_c_pos is a
2362 DATA is the contents of the screen line of interest; i.e., where
2363 the movement is being done.
2364 DATA is always the visible line or the invisible line */
2366 _rl_move_cursor_relative (int new, const char *data)
2369 int woff; /* number of invisible chars on current line */
2370 int cpos, dpos; /* current and desired cursor positions */
2373 int mb_cur_max = MB_CUR_MAX;
2375 woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset);
2376 cpos = _rl_last_c_pos;
2378 if (cpos == 0 && cpos == new)
2381 #if defined (HANDLE_MULTIBYTE)
2382 /* If we have multibyte characters, NEW is indexed by the buffer point in
2383 a multibyte string, but _rl_last_c_pos is the display position. In
2384 this case, NEW's display position is not obvious and must be
2385 calculated. We need to account for invisible characters in this line,
2386 as long as we are past them and they are counted by _rl_col_width. */
2387 if (mb_cur_max > 1 && rl_byte_oriented == 0)
2390 /* Try to short-circuit common cases and eliminate a bunch of multibyte
2391 character function calls. */
2392 /* 1. prompt string */
2393 if (new == local_prompt_len && memcmp (data, local_prompt, new) == 0)
2395 dpos = prompt_physical_chars;
2399 /* 2. prompt_string + line contents */
2400 else if (new > local_prompt_len && local_prompt && memcmp (data, local_prompt, local_prompt_len) == 0)
2402 dpos = prompt_physical_chars + _rl_col_width (data, local_prompt_len, new, 1);
2407 dpos = _rl_col_width (data, 0, new, 1);
2409 if (displaying_prompt_first_line == 0)
2412 /* yet another special case: printing the last line of a prompt with
2413 multibyte characters and invisible characters whose printable length
2414 exceeds the screen width with the last invisible character
2415 (prompt_last_invisible) in the last line. IN_INVISLINE is the
2416 offset of DATA in invisible_line */
2418 if (data > invisible_line && data < invisible_line+inv_lbreaks[_rl_inv_botlin+1])
2419 in_invisline = data - invisible_line;
2421 /* Use NEW when comparing against the last invisible character in the
2422 prompt string, since they're both buffer indices and DPOS is a
2423 desired display position. */
2424 /* NEW is relative to the current displayed line, while
2425 PROMPT_LAST_INVISIBLE is relative to the entire (wrapped) line.
2426 Need a way to reconcile these two variables by turning NEW into a
2427 buffer position relative to the start of the line */
2428 if (adjust && ((new > prompt_last_invisible) || /* XXX - don't use woff here */
2429 (new+in_invisline > prompt_last_invisible) || /* invisible line */
2430 (prompt_physical_chars >= _rl_screenwidth && /* visible line */
2431 _rl_last_v_pos == prompt_last_screen_line &&
2432 wrap_offset >= woff && dpos >= woff &&
2433 new > (prompt_last_invisible-(vis_lbreaks[_rl_last_v_pos])-wrap_offset))))
2434 /* XXX last comparison might need to be >= */
2437 /* Since this will be assigned to _rl_last_c_pos at the end (more
2438 precisely, _rl_last_c_pos == dpos when this function returns),
2439 let the caller know. */
2447 /* If we don't have to do anything, then return. */
2451 /* It may be faster to output a CR, and then move forwards instead
2452 of moving backwards. */
2453 /* i == current physical cursor position. */
2454 #if defined (HANDLE_MULTIBYTE)
2455 if (mb_cur_max > 1 && rl_byte_oriented == 0)
2459 i = _rl_last_c_pos - woff;
2460 if (dpos == 0 || CR_FASTER (dpos, _rl_last_c_pos) ||
2461 (_rl_term_autowrap && i == _rl_screenwidth))
2463 #if defined (__MSDOS__)
2464 putc ('\r', rl_outstream);
2466 tputs (_rl_term_cr, 1, _rl_output_character_function);
2467 #endif /* !__MSDOS__ */
2468 cpos = _rl_last_c_pos = 0;
2473 /* Move the cursor forward. We do it by printing the command
2474 to move the cursor forward if there is one, else print that
2475 portion of the output buffer again. Which is cheaper? */
2477 /* The above comment is left here for posterity. It is faster
2478 to print one character (non-control) than to print a control
2479 sequence telling the terminal to move forward one character.
2480 That kind of control is for people who don't know what the
2481 data is underneath the cursor. */
2483 /* However, we need a handle on where the current display position is
2484 in the buffer for the immediately preceding comment to be true.
2485 In multibyte locales, we don't currently have that info available.
2486 Without it, we don't know where the data we have to display begins
2487 in the buffer and we have to go back to the beginning of the screen
2488 line. In this case, we can use the terminal sequence to move forward
2489 if it's available. */
2490 if (mb_cur_max > 1 && rl_byte_oriented == 0)
2492 if (_rl_term_forward_char)
2494 for (i = cpos; i < dpos; i++)
2495 tputs (_rl_term_forward_char, 1, _rl_output_character_function);
2499 tputs (_rl_term_cr, 1, _rl_output_character_function);
2500 for (i = 0; i < new; i++)
2501 putc (data[i], rl_outstream);
2505 for (i = cpos; i < new; i++)
2506 putc (data[i], rl_outstream);
2509 #if defined (HANDLE_MULTIBYTE)
2510 /* NEW points to the buffer point, but _rl_last_c_pos is the display point.
2511 The byte length of the string is probably bigger than the column width
2512 of the string, which means that if NEW == _rl_last_c_pos, then NEW's
2513 display point is less than _rl_last_c_pos. */
2515 else if (cpos > dpos)
2516 _rl_backspace (cpos - dpos);
2518 _rl_last_c_pos = dpos;
2521 /* PWP: move the cursor up or down. */
2523 _rl_move_vert (int to)
2525 register int delta, i;
2527 if (_rl_last_v_pos == to || to > _rl_screenheight)
2530 if ((delta = to - _rl_last_v_pos) > 0)
2532 for (i = 0; i < delta; i++)
2533 putc ('\n', rl_outstream);
2534 #if defined (__MSDOS__)
2535 putc ('\r', rl_outstream);
2537 tputs (_rl_term_cr, 1, _rl_output_character_function);
2546 fflush (rl_outstream);
2547 ScreenGetCursor (&row, &col);
2548 ScreenSetCursor (row + delta, col);
2551 if (_rl_term_up && *_rl_term_up)
2552 for (i = 0; i < -delta; i++)
2553 tputs (_rl_term_up, 1, _rl_output_character_function);
2554 #endif /* !__DJGPP__ */
2557 _rl_last_v_pos = to; /* Now TO is here */
2560 /* Physically print C on rl_outstream. This is for functions which know
2561 how to optimize the display. Return the number of characters output. */
2563 rl_show_char (int c)
2566 if (META_CHAR (c) && (_rl_output_meta_chars == 0))
2568 fprintf (rl_outstream, "M-");
2573 #if defined (DISPLAY_TABS)
2574 if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
2576 if (CTRL_CHAR (c) || c == RUBOUT)
2577 #endif /* !DISPLAY_TABS */
2579 fprintf (rl_outstream, "C-");
2581 c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
2584 putc (c, rl_outstream);
2585 fflush (rl_outstream);
2590 rl_character_len (int c, int pos)
2594 uc = (unsigned char)c;
2597 return ((_rl_output_meta_chars == 0) ? 4 : 1);
2601 #if defined (DISPLAY_TABS)
2602 return (((pos | 7) + 1) - pos);
2605 #endif /* !DISPLAY_TABS */
2608 if (CTRL_CHAR (c) || c == RUBOUT)
2611 return ((ISPRINT (uc)) ? 1 : 2);
2613 /* How to print things in the "echo-area". The prompt is treated as a
2615 static int msg_saved_prompt = 0;
2617 #if defined (USE_VARARGS)
2619 #if defined (PREFER_STDARG)
2620 rl_message (const char *format, ...)
2622 rl_message (va_alist)
2627 #if defined (PREFER_VARARGS)
2630 #if defined (HAVE_VSNPRINTF)
2634 #if defined (PREFER_STDARG)
2635 va_start (args, format);
2638 format = va_arg (args, char *);
2642 msg_buf = xmalloc (msg_bufsiz = 128);
2644 #if defined (HAVE_VSNPRINTF)
2645 bneed = vsnprintf (msg_buf, msg_bufsiz, format, args);
2646 if (bneed >= msg_bufsiz - 1)
2648 msg_bufsiz = bneed + 1;
2649 msg_buf = xrealloc (msg_buf, msg_bufsiz);
2652 #if defined (PREFER_STDARG)
2653 va_start (args, format);
2656 format = va_arg (args, char *);
2658 vsnprintf (msg_buf, msg_bufsiz - 1, format, args);
2661 vsprintf (msg_buf, format, args);
2662 msg_buf[msg_bufsiz - 1] = '\0'; /* overflow? */
2666 if (saved_local_prompt == 0)
2669 msg_saved_prompt = 1;
2671 else if (local_prompt != saved_local_prompt)
2673 FREE (local_prompt);
2674 FREE (local_prompt_prefix);
2675 local_prompt = (char *)NULL;
2677 rl_display_prompt = msg_buf;
2678 local_prompt = expand_prompt (msg_buf, 0, &prompt_visible_length,
2679 &prompt_last_invisible,
2680 &prompt_invis_chars_first_line,
2681 &prompt_physical_chars);
2682 local_prompt_prefix = (char *)NULL;
2683 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
2684 (*rl_redisplay_function) ();
2688 #else /* !USE_VARARGS */
2690 rl_message (format, arg1, arg2)
2694 msg_buf = xmalloc (msg_bufsiz = 128);
2696 sprintf (msg_buf, format, arg1, arg2);
2697 msg_buf[msg_bufsiz - 1] = '\0'; /* overflow? */
2699 rl_display_prompt = msg_buf;
2700 if (saved_local_prompt == 0)
2703 msg_saved_prompt = 1;
2705 else if (local_prompt != saved_local_prompt)
2707 FREE (local_prompt);
2708 FREE (local_prompt_prefix);
2709 local_prompt = (char *)NULL;
2711 local_prompt = expand_prompt (msg_buf, 0, &prompt_visible_length,
2712 &prompt_last_invisible,
2713 &prompt_invis_chars_first_line,
2714 &prompt_physical_chars);
2715 local_prompt_prefix = (char *)NULL;
2716 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
2717 (*rl_redisplay_function) ();
2721 #endif /* !USE_VARARGS */
2723 /* How to clear things from the "echo-area". */
2725 rl_clear_message (void)
2727 rl_display_prompt = rl_prompt;
2728 if (msg_saved_prompt)
2730 rl_restore_prompt ();
2731 msg_saved_prompt = 0;
2733 (*rl_redisplay_function) ();
2738 rl_reset_line_state (void)
2742 rl_display_prompt = rl_prompt ? rl_prompt : "";
2747 /* Save all of the variables associated with the prompt and its display. Most
2748 of the complexity is dealing with the invisible characters in the prompt
2749 string and where they are. There are enough of these that I should consider
2752 rl_save_prompt (void)
2754 saved_local_prompt = local_prompt;
2755 saved_local_prefix = local_prompt_prefix;
2756 saved_prefix_length = prompt_prefix_length;
2757 saved_local_length = local_prompt_len;
2758 saved_last_invisible = prompt_last_invisible;
2759 saved_visible_length = prompt_visible_length;
2760 saved_invis_chars_first_line = prompt_invis_chars_first_line;
2761 saved_physical_chars = prompt_physical_chars;
2762 saved_local_prompt_newlines = local_prompt_newlines;
2764 local_prompt = local_prompt_prefix = (char *)0;
2765 local_prompt_len = 0;
2766 local_prompt_newlines = (int *)0;
2768 prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0;
2769 prompt_invis_chars_first_line = prompt_physical_chars = 0;
2773 rl_restore_prompt (void)
2775 FREE (local_prompt);
2776 FREE (local_prompt_prefix);
2777 FREE (local_prompt_newlines);
2779 local_prompt = saved_local_prompt;
2780 local_prompt_prefix = saved_local_prefix;
2781 local_prompt_len = saved_local_length;
2782 local_prompt_newlines = saved_local_prompt_newlines;
2784 prompt_prefix_length = saved_prefix_length;
2785 prompt_last_invisible = saved_last_invisible;
2786 prompt_visible_length = saved_visible_length;
2787 prompt_invis_chars_first_line = saved_invis_chars_first_line;
2788 prompt_physical_chars = saved_physical_chars;
2790 /* can test saved_local_prompt to see if prompt info has been saved. */
2791 saved_local_prompt = saved_local_prefix = (char *)0;
2792 saved_local_length = 0;
2793 saved_last_invisible = saved_visible_length = saved_prefix_length = 0;
2794 saved_invis_chars_first_line = saved_physical_chars = 0;
2795 saved_local_prompt_newlines = 0;
2799 _rl_make_prompt_for_search (int pchar)
2806 /* We've saved the prompt, and can do anything with the various prompt
2807 strings we need before they're restored. We want the unexpanded
2808 portion of the prompt string after any final newline. */
2809 p = rl_prompt ? strrchr (rl_prompt, '\n') : 0;
2812 len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
2813 pmt = (char *)xmalloc (len + 2);
2815 strcpy (pmt, rl_prompt);
2823 pmt = (char *)xmalloc (len + 2);
2830 /* will be overwritten by expand_prompt, called from rl_message */
2831 prompt_physical_chars = saved_physical_chars + 1;
2835 /* Quick redisplay hack when erasing characters at the end of the line. */
2837 _rl_erase_at_end_of_line (int l)
2842 for (i = 0; i < l; i++)
2843 putc (' ', rl_outstream);
2845 for (i = 0; i < l; i++)
2846 visible_line[--_rl_last_c_pos] = '\0';
2850 /* Clear to the end of the line. COUNT is the minimum
2851 number of character spaces to clear, but we use a terminal escape
2852 sequence if available. */
2854 _rl_clear_to_eol (int count)
2857 if (_rl_term_clreol)
2858 tputs (_rl_term_clreol, 1, _rl_output_character_function);
2862 space_to_eol (count);
2865 /* Clear to the end of the line using spaces. COUNT is the minimum
2866 number of character spaces to clear, */
2868 space_to_eol (int count)
2872 for (i = 0; i < count; i++)
2873 putc (' ', rl_outstream);
2875 _rl_last_c_pos += count;
2879 _rl_clear_screen (void)
2881 #if defined (__DJGPP__)
2883 ScreenSetCursor (0, 0);
2885 if (_rl_term_clrpag)
2886 tputs (_rl_term_clrpag, 1, _rl_output_character_function);
2889 #endif /* __DJGPP__ */
2892 /* Insert COUNT characters from STRING to the output stream at column COL. */
2894 insert_some_chars (char *string, int count, int col)
2896 open_some_spaces (col);
2897 _rl_output_some_chars (string, count);
2900 /* Insert COL spaces, keeping the cursor at the same position. We follow the
2901 ncurses documentation and use either im/ei with explicit spaces, or IC/ic
2902 by itself. We assume there will either be ei or we don't need to use it. */
2904 open_some_spaces (int col)
2906 #if !defined (__MSDOS__) && (!defined (__MINGW32__) || defined (NCURSES_VERSION))
2910 /* If IC is defined, then we do not have to "enter" insert mode. */
2913 buffer = tgoto (_rl_term_IC, 0, col);
2914 tputs (buffer, 1, _rl_output_character_function);
2916 else if (_rl_term_im && *_rl_term_im)
2918 tputs (_rl_term_im, 1, _rl_output_character_function);
2919 /* just output the desired number of spaces */
2920 for (i = col; i--; )
2921 _rl_output_character_function (' ');
2922 /* If there is a string to turn off insert mode, use it now. */
2923 if (_rl_term_ei && *_rl_term_ei)
2924 tputs (_rl_term_ei, 1, _rl_output_character_function);
2925 /* and move back the right number of spaces */
2926 _rl_backspace (col);
2928 else if (_rl_term_ic && *_rl_term_ic)
2930 /* If there is a special command for inserting characters, then
2931 use that first to open up the space. */
2932 for (i = col; i--; )
2933 tputs (_rl_term_ic, 1, _rl_output_character_function);
2935 #endif /* !__MSDOS__ && (!__MINGW32__ || NCURSES_VERSION)*/
2938 /* Delete COUNT characters from the display line. */
2940 delete_chars (int count)
2942 if (count > _rl_screenwidth) /* XXX */
2945 #if !defined (__MSDOS__) && (!defined (__MINGW32__) || defined (NCURSES_VERSION))
2946 if (_rl_term_DC && *_rl_term_DC)
2949 buffer = tgoto (_rl_term_DC, count, count);
2950 tputs (buffer, count, _rl_output_character_function);
2954 if (_rl_term_dc && *_rl_term_dc)
2956 tputs (_rl_term_dc, 1, _rl_output_character_function);
2958 #endif /* !__MSDOS__ && (!__MINGW32__ || NCURSES_VERSION)*/
2962 _rl_update_final (void)
2964 int full_lines, woff, botline_length;
2967 /* If the cursor is the only thing on an otherwise-blank last line,
2968 compensate so we don't print an extra CRLF. */
2969 if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
2970 visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
2975 _rl_move_vert (_rl_vis_botlin);
2976 woff = W_OFFSET(_rl_vis_botlin, wrap_offset);
2977 botline_length = VIS_LLEN(_rl_vis_botlin) - woff;
2978 /* If we've wrapped lines, remove the final xterm line-wrap flag. */
2979 if (full_lines && _rl_term_autowrap && botline_length == _rl_screenwidth)
2983 /* LAST_LINE includes invisible characters, so if you want to get the
2984 last character of the first line, you have to take WOFF into account.
2985 This needs to be done for both calls to _rl_move_cursor_relative,
2986 which takes a buffer position as the first argument, and any direct
2987 subscripts of LAST_LINE. */
2988 last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]]; /* = VIS_CHARS(_rl_vis_botlin); */
2989 cpos_buffer_position = -1; /* don't know where we are in buffer */
2990 _rl_move_cursor_relative (_rl_screenwidth - 1 + woff, last_line); /* XXX */
2991 _rl_clear_to_eol (0);
2992 putc (last_line[_rl_screenwidth - 1 + woff], rl_outstream);
2995 if (botline_length > 0 || _rl_last_c_pos > 0)
2997 fflush (rl_outstream);
3001 /* Move to the start of the current line. */
3007 #if defined (__MSDOS__)
3008 putc ('\r', rl_outstream);
3010 tputs (_rl_term_cr, 1, _rl_output_character_function);
3016 /* Redraw the last line of a multi-line prompt that may possibly contain
3017 terminal escape sequences. Called with the cursor at column 0 of the
3018 line to draw the prompt on. */
3020 redraw_prompt (char *t)
3024 oldp = rl_display_prompt;
3027 rl_display_prompt = t;
3028 local_prompt = expand_prompt (t, PMT_MULTILINE,
3029 &prompt_visible_length,
3030 &prompt_last_invisible,
3031 &prompt_invis_chars_first_line,
3032 &prompt_physical_chars);
3033 local_prompt_prefix = (char *)NULL;
3034 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
3036 rl_forced_update_display ();
3038 rl_display_prompt = oldp;
3039 rl_restore_prompt();
3042 /* Redisplay the current line after a SIGWINCH is received. */
3044 _rl_redisplay_after_sigwinch (void)
3048 /* Clear the last line (assuming that the screen size change will result in
3049 either more or fewer characters on that line only) and put the cursor at
3050 column 0. Make sure the right thing happens if we have wrapped to a new
3054 _rl_move_vert (_rl_vis_botlin);
3056 #if defined (__MSDOS__)
3057 putc ('\r', rl_outstream);
3059 tputs (_rl_term_cr, 1, _rl_output_character_function);
3062 #if defined (__MSDOS__)
3063 space_to_eol (_rl_screenwidth);
3064 putc ('\r', rl_outstream);
3066 if (_rl_term_clreol)
3067 tputs (_rl_term_clreol, 1, _rl_output_character_function);
3070 space_to_eol (_rl_screenwidth);
3071 tputs (_rl_term_cr, 1, _rl_output_character_function);
3074 if (_rl_last_v_pos > 0)
3080 /* Redraw only the last line of a multi-line prompt. */
3081 t = strrchr (rl_display_prompt, '\n');
3083 redraw_prompt (++t);
3085 rl_forced_update_display ();
3089 _rl_clean_up_for_exit (void)
3093 if (_rl_vis_botlin > 0) /* minor optimization plus bug fix */
3094 _rl_move_vert (_rl_vis_botlin);
3096 fflush (rl_outstream);
3097 rl_restart_output (1, 0);
3102 _rl_erase_entire_line (void)
3105 _rl_clear_to_eol (0);
3107 fflush (rl_outstream);
3113 fflush (rl_outstream);
3116 /* return the `current display line' of the cursor -- the number of lines to
3117 move up to get to the first screen line of the current readline line. */
3119 _rl_current_display_line (void)
3123 /* Find out whether or not there might be invisible characters in the
3125 if (rl_display_prompt == rl_prompt)
3126 nleft = _rl_last_c_pos - _rl_screenwidth - rl_visible_prompt_length;
3128 nleft = _rl_last_c_pos - _rl_screenwidth;
3131 ret = 1 + nleft / _rl_screenwidth;
3138 #if defined (HANDLE_MULTIBYTE)
3139 /* Calculate the number of screen columns occupied by STR from START to END.
3140 In the case of multibyte characters with stateful encoding, we have to
3141 scan from the beginning of the string to take the state into account. */
3143 _rl_col_width (const char *str, int start, int end, int flags)
3147 int tmp, point, width, max;
3151 if (MB_CUR_MAX == 1 || rl_byte_oriented)
3152 /* this can happen in some cases where it's inconvenient to check */
3153 return (end - start);
3155 memset (&ps, 0, sizeof (mbstate_t));
3160 /* Try to short-circuit common cases. The adjustment to remove wrap_offset
3161 is done by the caller. */
3162 /* 1. prompt string */
3163 if (flags && start == 0 && end == local_prompt_len && memcmp (str, local_prompt, local_prompt_len) == 0)
3164 return (prompt_physical_chars + wrap_offset);
3165 /* 2. prompt string + line contents */
3166 else if (flags && start == 0 && local_prompt_len > 0 && end > local_prompt_len && local_prompt && memcmp (str, local_prompt, local_prompt_len) == 0)
3168 tmp = prompt_physical_chars + wrap_offset;
3169 /* XXX - try to call ourselves recursively with non-prompt portion */
3170 tmp += _rl_col_width (str, local_prompt_len, end, flags);
3174 while (point < start)
3176 if (_rl_utf8locale && UTF8_SINGLEBYTE(str[point]))
3178 memset (&ps, 0, sizeof (mbstate_t));
3182 tmp = mbrlen (str + point, max, &ps);
3183 if (MB_INVALIDCH ((size_t)tmp))
3185 /* In this case, the bytes are invalid or too short to compose a
3186 multibyte character, so we assume that the first byte represents
3187 a single character. */
3191 /* Clear the state of the byte sequence, because in this case the
3192 effect of mbstate is undefined. */
3193 memset (&ps, 0, sizeof (mbstate_t));
3195 else if (MB_NULLWCH (tmp))
3196 break; /* Found '\0' */
3204 /* If START is not a byte that starts a character, then POINT will be
3205 greater than START. In this case, assume that (POINT - START) gives
3206 a byte count that is the number of columns of difference. */
3207 width = point - start;
3211 if (_rl_utf8locale && UTF8_SINGLEBYTE(str[point]))
3214 wc = (wchar_t) str[point];
3217 tmp = mbrtowc (&wc, str + point, max, &ps);
3218 if (MB_INVALIDCH ((size_t)tmp))
3220 /* In this case, the bytes are invalid or too short to compose a
3221 multibyte character, so we assume that the first byte represents
3222 a single character. */
3226 /* and assume that the byte occupies a single column. */
3229 /* Clear the state of the byte sequence, because in this case the
3230 effect of mbstate is undefined. */
3231 memset (&ps, 0, sizeof (mbstate_t));
3233 else if (MB_NULLWCH (tmp))
3234 break; /* Found '\0' */
3240 width += (tmp >= 0) ? tmp : 1;
3244 width += point - end;
3248 #endif /* HANDLE_MULTIBYTE */