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