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