]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libreadline/display.c
This commit was generated by cvs2svn to compensate for changes in r132943,
[FreeBSD/FreeBSD.git] / contrib / libreadline / display.c
1 /* $FreeBSD$ */
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__)
60 extern char *strchr (), *strrchr ();
61 #endif /* !strchr && !__STDC__ */
62
63 #if defined (HACK_TERMCAP_MOTION)
64 extern char *_rl_term_forward_char;
65 #endif
66
67 static void update_line PARAMS((char *, char *, int, int, int, int));
68 static void space_to_eol PARAMS((int));
69 static void delete_chars PARAMS((int));
70 static void insert_some_chars PARAMS((char *, int, int));
71 static void cr PARAMS((void));
72
73 #if defined (HANDLE_MULTIBYTE)
74 static int _rl_col_width PARAMS((char *, int, int));
75 static int *_rl_wrapped_line;
76 #else
77 #  define _rl_col_width(l, s, e)        (((e) <= (s)) ? 0 : (e) - (s))
78 #endif
79
80 static int *inv_lbreaks, *vis_lbreaks;
81 static 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. */
115 rl_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. */
119 int rl_display_fixed = 0;
120
121 int _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. */
125 char *rl_display_prompt = (char *)NULL;
126
127 /* Pseudo-global variables declared here. */
128 /* The visible cursor position.  If you print some text, adjust this. */
129 int _rl_last_c_pos = 0;
130 int _rl_last_v_pos = 0;
131
132 /* Number of lines currently on screen minus 1. */
133 int _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. */
138 static 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. */
142 static char *visible_line = (char *)NULL;
143 static char *invisible_line = (char *)NULL;
144
145 /* A buffer for `modeline' messages. */
146 static char msg_buf[128];
147
148 /* Non-zero forces the redisplay even if we thought it was unnecessary. */
149 static int forced_display;
150
151 /* Default and initial buffer size.  Can grow. */
152 static int line_size = 1024;
153
154 /* Variables to keep track of the expanded prompt string, which may
155    include invisible characters. */
156
157 static char *local_prompt, *local_prompt_prefix;
158 static int prompt_visible_length, prompt_prefix_length;
159
160 /* The number of invisible characters in the line currently being
161    displayed on the screen. */
162 static 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 */
166 static int wrap_offset;
167
168 /* The index of the last invisible character in the prompt string. */
169 static 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. */
173 static 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. */
178 static int prompt_invis_chars_first_line;
179
180 static 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
196 static char *
197 expand_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. */
260 char *
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  */
287 int
288 rl_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. */
337 static void
338 init_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. */
379 void
380 rl_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
1024 old:    eddie> Oh, my little gruntle-buggy is to me, as lurgid as
1025 new:    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 */
1034 static void
1035 update_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. */
1414 int
1415 rl_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. */
1431 int
1432 rl_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. */
1484 int
1485 rl_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. */
1503 void
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. */
1614 void
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. */
1646 int
1647 rl_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
1674 int
1675 rl_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)
1704 int
1705 #if defined (PREFER_STDARG)
1706 rl_message (const char *format, ...)
1707 #else
1708 rl_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 */
1737 int
1738 rl_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". */
1750 int
1751 rl_clear_message ()
1752 {
1753   rl_display_prompt = rl_prompt;
1754   (*rl_redisplay_function) ();
1755   return 0;
1756 }
1757
1758 int
1759 rl_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
1768 static char *saved_local_prompt;
1769 static char *saved_local_prefix;
1770 static int saved_last_invisible;
1771 static int saved_visible_length;
1772
1773 void
1774 rl_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
1785 void
1786 rl_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
1797 char *
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. */
1831 void
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, */
1848 void
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, */
1860 static void
1861 space_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
1872 void
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. */
1882 static void
1883 insert_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. */
1928 static void
1929 delete_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
1949 void
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. */
1981 static void
1982 cr ()
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. */
1998 static void
1999 redraw_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. */
2031 void
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
2072 void
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
2084 void
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. */
2095 int
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. */
2119 static 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