OSDN Git Service

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