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