source: trunk/third/readline/display.c @ 12992

Revision 12992, 43.6 KB checked in by kcr, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12991, which included commits to RCS files with non-trunk default branches.
Line 
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__)
60extern char *strchr (), *strrchr ();
61#endif /* !strchr && !__STDC__ */
62
63/* Global and pseudo-global variables and functions
64   imported from readline.c. */
65extern char *rl_prompt;
66extern int readline_echoing_p;
67
68extern int _rl_output_meta_chars;
69extern int _rl_horizontal_scroll_mode;
70extern int _rl_mark_modified_lines;
71extern int _rl_prefer_visible_bell;
72
73/* Variables and functions imported from terminal.c */
74extern void _rl_output_some_chars ();
75#ifdef _MINIX
76extern void _rl_output_character_function ();
77#else
78extern int _rl_output_character_function ();
79#endif
80extern int _rl_backspace ();
81
82extern char *term_clreol, *term_clrpag;
83extern char *term_im, *term_ic,  *term_ei, *term_DC;
84extern char *term_up, *term_dc, *term_cr, *term_IC;
85extern int screenheight, screenwidth, screenchars;
86extern int terminal_can_insert, _rl_term_autowrap;
87
88/* Pseudo-global functions (local to the readline library) exported
89   by this file. */
90void _rl_move_cursor_relative (), _rl_output_some_chars ();
91void _rl_move_vert ();
92void _rl_clear_to_eol (), _rl_clear_screen ();
93
94static void update_line (), space_to_eol ();
95static void delete_chars (), insert_some_chars ();
96static void cr ();
97
98static int *inv_lbreaks, *vis_lbreaks;
99
100extern 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. */
134VFunction *rl_redisplay_function = rl_redisplay;
135
136/* Global variables declared here. */
137/* What YOU turn on when you have handled all redisplay yourself. */
138int rl_display_fixed = 0;
139
140int _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. */
144char *rl_display_prompt = (char *)NULL;
145
146/* Pseudo-global variables declared here. */
147/* The visible cursor position.  If you print some text, adjust this. */
148int _rl_last_c_pos = 0;
149int _rl_last_v_pos = 0;
150
151/* Number of lines currently on screen minus 1. */
152int _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. */
157static 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. */
161static char *visible_line = (char *)NULL;
162static char *invisible_line = (char *)NULL;
163
164/* A buffer for `modeline' messages. */
165static char msg_buf[128];
166
167/* Non-zero forces the redisplay even if we thought it was unnecessary. */
168static int forced_display;
169
170/* Default and initial buffer size.  Can grow. */
171static int line_size = 1024;
172
173static char *local_prompt, *local_prompt_prefix;
174static int visible_length, prefix_length;
175
176/* The number of invisible characters in the line currently being
177   displayed on the screen. */
178static int visible_wrap_offset;
179
180/* static so it can be shared between rl_redisplay and update_line */
181static int wrap_offset;
182
183/* The index of the last invisible_character in the prompt string. */
184static 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. */
188static 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
202static char *
203expand_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 */
270int
271rl_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. */
311void
312rl_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 (term_cr)
655                tputs (term_cr, 1, _rl_output_character_function);
656              _rl_output_some_chars (local_prompt, nleft);
657              _rl_last_c_pos = nleft;
658            }
659
660          /* Where on that line?  And where does that line start
661             in the buffer? */
662          pos = inv_lbreaks[cursor_linenum];
663          /* nleft == number of characters in the line buffer between the
664             start of the line and the cursor position. */
665          nleft = c_pos - pos;
666
667          /* Since _rl_backspace() doesn't know about invisible characters in the
668             prompt, and there's no good way to tell it, we compensate for
669             those characters here and call _rl_backspace() directly. */
670          if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
671            {
672              _rl_backspace (_rl_last_c_pos - nleft);
673              _rl_last_c_pos = nleft;
674            }
675
676          if (nleft != _rl_last_c_pos)
677            _rl_move_cursor_relative (nleft, &invisible_line[pos]);
678        }
679    }
680  else                          /* Do horizontal scrolling. */
681    {
682#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
683      int lmargin, ndisp, nleft, phys_c_pos, t;
684
685      /* Always at top line. */
686      _rl_last_v_pos = 0;
687
688      /* Compute where in the buffer the displayed line should start.  This
689         will be LMARGIN. */
690
691      /* The number of characters that will be displayed before the cursor. */
692      ndisp = c_pos - wrap_offset;
693      nleft  = visible_length + wrap_offset;
694      /* Where the new cursor position will be on the screen.  This can be
695         longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
696      phys_c_pos = c_pos - (last_lmargin ? last_lmargin : wrap_offset);
697      t = screenwidth / 3;
698
699      /* If the number of characters had already exceeded the screenwidth,
700         last_lmargin will be > 0. */
701
702      /* If the number of characters to be displayed is more than the screen
703         width, compute the starting offset so that the cursor is about
704         two-thirds of the way across the screen. */
705      if (phys_c_pos > screenwidth - 2)
706        {
707          lmargin = c_pos - (2 * t);
708          if (lmargin < 0)
709            lmargin = 0;
710          /* If the left margin would be in the middle of a prompt with
711             invisible characters, don't display the prompt at all. */
712          if (wrap_offset && lmargin > 0 && lmargin < nleft)
713            lmargin = nleft;
714        }
715      else if (ndisp < screenwidth - 2)         /* XXX - was -1 */
716        lmargin = 0;
717      else if (phys_c_pos < 1)
718        {
719          /* If we are moving back towards the beginning of the line and
720             the last margin is no longer correct, compute a new one. */
721          lmargin = ((c_pos - 1) / t) * t;      /* XXX */
722          if (wrap_offset && lmargin > 0 && lmargin < nleft)
723            lmargin = nleft;
724        }
725      else
726        lmargin = last_lmargin;
727
728      /* If the first character on the screen isn't the first character
729         in the display line, indicate this with a special character. */
730      if (lmargin > 0)
731        line[lmargin] = '<';
732
733      /* If SCREENWIDTH characters starting at LMARGIN do not encompass
734         the whole line, indicate that with a special character at the
735         right edge of the screen.  If LMARGIN is 0, we need to take the
736         wrap offset into account. */
737      t = lmargin + M_OFFSET (lmargin, wrap_offset) + screenwidth;
738      if (t < out)
739        line[t - 1] = '>';
740
741      if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
742        {
743          forced_display = 0;
744          update_line (&visible_line[last_lmargin],
745                       &invisible_line[lmargin],
746                       0,
747                       screenwidth + visible_wrap_offset,
748                       screenwidth + (lmargin ? 0 : wrap_offset),
749                       0);
750
751          /* If the visible new line is shorter than the old, but the number
752             of invisible characters is greater, and we are at the end of
753             the new line, we need to clear to eol. */
754          t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
755          if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
756              (_rl_last_c_pos == out) &&
757              t < visible_first_line_len)
758            {
759              nleft = screenwidth - t;
760              _rl_clear_to_eol (nleft);
761            }
762          visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
763          if (visible_first_line_len > screenwidth)
764            visible_first_line_len = screenwidth;
765
766          _rl_move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
767          last_lmargin = lmargin;
768        }
769    }
770  fflush (rl_outstream);
771
772  /* Swap visible and non-visible lines. */
773  {
774    char *temp = visible_line;
775    int *itemp = vis_lbreaks;
776    visible_line = invisible_line;
777    invisible_line = temp;
778    vis_lbreaks = inv_lbreaks;
779    inv_lbreaks = itemp;
780    rl_display_fixed = 0;
781    /* If we are displaying on a single line, and last_lmargin is > 0, we
782       are not displaying any invisible characters, so set visible_wrap_offset
783       to 0. */
784    if (_rl_horizontal_scroll_mode && last_lmargin)
785      visible_wrap_offset = 0;
786    else
787      visible_wrap_offset = wrap_offset;
788  }
789}
790
791/* PWP: update_line() is based on finding the middle difference of each
792   line on the screen; vis:
793
794                             /old first difference
795        /beginning of line   |        /old last same       /old EOL
796        v                    v        v             v
797old:    eddie> Oh, my little gruntle-buggy is to me, as lurgid as
798new:    eddie> Oh, my little buggy says to me, as lurgid as
799        ^                    ^  ^                          ^
800        \beginning of line   |  \new last same     \new end of line
801                             \new first difference
802
803   All are character pointers for the sake of speed.  Special cases for
804   no differences, as well as for end of line additions must be handled.
805
806   Could be made even smarter, but this works well enough */
807static void
808update_line (old, new, current_line, omax, nmax, inv_botlin)
809     register char *old, *new;
810     int current_line, omax, nmax, inv_botlin;
811{
812  register char *ofd, *ols, *oe, *nfd, *nls, *ne;
813  int temp, lendiff, wsatend, od, nd;
814  int current_invis_chars;
815
816  /* If we're at the right edge of a terminal that supports xn, we're
817     ready to wrap around, so do so.  This fixes problems with knowing
818     the exact cursor position and cut-and-paste with certain terminal
819     emulators.  In this calculation, TEMP is the physical screen
820     position of the cursor. */
821  temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
822  if (temp == screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
823      && _rl_last_v_pos == current_line - 1)
824    {
825      if (new[0])
826        putc (new[0], rl_outstream);
827      else
828        putc (' ', rl_outstream);
829      _rl_last_c_pos = 1;               /* XXX */
830      _rl_last_v_pos++;
831      if (old[0] && new[0])
832        old[0] = new[0];
833    }
834     
835  /* Find first difference. */
836  for (ofd = old, nfd = new;
837       (ofd - old < omax) && *ofd && (*ofd == *nfd);
838       ofd++, nfd++)
839    ;
840
841  /* Move to the end of the screen line.  ND and OD are used to keep track
842     of the distance between ne and new and oe and old, respectively, to
843     move a subtraction out of each loop. */
844  for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
845  for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
846
847  /* If no difference, continue to next line. */
848  if (ofd == oe && nfd == ne)
849    return;
850
851  wsatend = 1;                  /* flag for trailing whitespace */
852  ols = oe - 1;                 /* find last same */
853  nls = ne - 1;
854  while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
855    {
856      if (*ols != ' ')
857        wsatend = 0;
858      ols--;
859      nls--;
860    }
861
862  if (wsatend)
863    {
864      ols = oe;
865      nls = ne;
866    }
867  else if (*ols != *nls)
868    {
869      if (*ols)                 /* don't step past the NUL */
870        ols++;
871      if (*nls)
872        nls++;
873    }
874
875  /* count of invisible characters in the current invisible line. */
876  current_invis_chars = W_OFFSET (current_line, wrap_offset);
877  if (_rl_last_v_pos != current_line)
878    {
879      _rl_move_vert (current_line);
880      if (current_line == 0 && visible_wrap_offset)
881        _rl_last_c_pos += visible_wrap_offset;
882    }
883
884  /* If this is the first line and there are invisible characters in the
885     prompt string, and the prompt string has not changed, and the current
886     cursor position is before the last invisible character in the prompt,
887     and the index of the character to move to is past the end of the prompt
888     string, then redraw the entire prompt string.  We can only do this
889     reliably if the terminal supports a `cr' capability.
890
891     This is not an efficiency hack -- there is a problem with redrawing
892     portions of the prompt string if they contain terminal escape
893     sequences (like drawing the `unbold' sequence without a corresponding
894     `bold') that manifests itself on certain terminals. */
895
896  lendiff = local_prompt ? strlen (local_prompt) : 0;
897  od = ofd - old;       /* index of first difference in visible line */
898  if (current_line == 0 && !_rl_horizontal_scroll_mode &&
899      term_cr && lendiff > visible_length && _rl_last_c_pos > 0 &&
900      od > lendiff && _rl_last_c_pos < last_invisible)
901    {
902      tputs (term_cr, 1, _rl_output_character_function);
903      _rl_output_some_chars (local_prompt, lendiff);
904      _rl_last_c_pos = lendiff;
905    }
906
907  _rl_move_cursor_relative (od, old);
908
909  /* if (len (new) > len (old)) */
910  lendiff = (nls - nfd) - (ols - ofd);
911
912  /* If we are changing the number of invisible characters in a line, and
913     the spot of first difference is before the end of the invisible chars,
914     lendiff needs to be adjusted. */
915  if (current_line == 0 && !_rl_horizontal_scroll_mode &&
916      current_invis_chars != visible_wrap_offset)
917    lendiff += visible_wrap_offset - current_invis_chars;
918
919  /* Insert (diff (len (old), len (new)) ch. */
920  temp = ne - nfd;
921  if (lendiff > 0)
922    {
923      /* Non-zero if we're increasing the number of lines. */
924      int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
925      /* Sometimes it is cheaper to print the characters rather than
926         use the terminal's capabilities.  If we're growing the number
927         of lines, make sure we actually cause the new line to wrap
928         around on auto-wrapping terminals. */
929      if (terminal_can_insert && ((2 * temp) >= lendiff || term_IC) && (!_rl_term_autowrap || !gl))
930        {
931          /* If lendiff > visible_length and _rl_last_c_pos == 0 and
932             _rl_horizontal_scroll_mode == 1, inserting the characters with
933             term_IC or term_ic will screw up the screen because of the
934             invisible characters.  We need to just draw them. */
935          if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 ||
936                        lendiff <= visible_length || !current_invis_chars))
937            {
938              insert_some_chars (nfd, lendiff);
939              _rl_last_c_pos += lendiff;
940            }
941          else if (*ols == 0)
942            {
943              /* At the end of a line the characters do not have to
944                 be "inserted".  They can just be placed on the screen. */
945              /* However, this screws up the rest of this block, which
946                 assumes you've done the insert because you can. */
947              _rl_output_some_chars (nfd, lendiff);
948              _rl_last_c_pos += lendiff;
949            }
950          else
951            {
952              /* We have horizontal scrolling and we are not inserting at
953                 the end.  We have invisible characters in this line.  This
954                 is a dumb update. */
955              _rl_output_some_chars (nfd, temp);
956              _rl_last_c_pos += temp;
957              return;
958            }
959          /* Copy (new) chars to screen from first diff to last match. */
960          temp = nls - nfd;
961          if ((temp - lendiff) > 0)
962            {
963              _rl_output_some_chars (nfd + lendiff, temp - lendiff);
964              _rl_last_c_pos += temp - lendiff;
965            }
966        }
967      else
968        {
969          /* cannot insert chars, write to EOL */
970          _rl_output_some_chars (nfd, temp);
971          _rl_last_c_pos += temp;
972        }
973    }
974  else                          /* Delete characters from line. */
975    {
976      /* If possible and inexpensive to use terminal deletion, then do so. */
977      if (term_dc && (2 * temp) >= -lendiff)
978        {
979          /* If all we're doing is erasing the invisible characters in the
980             prompt string, don't bother.  It screws up the assumptions
981             about what's on the screen. */
982          if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
983              -lendiff == visible_wrap_offset)
984            lendiff = 0;
985
986          if (lendiff)
987            delete_chars (-lendiff); /* delete (diff) characters */
988
989          /* Copy (new) chars to screen from first diff to last match */
990          temp = nls - nfd;
991          if (temp > 0)
992            {
993              _rl_output_some_chars (nfd, temp);
994              _rl_last_c_pos += temp;
995            }
996        }
997      /* Otherwise, print over the existing material. */
998      else
999        {
1000          if (temp > 0)
1001            {
1002              _rl_output_some_chars (nfd, temp);
1003              _rl_last_c_pos += temp;
1004            }
1005          lendiff = (oe - old) - (ne - new);
1006          if (lendiff)
1007            {     
1008              if (_rl_term_autowrap && current_line < inv_botlin)
1009                space_to_eol (lendiff);
1010              else
1011                _rl_clear_to_eol (lendiff);
1012            }
1013        }
1014    }
1015}
1016
1017/* Tell the update routines that we have moved onto a new (empty) line. */
1018int
1019rl_on_new_line ()
1020{
1021  if (visible_line)
1022    visible_line[0] = '\0';
1023
1024  _rl_last_c_pos = _rl_last_v_pos = 0;
1025  _rl_vis_botlin = last_lmargin = 0;
1026  if (vis_lbreaks)
1027    vis_lbreaks[0] = vis_lbreaks[1] = 0;
1028  visible_wrap_offset = 0;
1029  return 0;
1030}
1031
1032/* Actually update the display, period. */
1033int
1034rl_forced_update_display ()
1035{
1036  if (visible_line)
1037    {
1038      register char *temp = visible_line;
1039
1040      while (*temp)
1041        *temp++ = '\0';
1042    }
1043  rl_on_new_line ();
1044  forced_display++;
1045  (*rl_redisplay_function) ();
1046  return 0;
1047}
1048
1049/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
1050   DATA is the contents of the screen line of interest; i.e., where
1051   the movement is being done. */
1052void
1053_rl_move_cursor_relative (new, data)
1054     int new;
1055     char *data;
1056{
1057  register int i;
1058
1059  /* If we don't have to do anything, then return. */
1060  if (_rl_last_c_pos == new) return;
1061
1062  /* It may be faster to output a CR, and then move forwards instead
1063     of moving backwards. */
1064  /* i == current physical cursor position. */
1065  i = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
1066  if (new == 0 || CR_FASTER (new, _rl_last_c_pos) ||
1067      (_rl_term_autowrap && i == screenwidth))
1068    {
1069#if defined (__MSDOS__)
1070      putc ('\r', rl_outstream);
1071#else
1072      tputs (term_cr, 1, _rl_output_character_function);
1073#endif /* !__MSDOS__ */
1074      _rl_last_c_pos = 0;
1075    }
1076
1077  if (_rl_last_c_pos < new)
1078    {
1079      /* Move the cursor forward.  We do it by printing the command
1080         to move the cursor forward if there is one, else print that
1081         portion of the output buffer again.  Which is cheaper? */
1082
1083      /* The above comment is left here for posterity.  It is faster
1084         to print one character (non-control) than to print a control
1085         sequence telling the terminal to move forward one character.
1086         That kind of control is for people who don't know what the
1087         data is underneath the cursor. */
1088#if defined (HACK_TERMCAP_MOTION)
1089      extern char *term_forward_char;
1090
1091      if (term_forward_char)
1092        for (i = _rl_last_c_pos; i < new; i++)
1093          tputs (term_forward_char, 1, _rl_output_character_function);
1094      else
1095        for (i = _rl_last_c_pos; i < new; i++)
1096          putc (data[i], rl_outstream);
1097#else
1098      for (i = _rl_last_c_pos; i < new; i++)
1099        putc (data[i], rl_outstream);
1100#endif /* HACK_TERMCAP_MOTION */
1101    }
1102  else if (_rl_last_c_pos > new)
1103    _rl_backspace (_rl_last_c_pos - new);
1104  _rl_last_c_pos = new;
1105}
1106
1107/* PWP: move the cursor up or down. */
1108void
1109_rl_move_vert (to)
1110     int to;
1111{
1112  register int delta, i;
1113
1114  if (_rl_last_v_pos == to || to > screenheight)
1115    return;
1116
1117#if defined (__GO32__)
1118  {
1119    int row, col;
1120
1121    ScreenGetCursor (&row, &col);
1122    ScreenSetCursor ((row + to - _rl_last_v_pos), col);
1123  }
1124#else /* !__GO32__ */
1125
1126  if ((delta = to - _rl_last_v_pos) > 0)
1127    {
1128      for (i = 0; i < delta; i++)
1129        putc ('\n', rl_outstream);
1130      tputs (term_cr, 1, _rl_output_character_function);
1131      _rl_last_c_pos = 0;
1132    }
1133  else
1134    {                   /* delta < 0 */
1135      if (term_up && *term_up)
1136        for (i = 0; i < -delta; i++)
1137          tputs (term_up, 1, _rl_output_character_function);
1138    }
1139#endif /* !__GO32__ */
1140  _rl_last_v_pos = to;          /* Now TO is here */
1141}
1142
1143/* Physically print C on rl_outstream.  This is for functions which know
1144   how to optimize the display.  Return the number of characters output. */
1145int
1146rl_show_char (c)
1147     int c;
1148{
1149  int n = 1;
1150  if (META_CHAR (c) && (_rl_output_meta_chars == 0))
1151    {
1152      fprintf (rl_outstream, "M-");
1153      n += 2;
1154      c = UNMETA (c);
1155    }
1156
1157#if defined (DISPLAY_TABS)
1158  if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
1159#else
1160  if (CTRL_CHAR (c) || c == RUBOUT)
1161#endif /* !DISPLAY_TABS */
1162    {
1163      fprintf (rl_outstream, "C-");
1164      n += 2;
1165      c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
1166    }
1167
1168  putc (c, rl_outstream);
1169  fflush (rl_outstream);
1170  return n;
1171}
1172
1173int
1174rl_character_len (c, pos)
1175     register int c, pos;
1176{
1177  unsigned char uc;
1178
1179  uc = (unsigned char)c;
1180
1181  if (META_CHAR (uc))
1182    return ((_rl_output_meta_chars == 0) ? 4 : 1);
1183
1184  if (uc == '\t')
1185    {
1186#if defined (DISPLAY_TABS)
1187      return (((pos | 7) + 1) - pos);
1188#else
1189      return (2);
1190#endif /* !DISPLAY_TABS */
1191    }
1192
1193  if (CTRL_CHAR (c) || c == RUBOUT)
1194    return (2);
1195
1196  return ((isprint (uc)) ? 1 : 2);
1197}
1198
1199/* How to print things in the "echo-area".  The prompt is treated as a
1200   mini-modeline. */
1201
1202#if defined (USE_VARARGS)
1203int
1204#if defined (PREFER_STDARG)
1205rl_message (const char *format, ...)
1206#else
1207rl_message (va_alist)
1208     va_dcl
1209#endif
1210{
1211  va_list args;
1212#if defined (PREFER_VARARGS)
1213  char *format;
1214#endif
1215
1216#if defined (PREFER_STDARG)
1217  va_start (args, format);
1218#else
1219  va_start (args);
1220  format = va_arg (args, char *);
1221#endif
1222
1223  vsprintf (msg_buf, format, args);
1224  va_end (args);
1225
1226  rl_display_prompt = msg_buf;
1227  (*rl_redisplay_function) ();
1228  return 0;
1229}
1230#else /* !USE_VARARGS */
1231int
1232rl_message (format, arg1, arg2)
1233     char *format;
1234{
1235  sprintf (msg_buf, format, arg1, arg2);
1236  rl_display_prompt = msg_buf;
1237  (*rl_redisplay_function) ();
1238  return 0;
1239}
1240#endif /* !USE_VARARGS */
1241
1242/* How to clear things from the "echo-area". */
1243int
1244rl_clear_message ()
1245{
1246  rl_display_prompt = rl_prompt;
1247  (*rl_redisplay_function) ();
1248  return 0;
1249}
1250
1251int
1252rl_reset_line_state ()
1253{
1254  rl_on_new_line ();
1255
1256  rl_display_prompt = rl_prompt ? rl_prompt : "";
1257  forced_display = 1;
1258  return 0;
1259}
1260
1261static char *saved_local_prompt;
1262static char *saved_local_prefix;
1263static int saved_last_invisible;
1264static int saved_visible_length;
1265
1266void
1267rl_save_prompt ()
1268{
1269  saved_local_prompt = local_prompt;
1270  saved_local_prefix = local_prompt_prefix;
1271  saved_last_invisible = last_invisible;
1272  saved_visible_length = visible_length;
1273
1274  local_prompt = local_prompt_prefix = (char *)0;
1275  last_invisible = visible_length = 0;
1276}
1277
1278void
1279rl_restore_prompt ()
1280{
1281  if (local_prompt)
1282    free (local_prompt);
1283  if (local_prompt_prefix)
1284    free (local_prompt_prefix);
1285
1286  local_prompt = saved_local_prompt;
1287  local_prompt_prefix = saved_local_prefix;
1288  last_invisible = saved_last_invisible;
1289  visible_length = saved_visible_length;
1290}
1291
1292char *
1293_rl_make_prompt_for_search (pchar)
1294     int pchar;
1295{
1296  int len;
1297  char *pmt;
1298
1299  rl_save_prompt ();
1300
1301  if (saved_local_prompt == 0)
1302    {
1303      len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
1304      pmt = xmalloc (len + 2);
1305      if (len)
1306        strcpy (pmt, rl_prompt);
1307      pmt[len] = pchar;
1308      pmt[len+1] = '\0';
1309    }
1310  else
1311    {
1312      len = *saved_local_prompt ? strlen (saved_local_prompt) : 0;
1313      pmt = xmalloc (len + 2);
1314      if (len)
1315        strcpy (pmt, saved_local_prompt);
1316      pmt[len] = pchar;
1317      pmt[len+1] = '\0';
1318      local_prompt = savestring (pmt);
1319      last_invisible = saved_last_invisible;
1320      visible_length = saved_visible_length + 1;
1321    }
1322  return pmt;
1323}
1324
1325/* Quick redisplay hack when erasing characters at the end of the line. */
1326void
1327_rl_erase_at_end_of_line (l)
1328     int l;
1329{
1330  register int i;
1331
1332  _rl_backspace (l);
1333  for (i = 0; i < l; i++)
1334    putc (' ', rl_outstream);
1335  _rl_backspace (l);
1336  for (i = 0; i < l; i++)
1337    visible_line[--_rl_last_c_pos] = '\0';
1338  rl_display_fixed++;
1339}
1340
1341/* Clear to the end of the line.  COUNT is the minimum
1342   number of character spaces to clear, */
1343void
1344_rl_clear_to_eol (count)
1345     int count;
1346{
1347#if !defined (__GO32__)
1348  if (term_clreol)
1349    tputs (term_clreol, 1, _rl_output_character_function);
1350  else if (count)
1351#endif /* !__GO32__ */
1352    space_to_eol (count);
1353}
1354
1355/* Clear to the end of the line using spaces.  COUNT is the minimum
1356   number of character spaces to clear, */
1357static void
1358space_to_eol (count)
1359     int count;
1360{
1361  register int i;
1362
1363  for (i = 0; i < count; i++)
1364   putc (' ', rl_outstream);
1365
1366  _rl_last_c_pos += count;
1367}
1368
1369void
1370_rl_clear_screen ()
1371{
1372#if !defined (__GO32__)
1373  if (term_clrpag)
1374    tputs (term_clrpag, 1, _rl_output_character_function);
1375  else
1376#endif /* !__GO32__ */
1377    crlf ();
1378}
1379
1380/* Insert COUNT characters from STRING to the output stream. */
1381static void
1382insert_some_chars (string, count)
1383     char *string;
1384     int count;
1385{
1386#if defined (__GO32__)
1387  int row, col, width;
1388  char *row_start;
1389
1390  ScreenGetCursor (&row, &col);
1391  width = ScreenCols ();
1392  row_start = ScreenPrimary + (row * width);
1393
1394  memcpy (row_start + col + count, row_start + col, width - col - count);
1395
1396  /* Place the text on the screen. */
1397  _rl_output_some_chars (string, count);
1398#else /* !_GO32 */
1399
1400  /* If IC is defined, then we do not have to "enter" insert mode. */
1401  if (term_IC)
1402    {
1403      char *buffer;
1404      buffer = tgoto (term_IC, 0, count);
1405      tputs (buffer, 1, _rl_output_character_function);
1406      _rl_output_some_chars (string, count);
1407    }
1408  else
1409    {
1410      register int i;
1411
1412      /* If we have to turn on insert-mode, then do so. */
1413      if (term_im && *term_im)
1414        tputs (term_im, 1, _rl_output_character_function);
1415
1416      /* If there is a special command for inserting characters, then
1417         use that first to open up the space. */
1418      if (term_ic && *term_ic)
1419        {
1420          for (i = count; i--; )
1421            tputs (term_ic, 1, _rl_output_character_function);
1422        }
1423
1424      /* Print the text. */
1425      _rl_output_some_chars (string, count);
1426
1427      /* If there is a string to turn off insert mode, we had best use
1428         it now. */
1429      if (term_ei && *term_ei)
1430        tputs (term_ei, 1, _rl_output_character_function);
1431    }
1432#endif /* !__GO32__ */
1433}
1434
1435/* Delete COUNT characters from the display line. */
1436static void
1437delete_chars (count)
1438     int count;
1439{
1440#if defined (__GO32__)
1441  int row, col, width;
1442  char *row_start;
1443
1444  ScreenGetCursor (&row, &col);
1445  width = ScreenCols ();
1446  row_start = ScreenPrimary + (row * width);
1447
1448  memcpy (row_start + col, row_start + col + count, width - col - count);
1449  memset (row_start + width - count, 0, count * 2);
1450#else /* !_GO32 */
1451
1452  if (count > screenwidth)      /* XXX */
1453    return;
1454
1455  if (term_DC && *term_DC)
1456    {
1457      char *buffer;
1458      buffer = tgoto (term_DC, count, count);
1459      tputs (buffer, count, _rl_output_character_function);
1460    }
1461  else
1462    {
1463      if (term_dc && *term_dc)
1464        while (count--)
1465          tputs (term_dc, 1, _rl_output_character_function);
1466    }
1467#endif /* !__GO32__ */
1468}
1469
1470void
1471_rl_update_final ()
1472{
1473  int full_lines;
1474
1475  full_lines = 0;
1476  /* If the cursor is the only thing on an otherwise-blank last line,
1477     compensate so we don't print an extra CRLF. */
1478  if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
1479        visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
1480    {
1481      _rl_vis_botlin--;
1482      full_lines = 1;
1483    }
1484  _rl_move_vert (_rl_vis_botlin);
1485  /* If we've wrapped lines, remove the final xterm line-wrap flag. */
1486  if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == screenwidth))
1487    {
1488      char *last_line;
1489      last_line = &visible_line[inv_lbreaks[_rl_vis_botlin]];
1490      _rl_move_cursor_relative (screenwidth - 1, last_line);
1491      _rl_clear_to_eol (0);
1492      putc (last_line[screenwidth - 1], rl_outstream);
1493    }
1494  _rl_vis_botlin = 0;
1495  crlf ();
1496  fflush (rl_outstream);
1497  rl_display_fixed++;
1498}
1499
1500/* Move to the start of the current line. */
1501static void
1502cr ()
1503{
1504  if (term_cr)
1505    {
1506      tputs (term_cr, 1, _rl_output_character_function);
1507      _rl_last_c_pos = 0;
1508    }
1509}
1510
1511/* Redisplay the current line after a SIGWINCH is received. */
1512void
1513_rl_redisplay_after_sigwinch ()
1514{
1515  char *t, *oldp, *oldl, *oldlprefix;
1516
1517  /* Clear the current line and put the cursor at column 0.  Make sure
1518     the right thing happens if we have wrapped to a new screen line. */
1519  if (term_cr)
1520    {
1521      tputs (term_cr, 1, _rl_output_character_function);
1522      _rl_last_c_pos = 0;
1523      if (term_clreol)
1524        tputs (term_clreol, 1, _rl_output_character_function);
1525      else
1526        {
1527          space_to_eol (screenwidth);
1528          tputs (term_cr, 1, _rl_output_character_function);
1529        }
1530      if (_rl_last_v_pos > 0)
1531        _rl_move_vert (0);
1532    }
1533  else
1534    crlf ();
1535
1536  /* Redraw only the last line of a multi-line prompt. */
1537  t = strrchr (rl_display_prompt, '\n');
1538  if (t)
1539    {
1540      oldp = rl_display_prompt;
1541      oldl = local_prompt;
1542      oldlprefix = local_prompt_prefix;
1543      rl_display_prompt = ++t;
1544      local_prompt = local_prompt_prefix = (char *)NULL;
1545      rl_forced_update_display ();
1546      rl_display_prompt = oldp;
1547      local_prompt = oldl;
1548      local_prompt_prefix = oldlprefix;
1549    }
1550  else
1551    rl_forced_update_display ();
1552}
1553
1554void
1555_rl_clean_up_for_exit ()
1556{
1557  if (readline_echoing_p)
1558    {
1559      _rl_move_vert (_rl_vis_botlin);
1560      _rl_vis_botlin = 0;
1561      fflush (rl_outstream);
1562      rl_restart_output (1, 0);
1563    }
1564}
1565
1566void
1567_rl_erase_entire_line ()
1568{
1569  cr ();
1570  _rl_clear_to_eol (0);
1571  cr ();
1572  fflush (rl_outstream);
1573}
Note: See TracBrowser for help on using the repository browser.