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