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