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