f7ec69b247c121054ca97c6cb6148b498ade8c2f
[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 #if 0
427       temp = ((newlines + 1) * screenwidth) - ((newlines == 0) ? wrap_offset : 0);
428 #else
429       /* XXX - possible fix from Darin Johnson <darin@acuson.com> for prompt
430          string with invisible characters that is longer than the screen
431          width. */
432       temp = ((newlines + 1) * screenwidth) + ((newlines == 0) ? wrap_offset : 0);
433 #endif
434       inv_lbreaks[++newlines] = temp;
435       lpos -= screenwidth;
436     }
437
438   lb_linenum = 0;
439   for (in = 0; in < rl_end; in++)
440     {
441       c = (unsigned char)rl_line_buffer[in];
442
443       if (out + 8 >= line_size)         /* XXX - 8 for \t */
444         {
445           line_size *= 2;
446           visible_line = xrealloc (visible_line, line_size);
447           invisible_line = xrealloc (invisible_line, line_size);
448           line = invisible_line;
449         }
450
451       if (in == rl_point)
452         {
453           c_pos = out;
454           lb_linenum = newlines;
455         }
456
457       if (META_CHAR (c))
458         {
459           if (_rl_output_meta_chars == 0)
460             {
461               sprintf (line + out, "\\%o", c);
462
463               if (lpos + 4 >= screenwidth)
464                 {
465                   temp = screenwidth - lpos;
466                   inv_lbreaks[++newlines] = out + temp;
467                   lpos = 4 - temp;
468                 }
469               else
470                 lpos += 4;
471
472               out += 4;
473             }
474           else
475             {
476               line[out++] = c;
477               CHECK_LPOS();
478             }
479         }
480 #if defined (DISPLAY_TABS)
481       else if (c == '\t')
482         {
483           register int temp, newout;
484           newout = (out | (int)7) + 1;
485           temp = newout - out;
486           if (lpos + temp >= screenwidth)
487             {
488               register int temp2;
489               temp2 = screenwidth - lpos;
490               inv_lbreaks[++newlines] = out + temp2;
491               lpos = temp - temp2;
492               while (out < newout)
493                 line[out++] = ' ';
494             }
495           else
496             {
497               while (out < newout)
498                 line[out++] = ' ';
499               lpos += temp;
500             }
501         }
502 #endif
503       else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && term_up && *term_up)
504         {
505           line[out++] = '\0';   /* XXX - sentinel */
506           inv_lbreaks[++newlines] = out;
507           lpos = 0;
508         }
509       else if (CTRL_CHAR (c) || c == RUBOUT)
510         {
511           line[out++] = '^';
512           CHECK_LPOS();
513           line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
514           CHECK_LPOS();
515         }
516       else
517         {
518           line[out++] = c;
519           CHECK_LPOS();
520         }
521     }
522   line[out] = '\0';
523   if (c_pos < 0)
524     {
525       c_pos = out;
526       lb_linenum = newlines;
527     }
528
529   inv_botlin = lb_botlin = newlines;
530   inv_lbreaks[newlines+1] = out;
531   cursor_linenum = lb_linenum;
532
533   /* C_POS == position in buffer where cursor should be placed. */
534
535   /* PWP: now is when things get a bit hairy.  The visible and invisible
536      line buffers are really multiple lines, which would wrap every
537      (screenwidth - 1) characters.  Go through each in turn, finding
538      the changed region and updating it.  The line order is top to bottom. */
539
540   /* If we can move the cursor up and down, then use multiple lines,
541      otherwise, let long lines display in a single terminal line, and
542      horizontally scroll it. */
543
544   if (_rl_horizontal_scroll_mode == 0 && term_up && *term_up)
545     {
546       int nleft, pos, changed_screen_line;
547
548       if (!rl_display_fixed || forced_display)
549         {
550           forced_display = 0;
551
552           /* If we have more than a screenful of material to display, then
553              only display a screenful.  We should display the last screen,
554              not the first.  */
555           if (out >= screenchars)
556             out = screenchars - 1;
557
558           /* The first line is at character position 0 in the buffer.  The
559              second and subsequent lines start at inv_lbreaks[N], offset by
560              OFFSET (which has already been calculated above).  */
561
562 #define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
563 #define VIS_LLEN(l)     ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
564 #define INV_LLEN(l)     (inv_lbreaks[l+1] - inv_lbreaks[l])
565 #define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
566 #define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
567 #define INV_LINE(line) (invisible_line + inv_lbreaks[line])
568
569           /* For each line in the buffer, do the updating display. */
570           for (linenum = 0; linenum <= inv_botlin; linenum++)
571             {
572               update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
573                            VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
574
575               /* If this is the line with the prompt, we might need to
576                  compensate for invisible characters in the new line. Do
577                  this only if there is not more than one new line (which
578                  implies that we completely overwrite the old visible line)
579                  and the new line is shorter than the old.  Make sure we are
580                  at the end of the new line before clearing. */
581               if (linenum == 0 &&
582                   inv_botlin == 0 && _rl_last_c_pos == out &&
583                   (wrap_offset > visible_wrap_offset) &&
584                   (_rl_last_c_pos < visible_first_line_len))
585                 {
586                   nleft = screenwidth + wrap_offset - _rl_last_c_pos;
587                   if (nleft)
588                     _rl_clear_to_eol (nleft);
589                 }
590
591               /* Since the new first line is now visible, save its length. */
592               if (linenum == 0)
593                 visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
594             }
595
596           /* We may have deleted some lines.  If so, clear the left over
597              blank ones at the bottom out. */
598           if (_rl_vis_botlin > inv_botlin)
599             {
600               char *tt;
601               for (; linenum <= _rl_vis_botlin; linenum++)
602                 {
603                   tt = VIS_CHARS (linenum);
604                   _rl_move_vert (linenum);
605                   _rl_move_cursor_relative (0, tt);
606                   _rl_clear_to_eol
607                     ((linenum == _rl_vis_botlin) ? strlen (tt) : screenwidth);
608                 }
609             }
610           _rl_vis_botlin = inv_botlin;
611
612           /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
613              different screen line during this redisplay. */
614           changed_screen_line = _rl_last_v_pos != cursor_linenum;
615           if (changed_screen_line)
616             {
617               _rl_move_vert (cursor_linenum);
618               /* If we moved up to the line with the prompt using term_up,
619                  the physical cursor position on the screen stays the same,
620                  but the buffer position needs to be adjusted to account
621                  for invisible characters. */
622               if (cursor_linenum == 0 && wrap_offset)
623                 _rl_last_c_pos += wrap_offset;
624             }
625
626           /* We have to reprint the prompt if it contains invisible
627              characters, since it's not generally OK to just reprint
628              the characters from the current cursor position.  But we
629              only need to reprint it if the cursor is before the last
630              invisible character in the prompt string. */
631           nleft = visible_length + wrap_offset;
632           if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
633               _rl_last_c_pos <= last_invisible && local_prompt)
634             {
635               if (term_cr)
636                 tputs (term_cr, 1, _rl_output_character_function);
637               _rl_output_some_chars (local_prompt, nleft);
638               _rl_last_c_pos = nleft;
639             }
640
641           /* Where on that line?  And where does that line start
642              in the buffer? */
643           pos = inv_lbreaks[cursor_linenum];
644           /* nleft == number of characters in the line buffer between the
645              start of the line and the cursor position. */
646           nleft = c_pos - pos;
647
648           /* Since _rl_backspace() doesn't know about invisible characters in the
649              prompt, and there's no good way to tell it, we compensate for
650              those characters here and call _rl_backspace() directly. */
651           if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
652             {
653               _rl_backspace (_rl_last_c_pos - nleft);
654               _rl_last_c_pos = nleft;
655             }
656
657           if (nleft != _rl_last_c_pos)
658             _rl_move_cursor_relative (nleft, &invisible_line[pos]);
659         }
660     }
661   else                          /* Do horizontal scrolling. */
662     {
663 #define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
664       int lmargin, ndisp, nleft, phys_c_pos, t;
665
666       /* Always at top line. */
667       _rl_last_v_pos = 0;
668
669       /* Compute where in the buffer the displayed line should start.  This
670          will be LMARGIN. */
671
672       /* The number of characters that will be displayed before the cursor. */
673       ndisp = c_pos - wrap_offset;
674       nleft  = visible_length + wrap_offset;
675       /* Where the new cursor position will be on the screen.  This can be
676          longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
677       phys_c_pos = c_pos - (last_lmargin ? last_lmargin : wrap_offset);
678       t = screenwidth / 3;
679
680       /* If the number of characters had already exceeded the screenwidth,
681          last_lmargin will be > 0. */
682
683       /* If the number of characters to be displayed is more than the screen
684          width, compute the starting offset so that the cursor is about
685          two-thirds of the way across the screen. */
686       if (phys_c_pos > screenwidth - 2)
687         {
688           lmargin = c_pos - (2 * t);
689           if (lmargin < 0)
690             lmargin = 0;
691           /* If the left margin would be in the middle of a prompt with
692              invisible characters, don't display the prompt at all. */
693           if (wrap_offset && lmargin > 0 && lmargin < nleft)
694             lmargin = nleft;
695         }
696       else if (ndisp < screenwidth - 2)         /* XXX - was -1 */
697         lmargin = 0;
698       else if (phys_c_pos < 1)
699         {
700           /* If we are moving back towards the beginning of the line and
701              the last margin is no longer correct, compute a new one. */
702           lmargin = ((c_pos - 1) / t) * t;      /* XXX */
703           if (wrap_offset && lmargin > 0 && lmargin < nleft)
704             lmargin = nleft;
705         }
706       else
707         lmargin = last_lmargin;
708
709       /* If the first character on the screen isn't the first character
710          in the display line, indicate this with a special character. */
711       if (lmargin > 0)
712         line[lmargin] = '<';
713
714       /* If SCREENWIDTH characters starting at LMARGIN do not encompass
715          the whole line, indicate that with a special characters at the
716          right edge of the screen.  If LMARGIN is 0, we need to take the
717          wrap offset into account. */
718       t = lmargin + M_OFFSET (lmargin, wrap_offset) + screenwidth;
719       if (t < out)
720         line[t - 1] = '>';
721
722       if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
723         {
724           forced_display = 0;
725           update_line (&visible_line[last_lmargin],
726                        &invisible_line[lmargin],
727                        0,
728                        screenwidth + visible_wrap_offset,
729                        screenwidth + (lmargin ? 0 : wrap_offset),
730                        0);
731
732           /* If the visible new line is shorter than the old, but the number
733              of invisible characters is greater, and we are at the end of
734              the new line, we need to clear to eol. */
735           t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
736           if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
737               (_rl_last_c_pos == out) &&
738               t < visible_first_line_len)
739             {
740               nleft = screenwidth - t;
741               _rl_clear_to_eol (nleft);
742             }
743           visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
744           if (visible_first_line_len > screenwidth)
745             visible_first_line_len = screenwidth;
746
747           _rl_move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
748           last_lmargin = lmargin;
749         }
750     }
751   fflush (rl_outstream);
752
753   /* Swap visible and non-visible lines. */
754   {
755     char *temp = visible_line;
756     int *itemp = vis_lbreaks;
757     visible_line = invisible_line;
758     invisible_line = temp;
759     vis_lbreaks = inv_lbreaks;
760     inv_lbreaks = itemp;
761     rl_display_fixed = 0;
762     /* If we are displaying on a single line, and last_lmargin is > 0, we
763        are not displaying any invisible characters, so set visible_wrap_offset
764        to 0. */
765     if (_rl_horizontal_scroll_mode && last_lmargin)
766       visible_wrap_offset = 0;
767     else
768       visible_wrap_offset = wrap_offset;
769   }
770 }
771
772 /* PWP: update_line() is based on finding the middle difference of each
773    line on the screen; vis:
774
775                              /old first difference
776         /beginning of line   |        /old last same       /old EOL
777         v                    v        v             v
778 old:    eddie> Oh, my little gruntle-buggy is to me, as lurgid as
779 new:    eddie> Oh, my little buggy says to me, as lurgid as
780         ^                    ^  ^                          ^
781         \beginning of line   |  \new last same     \new end of line
782                              \new first difference
783
784    All are character pointers for the sake of speed.  Special cases for
785    no differences, as well as for end of line additions must be handeled.
786
787    Could be made even smarter, but this works well enough */
788 static void
789 update_line (old, new, current_line, omax, nmax, inv_botlin)
790      register char *old, *new;
791      int current_line, omax, nmax, inv_botlin;
792 {
793   register char *ofd, *ols, *oe, *nfd, *nls, *ne;
794   int temp, lendiff, wsatend, od, nd;
795   int current_invis_chars;
796
797   /* If we're at the right edge of a terminal that supports xn, we're
798      ready to wrap around, so do so.  This fixes problems with knowing
799      the exact cursor position and cut-and-paste with certain terminal
800      emulators.  In this calculation, TEMP is the physical screen
801      position of the cursor. */
802   temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
803   if (temp == screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
804       && _rl_last_v_pos == current_line - 1)
805     {
806       if (new[0])
807         putc (new[0], rl_outstream);
808       else
809         putc (' ', rl_outstream);
810       _rl_last_c_pos = 1;               /* XXX */
811       _rl_last_v_pos++;
812       if (old[0] && new[0])
813         old[0] = new[0];
814     }
815       
816   /* Find first difference. */
817   for (ofd = old, nfd = new;
818        (ofd - old < omax) && *ofd && (*ofd == *nfd);
819        ofd++, nfd++)
820     ;
821
822   /* Move to the end of the screen line.  ND and OD are used to keep track
823      of the distance between ne and new and oe and old, respectively, to
824      move a subtraction out of each loop. */
825   for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
826   for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
827
828   /* If no difference, continue to next line. */
829   if (ofd == oe && nfd == ne)
830     return;
831
832   wsatend = 1;                  /* flag for trailing whitespace */
833   ols = oe - 1;                 /* find last same */
834   nls = ne - 1;
835   while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
836     {
837       if (*ols != ' ')
838         wsatend = 0;
839       ols--;
840       nls--;
841     }
842
843   if (wsatend)
844     {
845       ols = oe;
846       nls = ne;
847     }
848   else if (*ols != *nls)
849     {
850       if (*ols)                 /* don't step past the NUL */
851         ols++;
852       if (*nls)
853         nls++;
854     }
855
856   /* count of invisible characters in the current invisible line. */
857   current_invis_chars = W_OFFSET (current_line, wrap_offset);
858   if (_rl_last_v_pos != current_line)
859     {
860       _rl_move_vert (current_line);
861       if (current_line == 0 && visible_wrap_offset)
862         _rl_last_c_pos += visible_wrap_offset;
863     }
864
865   /* If this is the first line and there are invisible characters in the
866      prompt string, and the prompt string has not changed, and the current
867      cursor position is before the last invisible character in the prompt,
868      and the index of the character to move to is past the end of the prompt
869      string, then redraw the entire prompt string.  We can only do this
870      reliably if the terminal supports a `cr' capability.
871
872      This is not an efficiency hack -- there is a problem with redrawing
873      portions of the prompt string if they contain terminal escape
874      sequences (like drawing the `unbold' sequence without a corresponding
875      `bold') that manifests itself on certain terminals. */
876
877   lendiff = local_prompt ? strlen (local_prompt) : 0;
878   od = ofd - old;       /* index of first difference in visible line */
879   if (current_line == 0 && !_rl_horizontal_scroll_mode &&
880       term_cr && lendiff > visible_length && _rl_last_c_pos > 0 &&
881       od > lendiff && _rl_last_c_pos < last_invisible)
882     {
883       tputs (term_cr, 1, _rl_output_character_function);
884       _rl_output_some_chars (local_prompt, lendiff);
885       _rl_last_c_pos = lendiff;
886     }
887
888   _rl_move_cursor_relative (od, old);
889
890   /* if (len (new) > len (old)) */
891   lendiff = (nls - nfd) - (ols - ofd);
892
893   /* If we are changing the number of invisible characters in a line, and
894      the spot of first difference is before the end of the invisible chars,
895      lendiff needs to be adjusted. */
896   if (current_line == 0 && !_rl_horizontal_scroll_mode &&
897       current_invis_chars != visible_wrap_offset)
898     {
899       temp = visible_wrap_offset - current_invis_chars;
900       lendiff += temp;
901     }
902
903   /* Insert (diff (len (old), len (new)) ch. */
904   temp = ne - nfd;
905   if (lendiff > 0)
906     {
907       /* Non-zero if we're increasing the number of lines. */
908       int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
909       /* Sometimes it is cheaper to print the characters rather than
910          use the terminal's capabilities.  If we're growing the number
911          of lines, make sure we actually cause the new line to wrap
912          around on auto-wrapping terminals. */
913       if (terminal_can_insert && ((2 * temp) >= lendiff || term_IC) && (!_rl_term_autowrap || !gl))
914         {
915           /* If lendiff > visible_length and _rl_last_c_pos == 0 and
916              _rl_horizontal_scroll_mode == 1, inserting the characters with
917              term_IC or term_ic will screw up the screen because of the
918              invisible characters.  We need to just draw them. */
919           if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 ||
920                         lendiff <= visible_length || !current_invis_chars))
921             {
922               insert_some_chars (nfd, lendiff);
923               _rl_last_c_pos += lendiff;
924             }
925           else if (*ols == 0)
926             {
927               /* At the end of a line the characters do not have to
928                  be "inserted".  They can just be placed on the screen. */
929               /* However, this screws up the rest of this block, which
930                  assumes you've done the insert because you can. */
931               _rl_output_some_chars (nfd, lendiff);
932               _rl_last_c_pos += lendiff;
933             }
934           else
935             {
936               /* We have horizontal scrolling and we are not inserting at
937                  the end.  We have invisible characters in this line.  This
938                  is a dumb update. */
939               _rl_output_some_chars (nfd, temp);
940               _rl_last_c_pos += temp;
941               return;
942             }
943           /* Copy (new) chars to screen from first diff to last match. */
944           temp = nls - nfd;
945           if ((temp - lendiff) > 0)
946             {
947               _rl_output_some_chars (nfd + lendiff, temp - lendiff);
948               _rl_last_c_pos += temp - lendiff;
949             }
950         }
951       else
952         {
953           /* cannot insert chars, write to EOL */
954           _rl_output_some_chars (nfd, temp);
955           _rl_last_c_pos += temp;
956         }
957     }
958   else                          /* Delete characters from line. */
959     {
960       /* If possible and inexpensive to use terminal deletion, then do so. */
961       if (term_dc && (2 * temp) >= -lendiff)
962         {
963           /* If all we're doing is erasing the invisible characters in the
964              prompt string, don't bother.  It screws up the assumptions
965              about what's on the screen. */
966           if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
967               -lendiff == visible_wrap_offset)
968             lendiff = 0;
969
970           if (lendiff)
971             delete_chars (-lendiff); /* delete (diff) characters */
972
973           /* Copy (new) chars to screen from first diff to last match */
974           temp = nls - nfd;
975           if (temp > 0)
976             {
977               _rl_output_some_chars (nfd, temp);
978               _rl_last_c_pos += temp;
979             }
980         }
981       /* Otherwise, print over the existing material. */
982       else
983         {
984           if (temp > 0)
985             {
986               _rl_output_some_chars (nfd, temp);
987               _rl_last_c_pos += temp;
988             }
989           lendiff = (oe - old) - (ne - new);
990           if (_rl_term_autowrap && current_line < inv_botlin)
991             space_to_eol (lendiff);
992           else
993             _rl_clear_to_eol (lendiff);
994         }
995     }
996 }
997
998 /* Tell the update routines that we have moved onto a new (empty) line. */
999 int
1000 rl_on_new_line ()
1001 {
1002   if (visible_line)
1003     visible_line[0] = '\0';
1004
1005   _rl_last_c_pos = _rl_last_v_pos = 0;
1006   _rl_vis_botlin = last_lmargin = 0;
1007   if (vis_lbreaks)
1008     vis_lbreaks[0] = vis_lbreaks[1] = 0;
1009   visible_wrap_offset = 0;
1010   return 0;
1011 }
1012
1013 /* Actually update the display, period. */
1014 int
1015 rl_forced_update_display ()
1016 {
1017   if (visible_line)
1018     {
1019       register char *temp = visible_line;
1020
1021       while (*temp)
1022         *temp++ = '\0';
1023     }
1024   rl_on_new_line ();
1025   forced_display++;
1026   (*rl_redisplay_function) ();
1027   return 0;
1028 }
1029
1030 /* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
1031    DATA is the contents of the screen line of interest; i.e., where
1032    the movement is being done. */
1033 void
1034 _rl_move_cursor_relative (new, data)
1035      int new;
1036      char *data;
1037 {
1038   register int i;
1039
1040   /* If we don't have to do anything, then return. */
1041   if (_rl_last_c_pos == new) return;
1042
1043   /* It may be faster to output a CR, and then move forwards instead
1044      of moving backwards. */
1045   /* i == current physical cursor position. */
1046   i = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
1047   if (new == 0 || CR_FASTER (new, _rl_last_c_pos) ||
1048       (_rl_term_autowrap && i == screenwidth))
1049     {
1050 #if defined (__MSDOS__)
1051       putc ('\r', rl_outstream);
1052 #else
1053       tputs (term_cr, 1, _rl_output_character_function);
1054 #endif /* !__MSDOS__ */
1055       _rl_last_c_pos = 0;
1056     }
1057
1058   if (_rl_last_c_pos < new)
1059     {
1060       /* Move the cursor forward.  We do it by printing the command
1061          to move the cursor forward if there is one, else print that
1062          portion of the output buffer again.  Which is cheaper? */
1063
1064       /* The above comment is left here for posterity.  It is faster
1065          to print one character (non-control) than to print a control
1066          sequence telling the terminal to move forward one character.
1067          That kind of control is for people who don't know what the
1068          data is underneath the cursor. */
1069 #if defined (HACK_TERMCAP_MOTION)
1070       extern char *term_forward_char;
1071
1072       if (term_forward_char)
1073         for (i = _rl_last_c_pos; i < new; i++)
1074           tputs (term_forward_char, 1, _rl_output_character_function);
1075       else
1076         for (i = _rl_last_c_pos; i < new; i++)
1077           putc (data[i], rl_outstream);
1078 #else
1079       for (i = _rl_last_c_pos; i < new; i++)
1080         putc (data[i], rl_outstream);
1081 #endif /* HACK_TERMCAP_MOTION */
1082     }
1083   else if (_rl_last_c_pos != new)
1084     _rl_backspace (_rl_last_c_pos - new);
1085   _rl_last_c_pos = new;
1086 }
1087
1088 /* PWP: move the cursor up or down. */
1089 void
1090 _rl_move_vert (to)
1091      int to;
1092 {
1093   register int delta, i;
1094
1095   if (_rl_last_v_pos == to || to > screenheight)
1096     return;
1097
1098 #if defined (__GO32__)
1099   {
1100     int row, col;
1101
1102     ScreenGetCursor (&row, &col);
1103     ScreenSetCursor ((row + to - _rl_last_v_pos), col);
1104   }
1105 #else /* !__GO32__ */
1106
1107   if ((delta = to - _rl_last_v_pos) > 0)
1108     {
1109       for (i = 0; i < delta; i++)
1110         putc ('\n', rl_outstream);
1111       tputs (term_cr, 1, _rl_output_character_function);
1112       _rl_last_c_pos = 0;
1113     }
1114   else
1115     {                   /* delta < 0 */
1116       if (term_up && *term_up)
1117         for (i = 0; i < -delta; i++)
1118           tputs (term_up, 1, _rl_output_character_function);
1119     }
1120 #endif /* !__GO32__ */
1121   _rl_last_v_pos = to;          /* Now TO is here */
1122 }
1123
1124 /* Physically print C on rl_outstream.  This is for functions which know
1125    how to optimize the display.  Return the number of characters output. */
1126 int
1127 rl_show_char (c)
1128      int c;
1129 {
1130   int n = 1;
1131   if (META_CHAR (c) && (_rl_output_meta_chars == 0))
1132     {
1133       fprintf (rl_outstream, "M-");
1134       n += 2;
1135       c = UNMETA (c);
1136     }
1137
1138 #if defined (DISPLAY_TABS)
1139   if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
1140 #else
1141   if (CTRL_CHAR (c) || c == RUBOUT)
1142 #endif /* !DISPLAY_TABS */
1143     {
1144       fprintf (rl_outstream, "C-");
1145       n += 2;
1146       c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
1147     }
1148
1149   putc (c, rl_outstream);
1150   fflush (rl_outstream);
1151   return n;
1152 }
1153
1154 int
1155 rl_character_len (c, pos)
1156      register int c, pos;
1157 {
1158   unsigned char uc;
1159
1160   uc = (unsigned char)c;
1161
1162   if (META_CHAR (uc))
1163     return ((_rl_output_meta_chars == 0) ? 4 : 1);
1164
1165   if (uc == '\t')
1166     {
1167 #if defined (DISPLAY_TABS)
1168       return (((pos | 7) + 1) - pos);
1169 #else
1170       return (2);
1171 #endif /* !DISPLAY_TABS */
1172     }
1173
1174   if (CTRL_CHAR (c) || c == RUBOUT)
1175     return (2);
1176
1177   return ((isprint (uc)) ? 1 : 2);
1178 }
1179
1180 /* How to print things in the "echo-area".  The prompt is treated as a
1181    mini-modeline. */
1182
1183 #if defined (USE_VARARGS)
1184 int
1185 #if defined (PREFER_STDARG)
1186 rl_message (const char *format, ...)
1187 #else
1188 rl_message (va_alist)
1189      va_dcl
1190 #endif
1191 {
1192   va_list args;
1193 #if defined (PREFER_VARARGS)
1194   char *format;
1195 #endif
1196
1197 #if defined (PREFER_STDARG)
1198   va_start (args, format);
1199 #else
1200   va_start (args);
1201   format = va_arg (args, char *);
1202 #endif
1203
1204   vsprintf (msg_buf, format, args);
1205   va_end (args);
1206
1207   rl_display_prompt = msg_buf;
1208   (*rl_redisplay_function) ();
1209   return 0;
1210 }
1211 #else /* !USE_VARARGS */
1212 int
1213 rl_message (format, arg1, arg2)
1214      char *format;
1215 {
1216   sprintf (msg_buf, format, arg1, arg2);
1217   rl_display_prompt = msg_buf;
1218   (*rl_redisplay_function) ();
1219   return 0;
1220 }
1221 #endif /* !USE_VARARGS */
1222
1223 /* How to clear things from the "echo-area". */
1224 int
1225 rl_clear_message ()
1226 {
1227   rl_display_prompt = rl_prompt;
1228   (*rl_redisplay_function) ();
1229   return 0;
1230 }
1231
1232 int
1233 rl_reset_line_state ()
1234 {
1235   rl_on_new_line ();
1236
1237   rl_display_prompt = rl_prompt ? rl_prompt : "";
1238   forced_display = 1;
1239   return 0;
1240 }
1241
1242 static char *saved_local_prompt;
1243 static char *saved_local_prefix;
1244 static int saved_last_invisible;
1245 static int saved_visible_length;
1246
1247 void
1248 _rl_save_prompt ()
1249 {
1250   saved_local_prompt = local_prompt;
1251   saved_local_prefix = local_prompt_prefix;
1252   saved_last_invisible = last_invisible;
1253   saved_visible_length = visible_length;
1254
1255   local_prompt = local_prompt_prefix = (char *)0;
1256   last_invisible = visible_length = 0;
1257 }
1258
1259 void
1260 _rl_restore_prompt ()
1261 {
1262   if (local_prompt)
1263     free (local_prompt);
1264   if (local_prompt_prefix)
1265     free (local_prompt_prefix);
1266
1267   local_prompt = saved_local_prompt;
1268   local_prompt_prefix = saved_local_prefix;
1269   last_invisible = saved_last_invisible;
1270   visible_length = saved_visible_length;
1271 }
1272
1273 char *
1274 _rl_make_prompt_for_search (pchar)
1275      int pchar;
1276 {
1277   int len;
1278   char *pmt;
1279
1280   _rl_save_prompt ();
1281
1282   if (saved_local_prompt == 0)
1283     {
1284       len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
1285       pmt = xmalloc (len + 2);
1286       if (len)
1287         strcpy (pmt, rl_prompt);
1288       pmt[len] = pchar;
1289       pmt[len+1] = '\0';
1290     }
1291   else
1292     {
1293       len = *saved_local_prompt ? strlen (saved_local_prompt) : 0;
1294       pmt = xmalloc (len + 2);
1295       if (len)
1296         strcpy (pmt, saved_local_prompt);
1297       pmt[len] = pchar;
1298       pmt[len+1] = '\0';
1299       local_prompt = savestring (pmt);
1300       last_invisible = saved_last_invisible;
1301       visible_length = saved_visible_length + 1;
1302     }
1303   return pmt;
1304 }
1305
1306 /* Quick redisplay hack when erasing characters at the end of the line. */
1307 void
1308 _rl_erase_at_end_of_line (l)
1309      int l;
1310 {
1311   register int i;
1312
1313   _rl_backspace (l);
1314   for (i = 0; i < l; i++)
1315     putc (' ', rl_outstream);
1316   _rl_backspace (l);
1317   for (i = 0; i < l; i++)
1318     visible_line[--_rl_last_c_pos] = '\0';
1319   rl_display_fixed++;
1320 }
1321
1322 /* Clear to the end of the line.  COUNT is the minimum
1323    number of character spaces to clear, */
1324 void
1325 _rl_clear_to_eol (count)
1326      int count;
1327 {
1328 #if !defined (__GO32__)
1329   if (term_clreol)
1330     tputs (term_clreol, 1, _rl_output_character_function);
1331   else if (count)
1332 #endif /* !__GO32__ */
1333     space_to_eol (count);
1334 }
1335
1336 /* Clear to the end of the line using spaces.  COUNT is the minimum
1337    number of character spaces to clear, */
1338 static void
1339 space_to_eol (count)
1340      int count;
1341 {
1342   register int i;
1343
1344   for (i = 0; i < count; i++)
1345    putc (' ', rl_outstream);
1346
1347   _rl_last_c_pos += count;
1348 }
1349
1350 void
1351 _rl_clear_screen ()
1352 {
1353 #if !defined (__GO32__)
1354   if (term_clrpag)
1355     tputs (term_clrpag, 1, _rl_output_character_function);
1356   else
1357 #endif /* !__GO32__ */
1358     crlf ();
1359 }
1360
1361 /* Insert COUNT characters from STRING to the output stream. */
1362 static void
1363 insert_some_chars (string, count)
1364      char *string;
1365      int count;
1366 {
1367 #if defined (__GO32__)
1368   int row, col, width;
1369   char *row_start;
1370
1371   ScreenGetCursor (&row, &col);
1372   width = ScreenCols ();
1373   row_start = ScreenPrimary + (row * width);
1374
1375   memcpy (row_start + col + count, row_start + col, width - col - count);
1376
1377   /* Place the text on the screen. */
1378   _rl_output_some_chars (string, count);
1379 #else /* !_GO32 */
1380
1381   /* If IC is defined, then we do not have to "enter" insert mode. */
1382   if (term_IC)
1383     {
1384       char *buffer;
1385       buffer = tgoto (term_IC, 0, count);
1386       tputs (buffer, 1, _rl_output_character_function);
1387       _rl_output_some_chars (string, count);
1388     }
1389   else
1390     {
1391       register int i;
1392
1393       /* If we have to turn on insert-mode, then do so. */
1394       if (term_im && *term_im)
1395         tputs (term_im, 1, _rl_output_character_function);
1396
1397       /* If there is a special command for inserting characters, then
1398          use that first to open up the space. */
1399       if (term_ic && *term_ic)
1400         {
1401           for (i = count; i--; )
1402             tputs (term_ic, 1, _rl_output_character_function);
1403         }
1404
1405       /* Print the text. */
1406       _rl_output_some_chars (string, count);
1407
1408       /* If there is a string to turn off insert mode, we had best use
1409          it now. */
1410       if (term_ei && *term_ei)
1411         tputs (term_ei, 1, _rl_output_character_function);
1412     }
1413 #endif /* !__GO32__ */
1414 }
1415
1416 /* Delete COUNT characters from the display line. */
1417 static void
1418 delete_chars (count)
1419      int count;
1420 {
1421 #if defined (__GO32__)
1422   int row, col, width;
1423   char *row_start;
1424
1425   ScreenGetCursor (&row, &col);
1426   width = ScreenCols ();
1427   row_start = ScreenPrimary + (row * width);
1428
1429   memcpy (row_start + col, row_start + col + count, width - col - count);
1430   memset (row_start + width - count, 0, count * 2);
1431 #else /* !_GO32 */
1432
1433   if (count > screenwidth)      /* XXX */
1434     return;
1435
1436   if (term_DC && *term_DC)
1437     {
1438       char *buffer;
1439       buffer = tgoto (term_DC, count, count);
1440       tputs (buffer, count, _rl_output_character_function);
1441     }
1442   else
1443     {
1444       if (term_dc && *term_dc)
1445         while (count--)
1446           tputs (term_dc, 1, _rl_output_character_function);
1447     }
1448 #endif /* !__GO32__ */
1449 }
1450
1451 void
1452 _rl_update_final ()
1453 {
1454   int full_lines;
1455
1456   full_lines = 0;
1457   /* If the cursor is the only thing on an otherwise-blank last line,
1458      compensate so we don't print an extra CRLF. */
1459   if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
1460         visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
1461     {
1462       _rl_vis_botlin--;
1463       full_lines = 1;
1464     }
1465   _rl_move_vert (_rl_vis_botlin);
1466   /* If we've wrapped lines, remove the final xterm line-wrap flag. */
1467   if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == screenwidth))
1468     {
1469       char *last_line;
1470       last_line = &visible_line[inv_lbreaks[_rl_vis_botlin]];
1471       _rl_move_cursor_relative (screenwidth - 1, last_line);
1472       _rl_clear_to_eol (0);
1473       putc (last_line[screenwidth - 1], rl_outstream);
1474     }
1475   _rl_vis_botlin = 0;
1476   crlf ();
1477   fflush (rl_outstream);
1478   rl_display_fixed++;
1479 }
1480
1481 /* Move to the start of the current line. */
1482 static void
1483 cr ()
1484 {
1485   if (term_cr)
1486     {
1487       tputs (term_cr, 1, _rl_output_character_function);
1488       _rl_last_c_pos = 0;
1489     }
1490 }
1491
1492 /* Redisplay the current line after a SIGWINCH is received. */
1493 void
1494 _rl_redisplay_after_sigwinch ()
1495 {
1496   char *t, *oldp, *oldl, *oldlprefix;
1497
1498   /* Clear the current line and put the cursor at column 0.  Make sure
1499      the right thing happens if we have wrapped to a new screen line. */
1500   if (term_cr)
1501     {
1502       tputs (term_cr, 1, _rl_output_character_function);
1503       _rl_last_c_pos = 0;
1504       if (term_clreol)
1505         tputs (term_clreol, 1, _rl_output_character_function);
1506       else
1507         {
1508           space_to_eol (screenwidth);
1509           tputs (term_cr, 1, _rl_output_character_function);
1510         }
1511       if (_rl_last_v_pos > 0)
1512         _rl_move_vert (0);
1513     }
1514   else
1515     crlf ();
1516
1517   /* Redraw only the last line of a multi-line prompt. */
1518   t = strrchr (rl_display_prompt, '\n');
1519   if (t)
1520     {
1521       oldp = rl_display_prompt;
1522       oldl = local_prompt;
1523       oldlprefix = local_prompt_prefix;
1524       rl_display_prompt = ++t;
1525       local_prompt = local_prompt_prefix = (char *)NULL;
1526       rl_forced_update_display ();
1527       rl_display_prompt = oldp;
1528       local_prompt = oldl;
1529       local_prompt_prefix = oldlprefix;
1530     }
1531   else
1532     rl_forced_update_display ();
1533 }
1534
1535 void
1536 _rl_clean_up_for_exit ()
1537 {
1538   if (readline_echoing_p)
1539     {
1540       _rl_move_vert (_rl_vis_botlin);
1541       _rl_vis_botlin = 0;
1542       fflush (rl_outstream);
1543       rl_restart_output ();
1544     }
1545 }