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