edb5b20dc556432ded643689d6d656455b58b91c
[platform/upstream/bash.git] / lib / readline / display.c
1 /* display.c -- readline redisplay facility. */
2
3 /* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
4
5    This file is part of the GNU Readline Library, a library for
6    reading lines of text with interactive input and history editing.
7
8    The GNU Readline Library is free software; you can redistribute it
9    and/or modify it under the terms of the GNU General Public License
10    as published by the Free Software Foundation; either version 1, 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    675 Mass Ave, Cambridge, MA 02139, 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 #if defined (__GO32__)
45 #  include <go32.h>
46 #  include <pc.h>
47 #endif /* __GO32__ */
48
49 /* System-specific feature definitions and include files. */
50 #include "rldefs.h"
51
52 /* Termcap library stuff. */
53 #include "tcap.h"
54
55 /* Some standard library routines. */
56 #include "readline.h"
57 #include "history.h"
58
59 #if !defined (strchr) && !defined (__STDC__)
60 extern char *strchr (), *strrchr ();
61 #endif /* !strchr && !__STDC__ */
62
63 /* Global and pseudo-global variables and functions
64    imported from readline.c. */
65 extern char *rl_prompt;
66 extern int readline_echoing_p;
67
68 extern int _rl_output_meta_chars;
69 extern int _rl_horizontal_scroll_mode;
70 extern int _rl_mark_modified_lines;
71 extern int _rl_prefer_visible_bell;
72
73 /* Variables and functions imported from terminal.c */
74 extern void _rl_output_some_chars ();
75 #ifdef _MINIX
76 extern void _rl_output_character_function ();
77 #else
78 extern int _rl_output_character_function ();
79 #endif
80 extern int _rl_backspace ();
81
82 extern char *term_clreol, *term_clrpag;
83 extern char *term_im, *term_ic,  *term_ei, *term_DC;
84 extern char *term_up, *term_dc, *term_cr, *term_IC;
85 extern int screenheight, screenwidth, screenchars;
86 extern int terminal_can_insert, _rl_term_autowrap;
87
88 /* Pseudo-global functions (local to the readline library) exported
89    by this file. */
90 void _rl_move_cursor_relative (), _rl_output_some_chars ();
91 void _rl_move_vert ();
92 void _rl_clear_to_eol (), _rl_clear_screen ();
93
94 static void update_line (), space_to_eol ();
95 static void delete_chars (), insert_some_chars ();
96 static void cr ();
97
98 static int *inv_lbreaks, *vis_lbreaks;
99
100 extern char *xmalloc (), *xrealloc ();
101
102 /* Heuristic used to decide whether it is faster to move from CUR to NEW
103    by backing up or outputting a carriage return and moving forward. */
104 #define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))
105
106 /* **************************************************************** */
107 /*                                                                  */
108 /*                      Display stuff                               */
109 /*                                                                  */
110 /* **************************************************************** */
111
112 /* This is the stuff that is hard for me.  I never seem to write good
113    display routines in C.  Let's see how I do this time. */
114
115 /* (PWP) Well... Good for a simple line updater, but totally ignores
116    the problems of input lines longer than the screen width.
117
118    update_line and the code that calls it makes a multiple line,
119    automatically wrapping line update.  Careful attention needs
120    to be paid to the vertical position variables. */
121
122 /* Keep two buffers; one which reflects the current contents of the
123    screen, and the other to draw what we think the new contents should
124    be.  Then compare the buffers, and make whatever changes to the
125    screen itself that we should.  Finally, make the buffer that we
126    just drew into be the one which reflects the current contents of the
127    screen, and place the cursor where it belongs.
128
129    Commands that want to can fix the display themselves, and then let
130    this function know that the display has been fixed by setting the
131    RL_DISPLAY_FIXED variable.  This is good for efficiency. */
132
133 /* Application-specific redisplay function. */
134 VFunction *rl_redisplay_function = rl_redisplay;
135
136 /* Global variables declared here. */
137 /* What YOU turn on when you have handled all redisplay yourself. */
138 int rl_display_fixed = 0;
139
140 int _rl_suppress_redisplay = 0;
141
142 /* The stuff that gets printed out before the actual text of the line.
143    This is usually pointing to rl_prompt. */
144 char *rl_display_prompt = (char *)NULL;
145
146 /* Pseudo-global variables declared here. */
147 /* The visible cursor position.  If you print some text, adjust this. */
148 int _rl_last_c_pos = 0;
149 int _rl_last_v_pos = 0;
150
151 /* Number of lines currently on screen minus 1. */
152 int _rl_vis_botlin = 0;
153
154 /* Variables used only in this file. */
155 /* The last left edge of text that was displayed.  This is used when
156    doing horizontal scrolling.  It shifts in thirds of a screenwidth. */
157 static int last_lmargin;
158
159 /* The line display buffers.  One is the line currently displayed on
160    the screen.  The other is the line about to be displayed. */
161 static char *visible_line = (char *)NULL;
162 static char *invisible_line = (char *)NULL;
163
164 /* A buffer for `modeline' messages. */
165 static char msg_buf[128];
166
167 /* Non-zero forces the redisplay even if we thought it was unnecessary. */
168 static int forced_display;
169
170 /* Default and initial buffer size.  Can grow. */
171 static int line_size = 1024;
172
173 static char *local_prompt, *local_prompt_prefix;
174 static int visible_length, prefix_length;
175
176 /* The number of invisible characters in the line currently being
177    displayed on the screen. */
178 static int visible_wrap_offset;
179
180 /* static so it can be shared between rl_redisplay and update_line */
181 static int wrap_offset;
182
183 /* The index of the last invisible_character in the prompt string. */
184 static int last_invisible;
185
186 /* The length (buffer offset) of the first line of the last (possibly
187    multi-line) buffer displayed on the screen. */
188 static int visible_first_line_len;
189
190 /* Expand the prompt string S and return the number of visible
191    characters in *LP, if LP is not null.  This is currently more-or-less
192    a placeholder for expansion.  LIP, if non-null is a place to store the
193    index of the last invisible character in ther eturned string. */
194
195 /* Current implementation:
196         \001 (^A) start non-visible characters
197         \002 (^B) end non-visible characters
198    all characters except \001 and \002 (following a \001) are copied to
199    the returned string; all characters except those between \001 and
200    \002 are assumed to be `visible'. */ 
201
202 static char *
203 expand_prompt (pmt, lp, lip)
204      char *pmt;
205      int *lp, *lip;
206 {
207   char *r, *ret, *p;
208   int l, rl, last, ignoring;
209
210   /* Short-circuit if we can. */
211   if (strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
212     {
213       r = savestring (pmt);
214       if (lp)
215         *lp = strlen (r);
216       return r;
217     }
218
219   l = strlen (pmt);
220   r = ret = xmalloc (l + 1);
221   
222   for (rl = ignoring = last = 0, p = pmt; p && *p; p++)
223     {
224       /* This code strips the invisible character string markers
225          RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
226       if (*p == RL_PROMPT_START_IGNORE)
227         {
228           ignoring++;
229           continue;
230         }
231       else if (ignoring && *p == RL_PROMPT_END_IGNORE)
232         {
233           ignoring = 0;
234           last = r - ret - 1;
235           continue;
236         }
237       else
238         {
239           *r++ = *p;
240           if (!ignoring)
241             rl++;
242         }
243     }
244
245   *r = '\0';
246   if (lp)
247     *lp = rl;
248   if (lip)
249     *lip = last;
250   return ret;
251 }
252
253 /*
254  * Expand the prompt string into the various display components, if
255  * necessary.
256  *
257  * local_prompt = expanded last line of string in rl_display_prompt
258  *                (portion after the final newline)
259  * local_prompt_prefix = portion before last newline of rl_display_prompt,
260  *                       expanded via expand_prompt
261  * visible_length = number of visible characters in local_prompt
262  * prefix_length = number of visible characters in local_prompt_prefix
263  *
264  * This function is called once per call to readline().  It may also be
265  * called arbitrarily to expand the primary prompt.
266  *
267  * The return value is the number of visible characters on the last line
268  * of the (possibly multi-line) prompt.
269  */
270 int
271 rl_expand_prompt (prompt)
272      char *prompt;
273 {
274   char *p, *t;
275   int c;
276
277   /* Clear out any saved values. */
278   if (local_prompt)
279     free (local_prompt);
280   if (local_prompt_prefix)
281     free (local_prompt_prefix);
282   local_prompt = local_prompt_prefix = (char *)0;
283   last_invisible = 0;
284
285   if (prompt == 0 || *prompt == 0)
286     return (0);
287
288   p = strrchr (prompt, '\n');
289   if (!p)
290     {
291       /* The prompt is only one line. */
292       local_prompt = expand_prompt (prompt, &visible_length, &last_invisible);
293       local_prompt_prefix = (char *)0;
294       return (visible_length);
295     }
296   else
297     {
298       /* The prompt spans multiple lines. */
299       t = ++p;
300       local_prompt = expand_prompt (p, &visible_length, &last_invisible);
301       c = *t; *t = '\0';
302       /* The portion of the prompt string up to and including the
303          final newline is now null-terminated. */
304       local_prompt_prefix = expand_prompt (prompt, &prefix_length, (int *)NULL);
305       *t = c;
306       return (prefix_length);
307     }
308 }
309
310 /* Basic redisplay algorithm. */
311 void
312 rl_redisplay ()
313 {
314   register int in, out, c, linenum, cursor_linenum;
315   register char *line;
316   int c_pos, inv_botlin, lb_botlin, lb_linenum;
317   int newlines, lpos, temp;
318   char *prompt_this_line;
319
320   if (!readline_echoing_p)
321     return;
322
323   if (!rl_display_prompt)
324     rl_display_prompt = "";
325
326   if (invisible_line == 0)
327     {
328       visible_line = xmalloc (line_size);
329       invisible_line = xmalloc (line_size);
330       for (in = 0; in < line_size; in++)
331         {
332           visible_line[in] = 0;
333           invisible_line[in] = 1;
334         }
335
336       /* should be enough, but then again, this is just for testing. */
337       inv_lbreaks = (int *)malloc (256 * sizeof (int));
338       vis_lbreaks = (int *)malloc (256 * sizeof (int));
339       inv_lbreaks[0] = vis_lbreaks[0] = 0;
340
341       rl_on_new_line ();
342     }
343
344   /* Draw the line into the buffer. */
345   c_pos = -1;
346
347   line = invisible_line;
348   out = inv_botlin = 0;
349
350   /* Mark the line as modified or not.  We only do this for history
351      lines. */
352   if (_rl_mark_modified_lines && current_history () && rl_undo_list)
353     {
354       line[out++] = '*';
355       line[out] = '\0';
356     }
357
358   /* If someone thought that the redisplay was handled, but the currently
359      visible line has a different modification state than the one about
360      to become visible, then correct the caller's misconception. */
361   if (visible_line[0] != invisible_line[0])
362     rl_display_fixed = 0;
363
364   /* If the prompt to be displayed is the `primary' readline prompt (the
365      one passed to readline()), use the values we have already expanded.
366      If not, use what's already in rl_display_prompt.  WRAP_OFFSET is the
367      number of non-visible characters in the prompt string. */
368   if (rl_display_prompt == rl_prompt || local_prompt)
369     {
370       int local_len = local_prompt ? strlen (local_prompt) : 0;
371       if (local_prompt_prefix && forced_display)
372         _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
373
374       if (local_len > 0)
375         {
376           strncpy (line + out, local_prompt, local_len);
377           out += local_len;
378         }
379       line[out] = '\0';
380       wrap_offset = local_len - visible_length;
381     }
382   else
383     {
384       int pmtlen;
385       prompt_this_line = strrchr (rl_display_prompt, '\n');
386       if (!prompt_this_line)
387         prompt_this_line = rl_display_prompt;
388       else
389         {
390           prompt_this_line++;
391           if (forced_display)
392             {
393               _rl_output_some_chars (rl_display_prompt, prompt_this_line - rl_display_prompt);
394               /* Make sure we are at column zero even after a newline,
395                  regardless of the state of terminal output processing. */
396               if (prompt_this_line[-2] != '\r')
397                 cr ();
398             }
399         }
400
401       pmtlen = strlen (prompt_this_line);
402       strncpy (line + out,  prompt_this_line, pmtlen);
403       out += pmtlen;
404       line[out] = '\0';
405       wrap_offset = 0;
406     }
407
408 #define CHECK_LPOS() \
409       do { \
410         lpos++; \
411         if (lpos >= screenwidth) \
412           { \
413             inv_lbreaks[++newlines] = out; \
414             lpos = 0; \
415           } \
416       } while (0)
417
418   /* inv_lbreaks[i] is where line i starts in the buffer. */
419   inv_lbreaks[newlines = 0] = 0;
420   lpos = out - wrap_offset;
421
422   /* XXX - what if lpos is already >= screenwidth before we start drawing the
423      contents of the command line? */
424   while (lpos >= screenwidth)
425     {
426       temp = ((newlines + 1) * screenwidth) - ((newlines == 0) ? wrap_offset : 0);
427       inv_lbreaks[++newlines] = temp;
428       lpos -= screenwidth;
429     }
430
431   lb_linenum = 0;
432   for (in = 0; in < rl_end; in++)
433     {
434       c = (unsigned char)rl_line_buffer[in];
435
436       if (out + 8 >= line_size)         /* XXX - 8 for \t */
437         {
438           line_size *= 2;
439           visible_line = xrealloc (visible_line, line_size);
440           invisible_line = xrealloc (invisible_line, line_size);
441           line = invisible_line;
442         }
443
444       if (in == rl_point)
445         {
446           c_pos = out;
447           lb_linenum = newlines;
448         }
449
450       if (META_CHAR (c))
451         {
452           if (_rl_output_meta_chars == 0)
453             {
454               sprintf (line + out, "\\%o", c);
455
456               if (lpos + 4 >= screenwidth)
457                 {
458                   temp = screenwidth - lpos;
459                   inv_lbreaks[++newlines] = out + temp;
460                   lpos = 4 - temp;
461                 }
462               else
463                 lpos += 4;
464
465               out += 4;
466             }
467           else
468             {
469               line[out++] = c;
470               CHECK_LPOS();
471             }
472         }
473 #if defined (DISPLAY_TABS)
474       else if (c == '\t')
475         {
476           register int temp, newout;
477           newout = (out | (int)7) + 1;
478           temp = newout - out;
479           if (lpos + temp >= screenwidth)
480             {
481               register int temp2;
482               temp2 = screenwidth - lpos;
483               inv_lbreaks[++newlines] = out + temp2;
484               lpos = temp - temp2;
485               while (out < newout)
486                 line[out++] = ' ';
487             }
488           else
489             {
490               while (out < newout)
491                 line[out++] = ' ';
492               lpos += temp;
493             }
494         }
495 #endif
496       else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && term_up && *term_up)
497         {
498           line[out++] = '\0';   /* XXX - sentinel */
499           inv_lbreaks[++newlines] = out;
500           lpos = 0;
501         }
502       else if (CTRL_CHAR (c) || c == RUBOUT)
503         {
504           line[out++] = '^';
505           CHECK_LPOS();
506           line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
507           CHECK_LPOS();
508         }
509       else
510         {
511           line[out++] = c;
512           CHECK_LPOS();
513         }
514     }
515   line[out] = '\0';
516   if (c_pos < 0)
517     {
518       c_pos = out;
519       lb_linenum = newlines;
520     }
521
522   inv_botlin = lb_botlin = newlines;
523   inv_lbreaks[newlines+1] = out;
524   cursor_linenum = lb_linenum;
525
526   /* C_POS == position in buffer where cursor should be placed. */
527
528   /* PWP: now is when things get a bit hairy.  The visible and invisible
529      line buffers are really multiple lines, which would wrap every
530      (screenwidth - 1) characters.  Go through each in turn, finding
531      the changed region and updating it.  The line order is top to bottom. */
532
533   /* If we can move the cursor up and down, then use multiple lines,
534      otherwise, let long lines display in a single terminal line, and
535      horizontally scroll it. */
536
537   if (_rl_horizontal_scroll_mode == 0 && term_up && *term_up)
538     {
539       int nleft, pos, changed_screen_line;
540
541       if (!rl_display_fixed || forced_display)
542         {
543           forced_display = 0;
544
545           /* If we have more than a screenful of material to display, then
546              only display a screenful.  We should display the last screen,
547              not the first.  */
548           if (out >= screenchars)
549             out = screenchars - 1;
550
551           /* The first line is at character position 0 in the buffer.  The
552              second and subsequent lines start at inv_lbreaks[N], offset by
553              OFFSET (which has already been calculated above).  */
554
555 #define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
556 #define VIS_LLEN(l)     ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
557 #define INV_LLEN(l)     (inv_lbreaks[l+1] - inv_lbreaks[l])
558 #define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
559 #define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
560 #define INV_LINE(line) (invisible_line + inv_lbreaks[line])
561
562           /* For each line in the buffer, do the updating display. */
563           for (linenum = 0; linenum <= inv_botlin; linenum++)
564             {
565               update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
566                            VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
567
568               /* If this is the line with the prompt, we might need to
569                  compensate for invisible characters in the new line. Do
570                  this only if there is not more than one new line (which
571                  implies that we completely overwrite the old visible line)
572                  and the new line is shorter than the old.  Make sure we are
573                  at the end of the new line before clearing. */
574               if (linenum == 0 &&
575                   inv_botlin == 0 && _rl_last_c_pos == out &&
576                   (wrap_offset > visible_wrap_offset) &&
577                   (_rl_last_c_pos < visible_first_line_len))
578                 {
579                   nleft = screenwidth + wrap_offset - _rl_last_c_pos;
580                   if (nleft)
581                     _rl_clear_to_eol (nleft);
582                 }
583
584               /* Since the new first line is now visible, save its length. */
585               if (linenum == 0)
586                 visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
587             }
588
589           /* We may have deleted some lines.  If so, clear the left over
590              blank ones at the bottom out. */
591           if (_rl_vis_botlin > inv_botlin)
592             {
593               char *tt;
594               for (; linenum <= _rl_vis_botlin; linenum++)
595                 {
596                   tt = VIS_CHARS (linenum);
597                   _rl_move_vert (linenum);
598                   _rl_move_cursor_relative (0, tt);
599                   _rl_clear_to_eol
600                     ((linenum == _rl_vis_botlin) ? strlen (tt) : screenwidth);
601                 }
602             }
603           _rl_vis_botlin = inv_botlin;
604
605           /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
606              different screen line during this redisplay. */
607           changed_screen_line = _rl_last_v_pos != cursor_linenum;
608           if (changed_screen_line)
609             {
610               _rl_move_vert (cursor_linenum);
611               /* If we moved up to the line with the prompt using term_up,
612                  the physical cursor position on the screen stays the same,
613                  but the buffer position needs to be adjusted to account
614                  for invisible characters. */
615               if (cursor_linenum == 0 && wrap_offset)
616                 _rl_last_c_pos += wrap_offset;
617             }
618
619           /* We have to reprint the prompt if it contains invisible
620              characters, since it's not generally OK to just reprint
621              the characters from the current cursor position.  But we
622              only need to reprint it if the cursor is before the last
623              invisible character in the prompt string. */
624           nleft = visible_length + wrap_offset;
625           if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
626               _rl_last_c_pos <= last_invisible && local_prompt)
627             {
628               if (term_cr)
629                 tputs (term_cr, 1, _rl_output_character_function);
630               _rl_output_some_chars (local_prompt, nleft);
631               _rl_last_c_pos = nleft;
632             }
633
634           /* Where on that line?  And where does that line start
635              in the buffer? */
636           pos = inv_lbreaks[cursor_linenum];
637           /* nleft == number of characters in the line buffer between the
638              start of the line and the cursor position. */
639           nleft = c_pos - pos;
640
641           /* Since _rl_backspace() doesn't know about invisible characters in the
642              prompt, and there's no good way to tell it, we compensate for
643              those characters here and call _rl_backspace() directly. */
644           if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
645             {
646               _rl_backspace (_rl_last_c_pos - nleft);
647               _rl_last_c_pos = nleft;
648             }
649
650           if (nleft != _rl_last_c_pos)
651             _rl_move_cursor_relative (nleft, &invisible_line[pos]);
652         }
653     }
654   else                          /* Do horizontal scrolling. */
655     {
656 #define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
657       int lmargin, ndisp, nleft, phys_c_pos, t;
658
659       /* Always at top line. */
660       _rl_last_v_pos = 0;
661
662       /* Compute where in the buffer the displayed line should start.  This
663          will be LMARGIN. */
664
665       /* The number of characters that will be displayed before the cursor. */
666       ndisp = c_pos - wrap_offset;
667       nleft  = visible_length + wrap_offset;
668       /* Where the new cursor position will be on the screen.  This can be
669          longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
670       phys_c_pos = c_pos - (last_lmargin ? last_lmargin : wrap_offset);
671       t = screenwidth / 3;
672
673       /* If the number of characters had already exceeded the screenwidth,
674          last_lmargin will be > 0. */
675
676       /* If the number of characters to be displayed is more than the screen
677          width, compute the starting offset so that the cursor is about
678          two-thirds of the way across the screen. */
679       if (phys_c_pos > screenwidth - 2)
680         {
681           lmargin = c_pos - (2 * t);
682           if (lmargin < 0)
683             lmargin = 0;
684           /* If the left margin would be in the middle of a prompt with
685              invisible characters, don't display the prompt at all. */
686           if (wrap_offset && lmargin > 0 && lmargin < nleft)
687             lmargin = nleft;
688         }
689       else if (ndisp < screenwidth - 2)         /* XXX - was -1 */
690         lmargin = 0;
691       else if (phys_c_pos < 1)
692         {
693           /* If we are moving back towards the beginning of the line and
694              the last margin is no longer correct, compute a new one. */
695           lmargin = ((c_pos - 1) / t) * t;      /* XXX */
696           if (wrap_offset && lmargin > 0 && lmargin < nleft)
697             lmargin = nleft;
698         }
699       else
700         lmargin = last_lmargin;
701
702       /* If the first character on the screen isn't the first character
703          in the display line, indicate this with a special character. */
704       if (lmargin > 0)
705         line[lmargin] = '<';
706
707       /* If SCREENWIDTH characters starting at LMARGIN do not encompass
708          the whole line, indicate that with a special characters at the
709          right edge of the screen.  If LMARGIN is 0, we need to take the
710          wrap offset into account. */
711       t = lmargin + M_OFFSET (lmargin, wrap_offset) + screenwidth;
712       if (t < out)
713         line[t - 1] = '>';
714
715       if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
716         {
717           forced_display = 0;
718           update_line (&visible_line[last_lmargin],
719                        &invisible_line[lmargin],
720                        0,
721                        screenwidth + visible_wrap_offset,
722                        screenwidth + (lmargin ? 0 : wrap_offset),
723                        0);
724
725           /* If the visible new line is shorter than the old, but the number
726              of invisible characters is greater, and we are at the end of
727              the new line, we need to clear to eol. */
728           t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
729           if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
730               (_rl_last_c_pos == out) &&
731               t < visible_first_line_len)
732             {
733               nleft = screenwidth - t;
734               _rl_clear_to_eol (nleft);
735             }
736           visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
737           if (visible_first_line_len > screenwidth)
738             visible_first_line_len = screenwidth;
739
740           _rl_move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
741           last_lmargin = lmargin;
742         }
743     }
744   fflush (rl_outstream);
745
746   /* Swap visible and non-visible lines. */
747   {
748     char *temp = visible_line;
749     int *itemp = vis_lbreaks;
750     visible_line = invisible_line;
751     invisible_line = temp;
752     vis_lbreaks = inv_lbreaks;
753     inv_lbreaks = itemp;
754     rl_display_fixed = 0;
755     /* If we are displaying on a single line, and last_lmargin is > 0, we
756        are not displaying any invisible characters, so set visible_wrap_offset
757        to 0. */
758     if (_rl_horizontal_scroll_mode && last_lmargin)
759       visible_wrap_offset = 0;
760     else
761       visible_wrap_offset = wrap_offset;
762   }
763 }
764
765 /* PWP: update_line() is based on finding the middle difference of each
766    line on the screen; vis:
767
768                              /old first difference
769         /beginning of line   |        /old last same       /old EOL
770         v                    v        v             v
771 old:    eddie> Oh, my little gruntle-buggy is to me, as lurgid as
772 new:    eddie> Oh, my little buggy says to me, as lurgid as
773         ^                    ^  ^                          ^
774         \beginning of line   |  \new last same     \new end of line
775                              \new first difference
776
777    All are character pointers for the sake of speed.  Special cases for
778    no differences, as well as for end of line additions must be handeled.
779
780    Could be made even smarter, but this works well enough */
781 static void
782 update_line (old, new, current_line, omax, nmax, inv_botlin)
783      register char *old, *new;
784      int current_line, omax, nmax, inv_botlin;
785 {
786   register char *ofd, *ols, *oe, *nfd, *nls, *ne;
787   int temp, lendiff, wsatend, od, nd;
788   int current_invis_chars;
789
790   /* If we're at the right edge of a terminal that supports xn, we're
791      ready to wrap around, so do so.  This fixes problems with knowing
792      the exact cursor position and cut-and-paste with certain terminal
793      emulators.  In this calculation, TEMP is the physical screen
794      position of the cursor. */
795   temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
796   if (temp == screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
797       && _rl_last_v_pos == current_line - 1)
798     {
799       if (new[0])
800         putc (new[0], rl_outstream);
801       else
802         putc (' ', rl_outstream);
803       _rl_last_c_pos = 1;               /* XXX */
804       _rl_last_v_pos++;
805       if (old[0] && new[0])
806         old[0] = new[0];
807     }
808       
809   /* Find first difference. */
810   for (ofd = old, nfd = new;
811        (ofd - old < omax) && *ofd && (*ofd == *nfd);
812        ofd++, nfd++)
813     ;
814
815   /* Move to the end of the screen line.  ND and OD are used to keep track
816      of the distance between ne and new and oe and old, respectively, to
817      move a subtraction out of each loop. */
818   for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
819   for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
820
821   /* If no difference, continue to next line. */
822   if (ofd == oe && nfd == ne)
823     return;
824
825   wsatend = 1;                  /* flag for trailing whitespace */
826   ols = oe - 1;                 /* find last same */
827   nls = ne - 1;
828   while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
829     {
830       if (*ols != ' ')
831         wsatend = 0;
832       ols--;
833       nls--;
834     }
835
836   if (wsatend)
837     {
838       ols = oe;
839       nls = ne;
840     }
841   else if (*ols != *nls)
842     {
843       if (*ols)                 /* don't step past the NUL */
844         ols++;
845       if (*nls)
846         nls++;
847     }
848
849   /* count of invisible characters in the current invisible line. */
850   current_invis_chars = W_OFFSET (current_line, wrap_offset);
851   if (_rl_last_v_pos != current_line)
852     {
853       _rl_move_vert (current_line);
854       if (current_line == 0 && visible_wrap_offset)
855         _rl_last_c_pos += visible_wrap_offset;
856     }
857
858   /* If this is the first line and there are invisible characters in the
859      prompt string, and the prompt string has not changed, and the current
860      cursor position is before the last invisible character in the prompt,
861      and the index of the character to move to is past the end of the prompt
862      string, then redraw the entire prompt string.  We can only do this
863      reliably if the terminal supports a `cr' capability.
864
865      This is not an efficiency hack -- there is a problem with redrawing
866      portions of the prompt string if they contain terminal escape
867      sequences (like drawing the `unbold' sequence without a corresponding
868      `bold') that manifests itself on certain terminals. */
869
870   lendiff = local_prompt ? strlen (local_prompt) : 0;
871   od = ofd - old;       /* index of first difference in visible line */
872   if (current_line == 0 && !_rl_horizontal_scroll_mode &&
873       term_cr && lendiff > visible_length && _rl_last_c_pos > 0 &&
874       od > lendiff && _rl_last_c_pos < last_invisible)
875     {
876       tputs (term_cr, 1, _rl_output_character_function);
877       _rl_output_some_chars (local_prompt, lendiff);
878       _rl_last_c_pos = lendiff;
879     }
880
881   _rl_move_cursor_relative (od, old);
882
883   /* if (len (new) > len (old)) */
884   lendiff = (nls - nfd) - (ols - ofd);
885
886   /* If we are changing the number of invisible characters in a line, and
887      the spot of first difference is before the end of the invisible chars,
888      lendiff needs to be adjusted. */
889   if (current_line == 0 && !_rl_horizontal_scroll_mode &&
890       current_invis_chars != visible_wrap_offset)
891     {
892       temp = visible_wrap_offset - current_invis_chars;
893       lendiff += temp;
894     }
895
896   /* Insert (diff (len (old), len (new)) ch. */
897   temp = ne - nfd;
898   if (lendiff > 0)
899     {
900       /* Non-zero if we're increasing the number of lines. */
901       int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
902       /* Sometimes it is cheaper to print the characters rather than
903          use the terminal's capabilities.  If we're growing the number
904          of lines, make sure we actually cause the new line to wrap
905          around on auto-wrapping terminals. */
906       if (terminal_can_insert && ((2 * temp) >= lendiff || term_IC) && (!_rl_term_autowrap || !gl))
907         {
908           /* If lendiff > visible_length and _rl_last_c_pos == 0 and
909              _rl_horizontal_scroll_mode == 1, inserting the characters with
910              term_IC or term_ic will screw up the screen because of the
911              invisible characters.  We need to just draw them. */
912           if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 ||
913                         lendiff <= visible_length || !current_invis_chars))
914             {
915               insert_some_chars (nfd, lendiff);
916               _rl_last_c_pos += lendiff;
917             }
918           else if (*ols == 0)
919             {
920               /* At the end of a line the characters do not have to
921                  be "inserted".  They can just be placed on the screen. */
922               /* However, this screws up the rest of this block, which
923                  assumes you've done the insert because you can. */
924               _rl_output_some_chars (nfd, lendiff);
925               _rl_last_c_pos += lendiff;
926             }
927           else
928             {
929               /* We have horizontal scrolling and we are not inserting at
930                  the end.  We have invisible characters in this line.  This
931                  is a dumb update. */
932               _rl_output_some_chars (nfd, temp);
933               _rl_last_c_pos += temp;
934               return;
935             }
936           /* Copy (new) chars to screen from first diff to last match. */
937           temp = nls - nfd;
938           if ((temp - lendiff) > 0)
939             {
940               _rl_output_some_chars (nfd + lendiff, temp - lendiff);
941               _rl_last_c_pos += temp - lendiff;
942             }
943         }
944       else
945         {
946           /* cannot insert chars, write to EOL */
947           _rl_output_some_chars (nfd, temp);
948           _rl_last_c_pos += temp;
949         }
950     }
951   else                          /* Delete characters from line. */
952     {
953       /* If possible and inexpensive to use terminal deletion, then do so. */
954       if (term_dc && (2 * temp) >= -lendiff)
955         {
956           /* If all we're doing is erasing the invisible characters in the
957              prompt string, don't bother.  It screws up the assumptions
958              about what's on the screen. */
959           if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
960               -lendiff == visible_wrap_offset)
961             lendiff = 0;
962
963           if (lendiff)
964             delete_chars (-lendiff); /* delete (diff) characters */
965
966           /* Copy (new) chars to screen from first diff to last match */
967           temp = nls - nfd;
968           if (temp > 0)
969             {
970               _rl_output_some_chars (nfd, temp);
971               _rl_last_c_pos += temp;
972             }
973         }
974       /* Otherwise, print over the existing material. */
975       else
976         {
977           if (temp > 0)
978             {
979               _rl_output_some_chars (nfd, temp);
980               _rl_last_c_pos += temp;
981             }
982           lendiff = (oe - old) - (ne - new);
983           if (_rl_term_autowrap && current_line < inv_botlin)
984             space_to_eol (lendiff);
985           else
986             _rl_clear_to_eol (lendiff);
987         }
988     }
989 }
990
991 /* Tell the update routines that we have moved onto a new (empty) line. */
992 int
993 rl_on_new_line ()
994 {
995   if (visible_line)
996     visible_line[0] = '\0';
997
998   _rl_last_c_pos = _rl_last_v_pos = 0;
999   _rl_vis_botlin = last_lmargin = 0;
1000   if (vis_lbreaks)
1001     vis_lbreaks[0] = vis_lbreaks[1] = 0;
1002   visible_wrap_offset = 0;
1003   return 0;
1004 }
1005
1006 /* Actually update the display, period. */
1007 int
1008 rl_forced_update_display ()
1009 {
1010   if (visible_line)
1011     {
1012       register char *temp = visible_line;
1013
1014       while (*temp)
1015         *temp++ = '\0';
1016     }
1017   rl_on_new_line ();
1018   forced_display++;
1019   (*rl_redisplay_function) ();
1020   return 0;
1021 }
1022
1023 /* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
1024    DATA is the contents of the screen line of interest; i.e., where
1025    the movement is being done. */
1026 void
1027 _rl_move_cursor_relative (new, data)
1028      int new;
1029      char *data;
1030 {
1031   register int i;
1032
1033   /* If we don't have to do anything, then return. */
1034   if (_rl_last_c_pos == new) return;
1035
1036   /* It may be faster to output a CR, and then move forwards instead
1037      of moving backwards. */
1038   /* i == current physical cursor position. */
1039   i = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
1040   if (new == 0 || CR_FASTER (new, _rl_last_c_pos) ||
1041       (_rl_term_autowrap && i == screenwidth))
1042     {
1043 #if defined (__MSDOS__)
1044       putc ('\r', rl_outstream);
1045 #else
1046       tputs (term_cr, 1, _rl_output_character_function);
1047 #endif /* !__MSDOS__ */
1048       _rl_last_c_pos = 0;
1049     }
1050
1051   if (_rl_last_c_pos < new)
1052     {
1053       /* Move the cursor forward.  We do it by printing the command
1054          to move the cursor forward if there is one, else print that
1055          portion of the output buffer again.  Which is cheaper? */
1056
1057       /* The above comment is left here for posterity.  It is faster
1058          to print one character (non-control) than to print a control
1059          sequence telling the terminal to move forward one character.
1060          That kind of control is for people who don't know what the
1061          data is underneath the cursor. */
1062 #if defined (HACK_TERMCAP_MOTION)
1063       extern char *term_forward_char;
1064
1065       if (term_forward_char)
1066         for (i = _rl_last_c_pos; i < new; i++)
1067           tputs (term_forward_char, 1, _rl_output_character_function);
1068       else
1069         for (i = _rl_last_c_pos; i < new; i++)
1070           putc (data[i], rl_outstream);
1071 #else
1072       for (i = _rl_last_c_pos; i < new; i++)
1073         putc (data[i], rl_outstream);
1074 #endif /* HACK_TERMCAP_MOTION */
1075     }
1076   else if (_rl_last_c_pos != new)
1077     _rl_backspace (_rl_last_c_pos - new);
1078   _rl_last_c_pos = new;
1079 }
1080
1081 /* PWP: move the cursor up or down. */
1082 void
1083 _rl_move_vert (to)
1084      int to;
1085 {
1086   register int delta, i;
1087
1088   if (_rl_last_v_pos == to || to > screenheight)
1089     return;
1090
1091 #if defined (__GO32__)
1092   {
1093     int row, col;
1094
1095     ScreenGetCursor (&row, &col);
1096     ScreenSetCursor ((row + to - _rl_last_v_pos), col);
1097   }
1098 #else /* !__GO32__ */
1099
1100   if ((delta = to - _rl_last_v_pos) > 0)
1101     {
1102       for (i = 0; i < delta; i++)
1103         putc ('\n', rl_outstream);
1104       tputs (term_cr, 1, _rl_output_character_function);
1105       _rl_last_c_pos = 0;
1106     }
1107   else
1108     {                   /* delta < 0 */
1109       if (term_up && *term_up)
1110         for (i = 0; i < -delta; i++)
1111           tputs (term_up, 1, _rl_output_character_function);
1112     }
1113 #endif /* !__GO32__ */
1114   _rl_last_v_pos = to;          /* Now TO is here */
1115 }
1116
1117 /* Physically print C on rl_outstream.  This is for functions which know
1118    how to optimize the display.  Return the number of characters output. */
1119 int
1120 rl_show_char (c)
1121      int c;
1122 {
1123   int n = 1;
1124   if (META_CHAR (c) && (_rl_output_meta_chars == 0))
1125     {
1126       fprintf (rl_outstream, "M-");
1127       n += 2;
1128       c = UNMETA (c);
1129     }
1130
1131 #if defined (DISPLAY_TABS)
1132   if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
1133 #else
1134   if (CTRL_CHAR (c) || c == RUBOUT)
1135 #endif /* !DISPLAY_TABS */
1136     {
1137       fprintf (rl_outstream, "C-");
1138       n += 2;
1139       c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
1140     }
1141
1142   putc (c, rl_outstream);
1143   fflush (rl_outstream);
1144   return n;
1145 }
1146
1147 int
1148 rl_character_len (c, pos)
1149      register int c, pos;
1150 {
1151   unsigned char uc;
1152
1153   uc = (unsigned char)c;
1154
1155   if (META_CHAR (uc))
1156     return ((_rl_output_meta_chars == 0) ? 4 : 1);
1157
1158   if (uc == '\t')
1159     {
1160 #if defined (DISPLAY_TABS)
1161       return (((pos | 7) + 1) - pos);
1162 #else
1163       return (2);
1164 #endif /* !DISPLAY_TABS */
1165     }
1166
1167   if (CTRL_CHAR (c) || c == RUBOUT)
1168     return (2);
1169
1170   return ((isprint (uc)) ? 1 : 2);
1171 }
1172
1173 /* How to print things in the "echo-area".  The prompt is treated as a
1174    mini-modeline. */
1175
1176 #if defined (USE_VARARGS)
1177 int
1178 #if defined (PREFER_STDARG)
1179 rl_message (const char *format, ...)
1180 #else
1181 rl_message (va_alist)
1182      va_dcl
1183 #endif
1184 {
1185   va_list args;
1186 #if defined (PREFER_VARARGS)
1187   char *format;
1188 #endif
1189
1190 #if defined (PREFER_STDARG)
1191   va_start (args, format);
1192 #else
1193   va_start (args);
1194   format = va_arg (args, char *);
1195 #endif
1196
1197   vsprintf (msg_buf, format, args);
1198   va_end (args);
1199
1200   rl_display_prompt = msg_buf;
1201   (*rl_redisplay_function) ();
1202   return 0;
1203 }
1204 #else /* !USE_VARARGS */
1205 int
1206 rl_message (format, arg1, arg2)
1207      char *format;
1208 {
1209   sprintf (msg_buf, format, arg1, arg2);
1210   rl_display_prompt = msg_buf;
1211   (*rl_redisplay_function) ();
1212   return 0;
1213 }
1214 #endif /* !USE_VARARGS */
1215
1216 /* How to clear things from the "echo-area". */
1217 int
1218 rl_clear_message ()
1219 {
1220   rl_display_prompt = rl_prompt;
1221   (*rl_redisplay_function) ();
1222   return 0;
1223 }
1224
1225 int
1226 rl_reset_line_state ()
1227 {
1228   rl_on_new_line ();
1229
1230   rl_display_prompt = rl_prompt ? rl_prompt : "";
1231   forced_display = 1;
1232   return 0;
1233 }
1234
1235 static char *saved_local_prompt;
1236 static char *saved_local_prefix;
1237 static int saved_last_invisible;
1238 static int saved_visible_length;
1239
1240 void
1241 _rl_save_prompt ()
1242 {
1243   saved_local_prompt = local_prompt;
1244   saved_local_prefix = local_prompt_prefix;
1245   saved_last_invisible = last_invisible;
1246   saved_visible_length = visible_length;
1247
1248   local_prompt = local_prompt_prefix = (char *)0;
1249   last_invisible = visible_length = 0;
1250 }
1251
1252 void
1253 _rl_restore_prompt ()
1254 {
1255   if (local_prompt)
1256     free (local_prompt);
1257   if (local_prompt_prefix)
1258     free (local_prompt_prefix);
1259
1260   local_prompt = saved_local_prompt;
1261   local_prompt_prefix = saved_local_prefix;
1262   last_invisible = saved_last_invisible;
1263   visible_length = saved_visible_length;
1264 }
1265
1266 char *
1267 _rl_make_prompt_for_search (pchar)
1268      int pchar;
1269 {
1270   int len;
1271   char *pmt;
1272
1273   _rl_save_prompt ();
1274
1275   if (saved_local_prompt == 0)
1276     {
1277       len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
1278       pmt = xmalloc (len + 2);
1279       if (len)
1280         strcpy (pmt, rl_prompt);
1281       pmt[len] = pchar;
1282       pmt[len+1] = '\0';
1283     }
1284   else
1285     {
1286       len = *saved_local_prompt ? strlen (saved_local_prompt) : 0;
1287       pmt = xmalloc (len + 2);
1288       if (len)
1289         strcpy (pmt, saved_local_prompt);
1290       pmt[len] = pchar;
1291       pmt[len+1] = '\0';
1292       local_prompt = savestring (pmt);
1293       last_invisible = saved_last_invisible;
1294       visible_length = saved_visible_length + 1;
1295     }
1296   return pmt;
1297 }
1298
1299 /* Quick redisplay hack when erasing characters at the end of the line. */
1300 void
1301 _rl_erase_at_end_of_line (l)
1302      int l;
1303 {
1304   register int i;
1305
1306   _rl_backspace (l);
1307   for (i = 0; i < l; i++)
1308     putc (' ', rl_outstream);
1309   _rl_backspace (l);
1310   for (i = 0; i < l; i++)
1311     visible_line[--_rl_last_c_pos] = '\0';
1312   rl_display_fixed++;
1313 }
1314
1315 /* Clear to the end of the line.  COUNT is the minimum
1316    number of character spaces to clear, */
1317 void
1318 _rl_clear_to_eol (count)
1319      int count;
1320 {
1321 #if !defined (__GO32__)
1322   if (term_clreol)
1323     tputs (term_clreol, 1, _rl_output_character_function);
1324   else if (count)
1325 #endif /* !__GO32__ */
1326     space_to_eol (count);
1327 }
1328
1329 /* Clear to the end of the line using spaces.  COUNT is the minimum
1330    number of character spaces to clear, */
1331 static void
1332 space_to_eol (count)
1333      int count;
1334 {
1335   register int i;
1336
1337   for (i = 0; i < count; i++)
1338    putc (' ', rl_outstream);
1339
1340   _rl_last_c_pos += count;
1341 }
1342
1343 void
1344 _rl_clear_screen ()
1345 {
1346 #if !defined (__GO32__)
1347   if (term_clrpag)
1348     tputs (term_clrpag, 1, _rl_output_character_function);
1349   else
1350 #endif /* !__GO32__ */
1351     crlf ();
1352 }
1353
1354 /* Insert COUNT characters from STRING to the output stream. */
1355 static void
1356 insert_some_chars (string, count)
1357      char *string;
1358      int count;
1359 {
1360 #if defined (__GO32__)
1361   int row, col, width;
1362   char *row_start;
1363
1364   ScreenGetCursor (&row, &col);
1365   width = ScreenCols ();
1366   row_start = ScreenPrimary + (row * width);
1367
1368   memcpy (row_start + col + count, row_start + col, width - col - count);
1369
1370   /* Place the text on the screen. */
1371   _rl_output_some_chars (string, count);
1372 #else /* !_GO32 */
1373
1374   /* If IC is defined, then we do not have to "enter" insert mode. */
1375   if (term_IC)
1376     {
1377       char *buffer;
1378       buffer = tgoto (term_IC, 0, count);
1379       tputs (buffer, 1, _rl_output_character_function);
1380       _rl_output_some_chars (string, count);
1381     }
1382   else
1383     {
1384       register int i;
1385
1386       /* If we have to turn on insert-mode, then do so. */
1387       if (term_im && *term_im)
1388         tputs (term_im, 1, _rl_output_character_function);
1389
1390       /* If there is a special command for inserting characters, then
1391          use that first to open up the space. */
1392       if (term_ic && *term_ic)
1393         {
1394           for (i = count; i--; )
1395             tputs (term_ic, 1, _rl_output_character_function);
1396         }
1397
1398       /* Print the text. */
1399       _rl_output_some_chars (string, count);
1400
1401       /* If there is a string to turn off insert mode, we had best use
1402          it now. */
1403       if (term_ei && *term_ei)
1404         tputs (term_ei, 1, _rl_output_character_function);
1405     }
1406 #endif /* !__GO32__ */
1407 }
1408
1409 /* Delete COUNT characters from the display line. */
1410 static void
1411 delete_chars (count)
1412      int count;
1413 {
1414 #if defined (__GO32__)
1415   int row, col, width;
1416   char *row_start;
1417
1418   ScreenGetCursor (&row, &col);
1419   width = ScreenCols ();
1420   row_start = ScreenPrimary + (row * width);
1421
1422   memcpy (row_start + col, row_start + col + count, width - col - count);
1423   memset (row_start + width - count, 0, count * 2);
1424 #else /* !_GO32 */
1425
1426   if (count > screenwidth)      /* XXX */
1427     return;
1428
1429   if (term_DC && *term_DC)
1430     {
1431       char *buffer;
1432       buffer = tgoto (term_DC, count, count);
1433       tputs (buffer, count, _rl_output_character_function);
1434     }
1435   else
1436     {
1437       if (term_dc && *term_dc)
1438         while (count--)
1439           tputs (term_dc, 1, _rl_output_character_function);
1440     }
1441 #endif /* !__GO32__ */
1442 }
1443
1444 void
1445 _rl_update_final ()
1446 {
1447   int full_lines;
1448
1449   full_lines = 0;
1450   /* If the cursor is the only thing on an otherwise-blank last line,
1451      compensate so we don't print an extra CRLF. */
1452   if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
1453         visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
1454     {
1455       _rl_vis_botlin--;
1456       full_lines = 1;
1457     }
1458   _rl_move_vert (_rl_vis_botlin);
1459   /* If we've wrapped lines, remove the final xterm line-wrap flag. */
1460   if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == screenwidth))
1461     {
1462       char *last_line;
1463       last_line = &visible_line[inv_lbreaks[_rl_vis_botlin]];
1464       _rl_move_cursor_relative (screenwidth - 1, last_line);
1465       _rl_clear_to_eol (0);
1466       putc (last_line[screenwidth - 1], rl_outstream);
1467     }
1468   _rl_vis_botlin = 0;
1469   crlf ();
1470   fflush (rl_outstream);
1471   rl_display_fixed++;
1472 }
1473
1474 /* Move to the start of the current line. */
1475 static void
1476 cr ()
1477 {
1478   if (term_cr)
1479     {
1480       tputs (term_cr, 1, _rl_output_character_function);
1481       _rl_last_c_pos = 0;
1482     }
1483 }
1484
1485 /* Redisplay the current line after a SIGWINCH is received. */
1486 void
1487 _rl_redisplay_after_sigwinch ()
1488 {
1489   char *t, *oldp, *oldl, *oldlprefix;
1490
1491   /* Clear the current line and put the cursor at column 0.  Make sure
1492      the right thing happens if we have wrapped to a new screen line. */
1493   if (term_cr)
1494     {
1495       tputs (term_cr, 1, _rl_output_character_function);
1496       _rl_last_c_pos = 0;
1497       if (term_clreol)
1498         tputs (term_clreol, 1, _rl_output_character_function);
1499       else
1500         {
1501           space_to_eol (screenwidth);
1502           tputs (term_cr, 1, _rl_output_character_function);
1503         }
1504       if (_rl_last_v_pos > 0)
1505         _rl_move_vert (0);
1506     }
1507   else
1508     crlf ();
1509
1510   /* Redraw only the last line of a multi-line prompt. */
1511   t = strrchr (rl_display_prompt, '\n');
1512   if (t)
1513     {
1514       oldp = rl_display_prompt;
1515       oldl = local_prompt;
1516       oldlprefix = local_prompt_prefix;
1517       rl_display_prompt = ++t;
1518       local_prompt = local_prompt_prefix = (char *)NULL;
1519       rl_forced_update_display ();
1520       rl_display_prompt = oldp;
1521       local_prompt = oldl;
1522       local_prompt_prefix = oldlprefix;
1523     }
1524   else
1525     rl_forced_update_display ();
1526 }
1527
1528 void
1529 _rl_clean_up_for_exit ()
1530 {
1531   if (readline_echoing_p)
1532     {
1533       _rl_move_vert (_rl_vis_botlin);
1534       _rl_vis_botlin = 0;
1535       fflush (rl_outstream);
1536       rl_restart_output ();
1537     }
1538 }