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