]> git.ipfire.org Git - thirdparty/bash.git/blame - lib/readline/display.c
bash-4.4 beta release
[thirdparty/bash.git] / lib / readline / display.c
CommitLineData
726f6388
JA
1/* display.c -- readline redisplay facility. */
2
73a146be 3/* Copyright (C) 1987-2013 Free Software Foundation, Inc.
726f6388 4
2e4498b3
CR
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.
726f6388 7
2e4498b3
CR
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
726f6388
JA
11 (at your option) any later version.
12
2e4498b3
CR
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
726f6388
JA
16 GNU General Public License for more details.
17
2e4498b3
CR
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/>.
20*/
21
726f6388
JA
22#define READLINE_LIBRARY
23
24#if defined (HAVE_CONFIG_H)
ccc6cda3 25# include <config.h>
726f6388
JA
26#endif
27
726f6388
JA
28#include <sys/types.h>
29
30#if defined (HAVE_UNISTD_H)
31# include <unistd.h>
32#endif /* HAVE_UNISTD_H */
33
d166f048
JA
34#include "posixstat.h"
35
726f6388
JA
36#if defined (HAVE_STDLIB_H)
37# include <stdlib.h>
38#else
39# include "ansi_stdlib.h"
40#endif /* HAVE_STDLIB_H */
41
d166f048
JA
42#include <stdio.h>
43
af32e54d
CR
44#ifdef __MSDOS__
45# include <pc.h>
46#endif
47
726f6388
JA
48/* System-specific feature definitions and include files. */
49#include "rldefs.h"
7117c2d2 50#include "rlmbutil.h"
726f6388 51
ccc6cda3
JA
52/* Termcap library stuff. */
53#include "tcap.h"
54
726f6388
JA
55/* Some standard library routines. */
56#include "readline.h"
57#include "history.h"
58
bb70624e
JA
59#include "rlprivate.h"
60#include "xmalloc.h"
61
726f6388
JA
62#if !defined (strchr) && !defined (__STDC__)
63extern char *strchr (), *strrchr ();
64#endif /* !strchr && !__STDC__ */
65
f73dda09
JA
66static void update_line PARAMS((char *, char *, int, int, int, int));
67static void space_to_eol PARAMS((int));
68static void delete_chars PARAMS((int));
7117c2d2 69static void insert_some_chars PARAMS((char *, int, int));
73a146be 70static void open_some_spaces PARAMS((int));
f73dda09 71static void cr PARAMS((void));
db02a175
CR
72static void redraw_prompt PARAMS((char *));
73
74/* Values for FLAGS */
75#define PMT_MULTILINE 0x01
76
77static char *expand_prompt PARAMS((char *, int, int *, int *, int *, int *));
ccc6cda3 78
d3ad40de
CR
79/* State of visible and invisible lines. */
80struct line_state
81 {
82 char *line;
83 int *lbreaks;
84 int lbsize;
85#if defined (HANDLE_MULTIBYTE)
d3ad40de 86 int wbsize;
54a5fbe1 87 int *wrapped_line;
d3ad40de
CR
88#endif
89 };
90
91/* The line display buffers. One is the line currently displayed on
92 the screen. The other is the line about to be displayed. */
93static struct line_state line_state_array[2];
94static struct line_state *line_state_visible = &line_state_array[0];
95static struct line_state *line_state_invisible = &line_state_array[1];
c2a47ea9 96static int line_structures_initialized = 0;
d3ad40de
CR
97
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)
103
104#define visible_line (line_state_visible->line)
105#define invisible_line (line_state_invisible->line)
106
7117c2d2 107#if defined (HANDLE_MULTIBYTE)
82a5df63 108static int _rl_col_width PARAMS((const char *, int, int, int));
7117c2d2 109#else
82a5df63 110# define _rl_col_width(l, s, e, f) (((e) <= (s)) ? 0 : (e) - (s))
7117c2d2
JA
111#endif
112
726f6388 113/* Heuristic used to decide whether it is faster to move from CUR to NEW
d3ad40de
CR
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. */
726f6388
JA
116#define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))
117
ac18b312
CR
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
d3ad40de 121 invisible characters. XXX - might need to take `modmark' into account. */
ac18b312 122#define PROMPT_ENDING_INDEX \
2abb7255 123 ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1)
ac18b312
CR
124
125
726f6388
JA
126/* **************************************************************** */
127/* */
128/* Display stuff */
129/* */
130/* **************************************************************** */
131
132/* This is the stuff that is hard for me. I never seem to write good
133 display routines in C. Let's see how I do this time. */
134
135/* (PWP) Well... Good for a simple line updater, but totally ignores
136 the problems of input lines longer than the screen width.
137
138 update_line and the code that calls it makes a multiple line,
139 automatically wrapping line update. Careful attention needs
140 to be paid to the vertical position variables. */
141
142/* Keep two buffers; one which reflects the current contents of the
143 screen, and the other to draw what we think the new contents should
144 be. Then compare the buffers, and make whatever changes to the
145 screen itself that we should. Finally, make the buffer that we
146 just drew into be the one which reflects the current contents of the
147 screen, and place the cursor where it belongs.
148
149 Commands that want to can fix the display themselves, and then let
150 this function know that the display has been fixed by setting the
151 RL_DISPLAY_FIXED variable. This is good for efficiency. */
152
ccc6cda3 153/* Application-specific redisplay function. */
28ef6c31 154rl_voidfunc_t *rl_redisplay_function = rl_redisplay;
ccc6cda3 155
726f6388
JA
156/* Global variables declared here. */
157/* What YOU turn on when you have handled all redisplay yourself. */
158int rl_display_fixed = 0;
159
ccc6cda3 160int _rl_suppress_redisplay = 0;
798a67db 161int _rl_want_redisplay = 0;
ccc6cda3 162
726f6388
JA
163/* The stuff that gets printed out before the actual text of the line.
164 This is usually pointing to rl_prompt. */
165char *rl_display_prompt = (char *)NULL;
166
db02a175
CR
167/* Variables used to include the editing mode in the prompt. */
168char *_rl_emacs_mode_str;
169int _rl_emacs_modestr_len;
170
171char *_rl_vi_ins_mode_str;
172int _rl_vi_ins_modestr_len;
173
174char *_rl_vi_cmd_mode_str;
175int _rl_vi_cmd_modestr_len;
176
726f6388 177/* Pseudo-global variables declared here. */
177d51f7 178
726f6388 179/* The visible cursor position. If you print some text, adjust this. */
177d51f7
CR
180/* NOTE: _rl_last_c_pos is used as a buffer index when not in a locale
181 supporting multibyte characters, and an absolute cursor position when
182 in such a locale. This is an artifact of the donated multibyte support.
183 Care must be taken when modifying its value. */
726f6388
JA
184int _rl_last_c_pos = 0;
185int _rl_last_v_pos = 0;
186
5c26afb8 187static int cpos_adjusted;
d3ad40de 188static int cpos_buffer_position;
77b3aacb 189static int displaying_prompt_first_line;
d3ad40de 190static int prompt_multibyte_chars;
5c26afb8 191
726f6388
JA
192/* Number of lines currently on screen minus 1. */
193int _rl_vis_botlin = 0;
194
195/* Variables used only in this file. */
196/* The last left edge of text that was displayed. This is used when
197 doing horizontal scrolling. It shifts in thirds of a screenwidth. */
ccc6cda3 198static int last_lmargin;
726f6388 199
726f6388 200/* A buffer for `modeline' messages. */
40647963
CR
201static char *msg_buf = 0;
202static int msg_bufsiz = 0;
726f6388
JA
203
204/* Non-zero forces the redisplay even if we thought it was unnecessary. */
ccc6cda3 205static int forced_display;
726f6388
JA
206
207/* Default and initial buffer size. Can grow. */
208static int line_size = 1024;
209
28ef6c31
JA
210/* Variables to keep track of the expanded prompt string, which may
211 include invisible characters. */
212
726f6388 213static char *local_prompt, *local_prompt_prefix;
d3ad40de 214static int local_prompt_len;
28ef6c31 215static int prompt_visible_length, prompt_prefix_length;
726f6388
JA
216
217/* The number of invisible characters in the line currently being
218 displayed on the screen. */
ccc6cda3
JA
219static int visible_wrap_offset;
220
28ef6c31
JA
221/* The number of invisible characters in the prompt string. Static so it
222 can be shared between rl_redisplay and update_line */
ccc6cda3
JA
223static int wrap_offset;
224
28ef6c31
JA
225/* The index of the last invisible character in the prompt string. */
226static int prompt_last_invisible;
726f6388
JA
227
228/* The length (buffer offset) of the first line of the last (possibly
229 multi-line) buffer displayed on the screen. */
ccc6cda3 230static int visible_first_line_len;
726f6388 231
28ef6c31
JA
232/* Number of invisible characters on the first physical line of the prompt.
233 Only valid when the number of physical characters in the prompt exceeds
234 (or is equal to) _rl_screenwidth. */
235static int prompt_invis_chars_first_line;
236
237static int prompt_last_screen_line;
238
43cdcad8
CR
239static int prompt_physical_chars;
240
d3ad40de
CR
241/* set to a non-zero value by rl_redisplay if we are marking modified history
242 lines and the current line is so marked. */
243static int modmark;
244
6e70dbff
CR
245/* Variables to save and restore prompt and display information. */
246
247/* These are getting numerous enough that it's time to create a struct. */
248
249static char *saved_local_prompt;
250static char *saved_local_prefix;
251static int saved_last_invisible;
252static int saved_visible_length;
253static int saved_prefix_length;
d3ad40de 254static int saved_local_length;
6e70dbff
CR
255static int saved_invis_chars_first_line;
256static int saved_physical_chars;
257
db02a175
CR
258/* Return a string indicating the editing mode, for use in the prompt. */
259
260static char *
261prompt_modestr (lenp)
262 int *lenp;
a7ad477f
CR
263{
264 if (rl_editing_mode == emacs_mode)
db02a175
CR
265 {
266 if (lenp)
267 *lenp = _rl_emacs_mode_str ? _rl_emacs_modestr_len : RL_EMACS_MODESTR_DEFLEN;
268 return _rl_emacs_mode_str ? _rl_emacs_mode_str : RL_EMACS_MODESTR_DEFAULT;
269 }
a7ad477f 270 else if (_rl_keymap == vi_insertion_keymap)
db02a175
CR
271 {
272 if (lenp)
273 *lenp = _rl_vi_ins_mode_str ? _rl_vi_ins_modestr_len : RL_VI_INS_MODESTR_DEFLEN;
274 return _rl_vi_ins_mode_str ? _rl_vi_ins_mode_str : RL_VI_INS_MODESTR_DEFAULT; /* vi insert mode */
275 }
a7ad477f 276 else
db02a175
CR
277 {
278 if (lenp)
279 *lenp = _rl_vi_cmd_mode_str ? _rl_vi_cmd_modestr_len : RL_VI_CMD_MODESTR_DEFLEN;
280 return _rl_vi_cmd_mode_str ? _rl_vi_cmd_mode_str : RL_VI_CMD_MODESTR_DEFAULT; /* vi command mode */
281 }
a7ad477f
CR
282}
283
726f6388
JA
284/* Expand the prompt string S and return the number of visible
285 characters in *LP, if LP is not null. This is currently more-or-less
ccc6cda3 286 a placeholder for expansion. LIP, if non-null is a place to store the
28ef6c31
JA
287 index of the last invisible character in the returned string. NIFLP,
288 if non-zero, is a place to store the number of invisible characters in
43cdcad8
CR
289 the first prompt line. The previous are used as byte counts -- indexes
290 into a character buffer. */
726f6388
JA
291
292/* Current implementation:
293 \001 (^A) start non-visible characters
294 \002 (^B) end non-visible characters
295 all characters except \001 and \002 (following a \001) are copied to
296 the returned string; all characters except those between \001 and
297 \002 are assumed to be `visible'. */
298
db02a175
CR
299/* Possible values for FLAGS:
300 PMT_MULTILINE caller indicates that this is part of a multiline prompt
301*/
302
726f6388 303static char *
db02a175 304expand_prompt (pmt, flags, lp, lip, niflp, vlp)
726f6388 305 char *pmt;
db02a175 306 int flags;
43cdcad8 307 int *lp, *lip, *niflp, *vlp;
726f6388 308{
db02a175 309 char *r, *ret, *p, *igstart, *nprompt, *ms;
b954488b 310 int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
db02a175
CR
311 int mlen;
312
313 /* We only expand the mode string for the last line of a multiline prompt
314 (a prompt with embedded newlines). */
315 ms = (((pmt == rl_prompt) ^ (flags & PMT_MULTILINE)) && _rl_show_mode_in_prompt) ? prompt_modestr (&mlen) : 0;
316 if (ms)
317 {
318 l = strlen (pmt);
319 nprompt = (char *)xmalloc (l + mlen + 1);
320 memcpy (nprompt, ms, mlen);
321 strcpy (nprompt + mlen, pmt);
322 }
323 else
324 nprompt = pmt;
726f6388
JA
325
326 /* Short-circuit if we can. */
db02a175 327 if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (nprompt, RL_PROMPT_START_IGNORE) == 0)
726f6388 328 {
db02a175 329 r = (nprompt == pmt) ? savestring (pmt) : nprompt;
a7ad477f 330
726f6388
JA
331 if (lp)
332 *lp = strlen (r);
43cdcad8
CR
333 if (lip)
334 *lip = 0;
335 if (niflp)
336 *niflp = 0;
337 if (vlp)
338 *vlp = lp ? *lp : strlen (r);
726f6388
JA
339 return r;
340 }
341
db02a175
CR
342 l = strlen (nprompt); /* XXX */
343 r = ret = (char *)xmalloc (l + 1);
28ef6c31 344
db02a175 345 rl = physchars = 0; /* mode string now part of nprompt */
28ef6c31 346 invfl = 0; /* invisible chars in first line of prompt */
b954488b 347 invflset = 0; /* we only want to set invfl once */
dc8fbaf9 348 igstart = 0;
db02a175
CR
349
350 for (ignoring = last = ninvis = 0, p = nprompt; p && *p; p++)
726f6388
JA
351 {
352 /* This code strips the invisible character string markers
353 RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
dc8fbaf9 354 if (ignoring == 0 && *p == RL_PROMPT_START_IGNORE) /* XXX - check ignoring? */
726f6388 355 {
5e4a95c7
CR
356 ignoring = 1;
357 igstart = p;
726f6388
JA
358 continue;
359 }
360 else if (ignoring && *p == RL_PROMPT_END_IGNORE)
361 {
362 ignoring = 0;
dc8fbaf9 363 if (p != (igstart + 1))
1569c106 364 last = r - ret - 1;
726f6388
JA
365 continue;
366 }
367 else
368 {
43cdcad8
CR
369#if defined (HANDLE_MULTIBYTE)
370 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
371 {
db02a175
CR
372 pind = p - nprompt;
373 ind = _rl_find_next_mbchar (nprompt, pind, 1, MB_FIND_NONZERO);
43cdcad8
CR
374 l = ind - pind;
375 while (l--)
376 *r++ = *p++;
377 if (!ignoring)
37c41ab1 378 {
d3ad40de
CR
379 /* rl ends up being assigned to prompt_visible_length,
380 which is the number of characters in the buffer that
381 contribute to characters on the screen, which might
382 not be the same as the number of physical characters
383 on the screen in the presence of multibyte characters */
37c41ab1 384 rl += ind - pind;
db02a175 385 physchars += _rl_col_width (nprompt, pind, ind, 0);
37c41ab1 386 }
43cdcad8
CR
387 else
388 ninvis += ind - pind;
389 p--; /* compensate for later increment */
390 }
28ef6c31 391 else
43cdcad8
CR
392#endif
393 {
394 *r++ = *p;
395 if (!ignoring)
37c41ab1
CR
396 {
397 rl++; /* visible length byte counter */
398 physchars++;
399 }
43cdcad8
CR
400 else
401 ninvis++; /* invisible chars byte counter */
402 }
403
b954488b
CR
404 if (invflset == 0 && rl >= _rl_screenwidth)
405 {
406 invfl = ninvis;
407 invflset = 1;
408 }
726f6388
JA
409 }
410 }
411
28ef6c31
JA
412 if (rl < _rl_screenwidth)
413 invfl = ninvis;
414
726f6388
JA
415 *r = '\0';
416 if (lp)
417 *lp = rl;
ccc6cda3
JA
418 if (lip)
419 *lip = last;
28ef6c31
JA
420 if (niflp)
421 *niflp = invfl;
43cdcad8
CR
422 if (vlp)
423 *vlp = physchars;
db02a175
CR
424
425 if (nprompt != pmt)
426 free (nprompt);
427
726f6388
JA
428 return ret;
429}
430
bb70624e
JA
431/* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from
432 PMT and return the rest of PMT. */
433char *
434_rl_strip_prompt (pmt)
435 char *pmt;
436{
437 char *ret;
438
db02a175 439 ret = expand_prompt (pmt, 0, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL);
bb70624e
JA
440 return ret;
441}
442
a7ad477f
CR
443void
444_rl_reset_prompt ()
445{
446 rl_visible_prompt_length = rl_expand_prompt (rl_prompt);
447}
448
726f6388
JA
449/*
450 * Expand the prompt string into the various display components, if
451 * necessary.
452 *
453 * local_prompt = expanded last line of string in rl_display_prompt
454 * (portion after the final newline)
455 * local_prompt_prefix = portion before last newline of rl_display_prompt,
456 * expanded via expand_prompt
28ef6c31
JA
457 * prompt_visible_length = number of visible characters in local_prompt
458 * prompt_prefix_length = number of visible characters in local_prompt_prefix
726f6388
JA
459 *
460 * This function is called once per call to readline(). It may also be
461 * called arbitrarily to expand the primary prompt.
462 *
463 * The return value is the number of visible characters on the last line
464 * of the (possibly multi-line) prompt.
465 */
466int
467rl_expand_prompt (prompt)
468 char *prompt;
469{
470 char *p, *t;
471 int c;
472
473 /* Clear out any saved values. */
28ef6c31
JA
474 FREE (local_prompt);
475 FREE (local_prompt_prefix);
476
726f6388 477 local_prompt = local_prompt_prefix = (char *)0;
d3ad40de 478 local_prompt_len = 0;
ec2199bd
CR
479 prompt_last_invisible = prompt_invis_chars_first_line = 0;
480 prompt_visible_length = prompt_physical_chars = 0;
726f6388 481
ccc6cda3 482 if (prompt == 0 || *prompt == 0)
726f6388
JA
483 return (0);
484
485 p = strrchr (prompt, '\n');
db02a175 486 if (p == 0)
726f6388 487 {
28ef6c31 488 /* The prompt is only one logical line, though it might wrap. */
db02a175
CR
489 local_prompt = expand_prompt (prompt, 0, &prompt_visible_length,
490 &prompt_last_invisible,
491 &prompt_invis_chars_first_line,
492 &prompt_physical_chars);
726f6388 493 local_prompt_prefix = (char *)0;
d3ad40de 494 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
28ef6c31 495 return (prompt_visible_length);
726f6388
JA
496 }
497 else
498 {
499 /* The prompt spans multiple lines. */
500 t = ++p;
db02a175
CR
501 local_prompt = expand_prompt (p, PMT_MULTILINE,
502 &prompt_visible_length,
28ef6c31 503 &prompt_last_invisible,
70694d2e 504 &prompt_invis_chars_first_line,
e6e3b444 505 &prompt_physical_chars);
726f6388
JA
506 c = *t; *t = '\0';
507 /* The portion of the prompt string up to and including the
508 final newline is now null-terminated. */
db02a175
CR
509 local_prompt_prefix = expand_prompt (prompt, PMT_MULTILINE,
510 &prompt_prefix_length,
28ef6c31 511 (int *)NULL,
70694d2e 512 (int *)NULL,
e6e3b444 513 (int *)NULL);
726f6388 514 *t = c;
d3ad40de 515 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
28ef6c31 516 return (prompt_prefix_length);
726f6388
JA
517 }
518}
519
bb70624e
JA
520/* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their associated
521 arrays of line break markers. MINSIZE is the minimum size of VISIBLE_LINE
522 and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is
523 increased. If the lines have already been allocated, this ensures that
524 they can hold at least MINSIZE characters. */
525static void
526init_line_structures (minsize)
527 int minsize;
528{
529 register int n;
530
531 if (invisible_line == 0) /* initialize it */
532 {
533 if (line_size < minsize)
534 line_size = minsize;
f73dda09
JA
535 visible_line = (char *)xmalloc (line_size);
536 invisible_line = (char *)xmalloc (line_size);
bb70624e
JA
537 }
538 else if (line_size < minsize) /* ensure it can hold MINSIZE chars */
539 {
540 line_size *= 2;
541 if (line_size < minsize)
542 line_size = minsize;
f73dda09
JA
543 visible_line = (char *)xrealloc (visible_line, line_size);
544 invisible_line = (char *)xrealloc (invisible_line, line_size);
bb70624e
JA
545 }
546
547 for (n = minsize; n < line_size; n++)
548 {
549 visible_line[n] = 0;
550 invisible_line[n] = 1;
551 }
552
553 if (vis_lbreaks == 0)
554 {
555 /* should be enough. */
556 inv_lbsize = vis_lbsize = 256;
c2a47ea9 557
7117c2d2 558#if defined (HANDLE_MULTIBYTE)
d3ad40de
CR
559 line_state_visible->wbsize = vis_lbsize;
560 line_state_visible->wrapped_line = (int *)xmalloc (line_state_visible->wbsize * sizeof (int));
561
562 line_state_invisible->wbsize = inv_lbsize;
563 line_state_invisible->wrapped_line = (int *)xmalloc (line_state_invisible->wbsize * sizeof (int));
7117c2d2 564#endif
c2a47ea9
CR
565
566 inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int));
567 vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int));
bb70624e
JA
568 inv_lbreaks[0] = vis_lbreaks[0] = 0;
569 }
c2a47ea9
CR
570
571 line_structures_initialized = 1;
bb70624e
JA
572}
573
726f6388
JA
574/* Basic redisplay algorithm. */
575void
576rl_redisplay ()
577{
ccc6cda3
JA
578 register int in, out, c, linenum, cursor_linenum;
579 register char *line;
d3ad40de 580 int inv_botlin, lb_botlin, lb_linenum, o_cpos;
57a3f689 581 int newlines, lpos, temp, n0, num, prompt_lines_estimate;
726f6388 582 char *prompt_this_line;
7117c2d2
JA
583#if defined (HANDLE_MULTIBYTE)
584 wchar_t wc;
585 size_t wc_bytes;
586 int wc_width;
587 mbstate_t ps;
588 int _rl_wrapped_multicolumn = 0;
3bf257a5 589 int mb_cur_max = MB_CUR_MAX;
7117c2d2 590#endif
726f6388 591
6fbe7620 592 if (_rl_echoing_p == 0)
726f6388
JA
593 return;
594
d356441f
CR
595 /* Block keyboard interrupts because this function manipulates global
596 data structures. */
597 _rl_block_sigint ();
83c14a20 598 RL_SETSTATE (RL_STATE_REDISPLAYING);
d356441f 599
726f6388
JA
600 if (!rl_display_prompt)
601 rl_display_prompt = "";
602
c2a47ea9 603 if (line_structures_initialized == 0)
726f6388 604 {
bb70624e 605 init_line_structures (0);
726f6388
JA
606 rl_on_new_line ();
607 }
608
609 /* Draw the line into the buffer. */
d3ad40de
CR
610 cpos_buffer_position = -1;
611
612 prompt_multibyte_chars = prompt_visible_length - prompt_physical_chars;
6ec48275 613
ccc6cda3
JA
614 line = invisible_line;
615 out = inv_botlin = 0;
616
726f6388
JA
617 /* Mark the line as modified or not. We only do this for history
618 lines. */
43cdcad8 619 modmark = 0;
726f6388
JA
620 if (_rl_mark_modified_lines && current_history () && rl_undo_list)
621 {
622 line[out++] = '*';
623 line[out] = '\0';
43cdcad8 624 modmark = 1;
726f6388
JA
625 }
626
627 /* If someone thought that the redisplay was handled, but the currently
628 visible line has a different modification state than the one about
629 to become visible, then correct the caller's misconception. */
630 if (visible_line[0] != invisible_line[0])
631 rl_display_fixed = 0;
632
633 /* If the prompt to be displayed is the `primary' readline prompt (the
634 one passed to readline()), use the values we have already expanded.
635 If not, use what's already in rl_display_prompt. WRAP_OFFSET is the
636 number of non-visible characters in the prompt string. */
ccc6cda3 637 if (rl_display_prompt == rl_prompt || local_prompt)
726f6388 638 {
726f6388
JA
639 if (local_prompt_prefix && forced_display)
640 _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
641
d3ad40de 642 if (local_prompt_len > 0)
ccc6cda3 643 {
d3ad40de 644 temp = local_prompt_len + out + 2;
b72432fd
JA
645 if (temp >= line_size)
646 {
647 line_size = (temp + 1024) - (temp % 1024);
f73dda09
JA
648 visible_line = (char *)xrealloc (visible_line, line_size);
649 line = invisible_line = (char *)xrealloc (invisible_line, line_size);
b72432fd 650 }
d3ad40de
CR
651 strncpy (line + out, local_prompt, local_prompt_len);
652 out += local_prompt_len;
ccc6cda3 653 }
726f6388 654 line[out] = '\0';
d3ad40de 655 wrap_offset = local_prompt_len - prompt_visible_length;
726f6388
JA
656 }
657 else
658 {
659 int pmtlen;
660 prompt_this_line = strrchr (rl_display_prompt, '\n');
661 if (!prompt_this_line)
662 prompt_this_line = rl_display_prompt;
663 else
664 {
665 prompt_this_line++;
bb70624e 666 pmtlen = prompt_this_line - rl_display_prompt; /* temp var */
726f6388 667 if (forced_display)
ccc6cda3 668 {
bb70624e 669 _rl_output_some_chars (rl_display_prompt, pmtlen);
ccc6cda3
JA
670 /* Make sure we are at column zero even after a newline,
671 regardless of the state of terminal output processing. */
bb70624e 672 if (pmtlen < 2 || prompt_this_line[-2] != '\r')
ccc6cda3
JA
673 cr ();
674 }
726f6388
JA
675 }
676
762a763b 677 prompt_physical_chars = pmtlen = strlen (prompt_this_line);
b72432fd
JA
678 temp = pmtlen + out + 2;
679 if (temp >= line_size)
680 {
681 line_size = (temp + 1024) - (temp % 1024);
f73dda09
JA
682 visible_line = (char *)xrealloc (visible_line, line_size);
683 line = invisible_line = (char *)xrealloc (invisible_line, line_size);
b72432fd 684 }
726f6388
JA
685 strncpy (line + out, prompt_this_line, pmtlen);
686 out += pmtlen;
687 line[out] = '\0';
28ef6c31 688 wrap_offset = prompt_invis_chars_first_line = 0;
726f6388
JA
689 }
690
bb70624e
JA
691#define CHECK_INV_LBREAKS() \
692 do { \
693 if (newlines >= (inv_lbsize - 2)) \
694 { \
695 inv_lbsize *= 2; \
696 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
697 } \
698 } while (0)
7117c2d2
JA
699
700#if defined (HANDLE_MULTIBYTE)
ccc6cda3
JA
701#define CHECK_LPOS() \
702 do { \
b72432fd 703 lpos++; \
28ef6c31 704 if (lpos >= _rl_screenwidth) \
b72432fd 705 { \
bb70624e
JA
706 if (newlines >= (inv_lbsize - 2)) \
707 { \
708 inv_lbsize *= 2; \
709 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
710 } \
b72432fd 711 inv_lbreaks[++newlines] = out; \
d3ad40de
CR
712 if (newlines >= (line_state_invisible->wbsize - 1)) \
713 { \
714 line_state_invisible->wbsize *= 2; \
715 line_state_invisible->wrapped_line = (int *)xrealloc (line_state_invisible->wrapped_line, line_state_invisible->wbsize * sizeof(int)); \
716 } \
717 line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; \
b72432fd
JA
718 lpos = 0; \
719 } \
ccc6cda3 720 } while (0)
7117c2d2
JA
721#else
722#define CHECK_LPOS() \
723 do { \
724 lpos++; \
725 if (lpos >= _rl_screenwidth) \
726 { \
727 if (newlines >= (inv_lbsize - 2)) \
728 { \
729 inv_lbsize *= 2; \
730 inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
731 } \
732 inv_lbreaks[++newlines] = out; \
733 lpos = 0; \
734 } \
735 } while (0)
736#endif
ccc6cda3
JA
737
738 /* inv_lbreaks[i] is where line i starts in the buffer. */
739 inv_lbreaks[newlines = 0] = 0;
43cdcad8 740 lpos = prompt_physical_chars + modmark;
43cdcad8 741
7117c2d2 742#if defined (HANDLE_MULTIBYTE)
d3ad40de 743 memset (line_state_invisible->wrapped_line, 0, line_state_invisible->wbsize * sizeof (int));
37c41ab1 744 num = 0;
7117c2d2 745#endif
d166f048 746
28ef6c31
JA
747 /* prompt_invis_chars_first_line is the number of invisible characters in
748 the first physical line of the prompt.
749 wrap_offset - prompt_invis_chars_first_line is the number of invis
57a3f689
CR
750 chars on the second (or, more generally, last) line. */
751
752 /* This is zero-based, used to set the newlines */
753 prompt_lines_estimate = lpos / _rl_screenwidth;
28ef6c31
JA
754
755 /* what if lpos is already >= _rl_screenwidth before we start drawing the
d166f048 756 contents of the command line? */
28ef6c31 757 while (lpos >= _rl_screenwidth)
d166f048 758 {
2171061f 759 int z, p;
28ef6c31
JA
760 /* fix from Darin Johnson <darin@acuson.com> for prompt string with
761 invisible characters that is longer than the screen width. The
762 prompt_invis_chars_first_line variable could be made into an array
763 saying how many invisible characters there are per line, but that's
764 probably too much work for the benefit gained. How many people have
545f34cf
CR
765 prompts that exceed two physical lines?
766 Additional logic fix from Edward Catmur <ed@catmur.co.uk> */
37c41ab1 767#if defined (HANDLE_MULTIBYTE)
3bf257a5 768 if (mb_cur_max > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
37c41ab1 769 {
d3ad40de
CR
770 n0 = num;
771 temp = local_prompt_len;
772 while (num < temp)
37c41ab1 773 {
82a5df63 774 z = _rl_col_width (local_prompt, n0, num, 1);
d3ad40de
CR
775 if (z > _rl_screenwidth)
776 {
777 num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
778 break;
779 }
780 else if (z == _rl_screenwidth)
2171061f
CR
781 {
782 /* If we are in the middle or at the end of a multibyte
783 character, we want to move to the start, then find out
784 where it ends so we know where to insert the newline.
785 If this isn't a multibyte character, its the same as num++ */
786 p = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
787 num = _rl_find_next_mbchar (local_prompt, p, 1, MB_FIND_ANY);
788 break;
789 }
d3ad40de 790 num++;
37c41ab1 791 }
d3ad40de 792 temp = num;
37c41ab1 793 }
d3ad40de 794 else
37c41ab1 795#endif /* !HANDLE_MULTIBYTE */
d3ad40de
CR
796 temp = ((newlines + 1) * _rl_screenwidth);
797
798 /* Now account for invisible characters in the current line. */
57a3f689
CR
799 /* XXX - this assumes that the invisible characters may be split, but only
800 between the first and the last lines. */
6e51e0d0
CR
801 temp += (newlines == 0) ? prompt_invis_chars_first_line
802 : ((newlines == prompt_lines_estimate) ? wrap_offset : prompt_invis_chars_first_line);
803
d166f048 804 inv_lbreaks[++newlines] = temp;
37c41ab1 805#if defined (HANDLE_MULTIBYTE)
3bf257a5 806 if (mb_cur_max > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0)
82a5df63 807 lpos -= _rl_col_width (local_prompt, n0, num, 1);
d3ad40de 808 else
37c41ab1 809#endif
d3ad40de 810 lpos -= _rl_screenwidth;
d166f048 811 }
ccc6cda3 812
28ef6c31
JA
813 prompt_last_screen_line = newlines;
814
815 /* Draw the rest of the line (after the prompt) into invisible_line, keeping
d3ad40de 816 track of where the cursor is (cpos_buffer_position), the number of the line containing
28ef6c31
JA
817 the cursor (lb_linenum), the last line number (lb_botlin and inv_botlin).
818 It maintains an array of line breaks for display (inv_lbreaks).
819 This handles expanding tabs for display and displaying meta characters. */
d166f048 820 lb_linenum = 0;
7117c2d2
JA
821#if defined (HANDLE_MULTIBYTE)
822 in = 0;
3bf257a5 823 if (mb_cur_max > 1 && rl_byte_oriented == 0)
7117c2d2
JA
824 {
825 memset (&ps, 0, sizeof (mbstate_t));
bf6bd355 826 /* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */
7117c2d2
JA
827 wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps);
828 }
829 else
830 wc_bytes = 1;
831 while (in < rl_end)
832#else
d166f048 833 for (in = 0; in < rl_end; in++)
7117c2d2 834#endif
726f6388
JA
835 {
836 c = (unsigned char)rl_line_buffer[in];
837
7117c2d2 838#if defined (HANDLE_MULTIBYTE)
3bf257a5 839 if (mb_cur_max > 1 && rl_byte_oriented == 0)
7117c2d2 840 {
d3a24ed2 841 if (MB_INVALIDCH (wc_bytes))
7117c2d2
JA
842 {
843 /* Byte sequence is invalid or shortened. Assume that the
844 first byte represents a character. */
845 wc_bytes = 1;
846 /* Assume that a character occupies a single column. */
847 wc_width = 1;
848 memset (&ps, 0, sizeof (mbstate_t));
849 }
d3a24ed2 850 else if (MB_NULLWCH (wc_bytes))
7117c2d2
JA
851 break; /* Found '\0' */
852 else
853 {
22818c14 854 temp = WCWIDTH (wc);
d3a24ed2 855 wc_width = (temp >= 0) ? temp : 1;
7117c2d2
JA
856 }
857 }
858#endif
859
726f6388
JA
860 if (out + 8 >= line_size) /* XXX - 8 for \t */
861 {
862 line_size *= 2;
f73dda09
JA
863 visible_line = (char *)xrealloc (visible_line, line_size);
864 invisible_line = (char *)xrealloc (invisible_line, line_size);
726f6388
JA
865 line = invisible_line;
866 }
867
868 if (in == rl_point)
ccc6cda3 869 {
d3ad40de 870 cpos_buffer_position = out;
ccc6cda3
JA
871 lb_linenum = newlines;
872 }
726f6388 873
7117c2d2
JA
874#if defined (HANDLE_MULTIBYTE)
875 if (META_CHAR (c) && _rl_output_meta_chars == 0) /* XXX - clean up */
876#else
726f6388 877 if (META_CHAR (c))
7117c2d2 878#endif
726f6388
JA
879 {
880 if (_rl_output_meta_chars == 0)
881 {
882 sprintf (line + out, "\\%o", c);
ccc6cda3 883
28ef6c31 884 if (lpos + 4 >= _rl_screenwidth)
ccc6cda3 885 {
28ef6c31 886 temp = _rl_screenwidth - lpos;
bb70624e 887 CHECK_INV_LBREAKS ();
ccc6cda3
JA
888 inv_lbreaks[++newlines] = out + temp;
889 lpos = 4 - temp;
890 }
891 else
892 lpos += 4;
893
726f6388
JA
894 out += 4;
895 }
896 else
ccc6cda3
JA
897 {
898 line[out++] = c;
899 CHECK_LPOS();
900 }
726f6388
JA
901 }
902#if defined (DISPLAY_TABS)
903 else if (c == '\t')
904 {
28ef6c31 905 register int newout;
b72432fd
JA
906
907#if 0
ccc6cda3 908 newout = (out | (int)7) + 1;
b72432fd
JA
909#else
910 newout = out + 8 - lpos % 8;
911#endif
ccc6cda3 912 temp = newout - out;
28ef6c31 913 if (lpos + temp >= _rl_screenwidth)
ccc6cda3
JA
914 {
915 register int temp2;
28ef6c31 916 temp2 = _rl_screenwidth - lpos;
bb70624e 917 CHECK_INV_LBREAKS ();
ccc6cda3
JA
918 inv_lbreaks[++newlines] = out + temp2;
919 lpos = temp - temp2;
920 while (out < newout)
921 line[out++] = ' ';
922 }
923 else
924 {
925 while (out < newout)
926 line[out++] = ' ';
927 lpos += temp;
928 }
726f6388
JA
929 }
930#endif
28ef6c31 931 else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
b72432fd
JA
932 {
933 line[out++] = '\0'; /* XXX - sentinel */
bb70624e 934 CHECK_INV_LBREAKS ();
b72432fd
JA
935 inv_lbreaks[++newlines] = out;
936 lpos = 0;
937 }
ccc6cda3 938 else if (CTRL_CHAR (c) || c == RUBOUT)
726f6388
JA
939 {
940 line[out++] = '^';
ccc6cda3
JA
941 CHECK_LPOS();
942 line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
943 CHECK_LPOS();
726f6388 944 }
ccc6cda3 945 else
726f6388 946 {
7117c2d2 947#if defined (HANDLE_MULTIBYTE)
3bf257a5 948 if (mb_cur_max > 1 && rl_byte_oriented == 0)
7117c2d2
JA
949 {
950 register int i;
951
952 _rl_wrapped_multicolumn = 0;
953
954 if (_rl_screenwidth < lpos + wc_width)
955 for (i = lpos; i < _rl_screenwidth; i++)
956 {
957 /* The space will be removed in update_line() */
958 line[out++] = ' ';
959 _rl_wrapped_multicolumn++;
960 CHECK_LPOS();
961 }
962 if (in == rl_point)
963 {
d3ad40de 964 cpos_buffer_position = out;
7117c2d2
JA
965 lb_linenum = newlines;
966 }
967 for (i = in; i < in+wc_bytes; i++)
968 line[out++] = rl_line_buffer[i];
969 for (i = 0; i < wc_width; i++)
970 CHECK_LPOS();
971 }
972 else
973 {
974 line[out++] = c;
975 CHECK_LPOS();
976 }
977#else
ccc6cda3
JA
978 line[out++] = c;
979 CHECK_LPOS();
7117c2d2
JA
980#endif
981 }
982
983#if defined (HANDLE_MULTIBYTE)
3bf257a5 984 if (mb_cur_max > 1 && rl_byte_oriented == 0)
7117c2d2
JA
985 {
986 in += wc_bytes;
bf6bd355 987 /* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */
7117c2d2 988 wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps);
726f6388 989 }
7117c2d2
JA
990 else
991 in++;
992#endif
993
726f6388
JA
994 }
995 line[out] = '\0';
d3ad40de 996 if (cpos_buffer_position < 0)
ccc6cda3 997 {
d3ad40de 998 cpos_buffer_position = out;
ccc6cda3
JA
999 lb_linenum = newlines;
1000 }
1001
1002 inv_botlin = lb_botlin = newlines;
bb70624e 1003 CHECK_INV_LBREAKS ();
ccc6cda3
JA
1004 inv_lbreaks[newlines+1] = out;
1005 cursor_linenum = lb_linenum;
726f6388 1006
d3ad40de 1007 /* CPOS_BUFFER_POSITION == position in buffer where cursor should be placed.
28ef6c31 1008 CURSOR_LINENUM == line number where the cursor should be placed. */
726f6388
JA
1009
1010 /* PWP: now is when things get a bit hairy. The visible and invisible
1011 line buffers are really multiple lines, which would wrap every
1012 (screenwidth - 1) characters. Go through each in turn, finding
1013 the changed region and updating it. The line order is top to bottom. */
1014
1015 /* If we can move the cursor up and down, then use multiple lines,
1016 otherwise, let long lines display in a single terminal line, and
1017 horizontally scroll it. */
77b3aacb 1018 displaying_prompt_first_line = 1;
28ef6c31 1019 if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
726f6388 1020 {
28089d04 1021 int nleft, pos, changed_screen_line, tx;
726f6388
JA
1022
1023 if (!rl_display_fixed || forced_display)
1024 {
1025 forced_display = 0;
1026
1027 /* If we have more than a screenful of material to display, then
1028 only display a screenful. We should display the last screen,
ccc6cda3 1029 not the first. */
28ef6c31 1030 if (out >= _rl_screenchars)
7117c2d2 1031 {
3bf257a5 1032 if (mb_cur_max > 1 && rl_byte_oriented == 0)
7117c2d2
JA
1033 out = _rl_find_prev_mbchar (line, _rl_screenchars, MB_FIND_ANY);
1034 else
1035 out = _rl_screenchars - 1;
1036 }
726f6388
JA
1037
1038 /* The first line is at character position 0 in the buffer. The
ccc6cda3
JA
1039 second and subsequent lines start at inv_lbreaks[N], offset by
1040 OFFSET (which has already been calculated above). */
726f6388 1041
866961ad 1042#define INVIS_FIRST() (prompt_physical_chars > _rl_screenwidth ? prompt_invis_chars_first_line : wrap_offset)
234d8729 1043#define WRAP_OFFSET(line, offset) ((line == 0) \
866961ad 1044 ? (offset ? INVIS_FIRST() : 0) \
234d8729 1045 : ((line == prompt_last_screen_line) ? wrap_offset-prompt_invis_chars_first_line : 0))
726f6388 1046#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
ccc6cda3
JA
1047#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
1048#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l])
1049#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
726f6388 1050#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
ccc6cda3 1051#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
726f6388 1052
4a8bb13f
CR
1053#define OLD_CPOS_IN_PROMPT() (cpos_adjusted == 0 && \
1054 _rl_last_c_pos != o_cpos && \
1055 _rl_last_c_pos > wrap_offset && \
1056 o_cpos < prompt_last_invisible)
1057
726f6388
JA
1058 /* For each line in the buffer, do the updating display. */
1059 for (linenum = 0; linenum <= inv_botlin; linenum++)
1060 {
d3ad40de
CR
1061 /* This can lead us astray if we execute a program that changes
1062 the locale from a non-multibyte to a multibyte one. */
28089d04 1063 o_cpos = _rl_last_c_pos;
5c26afb8 1064 cpos_adjusted = 0;
726f6388 1065 update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
ccc6cda3 1066 VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
726f6388 1067
28089d04
CR
1068 /* update_line potentially changes _rl_last_c_pos, but doesn't
1069 take invisible characters into account, since _rl_last_c_pos
1070 is an absolute cursor position in a multibyte locale. See
1071 if compensating here is the right thing, or if we have to
57a3f689 1072 change update_line itself. There are several cases in which
5c26afb8
CR
1073 update_line adjusts _rl_last_c_pos itself (so it can pass
1074 _rl_move_cursor_relative accurate values); it communicates
d3ad40de
CR
1075 this back by setting cpos_adjusted. If we assume that
1076 _rl_last_c_pos is correct (an absolute cursor position) each
1077 time update_line is called, then we can assume in our
1078 calculations that o_cpos does not need to be adjusted by
1079 wrap_offset. */
3bf257a5 1080 if (linenum == 0 && (mb_cur_max > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT())
33fe8777 1081 _rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */
234d8729 1082 else if (linenum == prompt_last_screen_line && prompt_physical_chars > _rl_screenwidth &&
3bf257a5 1083 (mb_cur_max > 1 && rl_byte_oriented == 0) &&
234d8729
CR
1084 cpos_adjusted == 0 &&
1085 _rl_last_c_pos != o_cpos &&
33fe8777 1086 _rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line))
234d8729 1087 _rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line);
0d9b018b 1088
726f6388
JA
1089 /* If this is the line with the prompt, we might need to
1090 compensate for invisible characters in the new line. Do
1091 this only if there is not more than one new line (which
1092 implies that we completely overwrite the old visible line)
ccc6cda3
JA
1093 and the new line is shorter than the old. Make sure we are
1094 at the end of the new line before clearing. */
726f6388 1095 if (linenum == 0 &&
ccc6cda3 1096 inv_botlin == 0 && _rl_last_c_pos == out &&
726f6388
JA
1097 (wrap_offset > visible_wrap_offset) &&
1098 (_rl_last_c_pos < visible_first_line_len))
1099 {
3bf257a5 1100 if (mb_cur_max > 1 && rl_byte_oriented == 0)
177d51f7
CR
1101 nleft = _rl_screenwidth - _rl_last_c_pos;
1102 else
1103 nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
726f6388 1104 if (nleft)
d166f048 1105 _rl_clear_to_eol (nleft);
726f6388 1106 }
234d8729
CR
1107#if 0
1108 /* This segment is intended to handle the case where the prompt
1109 has invisible characters on the second line and the new line
1110 to be displayed needs to clear the rest of the old characters
1111 out (e.g., when printing the i-search prompt). In general,
1112 the case of the new line being shorter than the old.
1113 Incomplete */
1114 else if (linenum == prompt_last_screen_line &&
1115 prompt_physical_chars > _rl_screenwidth &&
1116 wrap_offset != prompt_invis_chars_first_line &&
1117 _rl_last_c_pos == out &&
1118#endif
1119
726f6388
JA
1120
1121 /* Since the new first line is now visible, save its length. */
1122 if (linenum == 0)
ccc6cda3 1123 visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
726f6388
JA
1124 }
1125
1126 /* We may have deleted some lines. If so, clear the left over
1127 blank ones at the bottom out. */
1128 if (_rl_vis_botlin > inv_botlin)
1129 {
1130 char *tt;
1131 for (; linenum <= _rl_vis_botlin; linenum++)
1132 {
1133 tt = VIS_CHARS (linenum);
1134 _rl_move_vert (linenum);
1135 _rl_move_cursor_relative (0, tt);
d166f048 1136 _rl_clear_to_eol
28ef6c31 1137 ((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth);
726f6388
JA
1138 }
1139 }
1140 _rl_vis_botlin = inv_botlin;
1141
726f6388
JA
1142 /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
1143 different screen line during this redisplay. */
1144 changed_screen_line = _rl_last_v_pos != cursor_linenum;
1145 if (changed_screen_line)
1146 {
1147 _rl_move_vert (cursor_linenum);
28ef6c31 1148 /* If we moved up to the line with the prompt using _rl_term_up,
b72432fd
JA
1149 the physical cursor position on the screen stays the same,
1150 but the buffer position needs to be adjusted to account
1151 for invisible characters. */
3bf257a5 1152 if ((mb_cur_max == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset)
b72432fd 1153 _rl_last_c_pos += wrap_offset;
726f6388
JA
1154 }
1155
1156 /* We have to reprint the prompt if it contains invisible
1157 characters, since it's not generally OK to just reprint
ccc6cda3
JA
1158 the characters from the current cursor position. But we
1159 only need to reprint it if the cursor is before the last
1160 invisible character in the prompt string. */
28ef6c31 1161 nleft = prompt_visible_length + wrap_offset;
726f6388 1162 if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
2abb7255 1163#if 0
ac18b312 1164 _rl_last_c_pos <= PROMPT_ENDING_INDEX && local_prompt)
2abb7255
CR
1165#else
1166 _rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt)
1167#endif
726f6388 1168 {
bb70624e
JA
1169#if defined (__MSDOS__)
1170 putc ('\r', rl_outstream);
1171#else
28ef6c31
JA
1172 if (_rl_term_cr)
1173 tputs (_rl_term_cr, 1, _rl_output_character_function);
bb70624e 1174#endif
d3ad40de
CR
1175 if (modmark)
1176 _rl_output_some_chars ("*", 1);
1177
726f6388 1178 _rl_output_some_chars (local_prompt, nleft);
3bf257a5 1179 if (mb_cur_max > 1 && rl_byte_oriented == 0)
82a5df63 1180 _rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft, 1) - wrap_offset + modmark;
7117c2d2 1181 else
d3ad40de 1182 _rl_last_c_pos = nleft + modmark;
726f6388
JA
1183 }
1184
1185 /* Where on that line? And where does that line start
1186 in the buffer? */
ccc6cda3 1187 pos = inv_lbreaks[cursor_linenum];
726f6388 1188 /* nleft == number of characters in the line buffer between the
d3ad40de
CR
1189 start of the line and the desired cursor position. */
1190 nleft = cpos_buffer_position - pos;
726f6388 1191
6bf74e5a
CR
1192 /* NLEFT is now a number of characters in a buffer. When in a
1193 multibyte locale, however, _rl_last_c_pos is an absolute cursor
1194 position that doesn't take invisible characters in the prompt
1195 into account. We use a fudge factor to compensate. */
6bf74e5a 1196
ccc6cda3 1197 /* Since _rl_backspace() doesn't know about invisible characters in the
726f6388 1198 prompt, and there's no good way to tell it, we compensate for
ccc6cda3 1199 those characters here and call _rl_backspace() directly. */
726f6388
JA
1200 if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
1201 {
d3ad40de 1202 /* TX == new physical cursor position in multibyte locale. */
3bf257a5 1203 if (mb_cur_max > 1 && rl_byte_oriented == 0)
82a5df63 1204 tx = _rl_col_width (&visible_line[pos], 0, nleft, 1) - visible_wrap_offset;
7117c2d2 1205 else
177d51f7 1206 tx = nleft;
3d4e09aa 1207 if (tx >= 0 && _rl_last_c_pos > tx)
d11b8b46 1208 {
28089d04 1209 _rl_backspace (_rl_last_c_pos - tx); /* XXX */
d11b8b46
CR
1210 _rl_last_c_pos = tx;
1211 }
726f6388
JA
1212 }
1213
28089d04
CR
1214 /* We need to note that in a multibyte locale we are dealing with
1215 _rl_last_c_pos as an absolute cursor position, but moving to a
1216 point specified by a buffer position (NLEFT) that doesn't take
1217 invisible characters into account. */
3bf257a5 1218 if (mb_cur_max > 1 && rl_byte_oriented == 0)
7117c2d2
JA
1219 _rl_move_cursor_relative (nleft, &invisible_line[pos]);
1220 else if (nleft != _rl_last_c_pos)
726f6388
JA
1221 _rl_move_cursor_relative (nleft, &invisible_line[pos]);
1222 }
1223 }
1224 else /* Do horizontal scrolling. */
1225 {
1226#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
1227 int lmargin, ndisp, nleft, phys_c_pos, t;
1228
1229 /* Always at top line. */
1230 _rl_last_v_pos = 0;
1231
1232 /* Compute where in the buffer the displayed line should start. This
1233 will be LMARGIN. */
1234
1235 /* The number of characters that will be displayed before the cursor. */
d3ad40de 1236 ndisp = cpos_buffer_position - wrap_offset;
28ef6c31 1237 nleft = prompt_visible_length + wrap_offset;
726f6388 1238 /* Where the new cursor position will be on the screen. This can be
b72432fd 1239 longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
d3ad40de 1240 phys_c_pos = cpos_buffer_position - (last_lmargin ? last_lmargin : wrap_offset);
28ef6c31 1241 t = _rl_screenwidth / 3;
726f6388
JA
1242
1243 /* If the number of characters had already exceeded the screenwidth,
b72432fd 1244 last_lmargin will be > 0. */
726f6388
JA
1245
1246 /* If the number of characters to be displayed is more than the screen
b72432fd
JA
1247 width, compute the starting offset so that the cursor is about
1248 two-thirds of the way across the screen. */
28ef6c31 1249 if (phys_c_pos > _rl_screenwidth - 2)
726f6388 1250 {
d3ad40de 1251 lmargin = cpos_buffer_position - (2 * t);
726f6388
JA
1252 if (lmargin < 0)
1253 lmargin = 0;
1254 /* If the left margin would be in the middle of a prompt with
1255 invisible characters, don't display the prompt at all. */
1256 if (wrap_offset && lmargin > 0 && lmargin < nleft)
1257 lmargin = nleft;
1258 }
28ef6c31 1259 else if (ndisp < _rl_screenwidth - 2) /* XXX - was -1 */
b72432fd 1260 lmargin = 0;
726f6388
JA
1261 else if (phys_c_pos < 1)
1262 {
1263 /* If we are moving back towards the beginning of the line and
1264 the last margin is no longer correct, compute a new one. */
d3ad40de 1265 lmargin = ((cpos_buffer_position - 1) / t) * t; /* XXX */
726f6388
JA
1266 if (wrap_offset && lmargin > 0 && lmargin < nleft)
1267 lmargin = nleft;
1268 }
1269 else
b72432fd 1270 lmargin = last_lmargin;
726f6388 1271
77b3aacb
CR
1272 displaying_prompt_first_line = lmargin < nleft;
1273
726f6388
JA
1274 /* If the first character on the screen isn't the first character
1275 in the display line, indicate this with a special character. */
1276 if (lmargin > 0)
1277 line[lmargin] = '<';
1278
1279 /* If SCREENWIDTH characters starting at LMARGIN do not encompass
b72432fd
JA
1280 the whole line, indicate that with a special character at the
1281 right edge of the screen. If LMARGIN is 0, we need to take the
1282 wrap offset into account. */
28ef6c31 1283 t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth;
726f6388 1284 if (t < out)
b72432fd 1285 line[t - 1] = '>';
726f6388 1286
bf6bd355 1287 if (rl_display_fixed == 0 || forced_display || lmargin != last_lmargin)
726f6388
JA
1288 {
1289 forced_display = 0;
bf6bd355
CR
1290 o_cpos = _rl_last_c_pos;
1291 cpos_adjusted = 0;
726f6388
JA
1292 update_line (&visible_line[last_lmargin],
1293 &invisible_line[lmargin],
1294 0,
28ef6c31
JA
1295 _rl_screenwidth + visible_wrap_offset,
1296 _rl_screenwidth + (lmargin ? 0 : wrap_offset),
726f6388
JA
1297 0);
1298
3bf257a5 1299 if ((mb_cur_max > 1 && rl_byte_oriented == 0) &&
77b3aacb 1300 displaying_prompt_first_line && OLD_CPOS_IN_PROMPT())
4a8bb13f 1301 _rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */
bf6bd355 1302
726f6388
JA
1303 /* If the visible new line is shorter than the old, but the number
1304 of invisible characters is greater, and we are at the end of
1305 the new line, we need to clear to eol. */
1306 t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
1307 if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
77b3aacb 1308 (_rl_last_c_pos == out) && displaying_prompt_first_line &&
726f6388
JA
1309 t < visible_first_line_len)
1310 {
28ef6c31 1311 nleft = _rl_screenwidth - t;
d166f048 1312 _rl_clear_to_eol (nleft);
726f6388
JA
1313 }
1314 visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
28ef6c31
JA
1315 if (visible_first_line_len > _rl_screenwidth)
1316 visible_first_line_len = _rl_screenwidth;
726f6388 1317
d3ad40de 1318 _rl_move_cursor_relative (cpos_buffer_position - lmargin, &invisible_line[lmargin]);
726f6388
JA
1319 last_lmargin = lmargin;
1320 }
1321 }
1322 fflush (rl_outstream);
1323
1324 /* Swap visible and non-visible lines. */
1325 {
d3ad40de 1326 struct line_state *vtemp = line_state_visible;
bb70624e 1327
d3ad40de
CR
1328 line_state_visible = line_state_invisible;
1329 line_state_invisible = vtemp;
bb70624e 1330
726f6388
JA
1331 rl_display_fixed = 0;
1332 /* If we are displaying on a single line, and last_lmargin is > 0, we
1333 are not displaying any invisible characters, so set visible_wrap_offset
1334 to 0. */
1335 if (_rl_horizontal_scroll_mode && last_lmargin)
1336 visible_wrap_offset = 0;
1337 else
1338 visible_wrap_offset = wrap_offset;
1339 }
d356441f 1340
83c14a20 1341 RL_UNSETSTATE (RL_STATE_REDISPLAYING);
d356441f 1342 _rl_release_sigint ();
726f6388
JA
1343}
1344
1345/* PWP: update_line() is based on finding the middle difference of each
1346 line on the screen; vis:
1347
1348 /old first difference
1349 /beginning of line | /old last same /old EOL
1350 v v v v
1351old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as
1352new: eddie> Oh, my little buggy says to me, as lurgid as
1353 ^ ^ ^ ^
1354 \beginning of line | \new last same \new end of line
1355 \new first difference
1356
1357 All are character pointers for the sake of speed. Special cases for
b72432fd 1358 no differences, as well as for end of line additions must be handled.
726f6388
JA
1359
1360 Could be made even smarter, but this works well enough */
1361static void
1362update_line (old, new, current_line, omax, nmax, inv_botlin)
1363 register char *old, *new;
ccc6cda3 1364 int current_line, omax, nmax, inv_botlin;
726f6388
JA
1365{
1366 register char *ofd, *ols, *oe, *nfd, *nls, *ne;
3d4e09aa 1367 int temp, lendiff, wsatend, od, nd, twidth, o_cpos;
ccc6cda3 1368 int current_invis_chars;
7117c2d2 1369 int col_lendiff, col_temp;
73a146be 1370 int bytes_to_insert;
7117c2d2
JA
1371#if defined (HANDLE_MULTIBYTE)
1372 mbstate_t ps_new, ps_old;
dc8fbaf9 1373 int new_offset, old_offset;
7117c2d2 1374#endif
726f6388
JA
1375
1376 /* If we're at the right edge of a terminal that supports xn, we're
1377 ready to wrap around, so do so. This fixes problems with knowing
1378 the exact cursor position and cut-and-paste with certain terminal
1379 emulators. In this calculation, TEMP is the physical screen
1380 position of the cursor. */
177d51f7
CR
1381 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1382 temp = _rl_last_c_pos;
1383 else
234d8729 1384 temp = _rl_last_c_pos - WRAP_OFFSET (_rl_last_v_pos, visible_wrap_offset);
28ef6c31 1385 if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
7117c2d2 1386 && _rl_last_v_pos == current_line - 1)
726f6388 1387 {
7117c2d2
JA
1388#if defined (HANDLE_MULTIBYTE)
1389 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1390 {
1391 wchar_t wc;
1392 mbstate_t ps;
1393 int tempwidth, bytes;
1394 size_t ret;
1395
1396 /* This fixes only double-column characters, but if the wrapped
39feef01 1397 character consumes more than three columns, spaces will be
7117c2d2 1398 inserted in the string buffer. */
d3ad40de
CR
1399 if (current_line < line_state_visible->wbsize && line_state_visible->wrapped_line[current_line] > 0)
1400 _rl_clear_to_eol (line_state_visible->wrapped_line[current_line]);
7117c2d2
JA
1401
1402 memset (&ps, 0, sizeof (mbstate_t));
1403 ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps);
d3a24ed2 1404 if (MB_INVALIDCH (ret))
7117c2d2
JA
1405 {
1406 tempwidth = 1;
1407 ret = 1;
1408 }
d3a24ed2 1409 else if (MB_NULLWCH (ret))
7117c2d2
JA
1410 tempwidth = 0;
1411 else
22818c14 1412 tempwidth = WCWIDTH (wc);
7117c2d2
JA
1413
1414 if (tempwidth > 0)
1415 {
9dd88db7 1416 int count, i;
7117c2d2
JA
1417 bytes = ret;
1418 for (count = 0; count < bytes; count++)
1419 putc (new[count], rl_outstream);
1420 _rl_last_c_pos = tempwidth;
1421 _rl_last_v_pos++;
1422 memset (&ps, 0, sizeof (mbstate_t));
1423 ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps);
1424 if (ret != 0 && bytes != 0)
1425 {
d3a24ed2 1426 if (MB_INVALIDCH (ret))
9dd88db7
CR
1427 ret = 1;
1428 memmove (old+bytes, old+ret, strlen (old+ret));
7117c2d2 1429 memcpy (old, new, bytes);
9dd88db7
CR
1430 /* Fix up indices if we copy data from one line to another */
1431 omax += bytes - ret;
208fdb50 1432 for (i = current_line+1; i <= inv_botlin+1; i++)
9dd88db7 1433 vis_lbreaks[i] += bytes - ret;
7117c2d2
JA
1434 }
1435 }
1436 else
1437 {
1438 putc (' ', rl_outstream);
1439 _rl_last_c_pos = 1;
1440 _rl_last_v_pos++;
1441 if (old[0] && new[0])
1442 old[0] = new[0];
1443 }
1444 }
726f6388 1445 else
7117c2d2
JA
1446#endif
1447 {
1448 if (new[0])
1449 putc (new[0], rl_outstream);
1450 else
1451 putc (' ', rl_outstream);
5c26afb8 1452 _rl_last_c_pos = 1;
7117c2d2
JA
1453 _rl_last_v_pos++;
1454 if (old[0] && new[0])
1455 old[0] = new[0];
1456 }
726f6388 1457 }
7117c2d2 1458
726f6388
JA
1459
1460 /* Find first difference. */
7117c2d2
JA
1461#if defined (HANDLE_MULTIBYTE)
1462 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1463 {
5e13499c
CR
1464 /* See if the old line is a subset of the new line, so that the
1465 only change is adding characters. */
1466 temp = (omax < nmax) ? omax : nmax;
d3ad40de 1467 if (memcmp (old, new, temp) == 0) /* adding at the end */
7117c2d2 1468 {
22818c14 1469 new_offset = old_offset = temp;
5e13499c
CR
1470 ofd = old + temp;
1471 nfd = new + temp;
d3a24ed2
CR
1472 }
1473 else
5e13499c
CR
1474 {
1475 memset (&ps_new, 0, sizeof(mbstate_t));
1476 memset (&ps_old, 0, sizeof(mbstate_t));
1477
1478 if (omax == nmax && STREQN (new, old, omax))
d3a24ed2 1479 {
22818c14
CR
1480 old_offset = omax;
1481 new_offset = nmax;
5e13499c
CR
1482 ofd = old + omax;
1483 nfd = new + nmax;
1484 }
1485 else
1486 {
1487 new_offset = old_offset = 0;
1488 for (ofd = old, nfd = new;
1489 (ofd - old < omax) && *ofd &&
1490 _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
1491 {
1492 old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
1493 new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
22818c14 1494
5e13499c
CR
1495 ofd = old + old_offset;
1496 nfd = new + new_offset;
1497 }
d3a24ed2 1498 }
7117c2d2
JA
1499 }
1500 }
1501 else
1502#endif
726f6388
JA
1503 for (ofd = old, nfd = new;
1504 (ofd - old < omax) && *ofd && (*ofd == *nfd);
1505 ofd++, nfd++)
1506 ;
1507
1508 /* Move to the end of the screen line. ND and OD are used to keep track
1509 of the distance between ne and new and oe and old, respectively, to
1510 move a subtraction out of each loop. */
1511 for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
1512 for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
1513
1514 /* If no difference, continue to next line. */
1515 if (ofd == oe && nfd == ne)
1516 return;
1517
22818c14
CR
1518#if defined (HANDLE_MULTIBYTE)
1519 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && _rl_utf8locale)
1520 {
1521 wchar_t wc;
1522 mbstate_t ps = { 0 };
1523 int t;
1524
1525 /* If the first character in the difference is a zero-width character,
1526 assume it's a combining character and back one up so the two base
1527 characters no longer compare equivalently. */
1528 t = mbrtowc (&wc, ofd, MB_CUR_MAX, &ps);
1529 if (t > 0 && UNICODE_COMBINING_CHAR (wc) && WCWIDTH (wc) == 0)
1530 {
1531 old_offset = _rl_find_prev_mbchar (old, ofd - old, MB_FIND_ANY);
1532 new_offset = _rl_find_prev_mbchar (new, nfd - new, MB_FIND_ANY);
1533 ofd = old + old_offset; /* equal by definition */
1534 nfd = new + new_offset;
1535 }
1536 }
1537#endif
1538
726f6388 1539 wsatend = 1; /* flag for trailing whitespace */
7117c2d2
JA
1540
1541#if defined (HANDLE_MULTIBYTE)
1542 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1543 {
1544 ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY);
1545 nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY);
22818c14 1546
7117c2d2
JA
1547 while ((ols > ofd) && (nls > nfd))
1548 {
1549 memset (&ps_old, 0, sizeof (mbstate_t));
1550 memset (&ps_new, 0, sizeof (mbstate_t));
1551
d3a24ed2
CR
1552#if 0
1553 /* On advice from jir@yamato.ibm.com */
7117c2d2
JA
1554 _rl_adjust_point (old, ols - old, &ps_old);
1555 _rl_adjust_point (new, nls - new, &ps_new);
d3a24ed2 1556#endif
7117c2d2
JA
1557
1558 if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0)
1559 break;
1560
1561 if (*ols == ' ')
1562 wsatend = 0;
1563
1564 ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY);
1565 nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY);
1566 }
1567 }
1568 else
1569 {
1570#endif /* HANDLE_MULTIBYTE */
726f6388
JA
1571 ols = oe - 1; /* find last same */
1572 nls = ne - 1;
1573 while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
1574 {
1575 if (*ols != ' ')
1576 wsatend = 0;
1577 ols--;
1578 nls--;
1579 }
7117c2d2
JA
1580#if defined (HANDLE_MULTIBYTE)
1581 }
1582#endif
726f6388
JA
1583
1584 if (wsatend)
1585 {
1586 ols = oe;
1587 nls = ne;
1588 }
7117c2d2
JA
1589#if defined (HANDLE_MULTIBYTE)
1590 /* This may not work for stateful encoding, but who cares? To handle
1591 stateful encoding properly, we have to scan each string from the
1592 beginning and compare. */
1593 else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0)
1594#else
726f6388 1595 else if (*ols != *nls)
7117c2d2 1596#endif
726f6388
JA
1597 {
1598 if (*ols) /* don't step past the NUL */
7117c2d2
JA
1599 {
1600 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1601 ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY);
1602 else
1603 ols++;
1604 }
726f6388 1605 if (*nls)
7117c2d2
JA
1606 {
1607 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1608 nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY);
1609 else
1610 nls++;
1611 }
726f6388
JA
1612 }
1613
ccc6cda3
JA
1614 /* count of invisible characters in the current invisible line. */
1615 current_invis_chars = W_OFFSET (current_line, wrap_offset);
1616 if (_rl_last_v_pos != current_line)
1617 {
1618 _rl_move_vert (current_line);
177d51f7 1619 if ((MB_CUR_MAX == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset)
ccc6cda3
JA
1620 _rl_last_c_pos += visible_wrap_offset;
1621 }
726f6388
JA
1622
1623 /* If this is the first line and there are invisible characters in the
ccc6cda3
JA
1624 prompt string, and the prompt string has not changed, and the current
1625 cursor position is before the last invisible character in the prompt,
1626 and the index of the character to move to is past the end of the prompt
1627 string, then redraw the entire prompt string. We can only do this
1628 reliably if the terminal supports a `cr' capability.
726f6388 1629
ccc6cda3
JA
1630 This is not an efficiency hack -- there is a problem with redrawing
1631 portions of the prompt string if they contain terminal escape
1632 sequences (like drawing the `unbold' sequence without a corresponding
1633 `bold') that manifests itself on certain terminals. */
726f6388 1634
d3ad40de 1635 lendiff = local_prompt_len;
ccc6cda3 1636 od = ofd - old; /* index of first difference in visible line */
726f6388 1637 if (current_line == 0 && !_rl_horizontal_scroll_mode &&
28ef6c31 1638 _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 &&
d3ad40de 1639 od >= lendiff && _rl_last_c_pos < PROMPT_ENDING_INDEX)
726f6388 1640 {
bb70624e
JA
1641#if defined (__MSDOS__)
1642 putc ('\r', rl_outstream);
1643#else
28ef6c31 1644 tputs (_rl_term_cr, 1, _rl_output_character_function);
bb70624e 1645#endif
d3ad40de
CR
1646 if (modmark)
1647 _rl_output_some_chars ("*", 1);
726f6388 1648 _rl_output_some_chars (local_prompt, lendiff);
7117c2d2 1649 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
5c26afb8
CR
1650 {
1651 /* We take wrap_offset into account here so we can pass correct
1652 information to _rl_move_cursor_relative. */
82a5df63 1653 _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff, 1) - wrap_offset + modmark;
5c26afb8
CR
1654 cpos_adjusted = 1;
1655 }
7117c2d2 1656 else
d3ad40de 1657 _rl_last_c_pos = lendiff + modmark;
726f6388
JA
1658 }
1659
3d4e09aa
CR
1660 o_cpos = _rl_last_c_pos;
1661
d3ad40de 1662 /* When this function returns, _rl_last_c_pos is correct, and an absolute
39feef01 1663 cursor position in multibyte mode, but a buffer index when not in a
d3ad40de 1664 multibyte locale. */
ccc6cda3 1665 _rl_move_cursor_relative (od, old);
73a146be 1666
d3ad40de
CR
1667#if defined (HANDLE_MULTIBYTE)
1668 /* We need to indicate that the cursor position is correct in the presence of
1669 invisible characters in the prompt string. Let's see if setting this when
1670 we make sure we're at the end of the drawn prompt string works. */
3d4e09aa
CR
1671 if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 &&
1672 (_rl_last_c_pos > 0 || o_cpos > 0) &&
1673 _rl_last_c_pos == prompt_physical_chars)
d3ad40de 1674 cpos_adjusted = 1;
d3ad40de 1675#endif
726f6388 1676
7117c2d2 1677 /* if (len (new) > len (old))
73a146be
CR
1678 lendiff == difference in buffer (bytes)
1679 col_lendiff == difference on screen (columns)
7117c2d2 1680 When not using multibyte characters, these are equal */
726f6388 1681 lendiff = (nls - nfd) - (ols - ofd);
7117c2d2 1682 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
82a5df63 1683 col_lendiff = _rl_col_width (new, nfd - new, nls - new, 1) - _rl_col_width (old, ofd - old, ols - old, 1);
7117c2d2
JA
1684 else
1685 col_lendiff = lendiff;
726f6388 1686
ccc6cda3
JA
1687 /* If we are changing the number of invisible characters in a line, and
1688 the spot of first difference is before the end of the invisible chars,
1689 lendiff needs to be adjusted. */
0d9b018b 1690 if (current_line == 0 && /* !_rl_horizontal_scroll_mode && */
ccc6cda3 1691 current_invis_chars != visible_wrap_offset)
7117c2d2
JA
1692 {
1693 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1694 {
1695 lendiff += visible_wrap_offset - current_invis_chars;
1696 col_lendiff += visible_wrap_offset - current_invis_chars;
1697 }
1698 else
1699 {
1700 lendiff += visible_wrap_offset - current_invis_chars;
1701 col_lendiff = lendiff;
1702 }
1703 }
ccc6cda3 1704
73a146be
CR
1705 /* We use temp as a count of the number of bytes from the first difference
1706 to the end of the new line. col_temp is the corresponding number of
1707 screen columns. A `dumb' update moves to the spot of first difference
1708 and writes TEMP bytes. */
726f6388
JA
1709 /* Insert (diff (len (old), len (new)) ch. */
1710 temp = ne - nfd;
7117c2d2 1711 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
82a5df63 1712 col_temp = _rl_col_width (new, nfd - new, ne - new, 1);
7117c2d2
JA
1713 else
1714 col_temp = temp;
1715
73a146be
CR
1716 /* how many bytes from the new line buffer to write to the display */
1717 bytes_to_insert = nls - nfd;
1718
1719 /* col_lendiff > 0 if we are adding characters to the line */
7117c2d2 1720 if (col_lendiff > 0) /* XXX - was lendiff */
726f6388
JA
1721 {
1722 /* Non-zero if we're increasing the number of lines. */
1723 int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
b0c16657
CR
1724 /* If col_lendiff is > 0, implying that the new string takes up more
1725 screen real estate than the old, but lendiff is < 0, meaning that it
1726 takes fewer bytes, we need to just output the characters starting
1727 from the first difference. These will overwrite what is on the
1728 display, so there's no reason to do a smart update. This can really
1729 only happen in a multibyte environment. */
1730 if (lendiff < 0)
1731 {
1732 _rl_output_some_chars (nfd, temp);
73a146be 1733 _rl_last_c_pos += col_temp; /* XXX - was _rl_col_width (nfd, 0, temp, 1); */
b0c16657
CR
1734 /* If nfd begins before any invisible characters in the prompt,
1735 adjust _rl_last_c_pos to account for wrap_offset and set
1736 cpos_adjusted to let the caller know. */
73a146be 1737 if (current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible))
b0c16657
CR
1738 {
1739 _rl_last_c_pos -= wrap_offset;
1740 cpos_adjusted = 1;
1741 }
1742 return;
1743 }
726f6388
JA
1744 /* Sometimes it is cheaper to print the characters rather than
1745 use the terminal's capabilities. If we're growing the number
1746 of lines, make sure we actually cause the new line to wrap
1747 around on auto-wrapping terminals. */
b0c16657 1748 else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
726f6388 1749 {
28ef6c31 1750 /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
726f6388 1751 _rl_horizontal_scroll_mode == 1, inserting the characters with
28ef6c31 1752 _rl_term_IC or _rl_term_ic will screw up the screen because of the
726f6388 1753 invisible characters. We need to just draw them. */
57a3f689
CR
1754 /* The same thing happens if we're trying to draw before the last
1755 invisible character in the prompt string or we're increasing the
1756 number of invisible characters in the line and we're not drawing
1757 the entire prompt string. */
1758 if (*ols && ((_rl_horizontal_scroll_mode &&
1759 _rl_last_c_pos == 0 &&
1760 lendiff > prompt_visible_length &&
1761 current_invis_chars > 0) == 0) &&
1762 (((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
1763 current_line == 0 && wrap_offset &&
1764 ((nfd - new) <= prompt_last_invisible) &&
1765 (col_lendiff < prompt_visible_length)) == 0) &&
1766 (visible_wrap_offset >= current_invis_chars))
726f6388 1767 {
73a146be
CR
1768 open_some_spaces (col_lendiff);
1769 _rl_output_some_chars (nfd, bytes_to_insert);
c7e43312
CR
1770 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1771 _rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1);
1772 else
1773 _rl_last_c_pos += bytes_to_insert;
726f6388 1774 }
d90269dd 1775 else if ((MB_CUR_MAX == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0)
726f6388
JA
1776 {
1777 /* At the end of a line the characters do not have to
1778 be "inserted". They can just be placed on the screen. */
c7e43312
CR
1779 _rl_output_some_chars (nfd, temp);
1780 _rl_last_c_pos += col_temp;
1781 return;
726f6388 1782 }
73a146be 1783 else /* just write from first difference to end of new line */
ccc6cda3 1784 {
ccc6cda3 1785 _rl_output_some_chars (nfd, temp);
5c26afb8 1786 _rl_last_c_pos += col_temp;
57a3f689
CR
1787 /* If nfd begins before the last invisible character in the
1788 prompt, adjust _rl_last_c_pos to account for wrap_offset
1789 and set cpos_adjusted to let the caller know. */
77b3aacb 1790 if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible))
97c2aab2
CR
1791 {
1792 _rl_last_c_pos -= wrap_offset;
1793 cpos_adjusted = 1;
1794 }
ccc6cda3
JA
1795 return;
1796 }
73a146be
CR
1797
1798 if (bytes_to_insert > lendiff)
726f6388 1799 {
57a3f689
CR
1800 /* If nfd begins before the last invisible character in the
1801 prompt, adjust _rl_last_c_pos to account for wrap_offset
1802 and set cpos_adjusted to let the caller know. */
77b3aacb 1803 if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible))
57a3f689
CR
1804 {
1805 _rl_last_c_pos -= wrap_offset;
1806 cpos_adjusted = 1;
1807 }
726f6388
JA
1808 }
1809 }
1810 else
1811 {
1812 /* cannot insert chars, write to EOL */
1813 _rl_output_some_chars (nfd, temp);
7117c2d2 1814 _rl_last_c_pos += col_temp;
5c26afb8
CR
1815 /* If we're in a multibyte locale and were before the last invisible
1816 char in the current line (which implies we just output some invisible
28089d04
CR
1817 characters) we need to adjust _rl_last_c_pos, since it represents
1818 a physical character position. */
57a3f689
CR
1819 if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
1820 current_line == prompt_last_screen_line && wrap_offset &&
77b3aacb 1821 displaying_prompt_first_line &&
57a3f689
CR
1822 wrap_offset != prompt_invis_chars_first_line &&
1823 ((nfd-new) < (prompt_last_invisible-(current_line*_rl_screenwidth))))
1824 {
1825 _rl_last_c_pos -= wrap_offset - prompt_invis_chars_first_line;
1826 cpos_adjusted = 1;
1827 }
726f6388
JA
1828 }
1829 }
1830 else /* Delete characters from line. */
1831 {
1832 /* If possible and inexpensive to use terminal deletion, then do so. */
7117c2d2 1833 if (_rl_term_dc && (2 * col_temp) >= -col_lendiff)
726f6388
JA
1834 {
1835 /* If all we're doing is erasing the invisible characters in the
1836 prompt string, don't bother. It screws up the assumptions
1837 about what's on the screen. */
1838 if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
77b3aacb 1839 displaying_prompt_first_line &&
726f6388 1840 -lendiff == visible_wrap_offset)
7117c2d2 1841 col_lendiff = 0;
726f6388 1842
77b3aacb
CR
1843 /* If we have moved lmargin and we're shrinking the line, we've
1844 already moved the cursor to the first character of the new line,
1845 so deleting -col_lendiff characters will mess up the cursor
1846 position calculation */
1847 if (_rl_horizontal_scroll_mode && displaying_prompt_first_line == 0 &&
1848 col_lendiff && _rl_last_c_pos < -col_lendiff)
1849 col_lendiff = 0;
1850
7117c2d2
JA
1851 if (col_lendiff)
1852 delete_chars (-col_lendiff); /* delete (diff) characters */
726f6388 1853
73a146be
CR
1854 /* Copy (new) chars to screen from first diff to last match,
1855 overwriting what is there. */
1856 if (bytes_to_insert > 0)
726f6388 1857 {
d3ad40de
CR
1858 /* If nfd begins at the prompt, or before the invisible
1859 characters in the prompt, we need to adjust _rl_last_c_pos
1860 in a multibyte locale to account for the wrap offset and
1861 set cpos_adjusted accordingly. */
73a146be 1862 _rl_output_some_chars (nfd, bytes_to_insert);
d3ad40de
CR
1863 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1864 {
73a146be 1865 _rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1);
77b3aacb
CR
1866 if (current_line == 0 && wrap_offset &&
1867 displaying_prompt_first_line &&
1868 _rl_last_c_pos > wrap_offset &&
1869 ((nfd - new) <= prompt_last_invisible))
d3ad40de
CR
1870 {
1871 _rl_last_c_pos -= wrap_offset;
1872 cpos_adjusted = 1;
1873 }
1874 }
1875 else
73a146be 1876 _rl_last_c_pos += bytes_to_insert;
77b3aacb 1877
0d9b018b
CR
1878 /* XXX - we only want to do this if we are at the end of the line
1879 so we move there with _rl_move_cursor_relative */
77b3aacb 1880 if (_rl_horizontal_scroll_mode && ((oe-old) > (ne-new)))
0d9b018b
CR
1881 {
1882 _rl_move_cursor_relative (ne-new, new);
1883 goto clear_rest_of_line;
1884 }
726f6388
JA
1885 }
1886 }
1887 /* Otherwise, print over the existing material. */
1888 else
1889 {
1890 if (temp > 0)
1891 {
d3ad40de
CR
1892 /* If nfd begins at the prompt, or before the invisible
1893 characters in the prompt, we need to adjust _rl_last_c_pos
1894 in a multibyte locale to account for the wrap offset and
1895 set cpos_adjusted accordingly. */
726f6388 1896 _rl_output_some_chars (nfd, temp);
28089d04 1897 _rl_last_c_pos += col_temp; /* XXX */
d3ad40de
CR
1898 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1899 {
77b3aacb
CR
1900 if (current_line == 0 && wrap_offset &&
1901 displaying_prompt_first_line &&
1902 _rl_last_c_pos > wrap_offset &&
1903 ((nfd - new) <= prompt_last_invisible))
d3ad40de
CR
1904 {
1905 _rl_last_c_pos -= wrap_offset;
1906 cpos_adjusted = 1;
1907 }
1908 }
726f6388 1909 }
77b3aacb 1910clear_rest_of_line:
726f6388 1911 lendiff = (oe - old) - (ne - new);
7117c2d2 1912 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
82a5df63 1913 col_lendiff = _rl_col_width (old, 0, oe - old, 1) - _rl_col_width (new, 0, ne - new, 1);
7117c2d2
JA
1914 else
1915 col_lendiff = lendiff;
1916
57a3f689
CR
1917 /* If we've already printed over the entire width of the screen,
1918 including the old material, then col_lendiff doesn't matter and
1919 space_to_eol will insert too many spaces. XXX - maybe we should
1920 adjust col_lendiff based on the difference between _rl_last_c_pos
1921 and _rl_screenwidth */
83c14a20 1922 if (col_lendiff && ((MB_CUR_MAX == 1 || rl_byte_oriented) || (_rl_last_c_pos < _rl_screenwidth)))
b72432fd
JA
1923 {
1924 if (_rl_term_autowrap && current_line < inv_botlin)
7117c2d2 1925 space_to_eol (col_lendiff);
b72432fd 1926 else
7117c2d2 1927 _rl_clear_to_eol (col_lendiff);
b72432fd 1928 }
726f6388
JA
1929 }
1930 }
1931}
1932
1933/* Tell the update routines that we have moved onto a new (empty) line. */
ccc6cda3 1934int
726f6388
JA
1935rl_on_new_line ()
1936{
1937 if (visible_line)
1938 visible_line[0] = '\0';
1939
1940 _rl_last_c_pos = _rl_last_v_pos = 0;
1941 _rl_vis_botlin = last_lmargin = 0;
ccc6cda3
JA
1942 if (vis_lbreaks)
1943 vis_lbreaks[0] = vis_lbreaks[1] = 0;
1944 visible_wrap_offset = 0;
726f6388
JA
1945 return 0;
1946}
1947
bb70624e
JA
1948/* Tell the update routines that we have moved onto a new line with the
1949 prompt already displayed. Code originally from the version of readline
61deeb13
CR
1950 distributed with CLISP. rl_expand_prompt must have already been called
1951 (explicitly or implicitly). This still doesn't work exactly right. */
bb70624e
JA
1952int
1953rl_on_new_line_with_prompt ()
1954{
1955 int prompt_size, i, l, real_screenwidth, newlines;
61deeb13 1956 char *prompt_last_line, *lprompt;
bb70624e
JA
1957
1958 /* Initialize visible_line and invisible_line to ensure that they can hold
1959 the already-displayed prompt. */
1960 prompt_size = strlen (rl_prompt) + 1;
1961 init_line_structures (prompt_size);
1962
1963 /* Make sure the line structures hold the already-displayed prompt for
1964 redisplay. */
61deeb13
CR
1965 lprompt = local_prompt ? local_prompt : rl_prompt;
1966 strcpy (visible_line, lprompt);
1967 strcpy (invisible_line, lprompt);
bb70624e
JA
1968
1969 /* If the prompt contains newlines, take the last tail. */
1970 prompt_last_line = strrchr (rl_prompt, '\n');
1971 if (!prompt_last_line)
1972 prompt_last_line = rl_prompt;
1973
1974 l = strlen (prompt_last_line);
7117c2d2 1975 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
82a5df63 1976 _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l, 1); /* XXX */
7117c2d2
JA
1977 else
1978 _rl_last_c_pos = l;
bb70624e
JA
1979
1980 /* Dissect prompt_last_line into screen lines. Note that here we have
1981 to use the real screenwidth. Readline's notion of screenwidth might be
1982 one less, see terminal.c. */
28ef6c31 1983 real_screenwidth = _rl_screenwidth + (_rl_term_autowrap ? 0 : 1);
bb70624e
JA
1984 _rl_last_v_pos = l / real_screenwidth;
1985 /* If the prompt length is a multiple of real_screenwidth, we don't know
1986 whether the cursor is at the end of the last line, or already at the
1987 beginning of the next line. Output a newline just to be safe. */
1988 if (l > 0 && (l % real_screenwidth) == 0)
1989 _rl_output_some_chars ("\n", 1);
1990 last_lmargin = 0;
1991
1992 newlines = 0; i = 0;
1993 while (i <= l)
1994 {
1995 _rl_vis_botlin = newlines;
1996 vis_lbreaks[newlines++] = i;
1997 i += real_screenwidth;
1998 }
1999 vis_lbreaks[newlines] = l;
2000 visible_wrap_offset = 0;
2001
61deeb13
CR
2002 rl_display_prompt = rl_prompt; /* XXX - make sure it's set */
2003
bb70624e
JA
2004 return 0;
2005}
2006
726f6388 2007/* Actually update the display, period. */
ccc6cda3 2008int
726f6388
JA
2009rl_forced_update_display ()
2010{
0cc62c12
CR
2011 register char *temp;
2012
726f6388
JA
2013 if (visible_line)
2014 {
0cc62c12 2015 temp = visible_line;
ccc6cda3 2016 while (*temp)
b72432fd 2017 *temp++ = '\0';
726f6388
JA
2018 }
2019 rl_on_new_line ();
2020 forced_display++;
ccc6cda3 2021 (*rl_redisplay_function) ();
726f6388
JA
2022 return 0;
2023}
2024
db02a175
CR
2025/* Redraw only the last line of a multi-line prompt. */
2026void
2027rl_redraw_prompt_last_line ()
2028{
2029 char *t;
0a233f3e 2030
db02a175
CR
2031 t = strrchr (rl_display_prompt, '\n');
2032 if (t)
2033 redraw_prompt (++t);
2034 else
2035 rl_forced_update_display ();
2036}
2037
726f6388 2038/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
28089d04
CR
2039 (Well, when we don't have multibyte characters, _rl_last_c_pos is a
2040 buffer index.)
726f6388
JA
2041 DATA is the contents of the screen line of interest; i.e., where
2042 the movement is being done. */
2043void
2044_rl_move_cursor_relative (new, data)
2045 int new;
28ef6c31 2046 const char *data;
726f6388
JA
2047{
2048 register int i;
28089d04
CR
2049 int woff; /* number of invisible chars on current line */
2050 int cpos, dpos; /* current and desired cursor positions */
dfc21851 2051 int adjust;
726f6388 2052
234d8729 2053 woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset);
28089d04 2054 cpos = _rl_last_c_pos;
d0ca3503
CR
2055
2056 if (cpos == 0 && cpos == new)
2057 return;
2058
7117c2d2
JA
2059#if defined (HANDLE_MULTIBYTE)
2060 /* If we have multibyte characters, NEW is indexed by the buffer point in
2061 a multibyte string, but _rl_last_c_pos is the display position. In
d3a24ed2 2062 this case, NEW's display position is not obvious and must be
28089d04
CR
2063 calculated. We need to account for invisible characters in this line,
2064 as long as we are past them and they are counted by _rl_col_width. */
2065 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
d3a24ed2 2066 {
dfc21851
CR
2067 adjust = 1;
2068 /* Try to short-circuit common cases and eliminate a bunch of multibyte
2069 character function calls. */
2070 /* 1. prompt string */
2071 if (new == local_prompt_len && memcmp (data, local_prompt, new) == 0)
2072 {
82a5df63 2073 dpos = prompt_physical_chars;
dfc21851
CR
2074 cpos_adjusted = 1;
2075 adjust = 0;
2076 }
2077 /* 2. prompt_string + line contents */
2078 else if (new > local_prompt_len && local_prompt && memcmp (data, local_prompt, local_prompt_len) == 0)
2079 {
82a5df63 2080 dpos = prompt_physical_chars + _rl_col_width (data, local_prompt_len, new, 1);
dfc21851
CR
2081 cpos_adjusted = 1;
2082 adjust = 0;
2083 }
2084 else
82a5df63 2085 dpos = _rl_col_width (data, 0, new, 1);
dfc21851 2086
77b3aacb
CR
2087 if (displaying_prompt_first_line == 0)
2088 adjust = 0;
2089
d3ad40de
CR
2090 /* Use NEW when comparing against the last invisible character in the
2091 prompt string, since they're both buffer indices and DPOS is a
2092 desired display position. */
dfc21851 2093 if (adjust && ((new > prompt_last_invisible) || /* XXX - don't use woff here */
d0ca3503 2094 (prompt_physical_chars >= _rl_screenwidth &&
234d8729 2095 _rl_last_v_pos == prompt_last_screen_line &&
d0ca3503 2096 wrap_offset >= woff && dpos >= woff &&
dfc21851 2097 new > (prompt_last_invisible-(_rl_screenwidth*_rl_last_v_pos)-wrap_offset))))
57a3f689 2098 /* XXX last comparison might need to be >= */
d3ad40de
CR
2099 {
2100 dpos -= woff;
2101 /* Since this will be assigned to _rl_last_c_pos at the end (more
2102 precisely, _rl_last_c_pos == dpos when this function returns),
2103 let the caller know. */
2104 cpos_adjusted = 1;
2105 }
d3a24ed2 2106 }
28089d04 2107 else
7117c2d2 2108#endif
28089d04
CR
2109 dpos = new;
2110
2111 /* If we don't have to do anything, then return. */
2112 if (cpos == dpos)
2113 return;
726f6388
JA
2114
2115 /* It may be faster to output a CR, and then move forwards instead
2116 of moving backwards. */
2117 /* i == current physical cursor position. */
28089d04
CR
2118#if defined (HANDLE_MULTIBYTE)
2119 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
2120 i = _rl_last_c_pos;
2121 else
2122#endif
2123 i = _rl_last_c_pos - woff;
d3ad40de 2124 if (dpos == 0 || CR_FASTER (dpos, _rl_last_c_pos) ||
28ef6c31 2125 (_rl_term_autowrap && i == _rl_screenwidth))
726f6388
JA
2126 {
2127#if defined (__MSDOS__)
2128 putc ('\r', rl_outstream);
2129#else
28ef6c31 2130 tputs (_rl_term_cr, 1, _rl_output_character_function);
726f6388 2131#endif /* !__MSDOS__ */
28089d04 2132 cpos = _rl_last_c_pos = 0;
726f6388
JA
2133 }
2134
28089d04 2135 if (cpos < dpos)
726f6388
JA
2136 {
2137 /* Move the cursor forward. We do it by printing the command
2138 to move the cursor forward if there is one, else print that
2139 portion of the output buffer again. Which is cheaper? */
2140
2141 /* The above comment is left here for posterity. It is faster
2142 to print one character (non-control) than to print a control
2143 sequence telling the terminal to move forward one character.
2144 That kind of control is for people who don't know what the
2145 data is underneath the cursor. */
d3ad40de
CR
2146
2147 /* However, we need a handle on where the current display position is
2148 in the buffer for the immediately preceding comment to be true.
2149 In multibyte locales, we don't currently have that info available.
2150 Without it, we don't know where the data we have to display begins
2151 in the buffer and we have to go back to the beginning of the screen
2152 line. In this case, we can use the terminal sequence to move forward
2153 if it's available. */
7117c2d2
JA
2154 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
2155 {
d3ad40de
CR
2156 if (_rl_term_forward_char)
2157 {
2158 for (i = cpos; i < dpos; i++)
2159 tputs (_rl_term_forward_char, 1, _rl_output_character_function);
2160 }
2161 else
2162 {
2163 tputs (_rl_term_cr, 1, _rl_output_character_function);
2164 for (i = 0; i < new; i++)
2165 putc (data[i], rl_outstream);
2166 }
7117c2d2 2167 }
726f6388 2168 else
28089d04 2169 for (i = cpos; i < new; i++)
726f6388 2170 putc (data[i], rl_outstream);
726f6388 2171 }
28089d04 2172
7117c2d2
JA
2173#if defined (HANDLE_MULTIBYTE)
2174 /* NEW points to the buffer point, but _rl_last_c_pos is the display point.
2175 The byte length of the string is probably bigger than the column width
2176 of the string, which means that if NEW == _rl_last_c_pos, then NEW's
2177 display point is less than _rl_last_c_pos. */
7117c2d2 2178#endif
28089d04
CR
2179 else if (cpos > dpos)
2180 _rl_backspace (cpos - dpos);
7117c2d2 2181
28089d04 2182 _rl_last_c_pos = dpos;
726f6388
JA
2183}
2184
2185/* PWP: move the cursor up or down. */
2186void
2187_rl_move_vert (to)
2188 int to;
2189{
2190 register int delta, i;
2191
28ef6c31 2192 if (_rl_last_v_pos == to || to > _rl_screenheight)
726f6388
JA
2193 return;
2194
726f6388
JA
2195 if ((delta = to - _rl_last_v_pos) > 0)
2196 {
2197 for (i = 0; i < delta; i++)
2198 putc ('\n', rl_outstream);
bb70624e
JA
2199#if defined (__MSDOS__)
2200 putc ('\r', rl_outstream);
2201#else
28ef6c31 2202 tputs (_rl_term_cr, 1, _rl_output_character_function);
bb70624e 2203#endif
726f6388
JA
2204 _rl_last_c_pos = 0;
2205 }
2206 else
2207 { /* delta < 0 */
af32e54d
CR
2208#ifdef __DJGPP__
2209 int row, col;
2210
2211 fflush (rl_outstream);
2212 ScreenGetCursor (&row, &col);
2213 ScreenSetCursor (row + delta, col);
2214 i = -delta;
2215#else
28ef6c31 2216 if (_rl_term_up && *_rl_term_up)
726f6388 2217 for (i = 0; i < -delta; i++)
28ef6c31 2218 tputs (_rl_term_up, 1, _rl_output_character_function);
af32e54d 2219#endif /* !__DJGPP__ */
726f6388 2220 }
bb70624e 2221
726f6388
JA
2222 _rl_last_v_pos = to; /* Now TO is here */
2223}
2224
2225/* Physically print C on rl_outstream. This is for functions which know
2226 how to optimize the display. Return the number of characters output. */
ccc6cda3 2227int
726f6388
JA
2228rl_show_char (c)
2229 int c;
2230{
2231 int n = 1;
2232 if (META_CHAR (c) && (_rl_output_meta_chars == 0))
2233 {
2234 fprintf (rl_outstream, "M-");
2235 n += 2;
2236 c = UNMETA (c);
2237 }
2238
2239#if defined (DISPLAY_TABS)
ccc6cda3 2240 if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
726f6388 2241#else
ccc6cda3 2242 if (CTRL_CHAR (c) || c == RUBOUT)
726f6388
JA
2243#endif /* !DISPLAY_TABS */
2244 {
2245 fprintf (rl_outstream, "C-");
2246 n += 2;
ccc6cda3 2247 c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
726f6388
JA
2248 }
2249
2250 putc (c, rl_outstream);
2251 fflush (rl_outstream);
2252 return n;
2253}
2254
2255int
2256rl_character_len (c, pos)
2257 register int c, pos;
2258{
2259 unsigned char uc;
2260
2261 uc = (unsigned char)c;
2262
2263 if (META_CHAR (uc))
2264 return ((_rl_output_meta_chars == 0) ? 4 : 1);
2265
2266 if (uc == '\t')
2267 {
2268#if defined (DISPLAY_TABS)
2269 return (((pos | 7) + 1) - pos);
2270#else
2271 return (2);
2272#endif /* !DISPLAY_TABS */
2273 }
2274
ccc6cda3
JA
2275 if (CTRL_CHAR (c) || c == RUBOUT)
2276 return (2);
2277
f73dda09 2278 return ((ISPRINT (uc)) ? 1 : 2);
726f6388 2279}
726f6388
JA
2280/* How to print things in the "echo-area". The prompt is treated as a
2281 mini-modeline. */
6e70dbff 2282static int msg_saved_prompt = 0;
726f6388 2283
ccc6cda3
JA
2284#if defined (USE_VARARGS)
2285int
2286#if defined (PREFER_STDARG)
2287rl_message (const char *format, ...)
2288#else
726f6388
JA
2289rl_message (va_alist)
2290 va_dcl
ccc6cda3 2291#endif
726f6388 2292{
726f6388 2293 va_list args;
ccc6cda3
JA
2294#if defined (PREFER_VARARGS)
2295 char *format;
2296#endif
40647963
CR
2297#if defined (HAVE_VSNPRINTF)
2298 int bneed;
2299#endif
726f6388 2300
ccc6cda3
JA
2301#if defined (PREFER_STDARG)
2302 va_start (args, format);
2303#else
726f6388
JA
2304 va_start (args);
2305 format = va_arg (args, char *);
ccc6cda3
JA
2306#endif
2307
40647963
CR
2308 if (msg_buf == 0)
2309 msg_buf = xmalloc (msg_bufsiz = 128);
2310
f73dda09 2311#if defined (HAVE_VSNPRINTF)
138f0d61 2312 bneed = vsnprintf (msg_buf, msg_bufsiz, format, args);
40647963
CR
2313 if (bneed >= msg_bufsiz - 1)
2314 {
2315 msg_bufsiz = bneed + 1;
2316 msg_buf = xrealloc (msg_buf, msg_bufsiz);
2317 va_end (args);
2318
2319#if defined (PREFER_STDARG)
2320 va_start (args, format);
2321#else
2322 va_start (args);
2323 format = va_arg (args, char *);
2324#endif
2325 vsnprintf (msg_buf, msg_bufsiz - 1, format, args);
2326 }
f73dda09 2327#else
726f6388 2328 vsprintf (msg_buf, format, args);
40647963 2329 msg_buf[msg_bufsiz - 1] = '\0'; /* overflow? */
f73dda09 2330#endif
726f6388
JA
2331 va_end (args);
2332
6e70dbff
CR
2333 if (saved_local_prompt == 0)
2334 {
2335 rl_save_prompt ();
2336 msg_saved_prompt = 1;
2337 }
c84e5202
CR
2338 else if (local_prompt != saved_local_prompt)
2339 {
2340 FREE (local_prompt);
2341 FREE (local_prompt_prefix);
2342 local_prompt = (char *)NULL;
2343 }
726f6388 2344 rl_display_prompt = msg_buf;
db02a175
CR
2345 local_prompt = expand_prompt (msg_buf, 0, &prompt_visible_length,
2346 &prompt_last_invisible,
2347 &prompt_invis_chars_first_line,
2348 &prompt_physical_chars);
6e70dbff 2349 local_prompt_prefix = (char *)NULL;
d3ad40de 2350 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
ccc6cda3 2351 (*rl_redisplay_function) ();
6e70dbff 2352
726f6388
JA
2353 return 0;
2354}
ccc6cda3
JA
2355#else /* !USE_VARARGS */
2356int
726f6388
JA
2357rl_message (format, arg1, arg2)
2358 char *format;
2359{
40647963
CR
2360 if (msg_buf == 0)
2361 msg_buf = xmalloc (msg_bufsiz = 128);
2362
726f6388 2363 sprintf (msg_buf, format, arg1, arg2);
40647963 2364 msg_buf[msg_bufsiz - 1] = '\0'; /* overflow? */
6e70dbff 2365
726f6388 2366 rl_display_prompt = msg_buf;
6e70dbff
CR
2367 if (saved_local_prompt == 0)
2368 {
2369 rl_save_prompt ();
2370 msg_saved_prompt = 1;
2371 }
c84e5202
CR
2372 else if (local_prompt != saved_local_prompt)
2373 {
2374 FREE (local_prompt);
2375 FREE (local_prompt_prefix);
2376 local_prompt = (char *)NULL;
2377 }
db02a175
CR
2378 local_prompt = expand_prompt (msg_buf, 0, &prompt_visible_length,
2379 &prompt_last_invisible,
2380 &prompt_invis_chars_first_line,
2381 &prompt_physical_chars);
6e70dbff 2382 local_prompt_prefix = (char *)NULL;
d3ad40de 2383 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
ccc6cda3 2384 (*rl_redisplay_function) ();
6e70dbff 2385
726f6388
JA
2386 return 0;
2387}
ccc6cda3 2388#endif /* !USE_VARARGS */
726f6388
JA
2389
2390/* How to clear things from the "echo-area". */
ccc6cda3 2391int
726f6388
JA
2392rl_clear_message ()
2393{
2394 rl_display_prompt = rl_prompt;
6e70dbff
CR
2395 if (msg_saved_prompt)
2396 {
2397 rl_restore_prompt ();
2398 msg_saved_prompt = 0;
2399 }
ccc6cda3 2400 (*rl_redisplay_function) ();
726f6388
JA
2401 return 0;
2402}
2403
ccc6cda3 2404int
726f6388
JA
2405rl_reset_line_state ()
2406{
2407 rl_on_new_line ();
2408
2409 rl_display_prompt = rl_prompt ? rl_prompt : "";
2410 forced_display = 1;
2411 return 0;
2412}
2413
ccc6cda3 2414void
b72432fd 2415rl_save_prompt ()
ccc6cda3
JA
2416{
2417 saved_local_prompt = local_prompt;
2418 saved_local_prefix = local_prompt_prefix;
6e70dbff 2419 saved_prefix_length = prompt_prefix_length;
d3ad40de 2420 saved_local_length = local_prompt_len;
28ef6c31
JA
2421 saved_last_invisible = prompt_last_invisible;
2422 saved_visible_length = prompt_visible_length;
d3a24ed2 2423 saved_invis_chars_first_line = prompt_invis_chars_first_line;
762a763b 2424 saved_physical_chars = prompt_physical_chars;
ccc6cda3
JA
2425
2426 local_prompt = local_prompt_prefix = (char *)0;
d3ad40de 2427 local_prompt_len = 0;
6e70dbff 2428 prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0;
762a763b 2429 prompt_invis_chars_first_line = prompt_physical_chars = 0;
ccc6cda3
JA
2430}
2431
2432void
b72432fd 2433rl_restore_prompt ()
ccc6cda3 2434{
28ef6c31
JA
2435 FREE (local_prompt);
2436 FREE (local_prompt_prefix);
ccc6cda3
JA
2437
2438 local_prompt = saved_local_prompt;
2439 local_prompt_prefix = saved_local_prefix;
d3ad40de 2440 local_prompt_len = saved_local_length;
6e70dbff 2441 prompt_prefix_length = saved_prefix_length;
28ef6c31
JA
2442 prompt_last_invisible = saved_last_invisible;
2443 prompt_visible_length = saved_visible_length;
d3a24ed2 2444 prompt_invis_chars_first_line = saved_invis_chars_first_line;
762a763b 2445 prompt_physical_chars = saved_physical_chars;
6e70dbff
CR
2446
2447 /* can test saved_local_prompt to see if prompt info has been saved. */
2448 saved_local_prompt = saved_local_prefix = (char *)0;
d3ad40de 2449 saved_local_length = 0;
6e70dbff
CR
2450 saved_last_invisible = saved_visible_length = saved_prefix_length = 0;
2451 saved_invis_chars_first_line = saved_physical_chars = 0;
ccc6cda3
JA
2452}
2453
2454char *
2455_rl_make_prompt_for_search (pchar)
2456 int pchar;
2457{
2458 int len;
0cc62c12 2459 char *pmt, *p;
ccc6cda3 2460
b72432fd 2461 rl_save_prompt ();
ccc6cda3 2462
0cc62c12
CR
2463 /* We've saved the prompt, and can do anything with the various prompt
2464 strings we need before they're restored. We want the unexpanded
2465 portion of the prompt string after any final newline. */
2466 p = rl_prompt ? strrchr (rl_prompt, '\n') : 0;
2467 if (p == 0)
2468 {
2469 len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
2470 pmt = (char *)xmalloc (len + 2);
2471 if (len)
2472 strcpy (pmt, rl_prompt);
2473 pmt[len] = pchar;
2474 pmt[len+1] = '\0';
2475 }
2476 else
2477 {
2478 p++;
2479 len = strlen (p);
2480 pmt = (char *)xmalloc (len + 2);
2481 if (len)
2482 strcpy (pmt, p);
2483 pmt[len] = pchar;
2484 pmt[len+1] = '\0';
2485 }
762a763b 2486
2abb7255 2487 /* will be overwritten by expand_prompt, called from rl_message */
6e70dbff 2488 prompt_physical_chars = saved_physical_chars + 1;
ccc6cda3
JA
2489 return pmt;
2490}
2491
726f6388
JA
2492/* Quick redisplay hack when erasing characters at the end of the line. */
2493void
2494_rl_erase_at_end_of_line (l)
2495 int l;
2496{
2497 register int i;
2498
ccc6cda3 2499 _rl_backspace (l);
726f6388
JA
2500 for (i = 0; i < l; i++)
2501 putc (' ', rl_outstream);
ccc6cda3 2502 _rl_backspace (l);
726f6388
JA
2503 for (i = 0; i < l; i++)
2504 visible_line[--_rl_last_c_pos] = '\0';
2505 rl_display_fixed++;
2506}
2507
2508/* Clear to the end of the line. COUNT is the minimum
2509 number of character spaces to clear, */
d166f048
JA
2510void
2511_rl_clear_to_eol (count)
726f6388
JA
2512 int count;
2513{
af32e54d 2514#ifndef __MSDOS__
28ef6c31
JA
2515 if (_rl_term_clreol)
2516 tputs (_rl_term_clreol, 1, _rl_output_character_function);
af32e54d
CR
2517 else
2518#endif
2519 if (count)
2520 space_to_eol (count);
726f6388
JA
2521}
2522
2523/* Clear to the end of the line using spaces. COUNT is the minimum
2524 number of character spaces to clear, */
2525static void
2526space_to_eol (count)
2527 int count;
2528{
2529 register int i;
2530
2531 for (i = 0; i < count; i++)
2532 putc (' ', rl_outstream);
2533
2534 _rl_last_c_pos += count;
2535}
2536
d166f048
JA
2537void
2538_rl_clear_screen ()
2539{
af32e54d 2540#ifndef __DJGPP__
28ef6c31
JA
2541 if (_rl_term_clrpag)
2542 tputs (_rl_term_clrpag, 1, _rl_output_character_function);
d166f048 2543 else
28ef6c31 2544 rl_crlf ();
af32e54d
CR
2545#else
2546 ScreenClear ();
2547 ScreenSetCursor (0, 0);
2548#endif /* __DJGPP__ */
d166f048
JA
2549}
2550
7117c2d2 2551/* Insert COUNT characters from STRING to the output stream at column COL. */
726f6388 2552static void
7117c2d2 2553insert_some_chars (string, count, col)
726f6388 2554 char *string;
7117c2d2 2555 int count, col;
726f6388 2556{
73a146be 2557 open_some_spaces (col);
9607141c 2558 _rl_output_some_chars (string, count);
73a146be
CR
2559}
2560
2561/* Insert COL spaces, keeping the cursor at the same position. We follow the
2562 ncurses documentation and use either im/ei with explicit spaces, or IC/ic
2563 by itself. We assume there will either be ei or we don't need to use it. */
2564static void
2565open_some_spaces (col)
2566 int col;
2567{
8f50a023 2568#if !defined (__MSDOS__) && (!defined (__MINGW32__) || defined (NCURSES_VERSION))
73a146be
CR
2569 char *buffer;
2570 register int i;
7117c2d2 2571
726f6388 2572 /* If IC is defined, then we do not have to "enter" insert mode. */
28ef6c31 2573 if (_rl_term_IC)
726f6388 2574 {
7117c2d2 2575 buffer = tgoto (_rl_term_IC, 0, col);
726f6388 2576 tputs (buffer, 1, _rl_output_character_function);
726f6388 2577 }
73a146be 2578 else if (_rl_term_im && *_rl_term_im)
726f6388 2579 {
73a146be
CR
2580 tputs (_rl_term_im, 1, _rl_output_character_function);
2581 /* just output the desired number of spaces */
2582 for (i = col; i--; )
2583 _rl_output_character_function (' ');
2584 /* If there is a string to turn off insert mode, use it now. */
28ef6c31
JA
2585 if (_rl_term_ei && *_rl_term_ei)
2586 tputs (_rl_term_ei, 1, _rl_output_character_function);
73a146be
CR
2587 /* and move back the right number of spaces */
2588 _rl_backspace (col);
2589 }
2590 else if (_rl_term_ic && *_rl_term_ic)
2591 {
2592 /* If there is a special command for inserting characters, then
2593 use that first to open up the space. */
2594 for (i = col; i--; )
2595 tputs (_rl_term_ic, 1, _rl_output_character_function);
726f6388 2596 }
8f50a023 2597#endif /* !__MSDOS__ && (!__MINGW32__ || NCURSES_VERSION)*/
726f6388
JA
2598}
2599
2600/* Delete COUNT characters from the display line. */
2601static void
2602delete_chars (count)
2603 int count;
2604{
28ef6c31 2605 if (count > _rl_screenwidth) /* XXX */
726f6388
JA
2606 return;
2607
8f50a023 2608#if !defined (__MSDOS__) && (!defined (__MINGW32__) || defined (NCURSES_VERSION))
28ef6c31 2609 if (_rl_term_DC && *_rl_term_DC)
726f6388 2610 {
ccc6cda3 2611 char *buffer;
28ef6c31 2612 buffer = tgoto (_rl_term_DC, count, count);
726f6388
JA
2613 tputs (buffer, count, _rl_output_character_function);
2614 }
2615 else
2616 {
28ef6c31 2617 if (_rl_term_dc && *_rl_term_dc)
726f6388 2618 while (count--)
28ef6c31 2619 tputs (_rl_term_dc, 1, _rl_output_character_function);
726f6388 2620 }
8f50a023 2621#endif /* !__MSDOS__ && (!__MINGW32__ || NCURSES_VERSION)*/
726f6388
JA
2622}
2623
2624void
2625_rl_update_final ()
2626{
2627 int full_lines;
2628
2629 full_lines = 0;
ccc6cda3
JA
2630 /* If the cursor is the only thing on an otherwise-blank last line,
2631 compensate so we don't print an extra CRLF. */
2632 if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
d166f048 2633 visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
726f6388
JA
2634 {
2635 _rl_vis_botlin--;
2636 full_lines = 1;
2637 }
2638 _rl_move_vert (_rl_vis_botlin);
ccc6cda3 2639 /* If we've wrapped lines, remove the final xterm line-wrap flag. */
28ef6c31 2640 if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == _rl_screenwidth))
726f6388 2641 {
726f6388 2642 char *last_line;
7117c2d2 2643
bb70624e 2644 last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]];
d3ad40de
CR
2645 cpos_buffer_position = -1; /* don't know where we are in buffer */
2646 _rl_move_cursor_relative (_rl_screenwidth - 1, last_line); /* XXX */
d166f048 2647 _rl_clear_to_eol (0);
28ef6c31 2648 putc (last_line[_rl_screenwidth - 1], rl_outstream);
726f6388
JA
2649 }
2650 _rl_vis_botlin = 0;
28ef6c31 2651 rl_crlf ();
726f6388
JA
2652 fflush (rl_outstream);
2653 rl_display_fixed++;
2654}
2655
2656/* Move to the start of the current line. */
2657static void
2658cr ()
2659{
28ef6c31 2660 if (_rl_term_cr)
726f6388 2661 {
bb70624e
JA
2662#if defined (__MSDOS__)
2663 putc ('\r', rl_outstream);
2664#else
28ef6c31 2665 tputs (_rl_term_cr, 1, _rl_output_character_function);
bb70624e 2666#endif
726f6388
JA
2667 _rl_last_c_pos = 0;
2668 }
2669}
2670
bb70624e
JA
2671/* Redraw the last line of a multi-line prompt that may possibly contain
2672 terminal escape sequences. Called with the cursor at column 0 of the
2673 line to draw the prompt on. */
2674static void
2675redraw_prompt (t)
2676 char *t;
2677{
6e70dbff 2678 char *oldp;
bb70624e 2679
bb70624e 2680 oldp = rl_display_prompt;
6e70dbff 2681 rl_save_prompt ();
bb70624e
JA
2682
2683 rl_display_prompt = t;
db02a175
CR
2684 local_prompt = expand_prompt (t, PMT_MULTILINE,
2685 &prompt_visible_length,
28ef6c31 2686 &prompt_last_invisible,
43cdcad8
CR
2687 &prompt_invis_chars_first_line,
2688 &prompt_physical_chars);
bb70624e 2689 local_prompt_prefix = (char *)NULL;
d3ad40de 2690 local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
6e70dbff 2691
bb70624e
JA
2692 rl_forced_update_display ();
2693
2694 rl_display_prompt = oldp;
6e70dbff 2695 rl_restore_prompt();
bb70624e
JA
2696}
2697
726f6388
JA
2698/* Redisplay the current line after a SIGWINCH is received. */
2699void
2700_rl_redisplay_after_sigwinch ()
2701{
bb70624e 2702 char *t;
726f6388 2703
d3ad40de
CR
2704 /* Clear the last line (assuming that the screen size change will result in
2705 either more or fewer characters on that line only) and put the cursor at
2706 column 0. Make sure the right thing happens if we have wrapped to a new
2707 screen line. */
28ef6c31 2708 if (_rl_term_cr)
726f6388 2709 {
d3ad40de
CR
2710 _rl_move_vert (_rl_vis_botlin);
2711
bb70624e
JA
2712#if defined (__MSDOS__)
2713 putc ('\r', rl_outstream);
2714#else
28ef6c31 2715 tputs (_rl_term_cr, 1, _rl_output_character_function);
bb70624e 2716#endif
726f6388 2717 _rl_last_c_pos = 0;
bb70624e 2718#if defined (__MSDOS__)
28ef6c31 2719 space_to_eol (_rl_screenwidth);
bb70624e
JA
2720 putc ('\r', rl_outstream);
2721#else
28ef6c31
JA
2722 if (_rl_term_clreol)
2723 tputs (_rl_term_clreol, 1, _rl_output_character_function);
726f6388
JA
2724 else
2725 {
28ef6c31
JA
2726 space_to_eol (_rl_screenwidth);
2727 tputs (_rl_term_cr, 1, _rl_output_character_function);
726f6388 2728 }
bb70624e 2729#endif
726f6388
JA
2730 if (_rl_last_v_pos > 0)
2731 _rl_move_vert (0);
2732 }
2733 else
28ef6c31 2734 rl_crlf ();
726f6388
JA
2735
2736 /* Redraw only the last line of a multi-line prompt. */
2737 t = strrchr (rl_display_prompt, '\n');
2738 if (t)
bb70624e 2739 redraw_prompt (++t);
726f6388
JA
2740 else
2741 rl_forced_update_display ();
2742}
ccc6cda3
JA
2743
2744void
2745_rl_clean_up_for_exit ()
2746{
6fbe7620 2747 if (_rl_echoing_p)
ccc6cda3 2748 {
c28fcb7e
CR
2749 if (_rl_vis_botlin > 0) /* minor optimization plus bug fix */
2750 _rl_move_vert (_rl_vis_botlin);
ccc6cda3
JA
2751 _rl_vis_botlin = 0;
2752 fflush (rl_outstream);
b72432fd 2753 rl_restart_output (1, 0);
ccc6cda3
JA
2754 }
2755}
b72432fd
JA
2756
2757void
2758_rl_erase_entire_line ()
2759{
2760 cr ();
2761 _rl_clear_to_eol (0);
2762 cr ();
2763 fflush (rl_outstream);
2764}
bb70624e 2765
0d9b018b
CR
2766void
2767_rl_ttyflush ()
2768{
2769 fflush (rl_outstream);
2770}
2771
bb70624e
JA
2772/* return the `current display line' of the cursor -- the number of lines to
2773 move up to get to the first screen line of the current readline line. */
2774int
2775_rl_current_display_line ()
2776{
2777 int ret, nleft;
2778
2779 /* Find out whether or not there might be invisible characters in the
2780 editing buffer. */
2781 if (rl_display_prompt == rl_prompt)
28ef6c31 2782 nleft = _rl_last_c_pos - _rl_screenwidth - rl_visible_prompt_length;
bb70624e 2783 else
28ef6c31 2784 nleft = _rl_last_c_pos - _rl_screenwidth;
bb70624e
JA
2785
2786 if (nleft > 0)
28ef6c31 2787 ret = 1 + nleft / _rl_screenwidth;
bb70624e
JA
2788 else
2789 ret = 0;
2790
2791 return ret;
2792}
7117c2d2
JA
2793
2794#if defined (HANDLE_MULTIBYTE)
2795/* Calculate the number of screen columns occupied by STR from START to END.
2796 In the case of multibyte characters with stateful encoding, we have to
2797 scan from the beginning of the string to take the state into account. */
2798static int
82a5df63 2799_rl_col_width (str, start, end, flags)
d3a24ed2 2800 const char *str;
82a5df63 2801 int start, end, flags;
7117c2d2
JA
2802{
2803 wchar_t wc;
d3ad40de 2804 mbstate_t ps;
7117c2d2
JA
2805 int tmp, point, width, max;
2806
2807 if (end <= start)
2808 return 0;
d3ad40de 2809 if (MB_CUR_MAX == 1 || rl_byte_oriented)
c7e43312 2810 /* this can happen in some cases where it's inconvenient to check */
d3ad40de 2811 return (end - start);
d3ad40de
CR
2812
2813 memset (&ps, 0, sizeof (mbstate_t));
5cef52a7 2814
7117c2d2
JA
2815 point = 0;
2816 max = end;
2817
dfc21851
CR
2818 /* Try to short-circuit common cases. The adjustment to remove wrap_offset
2819 is done by the caller. */
2820 /* 1. prompt string */
82a5df63
CR
2821 if (flags && start == 0 && end == local_prompt_len && memcmp (str, local_prompt, local_prompt_len) == 0)
2822 return (prompt_physical_chars + wrap_offset);
dfc21851 2823 /* 2. prompt string + line contents */
82a5df63 2824 else if (flags && start == 0 && local_prompt_len > 0 && end > local_prompt_len && local_prompt && memcmp (str, local_prompt, local_prompt_len) == 0)
dfc21851 2825 {
82a5df63 2826 tmp = prompt_physical_chars + wrap_offset;
dfc21851 2827 /* XXX - try to call ourselves recursively with non-prompt portion */
82a5df63 2828 tmp += _rl_col_width (str, local_prompt_len, end, flags);
dfc21851
CR
2829 return (tmp);
2830 }
2831
7117c2d2
JA
2832 while (point < start)
2833 {
2834 tmp = mbrlen (str + point, max, &ps);
d3a24ed2 2835 if (MB_INVALIDCH ((size_t)tmp))
7117c2d2
JA
2836 {
2837 /* In this case, the bytes are invalid or too short to compose a
2838 multibyte character, so we assume that the first byte represents
2839 a single character. */
2840 point++;
2841 max--;
2842
2843 /* Clear the state of the byte sequence, because in this case the
2844 effect of mbstate is undefined. */
2845 memset (&ps, 0, sizeof (mbstate_t));
2846 }
d3a24ed2 2847 else if (MB_NULLWCH (tmp))
5e13499c 2848 break; /* Found '\0' */
7117c2d2
JA
2849 else
2850 {
2851 point += tmp;
2852 max -= tmp;
2853 }
2854 }
2855
2856 /* If START is not a byte that starts a character, then POINT will be
2857 greater than START. In this case, assume that (POINT - START) gives
2858 a byte count that is the number of columns of difference. */
2859 width = point - start;
2860
2861 while (point < end)
2862 {
2863 tmp = mbrtowc (&wc, str + point, max, &ps);
d3a24ed2 2864 if (MB_INVALIDCH ((size_t)tmp))
7117c2d2
JA
2865 {
2866 /* In this case, the bytes are invalid or too short to compose a
2867 multibyte character, so we assume that the first byte represents
2868 a single character. */
2869 point++;
2870 max--;
2871
2872 /* and assume that the byte occupies a single column. */
2873 width++;
2874
2875 /* Clear the state of the byte sequence, because in this case the
2876 effect of mbstate is undefined. */
2877 memset (&ps, 0, sizeof (mbstate_t));
2878 }
d3a24ed2 2879 else if (MB_NULLWCH (tmp))
5e13499c 2880 break; /* Found '\0' */
7117c2d2
JA
2881 else
2882 {
2883 point += tmp;
2884 max -= tmp;
22818c14 2885 tmp = WCWIDTH(wc);
7117c2d2
JA
2886 width += (tmp >= 0) ? tmp : 1;
2887 }
2888 }
2889
2890 width += point - end;
2891
2892 return width;
2893}
2894#endif /* HANDLE_MULTIBYTE */