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