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