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