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