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