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